A raw image of a hard disk or memory card has no header of its own: it starts with whatever the disk starts with, which is usually a master boot record (MBR) in the first 512-byte sector. The MBR comes from the IBM PC and was never formally standardised. Numbers are little-endian.
Sources: the MASTER_BOOT_RECORD and MBR_PARTITION_RECORD
structures in EDK2, the UEFI reference implementation
(MdePkg/Include/IndustryStandard/Mbr.h); util-linux’s
include/pt-mbr.h and include/pt-mbr-partnames.h; and Andries
Brouwer’s Minimal partition table specification (1999) and List of
partition identifiers for PCs; and the UEFI Specification 2.10, section
5.2 (read from the Internet Archive’s copy), which describes the legacy MBR, says UEFI
firmware never runs its boot code or uses its boot indicator and CHS fields, and
defines only types EE and EF, pointing to Brouwer’s list for
the rest.
Sector 0
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 440 | code | Boot code | Boot-strap code (EDK2: BootStrapCode). |
440 | 4 | uint32 | Disk signature | A number the operating system may use to tell the disk from others; written by the OS, never by firmware (UEFI Table 5.1; EDK2 UniqueMbrSignature; util-linux’s disk identifier). |
444 | 2 | – | Unknown | EDK2 names these two bytes Unknown. |
446 | 64 | entries | Partition table | Four 16-byte partition entries, at 446, 462, 478 and 494. |
510 | 2 | bytes | Signature | 55 AA (0xAA55 read little-endian). Brouwer: every partition table sector must carry it. |
Partition entry
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 1 | uint8 | Boot indicator | 80 marks the bootable legacy partition (UEFI Table 5.2; util-linux: active); other values mean not bootable. |
1 | 3 | CHS | Starting CHS | The first sector as cylinder, head, sector; see CHS. |
4 | 1 | uint8 | Partition type | What the partition holds; see types. 00 means the entry is unused. |
5 | 3 | CHS | Ending CHS | The last sector as cylinder, head, sector. |
8 | 4 | uint32 | Starting LBA | The first sector, counted from 0 (relative values in an extended partition: see below). |
12 | 4 | uint32 | Size | Number of sectors. Brouwer: an entry whose size is 0 is ignored. With 32-bit fields an MBR reaches 232 sectors, 2 TiB on 512-byte sectors. |
CHS addresses
Three bytes (Brouwer, section 2.2): the head, 0 to 255; then a byte whose low 6 bits are the sector, 1 to 63, and whose top 2 bits are bits 8–9 of the cylinder; then the low 8 bits of the cylinder, 0 to 1,023:
h = byte1; s = byte2 & 0x3f; c = ((byte2 & 0xc0) << 2) + byte3;
The values depend on a made-up geometry of H heads and S
sectors per track. util-linux’s fdisk fills them in as cylinder = LBA ÷ (H ×
S), head = (LBA ÷ S) mod H, sector = LBA mod
S + 1, so LBA = (cylinder × H + head) × S + sector − 1.
When the cylinder would pass 1,023 it uses the last addressable sector instead
(H × S × 1,024 − 1), which with 255 heads and 63 sectors gives
the bytes FE FF FF. Brouwer: as 24 bits cannot address more than
224 sectors, such CHS addresses should be ignored and the LBA fields
used.
Extended partitions
To have more than four partitions, a primary entry is an extended partition: Brouwer
lists types 05, 0F and 85 as extended (EDK2
defines the first two as EXTENDED_DOS_PARTITION and
EXTENDED_WINDOWS_PARTITION). Its first sector is another partition table
sector, with the same table at 446 and the same 55 AA signature, often
called an extended boot record (EBR). Brouwer’s rules (sections 2.4–2.6):
- A partition table sector other than the MBR has at most two used entries.
- An entry whose type is not extended is a logical partition; its starting LBA is an offset from the partition table sector holding the entry.
- An entry whose type is extended points to the next partition table sector; its starting LBA is an offset from the first sector of the primary extended partition. Only its start matters; its size need only be non-zero.
So the first sector of each primary extended partition heads a linked list of partition table sectors, usually one per logical partition.
Partition types
No body assigns MBR partition types; the IDs grew by custom, and many have been used
for more than one thing. The table gives every type util-linux’s fdisk names
(include/pt-mbr-partnames.h), with the description from Brouwer’s
List of partition identifiers for PCs where it adds to it. Brouwer’s list
records many more uses of each ID, and IDs fdisk does not name.
| ID | fdisk name | Brouwer’s description |
|---|---|---|
00 | Empty | Empty: an unused entry |
01 | FAT12 | DOS 12-bit FAT |
02 | XENIX root | |
03 | XENIX usr | |
04 | FAT16 <32M | DOS 3.0+ 16-bit FAT (up to 32M) |
05 | Extended | DOS 3.3+ extended partition |
06 | FAT16 | DOS 3.31+ 16-bit FAT (over 32M) |
07 | HPFS/NTFS/exFAT | OS/2 IFS (e.g. HPFS); Windows NT NTFS; exFAT |
08 | AIX | |
09 | AIX bootable | |
0A | OS/2 Boot Manager | |
0B | W95 FAT32 | WIN95 OSR2 FAT32 |
0C | W95 FAT32 (LBA) | WIN95 OSR2 FAT32, LBA-mapped |
0E | W95 FAT16 (LBA) | WIN95: DOS 16-bit FAT, LBA-mapped |
0F | W95 Ext’d (LBA) | WIN95: extended partition, LBA-mapped |
10 | OPUS | |
11 | Hidden FAT12 | Hidden DOS 12-bit FAT |
12 | Compaq diagnostics | Configuration/diagnostics partition |
14 | Hidden FAT16 <32M | Hidden DOS 16-bit FAT <32M |
16 | Hidden FAT16 | Hidden DOS 16-bit FAT >=32M |
17 | Hidden HPFS/NTFS | Hidden IFS (e.g. HPFS) |
18 | AST SmartSleep | |
1B | Hidden W95 FAT32 | Hidden WIN95 OSR2 FAT32 |
1C | Hidden W95 FAT32 (LBA) | Hidden WIN95 OSR2 FAT32, LBA-mapped |
1E | Hidden W95 FAT16 (LBA) | Hidden WIN95 16-bit FAT, LBA-mapped |
24 | NEC DOS | |
27 | Hidden NTFS WinRE | PQservice; Windows RE hidden partition; MirOS; RouterBOOT kernel |
39 | Plan 9 | Plan 9 partition |
3C | PartitionMagic recovery | PartitionMagic recovery partition |
40 | Venix 80286 | |
41 | PPC PReP Boot | |
42 | SFS | Windows 2000 dynamic extended partition marker |
4D | QNX4.x | QNX4.x |
4E | QNX4.x 2nd part | QNX4.x 2nd part |
4F | QNX4.x 3rd part | QNX4.x 3rd part; Oberon partition |
50 | OnTrack DM | |
51 | OnTrack DM6 Aux1 | |
52 | CP/M | CP/M |
53 | OnTrack DM6 Aux3 | |
54 | OnTrackDM6 | |
55 | EZ-Drive | |
56 | Golden Bow | |
5C | Priam Edisk | |
61 | SpeedStor | |
63 | GNU HURD or SysV | Unix System V (SCO, ISC Unix, UnixWare, …), Mach, GNU Hurd |
64 | Novell Netware 286 | Novell Netware 286, 2.xx |
65 | Novell Netware 386 | Novell Netware 386, 3.xx or 4.xx |
70 | DiskSecure Multi-Boot | |
75 | PC/IX | |
80 | Old Minix | MINIX until 1.4a |
81 | Minix / old Linux | MINIX since 1.4b, early Linux |
82 | Linux swap / Solaris | Linux swap; Solaris x86 |
83 | Linux | Linux native partition |
84 | OS/2 hidden or Intel hibernation | OS/2 hidden C: drive; hibernation partition |
85 | Linux extended | Linux extended partition |
86 | NTFS volume set | FAT16 volume set |
87 | NTFS volume set | NTFS volume set |
88 | Linux plaintext | Linux plaintext partition table |
8E | Linux LVM | Linux Logical Volume Manager partition |
93 | Amoeba | Hidden Linux native partition; Amoeba |
94 | Amoeba BBT | Amoeba bad block table |
9F | BSD/OS | BSD/OS |
A0 | IBM Thinkpad hibernation | Laptop hibernation partition |
A5 | FreeBSD | BSD/386, 386BSD, NetBSD, FreeBSD |
A6 | OpenBSD | OpenBSD |
A7 | NeXTSTEP | |
A8 | Darwin UFS | Mac OS-X |
A9 | NetBSD | NetBSD |
AB | Darwin boot | Mac OS-X Boot partition; GO! partition |
AF | HFS / HFS+ | MacOS X HFS |
B7 | BSDI fs | BSDI BSD/386 filesystem; corrupted Windows NT mirror set (master) |
B8 | BSDI swap | BSDI BSD/386 swap partition |
BB | Boot Wizard hidden | Boot Wizard hidden |
BC | Acronis FAT32 LBA | Acronis backup partition |
BE | Solaris boot | Solaris 8 boot partition |
BF | Solaris | New Solaris x86 partition |
C1 | DRDOS/sec (FAT-12) | DRDOS/secured (FAT-12) |
C4 | DRDOS/sec (FAT-16 < 32M) | |
C6 | DRDOS/sec (FAT-16) | |
C7 | Syrinx | |
DA | Non-FS data | Non-FS Data |
DB | CP/M / CTOS / … | Digital Research CP/M, Concurrent CP/M, Concurrent DOS; CTOS |
DE | Dell Utility | Dell PowerEdge Server utilities (FAT fs) |
DF | BootIt | DG/UX virtual disk manager partition; BootIt EMBRM |
E0 | NX emuMMC | |
E1 | DOS access | DOS access or SpeedStor 12-bit FAT extended partition |
E3 | DOS R/O | DOS R/O or SpeedStor |
E4 | SpeedStor | SpeedStor 16-bit FAT extended partition < 1024 cyl. |
EA | Linux extended boot | |
EB | BeOS fs | BeOS BFS |
EE | GPT | This legacy MBR is followed by an EFI header: see protective MBR (EDK2: PMBR_GPT_PARTITION) |
EF | EFI (FAT-12/16/32) | Partition that contains an EFI file system (EDK2: EFI_PARTITION) |
F0 | Linux/PA-RISC boot | Linux/PA-RISC boot loader |
F1 | SpeedStor | |
F2 | DOS secondary | DOS 3.3+ secondary partition |
F4 | SpeedStor | |
F8 | EBBR protective | |
FB | VMware VMFS | VMware File System partition |
FC | VMware VMKCORE | VMware Swap partition |
FD | Linux raid autodetect | Linux raid partition with autodetect using persistent superblock |
FE | LANstep | SpeedStor > 1024 cyl.; LANstep; Windows NT Disk Administrator hidden partition |
FF | BBT | Xenix Bad Block Table |
Example
The end of sector 0 of an SD card image with a FAT32 boot partition and a Linux root partition.
000001B0 00 00 00 00 00 00 00 00 4D 2C 1B 0A 00 00 00 20 ........M,.....
000001C0 21 00 0C C2 22 20 00 08 00 00 00 00 08 00 00 C2 !..." ..........
000001D0 23 20 83 A7 7E E9 00 08 08 00 00 00 70 00 00 00 # ..~.......p...
000001E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 AA ..............U.
Reading it: disk signature 0x0A1B2C4D. Entry 1 at 0x1BE: not active;
starts at head 32, sector 33, cylinder 0; type 0C, FAT32 (LBA); ends at
head 194, sector 34, cylinder 32; starting LBA 0x800 (2,048, 1 MiB in);
size 0x80000 sectors (256 MiB). Entry 2 at 0x1CE: type 83,
Linux; starting LBA 0x80800 (526,336), right after the first; size
0x700000 sectors (3.5 GiB); its ending CHS byte 7E carries
cylinder bit 8, so the cylinder is 0x1E9, 489. Entries 3 and 4 are empty;
the sector ends 55 AA.