07

Finding the Boot Device

The firmware searches for something it can boot from. This is how it decides.

The firmware has tested the hardware, trained the memory, and enumerated every bus. It knows what devices are connected. Now it faces a practical question: which one has an operating system on it?

A typical system might have an NVMe SSD, a SATA hard drive, a USB flash drive, and a network adapter. Any of them could potentially contain bootable code. The firmware needs a reliable method for deciding which one to try first, and a way to recognize bootable media when it finds one.

The Boot Order

Every firmware stores a list of boot devices, ordered by priority. This list lives in NVRAM -- a small region of non-volatile storage on the motherboard that persists across power cycles. When you enter the firmware setup screen and rearrange the boot order, you are editing this list.

The firmware works through the list from top to bottom. It tries the first entry. If that device is not present, or does not contain bootable data, the firmware moves to the next entry. If nothing on the list works, most systems display an error -- "No bootable device found" or similar -- and halt.

Key term: NVRAM (Non-Volatile Random-Access Memory) A small region of persistent storage on the motherboard, typically backed by flash memory or a battery-maintained CMOS chip. The firmware uses NVRAM to store configuration settings: boot order, date/time, hardware preferences, and (on UEFI systems) boot variables that point to specific files on specific partitions.

On legacy BIOS systems, the boot order is a simple list of device types: first hard disk, CD-ROM, USB, network. The firmware does not know about specific partitions or files. It just tries to read from each device in order.

On UEFI systems, the boot order is more specific. Each entry can point to a particular file on a particular partition of a particular disk. A UEFI boot entry might say: "load \EFI\ubuntu\shimx64.efi from partition 1 of NVMe disk 0." This precision means UEFI systems can have multiple operating systems installed on the same disk, each with its own boot entry, without conflict.

Fig. 07a -- Boot order resolution
Boot Order (NVRAM)

1. NVMe SSD 2. USB Drive 3. SATA HDD 4. Network (PXE) 5. CD-ROM

Try NVMe SSD Read sector 0 or locate ESP Bootable? YES Load it! NO Try next entry No bootable device found
The firmware walks the boot order list top to bottom, testing each device for bootable signatures or files. The first success wins. If nothing works, boot fails.

MBR: The Legacy Partition Table

The Master Boot Record is the original PC disk format, dating back to 1983. It occupies the very first sector of the disk -- 512 bytes at LBA 0 (Logical Block Address zero). Those 512 bytes are divided into three parts.

The first 446 bytes contain executable code -- the bootstrap program. The next 64 bytes contain the partition table: four entries of 16 bytes each, describing up to four primary partitions. The final 2 bytes are a magic number: 0x55AA. This signature tells the firmware that the sector contains valid boot code.

Key term: MBR (Master Boot Record) The first 512 bytes of a legacy-partitioned disk. It contains a small bootstrap program, a table of up to four partition entries, and a two-byte signature (0x55AA). The firmware loads this sector into memory and jumps to the code at offset zero.

Each MBR partition entry contains a start address, a size (both in 32-bit LBA), a partition type byte, and a status byte. The status byte is either 0x80 (active, or "bootable") or 0x00 (inactive). Only one partition should be marked active at a time. The bootstrap code in the MBR typically scans the partition table for the active partition, loads the first sector of that partition (the Volume Boot Record), and jumps to it.

Fig. 07b -- MBR structure (512 bytes)

Offset: 0x000 0x1BE 0x1FE

Bootstrap Code 446 bytes of x86 machine code Partition Table 4 entries x 16 bytes = 64B 0x55 0xAA

Partition Entry Format (16 bytes each)

Status 0x80 CHS Start 3 bytes Type 0x83 CHS End 3 bytes LBA Start 4 bytes Size (LBA) 4 bytes

0x80 = active 0x00 = inactive

0x83 = Linux 0x07 = NTFS 0x82 = swap

32-bit = max 2 TiB disk

The MBR packs bootstrap code, four partition entries, and a boot signature into exactly 512 bytes. The status byte marks which partition is "active" -- the one the bootstrap code should chain-load.

The Boot Flag

