Partition Tables, MBR and GPT
A partition table is what divides a single physical disk into the separate regions an operating system treats as independent volumes, each with its own filesystem and its own boundaries the rest of the disk is never expected to touch. BIOS vs. UEFI already names MBR and GPT as the partitioning scheme each firmware type conventionally pairs with; this article covers the two formats themselves; the VFS layer only enters the picture afterward, once a specific partition has already been located and handed to it as something resembling a plain disk.
The classic MBR
Section titled “The classic MBR”The Master Boot Record packs its partition table into the same 512-byte sector as the boot code itself and the 0x55AA boot signature, leaving room for exactly four primary partition entries, 16 bytes each, starting at a fixed offset (0x1BE) within the sector.
struct mbr_partition_entry { uint8_t boot_flag; // 0x80 = active/bootable, 0x00 otherwise uint8_t start_chs[3]; // legacy CHS address, rarely trusted today uint8_t type; // single byte identifying the filesystem/OS uint8_t end_chs[3]; uint32_t start_lba; uint32_t sector_count;} __attribute__((packed));Four entries is a hard ceiling built into the sector’s own fixed size, worked around in practice by an extended partition: one of the four primary slots is marked with a special type byte and, instead of describing an ordinary filesystem, points at a chain of further partition tables (each again in its own boot-sector-shaped block) holding any number of logical partitions linked one after another. The other consequential limit is sector_count’s 32-bit width: at the standard 512-byte sector size, that field can only address up to 2³² sectors, roughly 2 TiB, an amount many drives shipped in the years after MBR’s introduction have since exceeded, with no way for the format itself to describe anything past that boundary.
The GUID Partition Table replaces MBR’s fixed four-entry sector with a considerably larger, extensible structure, while still opening with something that looks like an ordinary MBR: a single protective MBR occupying the same first sector, its one partition entry marked with a type byte (0xEE) meaning “this entire disk is GPT,” specifically so that software that only understands MBR sees a disk that appears fully allocated rather than one it might otherwise try to reinitialize or overwrite.
struct gpt_header { char signature[8]; // "EFI PART" uint32_t revision; uint32_t header_size; uint32_t header_crc32; uint64_t my_lba; uint64_t alternate_lba; // backup header's location uint64_t partition_entries_lba; uint32_t num_partition_entries; uint32_t partition_entry_size; uint32_t partition_entry_array_crc32; // ...} __attribute__((packed));Immediately past the protective MBR sits the real GPT header, self-describing and checksummed (header_crc32 covers the header itself, partition_entry_array_crc32 covers the entries separately), followed by the partition entry array: each entry identifies its partition by a 128-bit GUID rather than a single type byte, giving GPT enough identifier space to distinguish filesystem types and specific volumes precisely, without the collisions a one-byte MBR type field is prone to as more filesystems and operating systems accumulate over decades. GPT keeps a complete backup of both the header and the entry array at the very end of the disk, referenced by the primary header’s own alternate_lba field, so a corrupted primary header (a bad primary sector, for instance) doesn’t necessarily mean the partition layout itself is lost, a redundancy MBR’s single, unmirrored sector never provided.
Implementation notes
Section titled “Implementation notes”A driver reading MBR-style CHS (cylinder-head-sector) fields at all is reading a legacy addressing scheme rarely trusted for anything beyond compatibility today; start_lba and sector_count, both already logical block addresses rather than physical geometry, are what actually matter on essentially any drive built since MBR’s early years. Locating a GPT disk’s actual usable partitions means reading partition_entries_lba and walking num_partition_entries fixed-size records from there, checking each entry’s GUID against a null GUID (all zero bytes) to distinguish an in-use slot from one that’s simply unallocated, rather than assuming every slot up to num_partition_entries names a real partition.
References
Section titled “References”- ^ UEFI Forum, UEFI Specification, Chapter 5: the formal GPT specification, including header layout, the protective MBR, and CRC32 placement.
See also
Section titled “See also”- BIOS vs. UEFI: the firmware types MBR and GPT are conventionally, though not exclusively, paired with.
- VFS: the layer that only takes over once a specific partition described here has already been located.
- Floppy Disk Controller: the CHS addressing scheme referenced above, used by the classic MBR itself.