Re: Runtime configuration methods for OVMF/AAVMF?

Laszlo Ersek

On 03/09/21 19:39, Aaron Young wrote:
Hello. What methods currently exist to configure OVMF/AAVMF dynamically at runtime?

For example, modify the preferred Language, set boot menu timeout or enable SecureBoot.

To my knowledge, the only way to configure OVMF/AAVMF is via the boot manager or perhaps via qemu args (i.e. fw_cfg, etc.).

Are there any other out-of-band methods or utilities out there that can be used to configure runtime settings (stored in the VARS file)?

Reason - Some users may wish to configure OVMF/AAVMF prior to first boot (i.e. can't use boot manager) and modification of qemu args is not always an easy (or even possible) option.

Thanks for any help/info/comments,
Sorry, can't give you anything.

The general approach is:

- UEFI variables are used for configuring firmware aspects, usually the
same as on physical platforms (meaning volatile/non-volatile, boot time
only access / runtime access as well) -- consult any individual edk2
UEFI variables for details

- for a number of behaviors / configuration knobs, dynamic PCDs are
used. Dynamic PCDs are boot time only. They are set from various
sources; sometimes they are exposed on the Setup TUI, sometimes they
come from UEFI variables (or vice versa).

- in a number of cases, these variables and these PCDs are set by OVMF
Platform Code (overriding defautls or previously set values) in
accordance with QEMU platform specifics -- for example (frequently),
fw_cfg. The most common "host integration" interface is indeed fw_cfg.
(As the name says: "firmware configuration".)

One telling example is "efibootmgr". It lets you tweak some stuff (boot
order, boot options, Timeout variable) on physical platforms at least.
However, when using OVMF, those settings are overridden dynamically on
every boot, when using the "bootindex" device properties, and/or the
"-boot menu=on" / "-boot splash-time=N" options.

If you name specifics, I can perhaps respond with more details.

Modifying the varstore file from the host side is not supported. The
wire format of that file is the functional composition of three OVMF /
edk2 drivers, namely the OVMF flash driver, the edk2 Fault Tolerant
Write (FTW) driver, and the edk2 Variable driver. Especially due to the
FTW abstraction, the varstore is a kind of "journaled storage", which is
supposed to protect against (and recover from) a power failure during a
flash write. In order to mess with the varstore from the host side,
you'd have to maintain a userspace utility in parallel with the edk2
drivers, and with the OVMF platform settings (flash size, internal
layout), to implement the same feature set (e.g., recognizing and
recovering from a power outage during a flash write).

"modification of qemu args is not always an easy (or even possible)
option" -- that's a feature gap in the virtualization management
application that drives QEMU. fw_cfg is the preferred configuration
method, and using QEMU's generic "-fw_cfg" switch, some firmware
tuneables don't even need a dedicated QEMU option. The important options
are then exposed through the libvirt domain XML format, for example. (A
case can always be made for exposing more.)

Regarding secure boot enablement: the
<> project provides a
utility that non-interactively enrolls some certificates in the variable
store (driving the guest's UEFI shell via the serial console), and
enables SB. The resultant variable store file can be used as a varstore
*template* for other (newly defined) domains.

An OVMF package on a Linux distro can offer multiple varstore templates.
To deal with these varstore templates, it is recommended that the OVMF
package also install a number of "firmware use case descriptors"
(firmware metadata files), which follow the JSON format defined in
QEMU's "docs/interop/firmware.json". A management application can then
parse the descriptors, and pick the best one for a particular use case
(for example, certificates enrolled vs. not enrolled). The descriptor
then exposes the firmware binary and the matching varstore template that
should be used for domain definition.

Libvirt has support for this, although more work is necessary (for
example it currently cannot filter for the "enrolled-keys" feature flag).


Join to automatically receive all group messages.