分析硬盘mbr分区表,手工计算每个分区大小

这个帖子源于我发的另一篇询问“怎样把知道把grub安装到mbr还是boot sector上”的文章,结论是我还没有什么快捷办法来得知grub的安装信息,只好用dd导出mbr进行分析了,顺便照着网上介绍的计算了一下其中的分 区表(DPT)部分,最后用win下的winhex验证了一下。这里把计算方法和大家分享一下,如果有错误请帮忙告诉我。
先说说我前一个帖子的问题:
用dd导出mbr后如果是grub则里面应该有“GRUB Geom Hard Disk Read Error”字符串,如果是ntldr则里面没有,取而代之的可能是“Missing operating system”字符串(ntldr的我没试验)。

下面看看我分析DPT的过程。

我的分区结构:
hda 标称为60G的硬盘
+
|— hda1 linux /boot ext3
|— hda2 winxp c: ntfs
|— hda3 extension
+
|— hda5 linux swap swap
|— hda6 linux / ext3
|— hda7 winxp d: ntfs

我的mbr中的DPT(disk partition table)部分,也就是从hda的第1个sector后偏移为0x01BE开始,到0x01FD结束的区域,大小为 0x01FD – 0x01BE + 0x1 = 0x40 = 64(dec) Byte。
这64B分为4个16B,每一个16B保存一个主分区的信息,所以最多可以有4个主分区,而我的hda只划出了3个主分区:hda1, hda2, hda3
每个16B都包含它描述的分区的8个信息,下面分别用(1)~(8)讲解。下面用(dec)标注的是10进制数,其余的大多为16进制或2进制,看情况自己判断。

1. 先看我的DPT中第1个16B,它描述的是我的 hda1 – linux /boot 分区:
offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
01B0   hh hh hh hh hh hh hh hh hh hh hh hh hh hh 00 01
01C0   01 00 83 FE 3F 0C 3F 00 00 00 8E 2F 03 00

(1)
offset from 01BE: 00
offset: 01BE
80表示该分区为active,而我的是00,表示我的hda1不为active。

(2)
offset from 01BE: 01
offset: 01BF
表示开始磁头,我的为 01

(3)
offset from 01BE: 02,03
offset: 01C0,01C1
表示开始扇区和开始柱面,我的为01 00,具体这么算:
把 01 00 化为二进制,
0000 0001,0000 0000
其中第一个字节的低6位是开始扇区,这里就是 000001
在第二个字节高位前再添加第一个字节的最高两位构成开始柱面,这里是 00 0000 0000
开始柱面是个10位二进制数,最大能表示2^10-1 = 1023(dec)

(4)
offset from 01BE: 04
offset: 01C2
指定系统ID(System ID) 定义了分区的类型,一般的有:
07: HPFS/NTFS
83: linux
82: linux swap
01: FAT32
06: FAT16

这里我的为83,表示我的hda1 – ext3

(5)
offset from 01BE: 05
offset: 0x01C3
结束磁头,我的为 FE = 254(dec)

(6)
offset from 01BE: 06,07
offset: 01C4,01C5
表示结束扇区和结束柱面,我的为3F 0C,算法和计算开始扇区、柱面一样,
把 3F 0C 化为二进制,
0011 1111,0000 1100
其中第一个字节的低6位是结束扇区,这里就是 111111 = 63(dec)
在第二个字节高位前再添加第一个字节的最高两位构成结束柱面,这里是 00 00001100 = 12(dec)

(7)
offset from 01BE: 08,09,0A,0B
offset: 01C6,01C7,01C8,01C9
这4个字节构成一个双字(DWORD)整数,表示相对扇区数(Relative Sectors),即从该磁盘的开始到该分区的开始的位移量(以扇区为单位)。注意,这里的数据采用little-edian的方式存贮DWORD数(数 学上的低位放在低字节),所以这里的3F 00 00 00 就表示数学上的0x0000003F = 63(dec)

(8)
offset from 01BE: 0C,0D,0E,0F
offset: 01CA,01CB,01CC,01CD
这4个字节构成一个DWORD整数,表示总扇区数(Total Sectors),即该分区中的扇区总数,这里为 8E 2F 03 00,表示数学上的0x00032F8E = 208782(dec),一个扇区为512B,则这个分区的大小为: 208782 * 512B = 106896384 B = 104391 KB = 101.944 MB,这就是我的hda1 – linux /boot的大小。

2. 再看看我的第2个16B,它描述的是我的 hda2 – winxp c: 分区
offset 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
01C0   HH HH HH HH HH HH HH HH HH HH HH HH HH HH 80 00
01D0   01 0D 07 FE BF DC CD 2F 03 00 D0 7E B0 00

(1)
offset from 01CE: 00
offset: 01CE
80表示该分区为active,这就是有人说的grub把win盘置为active的结果,也就是grub引导项中makeactive指令起作用的地方。

(2)
offset from 01CE: 01
offset: 01CF
表示开始磁头,这里为00,不要为hda2的磁头号排在hda1之前感到奇怪,我开始也感觉到奇怪,可是仔细想想就明白了,应该是这么一个3维量<柱面号, 磁头号, 扇区>,柱面号才是主序(可以联系2维数组来考虑),所以柱面号才是递增的,而不是磁头号。

(3)
offset from 01CE: 02,03
offset: 01D0,01D1
开始扇区和开始柱面,这里为 01 0D,化为二进制,
0000 0001,0000 1101
第一个字节的低6位是开始扇区,这里就是 000001
在第二个字节高位前再添加第一个字节的最高两位构成开始柱面,这里是 00 0000 1101 = 13

(4)
offset from 01CE: 04
offset: 01D2
指定系统ID(System ID)
这里我的为07,表示我的hda2 – ntfs

(5)
offset from 01CE: 05
offset: 0x01D3
结束磁头,我的为 FE = 254(dec)

(6)
offset from 01CE: 06,07
offset: 01D4,01D5
结束扇区和结束柱面,我的为BF DC,化为二进制,
1011 1111,1101 1100
其中第一个字节的低6位是结束扇区,这里就是 111111 = 63(dec)
在第二个字节高位前再添加第一个字节的最高两位构成结束柱面,这里是 10 11011100 = 732(dec)

(7)
offset from 01CE: 08,09,0A,0B
offset: 01D6,01D7,01D8,01D9
相对扇区数(Relative Sectors),这里的CD 2F 03 00 就表示数学上的0x00032FCD = 208845(dec)

(8)
offset from 01CE: 0C,0D,0E,0F
offset: 01DA,01DB,01DC,01DD
总扇区数(Total Sectors),这里为 D0 7E B0 00,表示数学上的0x00B07ED0 = 11566800(dec),则这个分区的大小为: 11566800 * 512B = 5922201600 B = 5.515 GB,这就是我的hda2 – winxp c:的大小。

还有一个hda3 – extension的主分区,就是能包含若干个逻辑分区的家伙,这里就不贴出来了,大家回去自己试试吧。
(上面的计算结果均在winhex下验证过,不过原理上哪里有错误的还请高人指教)

from http://www.linuxsir.org/bbs/thread280076.html

发表评论?

0 条评论。

发表评论