UEFI applications are simple COFF (Windows) executables, with the special
EFI_Application subsystem, and some limitations (such as no dynamic linking).
Rust supports building UEFI applications
though the x86_64-unknown-uefi target.
The following steps allow you to build a simple UEFI app.
-
Create a new
#![no_std]binary, add#![no_main]to use a custom entry point, and make sure you have an entry point function which matches the one below:#![feature(abi_efiapi)] use uefi::prelude::*; #[entry] fn efi_main(handle: Handle, system_table: SystemTable<Boot>) -> Status;
You will also want to add a dependency to the
rlibccrate, to avoid linking errors. -
Build using a
nightlyversion of the compiler and activate thebuild-stdCargo feature:cargo build -Z build-std --target x86_64-unknown-uefi. -
The
targetdirectory will contain ax86_64-unknown-uefisubdirectory, where you will find theuefi_app.efifile - a normal UEFI executable. -
To run this on a real computer:
- Find a USB drive which is FAT12 / FAT16 / FAT32 formatted
- Copy the file to the USB drive, to
/EFI/Boot/Bootx64.efi - In the UEFI BIOS, choose "Boot from USB" or similar
-
To run this in QEMU:
- You will need a recent version of QEMU as well as OVMF to provide UEFI support
- Check the
build.pyscript for an idea of what arguments to pass to QEMU
You can use the uefi-test-runner directory as sample code for building a simple UEFI app.