When a computer boots up, what does it do?
It thinks for a long time about the meaning of it all. This takes a very long time, but since it is very fast, we never notice it.
After it is done thinking and yet again doesn’t arrive at a satisfiable proposition (remember, from its perspective, it is happening the first time), it busies itself, and runs “UEFI” code present on the firmware.
UEFI is a standard, but the implementations are many and proprietary for the manufacturer of the motherboard. There is a reference implementation (which is also open source) called TianoCore EDK 2 (which can be used by qemu).
UEFI looks (or, to be more precise, the UEFI standard asks the implementation to go and look) for a ESP - EFI system partition. This is a small FAT partition that contains the bootloaders for one or more OSes. Depending on the user’s choice, it loads one of them.
The user’s choice and other settings can be persisted into NVRAM (non-volatile
storage). How these “UEFI vars” are saved is up to the implementation (e.g. qemu
can save them to a JSON file). The OS can also access these, e.g. using the
efivars
utility (which delegates to /sys/firmware/efi/efivars/
).
If you find yourself in the UEFI shell, things are not going well. Calm down, you haven’t been eaten by a grue (yet).
help
will give you help, but it will scroll out and there isn’t a scroll
bar.
Calm down, help -b
will paginate.
bcfg boot dump
will print something, which might or might not help.
You head out of the room by typing exit
. You find yourself in a new, more
welcoming cavern, lined with menu items and other niceities. Maybe the princess
is in this castle.
Using UEFI with QEMU requires two things:
QEMU comes with both (at least the homebrew version)
$(brew --prefix qemu)/share/qemu/edk2-aarch64-code.fd
$(brew --prefix qemu)/share/qemu/edk2-arm-vars.fd
Both of these can be offered to the QEMU machine as a pflash drives by tacking on something like the following to the QEMU invocation:
-drive file=edk2-aarch64-code.fd,if=pflash,format=raw,readonly=on \
-drive file=edk2-arm-vars.fd,if=pflash,format=raw \
There is also an option to store the UEFI variables in a JSON file instead of
the provided pflash file by using -device
uefi-vars-sysbus,jsonfile=uefi.json
. It works, but I was unable to persist the
UEFI boot delay when using this method (they work fine with the pflash
vars). The JSON variable support is very new, so likely it is still work in
progress, and future reader, don’t take my word for it, maybe it works now.