3、分区表的结构:MBR与GPT的底层拆解

分区表这东西,说白了就是一张“地图”。BootROM 上电后,得靠这张地图找到操作系统在哪儿。我早年做嵌入式开发时,亲手写过一段从 MBR 里捞内核地址的代码,那会儿才真正理解——分区表的结构,直接决定了启动流程怎么走。

今天咱们就把 MBR 和 GPT 这两张地图,从底层到上层,掰开揉碎讲清楚。

3.1 MBR 结构:传统但依然活跃

MBR(Master Boot Record)诞生于 DOS 时代,结构极其紧凑。它总共只有 512 字节,放在磁盘的 0 号扇区(LBA 0)。

这 512 字节被分成三块:

偏移地址 大小 内容 说明
0x000 - 0x1BD 446 字节 引导代码(Boot Code) 第一阶段引导程序,负责加载活动分区中的 VBR
0x1BE - 0x1FD 64 字节 分区表(Partition Table) 4 个分区表项,每项 16 字节
0x1FE - 0x1FF 2 字节 签名(Signature) 固定为 0x55AA,标识这是一个有效的 MBR

核心要点:MBR 的 512 字节是硬性限制。引导代码 + 分区表 + 签名,一个字节都不能多。这也是为什么 MBR 最多只支持 4 个主分区——64 字节分区表,每项 16 字节,刚好 4 项。

3.1.1 引导代码(Boot Code)

这 446 字节是 CPU 上电后最早执行的用户代码(在 BIOS 阶段)。它的任务很简单:

  • 扫描分区表,找到标记为“活动”(Active)的分区
  • 将该分区的第一个扇区(VBR)加载到内存
  • 跳转到 VBR 继续执行

我在一个老旧工控项目里遇到过一个问题:引导代码被意外覆盖,磁盘数据全在,但就是启动不了。排查了半天,最后用 hexdump 一看,0x55AA 还在,但引导代码区域全是 0x00。嗯,那之后我养成了习惯——每次烧写固件前,先备份 MBR 的前 446 字节。

3.1.2 分区表(Partition Table)

每个分区表项 16 字节,结构如下:

偏移 大小 字段 说明
0x00 1 字节 引导标志 0x80 = 活动分区,0x00 = 非活动
0x01-0x03 3 字节 起始 CHS 地址 磁头/扇区/柱面(已过时,但兼容保留)
0x04 1 字节 分区类型 如 0x0C = FAT32,0x83 = Linux ext
0x05-0x07 3 字节 结束 CHS 地址 同上,历史遗留
0x08-0x0B 4 字节 起始 LBA 地址 逻辑块地址,这才是现代系统用的
0x0C-0x0F 4 字节 分区总扇区数 该分区占用的扇区数量

注意:MBR 分区表使用 32 位 LBA 地址,最大只能寻址 2^32 × 512 字节 = 2 TB。超过 2 TB 的磁盘,必须用 GPT。我曾经被这个坑过——客户买了个 4 TB 硬盘,用 MBR 分区,结果只认出来 2 TB,数据全写在前面 2 TB 里,后面 2 TB 直接“消失”。

3.1.3 签名(0x55AA)

最后两个字节必须是 0x55 0xAA(注意是小端序,磁盘上看到的是 0x55 0xAA,但作为 16 位值读出来是 0xAA55)。

BootROM 或 BIOS 在加载 MBR 后,会检查这个签名。如果不匹配,就认为磁盘不可引导。你想想看,如果签名被破坏,整个磁盘就像“失忆”了一样——数据全在,但系统不认。

3.2 GPT 结构:现代系统的选择

GPT(GUID Partition Table)是 UEFI 时代的产物。它解决了 MBR 的三大痛点:

  • 最大磁盘容量从 2 TB 扩展到 9.4 ZB(2^64 扇区)
  • 主分区数量从 4 个扩展到理论上无限制(实际受分区表大小限制)
  • 增加了备份分区表,容错性更强

GPT 的磁盘布局是这样的:

LBA 0:     保护 MBR(Protective MBR)
LBA 1:     GPT 头(GPT Header)
LBA 2-33:  分区表项(Partition Entries),默认 128 项,每项 128 字节
LBA 34+:   用户数据区域
...
最后 33 个 LBA: 分区表项备份
最后一个 LBA:   GPT 头备份

3.2.1 保护 MBR(LBA 0)

这是一个“假”的 MBR。它的作用是:

  • 让不支持 GPT 的旧系统(如老 BIOS)识别到这是一个“已分区”的磁盘
  • 防止旧工具误认为磁盘“未初始化”而覆盖数据

保护 MBR 的分区表里只有一个分区表项:

  • 分区类型:0xEE(GPT 保护分区)
  • 起始 LBA:1
  • 大小:整个磁盘大小(或 2 TB,取决于旧工具)

