GRUB

From 15h.org
Revision as of 19:21, 22 January 2026 by Erox (talk | contribs) (Add basic example of 'create GRUB bootable USB stick for LUKS2')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

GRUB can be added to SeaBIOS as a floppy image to provide a reliable bootloader stored in the CBFS. GRUB can be used to verify kernel/initrd integrity and/or to support encrypted /boot partitions.

It is also possible to create a bootable GRUB USB stick, if you for some reason do not want to flash into CBFS.

GRUB on USB stick

If you want to boot an encrypted /boot partition the quickest way is to create a bootable GRUB USB stick. If LUKS2 is used, which commonly use argon2 for KDF, this requires at least GRUB 2.14 (modules: luks2, argon2).

Create bootable GRUB USB stick

# Basic example of bootable GRUB disk with LUKS support (not LUKS2 if you don't include modules such as luks2 and argon2 below)
grub-mkrescue -o grub.img --compress=xz --locale-directory=/usr/share/locale --locales=en@quot --fonts=none --modules="normal part_gpt part_msdos luks cryptodisk gcry_sha256 gcry_sha512 gcry_rijndael  gcry_twofish pbkdf2"

dd if=grub.img of=/dev/sdX 

Include the modules you need in the above command, available modules can generally be seen here:

ls /usr/lib/grub/i386-pc/ 

Boot the USB stick

It is more convenient to modify a grub.cfg to automatically boot your system. However in this simple example, you will need to boot the GRUB USB stick and then manually choose your system grub.cfg (or alternatively skip loading the 'real' grub.cfg on disk, and instead correctly point it to your rootfs path, kernel, and initramfs), on each boot.

Here is an example:

# Decrypt disk
cryptomount -a
# Find correct path
ls
# Set / for convenience
root=(lvm/matrix-bootvol)
# Boot the real GRUB config on disk to boot your system
configfile /boot/grub.cfg 

Build GRUB for LUKS2

If you want LUKS2 support and do not have GRUB >= 2.14, compile it as shown here.

# Instructions for Ubuntu 24 or Debian 13.
# I had issues on Debian 13 with an error "Gold bug?" upon running the grub-mkrescue binary. It however did work on Debian 12 and Ubuntu 24.04.
#
# Replace "user" with your system username!

sudo apt install -y build-essential git autoconf automake libtool bison flex gettext texinfo pkg-config help2man libgcrypt20-dev libdevmapper-dev liblzma-dev libzstd-dev libpcre2-dev libtasn1-6-dev autopoint autoconf-archive gawk mtools xorriso

git clone https://git.savannah.gnu.org/git/grub.git
cd grub
# Checkout latest stable tag, currently is 2.14 (2026-01)
git checkout grub-2.14

#use gawk not mawk which may be default on your system
export AWK=/usr/bin/gawk

./bootstrap
./configure --with-crypto=libgcrypto --prefix=/home/user/_0_my-grub
make -j$(nproc)

make install
# To /home/user/_0_my-grub (as set with 'prefix' in ./configure above)

# Create a bootable image "grub.img"
# note: add the modules you need, all these modules are generally not required
/home/user/_0_my-grub/bin/grub-mkrescue -o grub.img --compress=xz --locale-directory=/usr/share/locale --directory=/home/user/_0_my-grub/lib/grub/i386-pc --locales=en@quot --fonts=none --modules="normal part_gpt part_msdos luks cryptodisk gcry_sha256 gcry_sha512 gcry_arcfour gcry_blowfish gcry_camellia gcry_cast5  gcry_crc gcry_des gcry_dsa gcry_idea gcry_md4 gcry_md5 gcry_rfc2268 gcry_rijndael gcry_rmd160  gcry_rsa gcry_seed gcry_serpent gcry_sha1 gcry_tiger gcry_twofish  gcry_rijndael gcry_twofish pbkdf2 luks2 lvm zfs pbkdf2 password password_pbkdf2 random crypto cryptodisk gcry_blake2 argon2"

# Finally write to USB stick
dd if=grub.img of=/dev/sdX  


Verifying /boot

Prepare your GRUB image

If you have GPG signed files in /boot, GRUB can verify them each boot to prevent tampering.

Dependencies

apt install xorriso

file layout

Organize your files like this:

./generate.sh
./fdroot
./fdroot/boot/
./fdroot/boot/grub
./fdroot/boot/grub/grub.cfg
./fdroot/boot/grub/boot.key

grub.cfg

Review your systems current grub.cfg (/boot/grub/grub.cfg) to find your root UUID and other information you may need. You will need to load all necessary modules before loading your GPG key. Here is an example grub.cfg used on Debian 13.

insmod part_gpt
insmod crypto
insmod cryptodisk
insmod geli
insmod ufs2     
insmod search
insmod search_label
insmod usb_keyboard
insmod echo
insmod ls
insmod cat      
insmod test     
insmod configfile
insmod bsd
insmod reboot
insmod pbkdf2
insmod password
insmod password_pbkdf2
insmod gcry_rsa 
insmod gcry_sha512
insmod gcry_rijndael 
insmod verifiers
insmod play     
insmod part_msdos
insmod mdraid1x
insmod lvm
insmod ext2
insmod diskfilter
insmod gzio
insmod ntfs
insmod linux
insmod drivemap
insmod chain
insmod loopback

trust /boot/grub/boot.key

set timeout_style=menu
set timeout=5

play 480 440 1

menuentry 'Debian GNU/Linux (signed)' {
        set check_signatures=enforce
        search --no-floppy --fs-uuid --set=root xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

        echo    'Loading Linux ...'
        linux   /boot/latest/vmlinuz root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ro
        echo    'Loading initial ramdisk ...'
        initrd  /boot/latest/initrd.img
}

menuentry 'Debian GNU/Linux (unsigned)' {
        set check_signatures=no
        search --no-floppy --fs-uuid --set=root xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

        echo    'Loading Linux ...'
        linux   /boot/latest/vmlinuz root=UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx ro
        echo    'Loading initial ramdisk ...'
        initrd  /boot/latest/initrd.img
}

boot.key

This is the public key used to verify your files


generate.sh

#!/bin/bash

GRUB_MODULES+="usb_keyboard ls echo cat search_label search configfile part_gpt geli ufs2 cryptodisk gcry_rijndael bsd reboot pbkdf2 password password_pbkdf2 gcry_rsa gcry_sha512 test play verifiers"
GRUB_MODULES+=" part_msdos mdraid1x lvm ext2 diskfilter gzio ntfs linux drivemap chain part_acorn part_amiga part_apple part_bsd part_dfly part_dvh part_plan part_sun part_sunpc crypto loopback"

rm -f grub.img
grub-mkrescue --compress=gz -o grub.img --locale-directory=/usr/share/locale --locales=en@quot --fonts=none --install-modules="${GRUB_MODULES}" ./fdroot || exit

FDLEN=2949120
if [ $(stat -c %s "grub.img") -gt $FDLEN ]; then
    echo "Generated GRUB image is too large for a 2.88MB floppy image. Please adjust script."
    rm grub.img
    exit 1;
fi

truncate -s $FDLEN grub.img

grub.img

Create your grub floppy image

chmod +x generate.sh
./generate.sh

Add your GRUB image to coreboot

In your coreboot compilation directory, add grub.img and create the bootorder file

bootorder

/rom@floppyimg/grub
HALT

Attach grub.img and bootorder to coreboot

./build/cbfstool ./build/coreboot.rom add -f grub.img -n floppyimg/grub.lzma -t raw -c lzma
./build/cbfstool ./build/coreboot.rom add -f bootorder -n bootorder -t raw