OVMF: UEFI Firmware for QEMU/KVM via EDK II
OVMF (Open Virtual Machine Firmware) is an EDK II (EDK2) project that provides UEFI firmware for virtual machines. It includes reference firmware images for QEMU and KVM, supports the UEFI Shell, and can boot Linux in UEFI mode.
In the EDK II source tree, OVMF lives under OvmfPkg/ and is commonly built to produce
a firmware image such as OVMF.fd (x86_64) or QEMU_EFI.fd (AArch64).
1. Building OVMF
EDK2 build outputs are typically placed under:
Build/*/*/FV/
For OVMF, you will often see a firmware image such as OVMF.fd (or OVMF.FD)
in the FV directory. This is the UEFI firmware image used by QEMU.
1.1 Build OVMF for x86_64
Example build command:
OvmfPkg/build.sh -a X64 qemu
After a successful build, locate the firmware image under the corresponding FV directory, for example:
Build/OvmfX64/DEBUG_*/FV/OVMF.fd
(Exact directory name may vary depending on toolchain and build type.)
1.2 Build UEFI firmware for QEMU on AArch64 (ArmVirtualizationQemu)
For ARM/AArch64, a common flow is building the ArmVirtualizationQemu package. One sample command mentioned:
/uefi-tools/uefi-build.sh -b DEBUG -b RELEASE qemu64
Firmware output example:
Build/ArmVirtualizationQemu-AARCH64/{DEBUG,RELEASE}_GCC48/FV/QEMU_EFI.fd
2. Running OVMF in QEMU
QEMU can load UEFI firmware in multiple ways depending on platform and workflow:
- -pflash: attach firmware as persistent flash devices (typical for ARM/AArch64)
- -bios: load firmware as the BIOS/firmware image (commonly used on x86)
- -L: set the directory for firmware/BIOS lookup
A representative AArch64 example using two flash devices:
$ qemu-system-aarch64 \
-m 1024 \
-cpu cortex-a57 \
-M virt \
-pflash flash0.img \
-pflash flash1.img \
-serial stdio
In this setup, flash0.img usually contains the firmware code region (often read-only),
and flash1.img is typically used for variable storage (UEFI NVRAM).
Exact image preparation depends on your distribution/scripts.
3. OVMF Boot Flow Overview (SEC → PEI → DXE → BDS → ...)
UEFI firmware follows a well-defined sequence of phases. Understanding these phases helps when debugging boot issues, missing drivers, or unexpected behavior in QEMU/OVMF.
3.1 SEC (Security Phase)
The first code executed after reset. At this point:
- System RAM is not yet available
- Firmware often uses Cache-as-RAM (CAR) for temporary storage
- CPU is initialized for protected execution (UEFI does not require legacy x86 real mode)
- Mostly low-level assembly / platform bring-up logic
3.2 PEI (Pre-EFI Initialization)
PEI is responsible for fundamental platform initialization:
- Memory discovery and initialization
- CPU and chipset/platform early init
- Locating firmware volumes and boot paths
- Launching DXE IPL (DXE Initial Program Loader) to transition into DXE
3.3 DXE (Driver Execution Environment)
DXE is the core phase where most UEFI services and drivers come online:
- Loads and dispatches DXE drivers
- Installs Boot Services, Runtime Services, and DXE services
- Initializes UEFI platform devices and protocols
- Prepares the environment for OS boot (drivers, storage, networking, console, etc.)
Many services are only available before ExitBootServices() is called by the OS loader.
3.4 BDS (Boot Device Selection)
BDS determines how the system boots:
- Enumerates boot options
- Loads additional drivers as needed
- Selects and launches the OS bootloader based on boot order
- Transitions toward OS handoff once boot target is selected
3.5 TSL (Transient System Load)
This phase is where the OS bootloader or UEFI Shell runs (e.g., GRUB in UEFI mode, or the UEFI Shell for debugging and manual boot).
3.6 RT (Runtime Phase)
After the OS calls ExitBootServices():
- Boot Services are no longer available
- Only EFI Runtime Services and the EFI System Table remain accessible
- Runtime services support operations like time services, variables (depending on platform), and reset
3.7 AL (After Life)
Firmware re-enters control via:
ResetSystem()runtime call- Power state transitions (e.g., ACPI sleep states)
4. UEFI and ACPI
Modern boot on many platforms is effectively UEFI + ACPI. A key firmware responsibility is to provide ACPI tables to the OS kernel. The OS uses these tables for:
- Power management
- Device enumeration and configuration
- Platform topology and interrupt routing
ACPI details deserve a dedicated deep-dive, especially for ARM where the ecosystem has historically been more DTB-focused. UEFI+ACPI is increasingly important for server-class ARM platforms and virtualization scenarios.
Notes and Known Issues
OVMF/UEFI on QEMU is powerful but not always frictionless—particularly on ARM/AArch64. There may still be platform gaps, firmware-driver limitations, or device-model differences. That said, QEMU + EDK2 continues to evolve, and the path from virtual UEFI to real hardware enablement is becoming increasingly straightforward.
References
- OVMF project page (TianoCore)
- QEMU ARM UEFI notes
- OVMF Boot Overview (TianoCore wiki)
- ACPI/UEFI overview article