How GRUB Uses UEFI Services to Load OS Kernels

Operating system boot loaders like the Grand Unified Bootloader (GRUB) serve as the bridge between system firmware and the operating system. In modern systems, GRUB acts as a Unified Extensible Firmware Interface (UEFI) application that relies on standardized UEFI services to access storage devices, manage system memory, verify security policies, and prepare the operating environment. This article explains the technical mechanics of how GRUB interacts with UEFI services to read, verify, and execute kernel images before transferring complete control of the machine to the operating system.

The UEFI Execution Environment

Unlike legacy BIOS systems that rely on 16-bit real-mode interrupts (such as INT 13h), UEFI provides a modular, 32-bit or 64-bit execution environment. GRUB is compiled as a standard PE/COFF executable (e.g., grubx64.efi).

When the system powers on, the UEFI Boot Manager locates the boot loader on the EFI System Partition (ESP) and loads it into memory. Upon initialization, the UEFI firmware passes two primary parameters to GRUB's entry point:

  1. EFI_HANDLE ImageHandle: The firmware-assigned reference to the loaded GRUB binary itself.
  2. EFI_SYSTEM_TABLE *SystemTable: A pointer to the primary UEFI system table, which exposes pointers to console I/O, configuration tables, and two critical function suites: Boot Services and Runtime Services.

GRUB stores the SystemTable pointer globally to query protocols and invoke firmware functions throughout the loading phase.

Accessing Files via UEFI Device Protocols

To locate and load a kernel image and its initial RAM disk (initramfs), GRUB must read storage devices. While GRUB contains internal filesystem drivers for formats like ext4, Btrfs, and XFS, it depends on UEFI services to interface directly with physical storage controllers.

GRUB queries UEFI protocols using the LocateHandleBuffer and OpenProtocol functions from the Boot Services table:

  • EFI_BLOCK_IO_PROTOCOL: Provides low-level block-based read and write operations across attached drives (SATA, NVMe, USB). GRUB uses this protocol to read raw partitions and apply its own embedded filesystem drivers.
  • EFI_SIMPLE_FILE_SYSTEM_PROTOCOL: Exposes standard file operations (Open, Read, Close) for FAT-formatted partitions, particularly the EFI System Partition.

By leveraging these protocols, GRUB locates the target kernel image (such as vmlinuz) specified in the GRUB configuration file (grub.cfg).

Memory Allocation for the Kernel

The Linux kernel requires specific memory layout structures, such as page alignment and designated memory addresses for real-mode code, the 64-bit kernel payload, and the initramfs.

GRUB interacts with UEFI Boot Services memory management functions to secure these locations:

  • AllocatePages: Allocates contiguous physical memory pages of specified types, such as EfiLoaderData or EfiBootServicesData.
  • GetMemoryMap: Retrieves the system's current physical memory layout to identify reserved zones, ACPI tables, and usable RAM regions.

GRUB reads the kernel image from storage into a newly allocated memory buffer, verifies the kernel's setup headers, and places the kernel code and initramfs at appropriate, conflict-free physical memory boundaries.

Secure Boot and Image Verification

When UEFI Secure Boot is enabled, the firmware enforces integrity checks to prevent untrusted code execution. In many Linux distributions, the UEFI firmware loads a signed first-stage boot loader called shim, which verifies GRUB's digital signature using embedded keys or the Machine Owner Key (MOK) database.

When GRUB subsequently loads the kernel image:

  1. GRUB invokes the EFI_SECURITY_ARCHITECTURAL_PROTOCOL or custom interfaces exposed by shim to validate the kernel's cryptographic signature.
  2. If the signature matches a trusted database entry (such as Microsoft's third-party UEFI CA or a user-enrolled MOK), verification succeeds.
  3. If validation fails, GRUB halts execution and refuses to boot the untrusted binary.

Terminating Boot Services and Executing the Kernel

Once the kernel image and initramfs are placed into memory and configuration command-line arguments are established, UEFI Boot Services are no longer required. In fact, keeping them active would conflict with the operating system's own memory management and hardware drivers.

The handoff occurs through a strict sequence:

  1. Obtain the Final Memory Map: GRUB executes GetMemoryMap to receive the final physical memory layout descriptor and a unique MapKey.
  2. Exit Boot Services: GRUB calls ExitBootServices(ImageHandle, MapKey). This call terminates all UEFI boot-time drivers, frees EfiBootServicesCode and EfiBootServicesData memory regions for OS use, and disables boot-phase hardware abstraction.
  3. Pass Parameters: If ExitBootServices succeeds, GRUB constructs the boot parameters structure (such as boot_params or the zeropage in Linux x86_64) containing hardware information, memory maps, ACPI table pointers, and command-line arguments.
  4. Jump to Kernel: GRUB performs an indirect jump to the kernel's 64-bit entry point, formally transferring CPU execution to the operating system.

After this transition, the kernel assumes full hardware control, relying only on UEFI Runtime Services (such as NVRAM variable access and hardware clock management) via virtual address mapping provided by the operating system.