MBR,GPT与Boot Camp

MBR

作为BIOS时代的分区管理格式,MBR (Master Boot Record)已经走过了31个年头。1982年,MBR被引入IBM PC DOS 2.0,用来支持10MB大小的硬盘。

MBR的结构非常简单。前面446字节是引导代码,接着4条16字节的主分区信息,最后是两个字节的签名(魔数):

Start Size Description
0 446 Boot code
446 16 Primary partition entry 1
462 16 Primary partition entry 2
478 16 Primary partition entry 3
494 16 Primary partition entry 3
510 2 Signature (0xaa55)

这么看每个磁盘的分区数被限死在了4个,不过后来又引入了扩展分区技术(EBR)解决(或者说是绕过)了这个问题。简单来说,EBR就是把最后一个主分区特别对待,这个分区(又称扩展分区)的第一个扇区看成是一个MBR,又叫EBR,不过不同的是EBR只用了前两个分区项(同样从446字节处开始),第一项指明了新的普通分区,而第二项除了可以指新的普通分区外,还可能用来指向新的扩展分区。这样通过链表的形式把非主分区(又称逻辑分区)给串起来。下面这两张张图(来自MSDN)基本说明了是怎么回事:

 

上图前三个主分区项都指向了普通分区,最后一项指向了扩展分区。下图则演示了扩展分区的细节:

 

EBR

扩展分区里只用了两项分区项,第一项指向普通分区,第二项指向下一个扩展分区。前一级扩展分区总是涵盖了后面的所有分区,形成了嵌套的链接关系。

这样的做法缺点很明显,链表当中要是断了,后面的可就都丢掉了。另外要让一些主流操作系统从分主分区启动也要花一些功夫。

下面简单说说分区项的具体内容:

Start Size Descripton
0 1 Status (0×80 = boot flag)
1 3 CHS start (deprecated, use 0xfeffff)
4 1 Partition type
5 3 CHS end (deprecated, 0xfeffff)
8 4 LBA start (in sectors)
12 4 LBA size (in sectors)

可以看到一个明显的限制是磁盘的大小。LBA的宽度只有4个字节,这样只能用来描述最大2TB的磁盘,再大就不够了(有别的hack,不过至少肯定不能用来当启动盘)。另外分区类型最多256种,不够描述当今所有的文件系统类型(包括操作系统)。MBR格式(以及其背后的BIOS)过于古老,严重阻碍了新技术的推广。但是PC市场这么大,想要改也没那么容易,涉及到硬件软件以及大量第三方公司和整个产业链。

EFI

Intel和HP在90年代一起研发Itanium的时候,就打算趁引入新架构的机会也把老掉牙的BIOS踢到一边去。98年搞了一个项目叫Intel Boot Initiative,后来更名为EFI,2005年又更名为现在的名字UEFI。Itanium算是没做起来,UEFI这些年的势头开始起来了,除了Intel架构的Mac以外,Windows 8的加入无疑将大大加速UEFI的推广(虽然Secure Boot备受争议)。

EFI的一个组成部分是规定了新的磁盘分区格式GPT(GUID Partition Table)。首先GPT支持最高达8ZB(4PB*2M)的磁盘容量(在可见的未来足够了),以及最多128项磁盘分区。另外出于保护数据的目的,分区表在磁盘上存放了两份,分别放在磁盘的开头和结尾,以防以外丢失。

保护MBR(Protective MBR)

由于市场上大量非EFI机器的存在,GPT通过保护MBR来达成与MBR的兼容,或者说是保护GPT分区不被非EFI机器破坏。方法很简单,结合上面MBR的描述就可以明白:

  1. 占领MBR的第一项分区项;
  2. 分区类别设定为特殊类型;
  3. 起始地址为扇区1;
  4. 分区大小为磁盘大小-1。

这样非EFI机器读MBR的时候,就会发现整个磁盘已经被别的分区全部占满了,而用户也不会轻易的重新分区。这就是所谓的“保护性”。

GPT头和分区项

GPT头描述了磁盘和分区表的基本信息,如磁盘的GUID和分区表的大小。分区项最多有128项,一般4项为一个单位。分区项每项占128字节:

Start Size Descrption
0 16 Partition type GUID
16 16 Unique Partion GUID
32 8 Start LBA
40 8 Last LBA
48 8 Flags
56 72 Partition name

(令人意外的是,分区类型虽然是GUID,不过已经有冲突了)

GPT和MBR这两种磁盘分区格式可以说是天差地别,融合起来可不是很容易。不过好在GPT给MBR让出了扇区0作为保护MBR,在一个磁盘上支持两种分区格式也成为可能。典型的做法是Boot Camp的实现。

Boot Camp

苹果在2005年宣布使用Intel作为Mac平台以后,由于控制了硬件软件平台,使得它应用EFI没有什么问题。不过大部分Windows并不支持GPT而只能从MBR磁盘启动,苹果也提供了Boot Camp方便使用者在Mac上安装双系统。

Boot Camp的原理是混合MBR (Hybrid MBR)。利用MBR里的空余主分区项,使得一个分区在两个分区表里都有份。

前面说过了保护性MBR的做法是把整个磁盘写成一个大分区,这时候这个大分区被Mac OSX占据了。如果我们把Mac OSX分区缩小(比如一半),那后面一半分区就可以腾出来给Windows用了。要做到这一步很简单,只需要把保护性MBR里那条特殊的分区项的分区大小改小就可以了,另外需要往MBR里再加一条分区项(并设置成启动),描述后面半个磁盘上的Windows分区。

操作系统按道理可以安装启动了,不过下一步我们还需要在两个操作系统里分别都能看到对方操作系统的分区,至少方便拷贝数据(假定都有相应文件系统的驱动)。对于Windows来说,由于MBR里已经有两条分区项充分描述了这两个分区,所以Windows里能够看到两个分区;但是对于Mac OSX来说,它只认识GPT的分区,所以还看不到Windows的分区。当然这也很简单,只要往GPT分区表里加一条描述Windows分区的分区项就可以了。

具体来说Boot Camp做了三件事:

  • 把Mac OSX分区缩小(Shrink HFS+)
  • 改动GPT和MBR的分区表;
  • 在启动菜单里加上其他操作系统的选项,另外给其他操作系统提供驱动。

下面是我启用了Boot Camp的MBR导出结果:

00fe ffff eefe ffff 0100 0000 2740 0600   <<<< EFI partition (200M ESP)
00fe ffff affe ffff 2840 0600 0047 0740   <<<< Mac main partition, size 0×40074700 (512G)
00fe ffff abfe ffff 2887 0d40 205f 1300   <<<< Mac recovery partition
80fe ffff 07fe ffff 00e8 2040 0078 3317   <<<< Windows partition, size 0×1733008 (185G), boot bit             
                                               (first bit) is set

或者是用fdisk导出结果

wum@dev$ sudo fdisk -d /dev/rdisk0

1,409639,0xEE,-,1023,254,63,1023,254,63
409640,1074218752,0xAF,-,1023,254,63,1023,254,63
1074628392,1269536,0xAB,-,1023,254,63,1023,254,63
1075898368,389249024,0×07,*,1023,254,63,1023,254,63

参考文献

Hybrid MBRs

What's a GPT?

Apple support of GPT

此条目发表在 Mac OSX & iOS, 文件系统 分类目录。将固定链接加入收藏夹。