Understanding MBR’s 4-Partition Limit: Technical Deep Dive for Developers


1 views

The Master Boot Record (MBR) partitioning scheme dates back to the early 1980s with IBM PC DOS 2.0. The original design allocated exactly 64 bytes for the partition table in the MBR structure, with each partition entry requiring 16 bytes. This fundamental design choice established the 4-partition limit:

struct PartitionEntry {
    uint8_t  boot_flag;       // 1 byte
    uint8_t  start_CHS[3];    // 3 bytes
    uint8_t  partition_type;  // 1 byte
    uint8_t  end_CHS[3];      // 3 bytes
    uint32_t start_LBA;       // 4 bytes
    uint32_t size_sectors;    // 4 bytes
};                            // Total = 16 bytes

The MBR resides in the first sector (512 bytes) of a storage device, with this strict layout:

+---------------------+
| Bootstrap Code      | (440 bytes)
| Disk Signature      | (4 bytes)
| Null                | (2 bytes)
| Partition Table     | (64 bytes - 4 entries × 16 bytes)
| Boot Signature      | (2 bytes)
+---------------------+

To demonstrate how partitions are actually read from disk, here's a Python example using direct disk access:

import struct

def read_mbr(device):
    with open(device, 'rb') as f:
        mbr = f.read(512)
    
    # Parse partition entries (starts at offset 446)
    partitions = []
    for i in range(4):
        offset = 446 + i * 16
        entry = mbr[offset:offset+16]
        partitions.append(struct.unpack('

While limited to four primary partitions, the extended partition concept was introduced to overcome this constraint. Here's how Linux tools handle this:

# Creating extended and logical partitions example:
fdisk /dev/sda
> n   # new partition
> e   # extended partition
> 3   # partition number
> +10G # size

# Then create logical partitions within the extended space
> n
> l   # logical partition
> +2G

Modern systems use GUID Partition Table (GPT) which supports up to 128 partitions by default. Here's how to check partition style in Windows PowerShell:

Get-Disk | Select-Object Number, PartitionStyle

When converting from MBR to GPT, be aware of these critical factors:

  • BIOS vs UEFI firmware compatibility
  • Operating system boot requirements (Windows requires UEFI for GPT boot)
  • Backup strategies before conversion

Here's a safe conversion command using gdisk:

gdisk /dev/sda
> r   # recovery/transformation menu
> g   # convert MBR to GPT
> w   # write to disk
> y   # confirm

The 4-primary-partition limitation stems from the original IBM PC architecture designed in the early 1980s. The Master Boot Record (MBR) partitioning scheme reserves exactly 64 bytes for partition entries in its data structure, with each partition entry requiring 16 bytes. This creates the mathematical limit: 64 bytes / 16 bytes per partition = 4 partitions.

Here's the actual structure definition from modern operating systems (Linux kernel example):


struct partition {
    unsigned char bootable;    // 0x80 = bootable
    unsigned char start_head;  // starting head
    unsigned char start_sector:6; // starting sector
    unsigned char start_cylinder_hi:2; // high 2 bits of cylinder
    unsigned char start_cylinder_lo; // low 8 bits of cylinder
    unsigned char type;        // partition type
    unsigned char end_head;    // ending head
    unsigned char end_sector:6;   // ending sector
    unsigned char end_cylinder_hi:2; // high 2 bits of ending cylinder
    unsigned char end_cylinder_lo; // low 8 bits of ending cylinder
    unsigned int start_lba;    // starting LBA
    unsigned int size;         // size in sectors
} __attribute__((packed));

To overcome this limitation while maintaining backward compatibility, the extended partition concept was introduced. An extended partition serves as a container for logical partitions. Here's how to create one using fdisk:


# Start fdisk on device /dev/sda
sudo fdisk /dev/sda

Command (m for help): n   # Create new partition
Partition type:
   p   primary (0 primary, 0 extended, 4 free)
   e   extended
Select (default p): e    # Choose extended partition
Partition number (1-4, default 1): 1
First sector (2048-20971519, default 2048): [Enter]
Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519): [Enter]

Command (m for help): n   # Now create logical partitions
Partition type:
   p   primary (0 primary, 1 extended, 3 free)
   l   logical (numbered from 5)
Select (default p): l    # Create logical partition

For systems needing more partitions or larger disk support (beyond 2TB), GPT (GUID Partition Table) is the modern replacement. GPT allows:

  • 128 partitions by default (can be extended)
  • Support for disks up to 9.4 zettabytes
  • Improved data integrity with CRC32 checksums

Conversion example from MBR to GPT using gdisk:


sudo gdisk /dev/sda
Command (? for help): w   # write table to disk

When working with older systems that require MBR, you can implement a hybrid approach. The Linux kernel's CONFIG_EFI_PARTITION configuration option supports this dual scheme. Sample GRUB configuration for hybrid boot:


menuentry 'Hybrid MBR/GPT System' {
    insmod part_gpt
    insmod part_msdos
    set root='(hd0,gpt2)'
    linux /vmlinuz root=/dev/sda2
}