See end of post for an important update
UEFI firmware has a concept of persistent variables. They are used to control the boot order amongst other things. They are stored in non-volatile RAM on the system board, or for virtual machines in a host file.
When a UEFI machine is running you can edit these variables using various tools, such as Peter Jones’s efivar library, or the efibootmgr program.
These programs don’t actually edit the varstore directly. They access the kernel /sys/firmware/efi
interface, but even the kernel doesn’t edit the varstore. It just redirects to the UEFI runtime “Variable Services”, so what is really running is UEFI code (possibly proprietary, but more usually from the open source TianoCore project).
So how can you edit varstores offline? The NVRAM file format is peculiar to say the least, and the only real specification is the code that writes it from Tianocore. So somehow you must reuse that code. To make it more complicated, the varstore NVRAM format is tied to the specific firmware that uses it, so varstores used on aarch64 aren’t compatible with those on x86-64, nor are SecureBoot varstores compatible with normal ones.
virt-efivars is an attempt to do that. It’s rather “meta”. You write a small editor program (an example is included), and virt-efivars compiles it into a tiny appliance. You then boot the appliance using qemu + UEFI firmware + varstore combination, the editor program runs and edits the varstore, using the UEFI code.
It works .. at least on aarch64 which is the only convenient machine I have that has virtualized UEFI.
Git repo: http://git.annexia.org/?p=virt-efivars.git;a=summary
Update:
After studying this problem some more, Laszlo Ersek came up with a different and better plan:
- Boot qemu with only the OVMF code & varstore attached. No OS or appliance.
- This should drop you into a UEFI shell which is accessible over qemu’s serial port.
- Send appropriate
setvar
commands to update the variables. Usingexpect
this should be automatable.