EFI and Secure Boot Notes
Published inTo create a bootable EFI drive to use with QEMU, first make a disk image and
create a vfat
filesystem on it.
$ dd if=/dev/zero of=boot.img bs=1M count=512 $ sudo mkfs.vfat boot.img
By default, EFI firmwares boot a specific file under /efi/boot/
. The name of
such file depends on the architecture: for example, on 64 bit x86 systems it is
bootx64.efi
, while on ARM it is bootaa64.efi
.
Copy /usr/lib/grub/x86_64-efi/monolithic/grubx64.efi
from package
grub-efi-amd64-bin
to /efi/boot/bootx64.efi
on the boot image, and that
should be enough to start GRUB.
# mount boot.img /mnt/ # mkdir -p /mnt/efi/boot/ # cp /usr/lib/grub/x86_64-efi/monolithic/grubx64.efi /mnt/efi/boot/bootx64.efi # umount /mnt/
Now get the x86 firmware from package ovmf
and start qemu
:
$ cp /usr/share/OVMF/OVMF_CODE.fd /tmp/code.fd $ qemu-system-x86_64 -drive file=/tmp/code.fd,format=raw,if=pflash -cdrom boot.img
GRUB looks fine, but it would be good to have a kernel to boot. Let’s add one
to boot.img
.
# mount boot.img /mnt # cp vmlinuz-6.1.0-7-amd64 /mnt/vmlinuz # umount /mnt/
Boot with qemu again, but this time pass -m 1G
. The default amount of
memory is not enough to boot.
$ qemu-system-x86_64 -drive file=/tmp/code.fd,format=raw,if=pflash -cdrom boot.img -m 1G
At the grub prompt, type the following to boot:
grub> linux /vmlinuz grub> boot
The kernel will start and reach the point of trying to mount the root fs. This is great but it would now be useful to have some sort of shell access in order to look around. Let’s add an initrd!
# mount boot.img /mnt # cp initrd.img-6.1.0-7-amd64 /mnt/initrd # umount /mnt/
There’s the option of starting qemu in console, let’s try that out. Start qemu
with -nographic
, and append console=ttyS0
to the kernel command line
arguments.
$ qemu-system-x86_64 -drive file=/tmp/code.fd,format=raw,if=pflash -cdrom boot.img -m 1G -nographic grub> linux /vmlinuz console=ttyS0 grub> initrd /initrd grub> boot
If all went well we are now in the initramfs shell. We can now run commands! At this point we can see that the system has Secure boot disabled:
(initramfs) dmesg | grep secureboot [ 0.000000] secureboot: Secure boot disabled
In order to boot with Secure boot, we need:
-
a signed shim, grub, and kernel
-
the right EFI variables for Secure boot
The package shim-signed
provides a shim signed with Microsoft’s key, while
grub-efi-amd64-signed
has GRUB signed with Debian’s key.
The signatures can be shown with sbverify --list
:
$ sbverify --list /usr/lib/shim/shimx64.efi.signed warning: data remaining[823184 vs 948768]: gaps between PE/COFF sections? signature 1 image signature issuers: - /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation UEFI CA 2011 image signature certificates: - subject: /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Windows UEFI Driver Publisher issuer: /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation UEFI CA 2011 - subject: /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation UEFI CA 2011 issuer: /C=US/ST=Washington/L=Redmond/O=Microsoft Corporation/CN=Microsoft Corporation Third Party Marketplace Root
Similarly for GRUB and the kernel:
$ sbverify --list /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed signature 1 image signature issuers: - /CN=Debian Secure Boot CA image signature certificates: - subject: /CN=Debian Secure Boot Signer 2022 - grub2 issuer: /CN=Debian Secure Boot CA $ sbverify --list /mnt/vmlinuz signature 1 image signature issuers: - /CN=Debian Secure Boot CA image signature certificates: - subject: /CN=Debian Secure Boot Signer 2022 - linux issuer: /CN=Debian Secure Boot CA
Let’s use the signed shim and grub in the boot image:
# mount boot.img /mnt # cp /usr/lib/shim/shimx64.efi.signed /mnt/efi/boot/bootx64.efi # cp /usr/lib/grub/x86_64-efi-signed/grubx64.efi.signed /mnt/efi/boot/grubx64.efi # umount /mnt
And start QEMU with the appropriate EFI variables for Secure boot:
$ cp /usr/share/OVMF/OVMF_VARS.ms.fd /tmp/vars.fd $ qemu-system-x86_64 -drive file=/tmp/code.fd,format=raw,if=pflash -drive file=/tmp/vars.fd,format=raw,if=pflash -cdrom boot.img -m 1G -nographic
We can double-check in the firmware settings if Secure boot is indeed enabled.
At the GRUB prompt, type fwsetup
:
grub> fwsetup
Check under "Device Manager" → "Secure Boot Configuration" that "Attempt Secure Boot" is selected, then boot from GRUB as before. If all went well, the kernel should confirm that we have booted with Secure boot:
(initramfs) dmesg | grep secureboot [ 0.000000] secureboot: Secure boot enabled