Skip to content

Instantly share code, notes, and snippets.

@earlchew
Created February 25, 2024 17:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earlchew/72b984846a57e755363c9c8043e9c84b to your computer and use it in GitHub Desktop.
Save earlchew/72b984846a57e755363c9c8043e9c84b to your computer and use it in GitHub Desktop.
GRUB UEFI BIOS Dual Boot

Overview

This configuration supports an UEFI boot, as well as a fallback to support a BIOS boot using the largely the same configuration. This improves the availability of the system by housing two copies of the GRUB bootloader, the first in the EFI System Partition, and the second in the BIOS Boot Partition.

UEFI Boot Sequence

The UEFI boot is supported by the presence of a FAT32 filesystem located in a RAID1 enabled EFI System Partition (ESP). The use of RAID1 improves durability of the ESP while allowing the content of the filesystem to be available during boot when RAID support is not available.

The filesystem hosts the expected EFI\BOOT\ directory in which is placed a copy of the EFI Boot Guard. The executable is located in EBG\EBGX64.EFI and is copied to EFI\BOOT\BOOTX64.EFI. The EFI Boot Guard configuration is located at BGENV.DAT, and directs it to load the EFI shell. The shell is co-located with STARTUP.NSH which provides instructions to load GRUB.

During a UEFI enabled boot:

  • The BIOS scans the media to find the ESP
  • The BIOS starts EFI\BOOT\BOOTX64.EFI
  • The EBG configures the watchdog
  • The EBG starts \EFI\BOOT\SHELLX64.EFI
  • The UEFI shell executes STARTUP.NSH
  • The commands in STARTUP.NSH instruct the shell to execute %0%\..\..\..\GRUB\SHIMX64.EFI GRUBX64.EFI

When UEFI starts GRUB, execution begins at efi/startup.S which transfers control to grub_main() in kern/main.c which resolves both root and prefix via grub_machine_get_bootlocation(). For UEFI, this is implemented in efi/init.c which finds a handle to the loaded image (ie GRUBX64.EFI) and uses that to determine the device and directory containing the image. Using this, GRUB sets root to the name of the device, and prefix to the (device, directory) tuple.

BIOS Boot Sequence

The BIOS boot is supported by the boot code in the Master Boot Record (MBR) in the protective MBR located in the first sector of each disk. The MBR loads the remainder of the GRUB image from the BIOS Boot Partition. This partition does not have a filesystem, and houses the GRUB executable directly in the leading sectors of the partition.

During a BIOS enabled boot:

  • The BIOS scans the media to find a bootable disk
  • The BIOS loads the bootstrap code from the MBR
  • The MBR code starts the GRUB executable by loading it from the BPB

The MBR was installed by grub-mkimage invoked during bin/install-grub. The image is configured to set the prefix to the RAID UUID of the ESP and the name of the \GRUB\ directory. This also writes the GRUB executable directly into the leading sectors of the BPB, and records their locations as a sector list in the MBR.

Common GRUB Boot Sequence

  • Both the ESP and BIOS boot configure the GRUB prefix to \GRUB\ in the ESP
  • The GRUB executes commands in initialisation script ($prefix)/grub.cfg
  • The initialisation script finds the IPL partition via its RAID1 UUID
  • The initialisation script executes /boot/grub.cfg from the IPL partition
  • The boot script uses a menu to specify the correct kernel image

When GRUB engages normal mode, in the absence of other configuration, GRUB will use the prefix to find grub.cfg when triggered by the implicit invocation of grub_cmd_normal() via grub_load_normal_mode() in kern/main.c.

Conclusion

Housing the main kernel selection in a separate RAID partition allows it to be decoupled from the specific details of the different boot loaders. Using a common GRUB initialisation configuration in the ESP provides a means to converge the behaviours of the two GRUB instances. The GRUB BIOS instance locates the ESP using its RAID UUID, and completes the boot without supervision. The GRUB UEFI instance uses the ESP directly, and also engages the EBG so that the boot is supervised by a watchdog.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment