├── README.md └── main.c /README.md: -------------------------------------------------------------------------------- 1 | # minimal-efi 2 | A bare-bones minimal executable application for efi on the x64 platform 3 | - 0 external dependencies 4 | - 1 source file 5 | - 2 compile commands 6 | - 42 SLOC 7 | - 720 bytes binary 8 | 9 | ## Build tools 10 | The only build tools required are `clang` and `lld`. This project does not depend on any external headers, libraries, or link files. 11 | 12 | On arch linux this can be easily installed with the command 13 | `pacman -S clang lld` 14 | 15 | ## Building 16 | Assuming you are in the same directory as `main.c`, you simply need to run these 2 commands: 17 | 18 | 1. `clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -c main.c -o main.o` 19 | 2. `lld-link -filealign:16 -subsystem:efi_application -nodefaultlib -dll -entry:efi_main main.o -out:BOOTX64.EFI` 20 | 21 | ## Testing 22 | To test, use a GPT partitioned drive, and on a partition formated as FAT32 (FAT16 and FAT12 are acceptable as well), create a directory called `EFI` in the partition's root directory, create a directory called `BOOT` inside the `EFI` directory, and finally, place your `BOOTX64.EFI` file inside the `BOOT` directory. The final directory structure should be `/EFI/BOOT/BOOTX64.EFI`. 23 | 24 | Now you can simply select that partition on your motherboard's boot selector/menu and you will be able to boot to it. 25 | 26 | ## Acknowledgments 27 | Code mostly derived from: 28 | - https://github.com/yoppeh/efi-clang 29 | - https://kazlauskas.me/entries/x64-uefi-os-1.html 30 | - https://www.tianocore.org 31 | 32 | Further explanation can be found from these sources: 33 | - https://www.rodsbooks.com/efi-programming/hello.html 34 | - https://wiki.osdev.org/UEFI_Bare_Bones 35 | - https://www.happyassassin.net/2014/01/25/uefi-boot-how-does-that-actually-work-then/ 36 | - https://dvdhrm.github.io/2019/01/31/goodbye-gnuefi/ 37 | - https://uefi.org/specifications 38 | 39 | ## Extra 40 | One-liner with cleanup: 41 | `clang -target x86_64-pc-win32-coff -fno-stack-protector -fshort-wchar -mno-red-zone -c main.c -o main.o && lld-link -filealign:16 -subsystem:efi_application -nodefaultlib -dll -entry:efi_main main.o -out:BOOTX64.EFI && rm main.o BOOTX64.lib` 42 | 43 | ![scrot](https://user-images.githubusercontent.com/39736205/61829719-7c19a300-ae37-11e9-8571-86df407a81b3.png) 44 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct EfiTableHeader { 4 | uint64_t signature; 5 | uint32_t revision; 6 | uint32_t headerSize; 7 | uint32_t crc32; 8 | uint32_t reserved; 9 | } EfiTableHeader; 10 | 11 | struct EfiSimpleTextOutputProtocol; 12 | typedef uint64_t (*EfiTextString)(struct EfiSimpleTextOutputProtocol* this, int16_t* string); 13 | typedef struct EfiSimpleTextOutputProtocol { 14 | uint64_t reset; 15 | EfiTextString output_string; 16 | uint64_t test_string; 17 | uint64_t query_mode; 18 | uint64_t set_mode; 19 | uint64_t set_attribute; 20 | uint64_t clear_screen; 21 | uint64_t set_cursor_position; 22 | uint64_t enable_cursor; 23 | uint64_t mode; 24 | } EfiSimpleTextOutputProtocol; 25 | 26 | typedef struct EfiSystemTable { 27 | EfiTableHeader hdr; 28 | int16_t* firmwareVendor; 29 | uint32_t firmwareRevision; 30 | void* consoleInHandle; 31 | uint64_t conIn; 32 | void* consoleOutHandle; 33 | EfiSimpleTextOutputProtocol* conOut; 34 | void* standardErrorHandle; 35 | uint64_t stdErr; 36 | uint64_t runtimeServices; 37 | uint64_t bootServices; 38 | uint64_t numberOfTableEntries; 39 | uint64_t configurationTable; 40 | } EfiSystemTable; 41 | 42 | int efi_main(void *imageHandle, EfiSystemTable* systemTable) { 43 | systemTable->conOut->output_string(systemTable->conOut, (int16_t *)L"Hello, World!"); 44 | for(;;); 45 | return 0; 46 | } 47 | --------------------------------------------------------------------------------