Firststeps in bare-metal programming using UEFI
9 points by tffr
9 points by tffr
you’ll need the gnu-efi library and include files [...] There are more sophisticated EFI libraries, but this is an educational article, so simplest is best.
gnu-efi is not the simplest way to generate EFI executables, at least for x86-64 targets, and it's not the best by any stretch.
gnu-efi works by linking to an ELF, and then use (GNU) "objcopy" to convert to PE+ (the EFI executable format). This doesn't work particularly well; the relocations in particular don't get converted. As a result a stub is needed to perform the ELF relocations at run time. There are various other complications; there's a much longer (more complete) explanation in the linked post.
GNU ld, on the other hand - part of the same binutils package as objcopy - can output to PE+ while converting the relocations as well. All you need is appropriate EFI headers (which you can get from sources other than gnu-efi), compile your code, and link it directly to PE+ (or PE32+ as the post refers to it). You can also link to ELF and then re-link to PE+ (having an ELF file can be useful for debugging), effectively using the linker as a better version of objcopy.
For example, this hello-world Makefile has a commented-out target to use exactly this method (the primary method in that Makefile uses "elf2efi", a utility available from various sources including the linked repo, which works similar to objcopy but properly supports relocations etc. The main benefit of using elf2efi is that it doesn't require a binutils that has been built with support for PE+. If you're using gnu efi you need that support regardless).
This technique should also work in principle for other-than x86-64, but I've no experience with that.
For Rust, uefi-rs makes this pretty pleasant: cargo build --target x86_64-unknown-uefi and no gnu-efi or objcopy step.
If you're looking for a GUI framework that works on UEFI: Slint (which I work on) can do it. We have a demo here https://github.com/slint-ui/slint/tree/master/examples/uefi-demo built on top of uefi-rs