我见过一个案例:有人用老版本的 fdisk 直接写 MBR,结果把 GPT 的保护 MBR 覆盖了。虽然 GPT 头和数据还在,但某些系统死活不认盘。最后用 gdisk 重建保护 MBR 才救回来。

3.2.2 GPT 头(LBA 1)

GPT 头是整个分区表的“总指挥”。它的结构如下:

偏移 大小 字段 说明
0x00 8 字节 签名 "EFI PART"(45 46 49 20 50 41 52 54)
0x08 4 字节 版本号 当前为 1.0(0x00010000)
0x0C 4 字节 头大小 通常为 92 字节(0x5C)
0x10 4 字节 头 CRC32 对整个头计算校验,用于完整性检查
0x14 4 字节 保留 必须为 0
0x18 8 字节 当前 LBA GPT 头所在位置,即 LBA 1
0x20 8 字节 备份 LBA 备份 GPT 头所在位置(最后一个 LBA)
0x28 8 字节 分区表起始 LBA 通常为 LBA 2
0x30 4 字节 分区表项数量 默认 128
0x34 4 字节 每项大小 固定 128 字节
0x38 4 字节 分区表 CRC32 对整个分区表计算校验
0x3C 420 字节 保留/填充 填 0,凑够 512 字节

个人建议:调试 GPT 问题时,先检查 GPT 头的 CRC32。如果头被破坏,系统会尝试加载备份 GPT 头。我曾经用 dd 命令直接读取 LBA 1,然后用 Python 算 CRC,对比头里的值——不一致就说明有人动过 GPT 头。

3.2.3 分区表项(LBA 2-33)

每个分区表项 128 字节,结构如下:

偏移 大小 字段 说明
0x00 16 字节 分区类型 GUID 标识分区用途(如 EFI 系统分区、Microsoft 基本数据分区)
0x10 16 字节 唯一分区 GUID 每个分区的全球唯一标识
0x20 8 字节 起始 LBA 64 位,支持超大磁盘
0x28 8 字节 结束 LBA 包含关系(即分区占用 [start, end])
0x30 8 字节 属性标志 如 0x01 = 系统分区,0x02 = 隐藏
0x38 72 字节 分区名称 UTF-16LE 编码,最多 36 个字符

默认 128 个分区表项,占用 128 × 128 = 16384 字节 = 32 个扇区(LBA 2-33)。

3.2.4 分区表备份

GPT 在磁盘末尾完整备份了:

  • 分区表项(最后 33 个 LBA,与 LBA 2-33 一一对应)
  • GPT 头(最后一个 LBA)

这个设计非常实用。我记得有一次,一个同事误操作把磁盘前 64 个扇区全写零了。要是 MBR,这盘就废了。但因为是 GPT,我们用 gdisk 的恢复功能,从备份 GPT 头重建了主 GPT,数据完好无损。

关键区别:MBR 没有备份机制,一旦 0 号扇区损坏,整个分区表丢失。GPT 有主备两份,只要备份没坏,就能恢复。这也是为什么现代系统(尤其是服务器)都推荐 GPT。

3.3 MBR vs GPT:一张图看懂

下面这张 SVG 图展示了两种分区表的磁盘布局对比:

MBR 与 GPT 磁盘布局对比 MBR 磁盘布局 LBA 0: MBR (引导代码 + 分区表 + 0x55AA) LBA 1~: 用户数据 / 扩展分区 最大 2 TB,4 个主分区,无备份 GPT 磁盘布局 LBA 0: 保护 MBR LBA 1: GPT 头 LBA 2-33: 分区表项 (128项) LBA 34~: 用户数据区域 最后 33 个 LBA: 分区表项备份 最后 1 个 LBA: GPT 头备份 MBR 所有信息集中在 LBA 0,损坏即丢失 GPT 主备分离,头损坏可从备份恢复,分区表损坏也可从备份重建 核心差异对比 特性 MBR GPT 最大容量 2 TB 9.4 ZB 主分区数 4 个 128 个(可扩展) 备份机制 无 主备两份

3.4 实际项目中的选择建议

说了这么多,到底什么时候用 MBR,什么时候用 GPT?我个人的经验是这样的:

  • 2 TB 以下、传统 BIOS 启动、兼容性优先 → MBR。比如一些老旧的工控主板,只支持 BIOS 模式,用 MBR 最稳。
  • 2 TB 以上、UEFI 启动、需要可靠性 → GPT。服务器、新式 PC、嵌入式设备(如树莓派 4 以上),无脑选 GPT。
  • 混合场景 → 有些 BIOS 也支持 GPT 启动(通过 CSM 模块),但兼容性参差不齐。我建议:能用 UEFI 就用 GPT,省心。

避坑提醒:我曾经在一个项目里,为了兼容旧系统,强行在 4 TB 磁盘上用 MBR。结果系统只认前 2 TB,后面 2 TB 完全不可见。最后不得不重新分区,把数据迁移到 GPT 上。折腾了两天。所以,容量超过 2 TB,直接上 GPT,别犹豫。