The "active" status byte -- 0x80 -- is commonly called the boot flag. It is how the MBR bootstrap code decides which partition to load next. The firmware itself does not check the boot flag. The firmware only checks the 0x55AA signature at the end of the sector. The boot flag is interpreted by the code within the MBR.

This is a subtle but important distinction. The firmware's job is to find a disk with a valid MBR signature and execute the code there. That code is then responsible for finding the active partition and loading its boot sector. The firmware does not know or care about partitions. It only knows about whole disks.

MBR Limitations

MBR has two significant limitations. First, the four-partition limit. You can work around it using "extended partitions" -- one of the four primary entries can point to a chain of logical partitions -- but the scheme is fragile and complicates boot code. Second, the 32-bit LBA fields limit addressable disk space to 2 TiB with 512-byte sectors. There is no way to extend this without breaking the format.

GPT: The Modern Partition Table

The GUID Partition Table, introduced alongside UEFI, solves both of MBR's problems. It uses 64-bit LBA fields, supporting disks up to 9.4 ZB (zettabytes) -- far beyond anything that exists today. It supports up to 128 partition entries by default, each identified by a 128-bit GUID.

A GPT disk starts with a protective MBR at LBA 0. This is a standard MBR with a single partition entry covering the entire disk, typed as 0xEE (GPT protective). Its purpose is to prevent MBR-only tools from treating the disk as unpartitioned and overwriting the GPT data.

The actual GPT header lives at LBA 1. It contains a magic signature (EFI PART), the disk GUID, the number of partition entries, and the LBA of the partition entry array. The partition entries follow the header, typically occupying LBA 2 through 33.

Key term: GPT (GUID Partition Table) The modern partition table format used on UEFI systems. Each partition has a 128-bit type GUID and a 128-bit unique GUID. GPT supports 64-bit addressing (no practical disk size limit) and up to 128 partitions. A backup copy of the header and entries is stored at the end of the disk.

GPT also stores a backup copy of the header and all partition entries at the end of the disk. If the primary header is corrupted, the firmware or OS can recover from the backup. MBR has no such redundancy.

The EFI System Partition and Boot Discovery

On a UEFI system, the firmware does not execute code from the first sector. Instead, it looks for an EFI System Partition -- a partition with the specific type GUID C12A7328-F81F-11D2-BA4B-00A0C93EC93B. This partition must be formatted as FAT32 (or FAT12/FAT16 for small media).

The firmware reads the UEFI boot variables from NVRAM. Each variable specifies a file path on a specific partition of a specific disk. For example: "disk 0, partition 1, \EFI\fedora\shimx64.efi." The firmware mounts the FAT32 partition, navigates to that path, and loads the EFI executable.

If no boot variable matches, or the specified file is missing, the firmware falls back to a default path: \EFI\BOOT\BOOTX64.EFI for 64-bit x86, \EFI\BOOT\BOOTAA64.EFI for ARM64. This fallback is what makes USB installation media work without special NVRAM configuration -- the installer puts a bootloader at the default path, and any UEFI system will find it.

Fig. 07c -- UEFI boot device discovery
UEFI Boot Variables Boot0001: NVMe0, Part1 \EFI\ubuntu\shimx64.efi Boot0002: SATA0, Part1 \EFI\BOOT\BOOTX64.EFI NVMe SSD (GPT) P-MBR GPT Hdr ESP (P1) Root (P2) ESP Contents (FAT32) \EFI\ubuntu\shimx64.efi \EFI\BOOT\BOOTX64.EFI Load shimx64.efi Verify Secure Boot signature Execute bootloader If boot variable fails: Try \EFI\BOOT\BOOTX64.EFI
UEFI reads boot variables from NVRAM, locates the ESP on the specified disk, and loads the named EFI executable. If that fails, it falls back to the default boot path.

Network Boot: PXE

Not all boot devices are local disks. PXE -- Preboot Execution Environment -- allows a system to boot over the network. The firmware's network stack sends a DHCP request to get an IP address. The DHCP response includes the address of a TFTP server and the filename of a boot program. The firmware downloads that program over TFTP and executes it.

