Learn · File systems in hex

Partition tables: MBR, EBR, GPT

Before any file system can be read you need to know where it starts. That is the partition table's only job, and it does it in a few dozen bytes.

1 The Master Boot Record

The MBR is sector 0 of the disk (bytes 0–511). The first 446 bytes are boot code, followed by four 16-byte partition entries starting at 0x1BE, and the signature 55 AA at 0x1FE.

Boot code0x000–0x1BD
4 × entry0x1BE–0x1FD
55 AA0x1FE

Each entry holds a status byte, a type ID, and two numbers that matter: the start LBA (offset 8) and the number of sectors (offset 12). The CHS fields are leftovers from the 1980s and can be ignored.

partition start (bytes) = start LBA × 512 next free sector = start LBA + number of sectors

This sample disk (8 MiB) has a primary Linux partition, and an extended partition (type 05) that holds two logical partitions:

What sfdisk -l says about this disk
Check the gaps. Add start + size for each partition and compare with the next start and the disk size. Unpartitioned space is not empty space: it can hold an old, deleted partition or hidden data.

2 Logical partitions: the EBR chain

Four entries were never enough. The workaround: one entry describes an extended partition, a container. Its first sector is an Extended Boot Record (EBR), which has the same layout as an MBR but uses only two entries:

Linux numbers logical partitions from 5 upwards, in chain order. The extended partition here starts at sector 6144, so the first EBR is at byte 0x300000:

logical partition = EBR sector + entry 1 start = 6144 + 2048 = 8192 next EBR = extended start + entry 2 start = 6144 + 4096 = 10240
Two different bases. Getting the relative starts wrong is the classic EBR mistake. Use the formula and check that the result holds a boot sector or superblock.

3 GPT: the GUID Partition Table

Modern disks use GPT (part of UEFI). It keeps a protective MBR in sector 0, so old tools see one partition of type EE spanning the whole disk and leave it alone:

The real table starts at LBA 1 with the header (signature EFI PART). It records where the entry array lives, how many entries it has (normally 128 × 128 bytes), the usable sector range, the disk GUID, and two CRC32 checksums: one over the header itself and one over the entry array.

Each entry has a type GUID (what kind of partition), a unique GUID, first and last LBA (inclusive!), attribute flags and a UTF-16 name. Partition 3 here has attribute bit 62 set, which Windows reads as "hidden".

What sgdisk -p says about this disk

The backup header

A copy of the header sits in the last sector of the disk, with the entry array right before it. Its "current" and "backup" LBA fields are swapped, so its CRC differs while the entries CRC is the same. If someone edits only the primary table, the backup gives them away.

Mixed-endian GUIDs. The first three groups of a GUID are stored little-endian: the type GUID C12A7328-F81F-11D2-… (EFI System) appears on disk as 28 73 2A C1 1F F8 D2 11 ….

4 Try it yourself

Answer from the hex views above. Numbers can be typed in decimal or hex (0x…).

How many sectors long is the first primary partition in the MBR?

Partition entry 1 starts at 0x1BE. The size is a 4-byte little-endian number at offset 12 of the entry.

Entry 1 + 12 = 0x1CA. The bytes are 00 10 00 00. Read little-endian: 0x00001000 = 4,096 sectors (2 MiB).

It starts at 2,048, so the next free sector is 2,048 + 4,096 = 6,144: exactly where the extended partition begins. No gap.

How many bytes is logical partition 6 (the second logical partition, described by the second EBR)?

Read "Number of sectors" in entry 1 of the EBR at 0x500000, then multiply by 512.

EBR 2, entry 1 at 0x5001BE: number of sectors at +0x0C = 00 10 00 00 = 0x1000 = 4,096.

4,096 × 512 = 2,097,152 bytes (2 MiB). The relative start does not matter here: the two different bases only affect where a partition begins.

How many sectors does GPT partition 2 ("Linux data") span?

GPT stores the first and the last LBA, both 8-byte little-endian, at +0x20 and +0x28 of the entry. The last LBA belongs to the partition.

Entry 2 starts at 0x480. First LBA 00 18 00 00 00 00 00 00 = 6,144; last LBA FF 2F 00 00 00 00 00 00 = 0x2FFF = 12,287.

Inclusive range: 12,287 − 6,144 + 1 = 6,144 sectors (3 MiB). Forgetting the + 1 is the usual off-by-one.

The type GUID of GPT partition 3 is EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (Microsoft basic data). Which 4 bytes are stored first on disk?

The first group (32 bits) is stored little-endian. Look at the first bytes of entry 3 at 0x500.

The group EBD0A0A2 is a 32-bit number. Little-endian puts its lowest byte first: A2 A0 D0 EB. The next two groups follow the same rule (E5 B9, 33 44); the last two groups (87 C0 …) are stored as written.

These are the 16 bytes of MBR partition entry 1. Edit them and watch the decoded MBR below:

  • Change the status byte 80 to 00, then to 12. Only 80 and 00 are valid.
  • Change the type byte at +4 from 83 to 07. The bytes of the partition are unchanged; only the label a tool shows is different.
  • Change the start LBA at +8 from 00 08 00 00 to 00 10 00 00. Where does the partition end now, and what does it overlap?