systemd-boot does not have built in entries for powering off/reseting from the menu. This provides two simple UEFI programs for performing those actions. Original code from arch-wiki, but I made the makefile made more robust and packaged it for nix.
Cross compilation utilizes nixpkgs. Just change the cross system with Nix and the efi image will cross compile.
Tested on the following using qemu:
x86-64
x86_64-unknown-linux-gnu
$ cp $OVMF_DIR/OVMF.fd ./qemu/ovmf.fd
$ make/nix build
$ cp XXX.efi root/XXX.efi
$ qemu-system-x86_64 \
-bios qemu/ovmf.fd \
-drive format=raw,file=fat:rw:root \
-net none \
-nographic
aarch64
Help from: http://cdn.kernel.org/pub/linux/kernel/people/will/docs/qemu/qemu-arm64-howto.html
aarch64-unknown-linux-gnu
$ truncate -s 64m efi-aarch.img
$ truncate -s 64m varstore.img
$ dd if=$OVMF_DIR/QEMU_EFI.fd of=efi-aarch.img conv=notrunc
$ make/nix build
$ cp XXX.efi root/XXX.efi
$ qemu-system-aarch64 -M virt -cpu cortex-a57 \
-drive file=qemu/efi-aarch.img,if=pflash,format=raw,readonly=true \
-drive file=qemu/varstore.img,if=pflash,format=raw \
-net none -nographic \
-drive format=raw,file=fat:rw:root
arm
armv7l-unknown-linux-gnueabihf
Same as above.
$ truncate -s 64m efi-aarch.img
$ truncate -s 64m varstore.img
$ dd if=$OVMF_DIR/QEMU_EFI.fd of=efi-arm.img conv=notrunc
$ make/nix build
$ cp XXX.efi root/XXX.efi
$ qemu-system-arm -M virt -cpu cortex-a7 \
-drive file=qemu/efi-arm.img,if=pflash,format=raw,readonly=true \
-drive file=qemu/varstore.img,if=pflash,format=raw \
-net none -nographic \
-drive format=raw,file=fat:rw:root
See boot tests for inspiration:
https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/boot.nix
- How to develop UEFI applications
- Calling conventions
- x86-64 uses microsoft ABI for interaction with firmware
- All else uses c decltype
EFIAPI
is just a preprocessor for choosing when to use a different abi- do not use on
efi_main
as that is always a cdecltype from gnu-efi - Not entirely sure why so many examples have it set (bad makefiles is my guess)
- Set by
CPPFLAGS += -DGNU_EFI_USE_MS_ABI -maccumulate-outgoing-args
on x86-64 arch as ms_abi does not work without accumulate-outgoing-args
- do not use on
- Non-root qemu: https://wiki.osdev.org/UEFI#Linux.2C_root_not_required
- Expected to be position independent (no guarantee that it will be loaded at fixed address)
- Binary format is PE32+
- Provide
-s -S
to qemu to start gdb server - Call
info files
,file
,target remote :1234
, thenadd-symbol-file xxx.efi.debug 0xTEXT_LOCATION -s .data 0xDATA_LOCATION
- To get data location use
status = uefi_call_wrapper(systab->BootServices->HandleProtocol, 3, image, &LoadedImageProtocol, (void **)&loaded_image); if (EFI_ERROR(status)) { Print(L"handleprotocol: %r\n", status); } Print(L"Image base: 0x%lx\n", loaded_image->ImageBase);
- Add the offsets to the image base location