Using UEFI in a QEMU/KVM VM
Installing 'UEFI for QEMU' nightly builds
UEFI for x86 QEMU/KVM VMs is called OVMF (Open Virtual Machine Firmware). It comes from EDK2 (EFI Development Kit), which is the UEFI reference implementation.
Unfortunately there are licensing issues which prevent us getting EDK2/OVMF into Fedora (see #EDK2 Licensing Issues for more info). So we have to grab external packages.
Gerd Hoffman, Red Hatter and QEMU developer, has a yum repo on his personal site that provides nightly builds of a whole bunch of QEMU/KVM firmware, including EDK2/OVMF.
Here's how to pull down the nightly builds for x86:
sudo wget http://www.kraxel.org/repos/firmware.repo -O /etc/yum.repos.d/firmware.repo sudo yum install edk2.git-ovmf-x64
Install a Fedora VM with UEFI
First we need to install a guest using UEFI instead of traditional bios. Anaconda will put all the right bits in place for us.
Here's an example F20 install:
sudo virt-install --name f20-uefi \ --ram 2048 --disk size=20 \ --boot loader_type=pflash,loader_ro=yes,loader=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd,nvram_template=/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd \ --location https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Fedora/x86_64/os/
Booting the VM with OVMF
If Fedora doesn't boot, try the following steps. First you'll need to be at the EFI Internal Shell. If you see a 'Shell> ' prompt you are in the shell. If OVMF doesn't drop you into the EFI Internal Shell automatically, do the following:
- Wait until the TianoCore splash screen pops up, hit ESC
- Select 'Boot Manager'
- Select 'EFI Internal Shell'
Once in the EFI Internal Shell, here are the commands you need to boot Fedora (assuming your guest only has a CDROM attached):
fs0: \EFI\fedora\shim.efi
The above commands just get Fedora going, we haven't set up secure boot yet.
Testing Secureboot in a VM
These steps describe how to test Fedora Secureboot support inside a KVM VM. The audience here is QA folks that want to test secureboot, and any other curious parties. This requires configuring the VM to use UEFI, so it builds upon the previous UEFI steps.
Grab LockDown_ms.efi
Since OVMF doesn't ship with any SecureBoot keys installed, we need to install some to mimic what an MS certified UEFI machine will ship with. But here's a crappy thing about OVMF and KVM: right now there's no way to persist UEFI config across VM start/stop, although we'll come close with the script we'll create below.
So if we want to test SecureBoot, we need to install the MS keys and enable secureboot on every VM restart.
Luckily there's a tool that does all this for us, called LockDown_ms.efi. This is derived from code in efitools.git.
Inside the guest, do:
sudo wget http://fedorapeople.org/~crobinso/secureboot/LockDown_ms.efi -O /boot/efi/EFI/fedora/LockDown_ms.efi
Automate SecureBoot startup
As mentioned above, we have to install the MS keys and enable secureboot on every VM restart. Luckily, OVMF by default runs a script at startup, called startup.nsh. We'll use this to automate startup. All we really need in the script are the following commands:
fs0: \EFI\fedora\LockDown_ms.efi \EFI\fedora\shim.efi
But, life is complicated by the fact that if you are rebooting the VM where LockDown_ms.efi has been loaded, it can't be loaded a second time (without powering off the VM). If you try, you'll get a "Error reported: Security Violation" message when loading LockDown_ms.efi and the script will stop. So, the script needs to check if SecureBoot is already on before trying to load LockDown_ms.efi.
Inside the guest, as root edit /boot/efi/startup.nsh and add the following text:
fs0: # If we don't have the secure boot dmp file, assume this is the first # time this script has been run and secure boot is off. set __lockdown 0 if not exist SecureBoot.dmp then set __lockdown 1 # Otherwise we check the current state of the 'SecureBoot' variable # to see if LockDown_ms.efi has already been loaded. else dmpstore SecureBoot -s SecureBoot.tmp comp SecureBoot.dmp SecureBoot.tmp if not %lasterror% == 0 then set __lockdown 1 endif rm SecureBoot.tmp endif if %__lockdown% == 1 then \EFI\fedora\LockDown_ms.efi dmpstore SecureBoot -s SecureBoot.dmp endif \EFI\fedora\shim.efi
Verify SecureBoot
At this point reboot the guest. After logging in, you should see 'Secure boot enabled' in dmesg. Success!
Testing F18 DVD Secure Boot in a VM
Since we can't easily alter the DVD to add LockDown_ms.efi, we get it into the VM using a mini disk image:
wget http://fedorapeople.org/~crobinso/secureboot/lockdown.qcow2 sudo virsh attach-disk $VMNAME --target hdb --source lockdown.qcow2 --subdriver qcow2 --config
Then do
- Launch the VM, drop to the EFI shell
- If your guest only has a CDROM attached, lockdown.qcow2 should be fs0
Shell> fs0:
fs0:\> LockDown_ms.efi
fs0:\> exit
- Back in the config screen, Select 'Boot Manager'
- Select 'EFI DVD/CDROM'
- Once anaconda starts, grab shell, log in, verify secure boot is enabled
Notes
EDK2 Licensing Issues
EDK2 contains a FAT filesystem driver that is licensed under terms that make it not acceptable for packaging in Fedora. Particularly that there's a usage restricition only allowing the code to be used in a UEFI implementation. More details here at Edk2-fat-driver
The driver is critical functionality so removing it is not an option.
Using UEFI with AArch64 VMs
Fedora's AArch64 releases will only run on UEFI, so require UEFI inside the VM. However the steps are slightly different. See this page for complete documentation: https://fedoraproject.org/wiki/Architectures/AArch64/Install_with_QEMU