PXE is essential in data centers and labs where hundreds of machines need to be installed or re-imaged without anyone plugging in USB drives. It is also the fallback when local disks fail -- a system with a dead SSD can PXE boot into a recovery environment.

On UEFI systems, network boot loads an EFI executable over TFTP or HTTP. On legacy BIOS systems, it loads a 16-bit bootstrap program called a Network Bootstrap Program (NBP). In both cases, the network boot entry is just another item in the boot order list, tried in sequence like any disk.

The firmware discovers boot devices by walking the boot order stored in NVRAM. For legacy BIOS, it looks for the 0x55AA signature in the first sector of each disk. For UEFI, it reads structured boot variables that point to specific EFI executables on specific partitions. PXE allows booting over the network when no local disk is available or desired.

How the Firmware Talks to Disks

The firmware needs storage drivers to read from disks. On a legacy BIOS system, these drivers are the INT 13h interrupt routines -- firmware-provided functions that can read and write disk sectors. INT 13h is slow (it reads one sector at a time through the CPU) and limited, but it works for the boot process.

On a UEFI system, the firmware loads Block I/O Protocol drivers during the DXE phase. These drivers can talk to NVMe controllers, SATA controllers, and USB mass storage devices. The firmware also loads a Simple File System Protocol driver for FAT32, which is how it reads files from the ESP. These drivers are full 64-bit code with access to all system memory -- a far cry from the 16-bit, 1 MB world of INT 13h.

The firmware does not need to understand every filesystem. It only needs FAT32 for reading the ESP. The operating system brings its own drivers for ext4, NTFS, XFS, Btrfs, and everything else. The firmware's job is strictly to get the bootloader loaded and running.

Removable Media and Hot-Plug

USB drives and optical media add a complication: they can be inserted after power-on. The firmware must periodically re-scan USB buses to detect new devices. Most UEFI implementations do this automatically. Legacy BIOS systems vary -- some re-scan USB at boot menu time, others only detect devices that were present at POST.

This is why the timing of inserting a USB boot drive matters. On some systems, you need to plug in the USB drive before powering on. On others, you can insert it at the boot menu. UEFI systems are generally more flexible because their USB drivers run continuously during the firmware phase.

Fig. 07d -- Boot media detection methods compared

How Firmware Validates Boot Media

Legacy BIOS

1. Read LBA 0 (512 bytes) 2. Check bytes 510-511 Must be 0x55 0xAA 3. Copy sector to 0x7C00 4. Jump to 0x7C00 No signature check No file path awareness

UEFI

1. Read GPT, find ESP 2. Mount FAT32 filesystem 3. Locate .EFI file by path 4. Verify Secure Boot sig 5. Load into memory, execute Cryptographic verification Named file on known path

BIOS trusts a two-byte magic number. UEFI verifies a cryptographic signature on a named file. The difference in security posture is enormous.

Putting It Together

Here is the complete sequence, from the moment the firmware starts looking for a boot device to the moment it hands off to the bootloader:

  1. The firmware reads the boot order from NVRAM.
  2. For each entry, it checks whether the device is present.
  3. If present, it reads the disk's partition table (MBR or GPT).
  4. On a BIOS system: it checks the MBR for the 0x55AA signature, loads the 512-byte sector to memory address 0x7C00, and jumps to it.
  5. On a UEFI system: it locates the ESP, mounts the FAT32 filesystem, finds the specified EFI file, optionally verifies its Secure Boot signature, loads it into memory, and calls its entry point.
  6. If the boot attempt fails, it moves to the next entry in the boot order.
  7. If all entries fail, it displays an error and halts (or offers a setup menu).
Finding the boot device is a search problem with a strict protocol. The firmware does not guess. It follows the boot order list, checks each device against known criteria (MBR signature or ESP with an EFI executable), and loads the first thing that passes the test. This is the last step the firmware performs on its own. From here, control passes to the bootloader -- the first piece of software that was chosen by the user or the OS installer, not by the hardware vendor.

The firmware's work is now done. The bootloader it loaded will take over, find the operating system kernel, and begin the process of bringing up a full OS. That is the next chapter in the boot sequence.

Next: Stage 1: The Bootloader