In the previous article, the firmware found a boot device. It read the very first sector from that disk -- 512 bytes -- and loaded it into memory at address 0x7C00. Now the CPU's instruction pointer is aimed at that address, and execution begins.
Those 512 bytes are the Master Boot Record, and the tiny program inside it is the Stage 1 bootloader. It is the smallest useful program in the entire boot chain. It has one job: load something bigger.
The 512-Byte Constraint
A single disk sector is 512 bytes. That is not a lot of space. To put it in perspective, this sentence alone is about 70 bytes of ASCII text. The entire Stage 1 bootloader has to fit in roughly seven sentences worth of raw data -- and that space is shared with other structures.
The 512-byte sector is divided into three regions. The first 440 bytes (sometimes 446, depending on the convention) hold executable machine code. The next 64 bytes hold the partition table -- four entries of 16 bytes each, describing how the disk is divided. The final 2 bytes hold the boot signature: 0x55 followed by 0xAA.
The firmware does not care what the boot code does. It does not validate the instructions. It checks for 0x55AA, loads the sector, and jumps. From that point on, the boot code is in complete control.
Real Mode: The 1981 Prison
When the Stage 1 code starts running, the CPU is in real mode. This is the processor's most primitive operating state -- the same mode the original IBM PC's 8086 processor used in 1981. Every x86 processor since then, no matter how advanced, starts in this mode for backward compatibility.
Real mode imposes harsh constraints. The CPU uses 16-bit registers, which means a single register can hold a value between 0 and 65,535. Memory addresses use a segment:offset scheme where a 16-bit segment register is shifted left by 4 bits and added to a 16-bit offset, giving a 20-bit physical address. That is enough to address exactly 1,048,576 bytes -- one megabyte.
One megabyte sounds generous for 440 bytes of boot code, but the address space is not empty. The BIOS and hardware claim large chunks of it. The usable region for loading data is surprisingly small.
Notice where the MBR loads: address 0x7C00. This is not at the bottom of memory (reserved for the interrupt vector table) and not at the top (reserved for the BIOS ROM and video hardware). It sits in a gap of free memory, chosen decades ago for the original IBM PC and preserved ever since.
What the Boot Code Actually Does
The Stage 1 boot code has 440 bytes to work with. That is too small for a filesystem driver, too small for a configuration parser, too small for anything complicated. The code does the absolute minimum needed to load the next piece of the chain.
Here is the typical sequence:
-
Set up segment registers. The code sets CS, DS, ES, and SS to known values. The firmware does not guarantee these are correct, so the boot code normalizes them immediately.
-
Relocate itself. Many bootloaders copy themselves from 0x7C00 to a lower address (often 0x0600) to free up the area around 0x7C00 for loading the next stage. Then they jump to the relocated copy and continue from there.
-
Scan the partition table. The code reads the four 16-byte partition table entries starting at offset 0x1BE. It looks for the entry marked as "active" -- the one with 0x80 in its first byte. This is the bootable partition.
-
Load the first sector of the active partition. Using BIOS interrupt 0x13 (the disk read service), the code loads the first sector of the active partition into memory at 0x7C00 -- the same address the MBR was originally loaded to.
-
Jump to the loaded code. The CPU begins executing the newly loaded sector. This is the Volume Boot Record (VBR) of the active partition, and it typically contains the start of a larger bootloader.
The BIOS Disk Interface
Reading from disk in real mode means using BIOS services. The CPU cannot talk to a SATA controller or NVMe drive directly -- those protocols require setup that only the firmware has done. Instead, the boot code uses INT 0x13 with function 0x02 (read sectors).
The original interface uses Cylinder-Head-Sector (CHS) addressing. You specify which cylinder, which head, and which sector to read. CHS has a hard limit: it can address about 8 GB of disk space. For disks larger than that, an extended interface (INT 0x13 with function 0x42) uses Logical Block Addressing (LBA), where sectors are numbered sequentially from zero.
The Stage 1 code in a modern bootloader like GRUB uses LBA when available. It checks whether the BIOS supports the extensions (INT 0x13, function 0x41) and falls back to CHS if not.
The Chain Continues
The code that Stage 1 loads from the active partition is sometimes called the Volume Boot Record. For simple bootloaders, this might be enough to start an operating system directly. But for modern systems with large kernels, compressed images, and configuration files, even the VBR is too small.
This is why GRUB and similar bootloaders use a multi-stage design. Stage 1 loads a small intermediate piece (often called Stage 1.5), which contains just enough code to read a filesystem. That intermediate piece then loads the full Stage 2 from a known location on the partition.
Where Does Stage 1.5 Live?
On an MBR-partitioned disk, the first partition typically does not start until sector 63 (or sector 2048 on modern tools). The sectors between the MBR (sector 0) and the first partition form a gap. GRUB installs its Stage 1.5 -- called core.img -- in this gap. It contains enough code to understand a filesystem (ext4, XFS, Btrfs, or whatever /boot uses) so it can find and load the full GRUB Stage 2.
On a GPT-partitioned disk, the partition entries occupy the sectors immediately after the protective MBR, so there is no convenient gap. Instead, GPT systems use a dedicated BIOS Boot Partition -- a small partition (typically 1 MB) with a specific type GUID, reserved for the bootloader's intermediate code.
The Fragility of Stage 1
The MBR is a single point of failure. If those 512 bytes are corrupted -- by a bug, a careless dd command, or malware -- the system will not boot. The firmware will either fail the 0x55AA check and move to the next device, or execute garbage instructions and crash.
This is why disk cloning tools and system administrators treat the MBR with care. Overwriting the first sector of a disk destroys the bootloader and the partition table in one stroke. Backup tools like dd if=/dev/sda of=mbr.bin bs=512 count=1 exist specifically to preserve it.
The MBR design dates to 1983. It was built for disks measured in tens of megabytes. The 4-entry partition table can describe at most four primary partitions, and CHS addressing limits disk access to about 8 GB. These limitations are why GPT and UEFI eventually replaced the MBR scheme -- but legacy BIOS booting with MBR is still common, and understanding it explains why the newer systems were designed the way they were.
What Happens Next
Stage 1 has done its job. It found the active partition (or loaded GRUB's core.img from the post-MBR gap), read it into memory, and jumped to it. The CPU is still in real mode. It still has only 1 MB of address space. But now there is a much larger program running -- one with enough code to read filesystems, parse configuration files, and present a menu.
That program is GRUB Stage 2, and it is the subject of the next article.
Next: Stage 2: GRUB