OVMF (Open Virtual Machine Firmware) is a project that aim is to enable UEFI
support in various virtual machines. According to
various projects have interest in supporting OVFM ie. VirtualBox, Xen, BHyVe
and of course QEMU. Why may someone be interested in OVMF ?
- IMHO the most important reason is that OVMF give the ability to develop UEFI
applications without using real hardware. This speeds up development cycle by giving the ability to start before hardware prototype arrives. There are also cases when the hardware is available only remotely, dealing with the remote setup is
usually annoying, so part of development can be performed locally.
- It also improves testing and debugging, because we have full control over
execution environment internals. Error injection and corner case analysis can
be ineffective in the real world. OVMF and qemu open debugging to new levels.
- It enables training and learning environment. Not everyone can obtain UEFI
PC and mess with it when there is a risk of destroying sth.
- Many other reasons like the ability to test/develop UEFI support for various OSes,
simplified debugging, lack of dependencies on legacy address space and
devices. This and other interesting reasons can be found in Laszlo Ersek whitepaper
What I want to show below is the procedure for setting up a development environment
for UEFI applications and show how to compile and deploy
application in that environment.
Let’s use an upstream version of QEMU:
git clone https://github.com/qemu/qemu.git
git submodule init
git submodule update
Prepare application image
Of course, size depends on your application requirements. Usually, 128MB is way
dd if=/dev/zero of=app.disk bs=1 count=1 seek=$(( (128 * 1024 * 1024) - 1))
sudo mkfs.vfat app.disk
First build UEFI firmware with shell:
git clone https://github.com/tianocore/edk2.git
nice OvmfPkg/build.sh -a X64 -n $(nproc)
cp Build/OvmfX64/DEBUG_GCC4?/FV/OVMF.fd ovmf.flash
Now we need some application that can be delivered over
app.disk to the virtual
machine. There are couple examples of UEFI applications in
edk2 source code,
but let’s start with classical
Hello World. Source code can be found in
MdeModulePkg/Application/HelloWorld. This module is built in
because of that, we can build it as follows:
build -a X64 -p MdeModulePkg/MdeModulePkg.dsc -t GCC49 -n$(nproc)
Let’s put it into
cp ../qemu/app.disk .
sudo mount app.disk mnt_app
sudo cp Build/MdeModule/DEBUG_GCC49/X64/HelloWorld.efi mnt_app
sudo umount mnt_app
When we develop UEFI application best way would be to run OVMF to UEFI Shell
for test purposes. This is not a default option. How to change the boot order so we
every time will lend in shell?
On booting screen hit
You should be on the main menu of UEFI setup:
Boot Maintenance Manager -> Boot Options -> Change Boot Order,
Change Boot Order and hit
<Enter>. Then using
+/- keys move
EFI Internal Shell to the top.
Do not forget to save the configuration with
To boot OVMF I’m using Laszlo’s slightly modified script which can be found
After booting to UEFI Shell we should look something like this:
FS0: in mapping table list – this is our
The result should look like this:
NOTE: If your result is different then make sure to check last lines of
app.ovmf.log it can give you some hints.
Hopefully at least part of above article was useful somehow. There are many
ways to extend this sample presentation. For example, application delivery can be
achieved by network transfer. If you have any question or need UEFI support
please do not bother to ping me in comments or using any other medium.