2014-08-13 11:25:52 +02:00
|
|
|
Running the OVMF image in qemu
|
|
|
|
==============================
|
|
|
|
|
|
|
|
There are two flavors of the OVMF efi images: the 64 bit and 32 bit one.
|
|
|
|
For the 64 bit image, use the following command:
|
|
|
|
|
|
|
|
qemu-system-x86_64 -bios /usr/share/qemu/ovmf-x86_64.bin
|
|
|
|
|
|
|
|
For 32 bit:
|
|
|
|
|
|
|
|
qemu-system-i386 -bios /usr/share/qemu/ovmf-ia32.bin
|
|
|
|
|
|
|
|
The rom will boot up to an EFI shell. If you add standard things like a USB
|
|
|
|
drive, you can also run efi executables.
|
|
|
|
|
|
|
|
To enrol the platform and key exchange keys, exit the efi shell, select
|
|
|
|
'Device Manager' then 'Secure Boot Configuration' and change the secure boot
|
|
|
|
mode from "Standard Mode" to "Custom Mode". This will cause an extra "Custom
|
|
|
|
Secure Boot Options" menu to appear from which you can enrol the Platform and
|
|
|
|
Key Exchange keys (these need to be present on external media, like a USB
|
|
|
|
key).
|
|
|
|
|
|
|
|
Note that enroling the KEK will require you to specify a GUID. The GUID is
|
|
|
|
used only to identify the keys later (it's essentially the globally unique
|
|
|
|
label for the key). If you only enrol one KEK, you can ignore this and it
|
|
|
|
will end up with a GUID of all zeros.
|
|
|
|
|
2014-09-17 06:25:44 +02:00
|
|
|
Flash Mode
|
|
|
|
----------
|
2014-08-13 11:25:52 +02:00
|
|
|
|
|
|
|
For version >= r14840, OVMF supports the qemu flash mode. The non-volatile
|
|
|
|
variables were originally stored in NvVars, a file in the ESP. With the flash
|
|
|
|
mode support, all changes will be saved in the firmware file directly.
|
|
|
|
|
|
|
|
Here is the example to use OVMF in the flash mode:
|
|
|
|
|
|
|
|
qemu-system-x86_64 -pflash ovmf-x86_64.bin
|
|
|
|
|
|
|
|
Please make sure the firmware is writable before using the flash mode, or all
|
|
|
|
your changes won't be saved.
|
|
|
|
|
2014-09-17 06:25:44 +02:00
|
|
|
Starting from r15670, two extra firmware files are provided for the flash mode:
|
|
|
|
ovmf-*-code.bin and ovmf-*-vars.bin, and all non-volatile variables will be
|
|
|
|
stored in ovmf-*-vars.bin. Example:
|
|
|
|
|
2015-07-08 10:49:39 +02:00
|
|
|
qemu-system-x86_64 -drive if=pflash,format=raw,readonly,file=ovmf-x86_64-code.bin \
|
|
|
|
-drive if=pflash,format=raw,file=ovmf-x86_64-vars.bin
|
2014-09-17 06:25:44 +02:00
|
|
|
|
|
|
|
It would be easier to manage the NV variables with the separated vars firmware.
|
|
|
|
|
2014-08-13 11:25:52 +02:00
|
|
|
Image with preloaded keys
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
Besides the generic OVMF images, there are images preloaded with different
|
|
|
|
vendor keys.
|
|
|
|
|
|
|
|
ovmf-x86_64-ms.bin
|
|
|
|
- PK: Microsoft Corporation KEK CA 2011
|
|
|
|
- KEK: Microsoft Corporation KEK CA 2011
|
|
|
|
- db: Microsoft Corporation UEFI CA 2011
|
|
|
|
|
|
|
|
ovmf-x86_64-opensuse.bin
|
|
|
|
- PK: openSUSE Secure Boot CA
|
|
|
|
- KEK: openSUSE Secure Boot CA
|
|
|
|
- db: openSUSE Secure Boot Signkey
|
|
|
|
|
|
|
|
ovmf-x86_64-suse.bin
|
|
|
|
- PK: SUSE Linux Enterprise Secure Boot CA
|
|
|
|
- KEK: SUSE Linux Enterprise Secure Boot CA
|
|
|
|
- db: SUSE Linux Enterprise Secure Boot Signkey
|
|
|
|
|
|
|
|
Note that the preloaded key images are all 64 bit because openSUSE/SLE and
|
|
|
|
Windows only support Secure Boot in 64 bit mode.
|
|
|
|
|
|
|
|
Creating Platform and Key Exchange keys
|
|
|
|
=======================================
|
|
|
|
|
|
|
|
A note about terminology. In UEFI terms, "key" means certificate (not the
|
|
|
|
openssl key). UEFI keys are required to be based on RSA 2048 bit keys.
|
|
|
|
|
|
|
|
The Platform key and Key Exchange Keys should be the equivalent of CA root
|
|
|
|
certificates (i.e. a self signed certificate). Note that in current tianocore
|
|
|
|
OVMF, the input certificates, if taken from external media, *must* be in a
|
|
|
|
file with a .cer extension and in DER format.
|
|
|
|
|
|
|
|
The platform key is the key which controls updates to the Key Exchange Key
|
|
|
|
database. The Key Exchange Key controls updates to the signature databases.
|
|
|
|
Note that if the Key Exchange Key is an X509 key, any key which has the KEK as
|
|
|
|
its root signature can also be used to validate an efi binary without need for
|
|
|
|
any entries in the signatures database.
|
|
|
|
|
|
|
|
|
|
|
|
Create Platform Key (PK)
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
openssl req -new -x509 -newkey rsa:2048 -keyout PK.key -out PK.crt -days <length>
|
|
|
|
|
|
|
|
Note that the Key is PK.crt (PK.key is the private key you use to sign other
|
|
|
|
certificates)
|
|
|
|
|
|
|
|
Now convert to DER format
|
|
|
|
|
|
|
|
openssl x509 -in PK.crt -out PK.cer -outform DER
|
|
|
|
|
|
|
|
The file PK.cer can be placed on a USB key for enrolling as the platform key.
|
|
|
|
|
|
|
|
Create Key Exchange Key (KEK)
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
This is done exactly as the Platform key above, except call the file KEK.cer
|
|
|
|
instead.
|
|
|
|
|
|
|
|
Note, for expermentation purposes, there's no reason the KEK and the PK can't
|
|
|
|
be the same certificate.
|
|
|
|
|
|
|
|
Creating derived keys from the KEK
|
|
|
|
----------------------------------
|
|
|
|
|
|
|
|
This process can be used to create subordinate keys which can be used to sign
|
|
|
|
efi binaries (since their roots can be traced back to the KEK).
|
|
|
|
|
|
|
|
openssl req -new -newkey rsa:2048 -keyout new.key -out new.csr -days <length>
|
|
|
|
|
|
|
|
Now sign the certificate request with the KEK:
|
|
|
|
|
|
|
|
openssl x509 -req -in new.csr -CA KEK.crt -CAkey KEK.key -set_serial 1 -out new.crt
|
|
|
|
|
|
|
|
Note that since the new key doesn't have to be enrolled in the platform
|
|
|
|
because its root of trust can be traced back to the KEK, there's no need to
|
|
|
|
create a DER form of the key (the sbsign utilites used to sign efi binaries
|
|
|
|
take the key.crt file which is in PEM form).
|
2014-10-02 13:07:59 +02:00
|
|
|
|
|
|
|
Running the UEFI ARM image in qemu
|
|
|
|
==================================
|
|
|
|
There are two flavors of the UEFI ARM images: AArch32 and AArch64.
|
|
|
|
For the AArch64 image, use the following command:
|
|
|
|
|
|
|
|
qemu-system-aarch64 -m 1024 -M virt -cpu cortex-a57 -bios /usr/share/qemu/qemu-uefi-aarch64.bin -serial stdio
|
|
|
|
|
|
|
|
For AArch32:
|
|
|
|
qemu-system-arm -m 1024 -M virt -cpu cortex-a15 -bios /usr/share/qemu/qemu-uefi-aarch32.bin -serial stdio
|
2015-07-08 10:49:39 +02:00
|
|
|
|
|
|
|
Source Level Debugging
|
|
|
|
======================
|
|
|
|
It's possible to debug OVMF with gdb connecting to qemu with the following
|
|
|
|
steps:
|
|
|
|
|
|
|
|
(1) install the debug package: qemu-ovmf-x86_64-debug
|
|
|
|
|
|
|
|
(2) Start the virtual machine with '-s' or "-gdb tcp::1234"
|
|
|
|
|
|
|
|
(3) Start gdb in another terminal and issue the following commands:
|
|
|
|
|
|
|
|
(gdb) set architecture i386:x86-64:intel
|
|
|
|
(gdb) target remote localhost:1234
|
|
|
|
(gdb) source /usr/share/ovmf-x86_64/gdb_uefi-ovmf-x86_64-<flavor>.py
|
|
|
|
(gdb) reload-uefi -o /usr/lib/debug/ovmf-x86_64/DebugPkg/GdbSyms/GdbSyms/DEBUG/GdbSyms.dll
|
|
|
|
|
|
|
|
(4) Happy debugging
|
|
|
|
|
|
|
|
Reference: https://www.mail-archive.com/edk2-devel@lists.sourceforge.net/msg07075.html
|
2016-05-25 21:28:38 +02:00
|
|
|
|
|
|
|
Note: It's also possible to debug OVMF with Xen, but the way to set up the port
|
|
|
|
is differnt. Instead of adding the port number to qemu, you need gdbsx.
|
|
|
|
Before starting gdb, execute this command:
|
|
|
|
|
|
|
|
# gdbsx -a <domainid> 64 1234
|
|
|
|
|
|
|
|
Then gdbsx will listen to port 1234 for the specific domainU. The rest is
|
|
|
|
the same as qemu.
|