GRUB2: add custom font with secureboot

In the latest versions of GRUB2, loading unsigned custom fonts have been disabled when secureboot is active. A workaround is creating a custom grub efi binary with the font file built in.

Create a custom font

use grub2-mkfont to create a custom font with size 32:

# grub2-mkfont -s 32 \
-o /efi/mygrub/fonts/my_custom_font.pf2 \
/usr/share/fonts/dejavu-sans-mono-fonts/DejaVuSansMono.ttf

Create a standalone grub binary

use grub2-mkstandlone:

grub2-mkstandalone --format x86_64-efi \
-o /boot/efi/EFI/mygrub/grubx64.efi \
--modules="configfile test echo normal ls linux chain \
gcry_sha512 gcry_rsa search search_fs_uuid part_gpt ext2 \
xfs fat all_video efi_gop efi_uga video_bochs video_cirrus \ gfxterm gettext gzio xzio lzopio chain blscfg" \ --fonts="my_custom_font" \
"/efi/mygrub/fonts/my_custom_font.pf2"

Sign the created binary

sign efi:

sbsign --key /etc/MOK.pem --cert /etc/MOK.pem \
/boot/efi/EFI/mygrub/grubx64.efi

replace the unsigned binary with signed binary:

mv /boot/efi/EFI/mygrub/grubx64.efi.signed \
/boot/efi/EFI/mygrub/grubx64.efi

Load the custom font in grub

Now that we have bundled the font file inside our grub binary, we can load it without extra signing. in grub.cfg, add:

if loadfont (memdisk)/efi/mygrub/fonts/my_custom_font.pf2
then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=en_US
  insmod gettext
fi

Chainload into the new bootloader

if you use distribution supplied’s shim binary to boot into secureboot, shim will refuse to boot our self-signed grub binary. so we need to chainload from distribution’s grub binary into our self-signed one. replace distribution’s grub.cfg:

insmod part_gpt
insmod fat
search --no-floppy --fs-uuid --set=root <EFI PARTITION>
chainloader /EFI/mygrub/grubx64.efi
boot

Posted

in

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *