#efi #run-time #kernel #linux #protocols #boot #path

no-std efiloader

A library implementing a EFI runtime that can boot Linux kernels and related executables

1 unstable release

0.0.1 Nov 7, 2023

#24 in #efi

24 downloads per month

GPL-2.0 license

145KB
4K SLoC

This crate implements a stripped down EFI runtime that can be used by bootloader implementations to provide the EFI context needed by OS loaders such as EFI stub Linux kernels, systemd-boot UKI images or even GRUB+shim.

The EFI runtime implements the following features/APIs:

  • a memory map and associated page and pool allocation routines, as well as an implementation of the GetMemoryMap() EFI boot service to deliver the final memory map to the OS;
  • a EFI protocol database that supports installing and uninstalling protocols, locating handle and protocol buffers and locating device paths;
  • a EFI configuration table database

The following EFI features are NOT supported:

  • the UEFI driver model
  • asynchronous events and notifications

The runtime services related to timekeeping, the EFI variable store and reset/poweroff are left to the caller to implement, as they cannot be implemented generically. The same applies to the Stall() boot services.

Example

fn run_efi_image(
    image: impl efiloader::FileLoader + Send + 'static,
    mapper: impl efiloader::MemoryMapper + 'static,
    random: impl efiloader::Random + 'static,
) {
    let ram = 0..0x100_0000;
    let memmap = efiloader::memmap::MemoryMap::new();
    memmap.declare_memory_region(&ram).unwrap();

    let efi = efiloader::init(
        None::<&dyn efiloader::SimpleConsole>,
        memmap,
        mapper,
        Some(random),
    )
    .expect("Failed to init EFI runtime");

    if let Some(mut li) = efi.load_image(&image) {
        let ret = li.start_image();
        println!("EFI app returned {ret:?}\n");
    }
}

Dependencies

~1MB
~12K SLoC