BIOS vs. UEFI
Firmware is the first code to run on any x86 machine, and its choice of interface, legacy BIOS or modern UEFI, shapes nearly everything about how a kernel gets loaded before it can begin managing the machine itself. The two differ in partition scheme, in what state they leave the CPU in, and in how much of the loading process they perform on a kernel’s behalf.
A BIOS-based system locates a boot device by reading its first 512-byte sector, the Master Boot Record, checking for the boot signature 0x55, 0xAA at its end, and if present, loading the entire sector to physical address 0x7C00 and jumping to it, still in 16-bit real mode, with disk access available only through BIOS interrupt services (int 0x13) rather than any driver the boot code itself provides. Partitioning under this scheme uses the MBR partition table, embedded within the same 512-byte sector as the boot code, limiting a disk to four primary partitions (extended partitions work around this in practice) and, more consequentially for very large drives, a 32-bit sector count that caps an MBR-addressable disk at 2 TB. BIOS itself was never formally specified by a single standards body in the way UEFI is; it is better understood as a long-lived, informally standardized convention each firmware vendor implemented compatibly with the IBM PC’s original behavior.
UEFI (Unified Extensible Firmware Interface) replaces this with a considerably more structured model. Rather than a raw 512-byte boot sector, a UEFI system locates and directly executes a PE-format .efi executable (conventionally \EFI\BOOT\BOOTX64.EFI as a fallback default), from a FAT32-formatted EFI System Partition on a GPT-partitioned disk, which uses 64-bit sector addressing and removes MBR’s four-partition and 2 TB limitations. Critically, UEFI firmware runs boot-time code in a flat, non-segmented addressing mode already close to what a 32-bit or 64-bit kernel expects, rather than 16-bit real mode: UEFI application code is ordinary C-callable machine code from the outset, not real-mode assembly, and UEFI additionally exposes a defined set of boot services (memory allocation, the memory map, file and disk I/O) as callable functions rather than the more ad hoc software-interrupt interface BIOS provides.
Practical differences for a kernel
Section titled “Practical differences for a kernel”The two paths lead to meaningfully different starting conditions for a kernel or bootloader. BIOS boot code inherits real mode and has to perform the protected/long mode transitions itself, or rely on a bootloader that does; UEFI boot code starts already past that boundary, in a flat 32-bit or 64-bit environment, though it must still explicitly call ExitBootServices before firmware’s own memory management and services can be considered fully relinquished to the OS. Memory discovery differs correspondingly: BIOS-era code retrieves a memory map via int 0x15, EAX=0xE820, while UEFI code calls GetMemoryMap, a different mechanism serving the same purpose described under Physical Memory. A Multiboot-compliant bootloader such as GRUB can target either firmware type and normalizes most of this difference away for the kernel, at the cost of depending on that bootloader rather than controlling firmware interaction directly.
Secure Boot
Section titled “Secure Boot”UEFI additionally defines Secure Boot, an optional mechanism verifying a boot executable’s cryptographic signature against a set of keys firmware trusts before executing it, intended to prevent unsigned or tampered boot code from running. A hobby kernel’s own bootloader or .efi executable is, by definition, not signed by any key firmware already trusts, which generally means either disabling Secure Boot in firmware settings for development, or separately arranging to sign the boot executable and enroll a corresponding key, a step with no equivalent at all under legacy BIOS, which has no comparable verification concept.
Implementation notes
Section titled “Implementation notes”Firmware vendors increasingly deprecate legacy BIOS support entirely in favor of a “CSM” (Compatibility Support Module), a UEFI feature emulating BIOS-style booting for older operating systems, or drop BIOS-mode booting altogether, which makes UEFI the more future-proof target for new kernel development even though the BIOS/MBR path remains extremely well-documented and, inside most emulators, marginally simpler to get a first boot working under. Testing against both paths early, rather than committing exclusively to one, avoids a rewrite later if firmware support for the chosen path becomes unavailable on real hardware the kernel is eventually tested against.
References
Section titled “References”- ^ UEFI Specification: the formal specification governing UEFI boot services, GPT, and Secure Boot.
See also
Section titled “See also”- The Boot Process: the broader sequence from firmware to kernel entry this article is part of.
- Bootloaders: the layer that commonly normalizes the difference described above away from the kernel.
- Partition Tables, MBR and GPT: the two partitioning schemes named above, covered in full.
- Writing a UEFI Bootloader: the PE32+ application format and Boot Services API this article’s UEFI section only summarizes.