- 论坛徽章:
- 2
|
上面雨丝风片结合bochs的汇编调试器详细描述了mbr的引导过程。作为上文的延续,这里我和大家一起用基于实验的手法观察PC机上FreeBSD的分区。
FreeBSD在PC结构的计算机上,有两种同时使用的,也是十分容易混淆的分区概念:一是DOS分区,一是BSD分区。本文的重点在帮助大家准确理解这两种分区。
为了理解分区,我们最好的插手阶段是FreeBSD的引导过程。简单的说,完整的FreeBSD的引导分为四部分:第一部分是DOS分区的mbr引导,FreeBSD将之称为boot0;第二部分是FreeBSD分区的引导,FreeBSD将之称为boot1;然后是FreeBSD所谓的boot2引导,最后是loader引导。
整个过程如下图1示
图1:引导过程简图
其中mbr引导是与FreeBSD无关的,也就是说我们可以使用很多不同的引导工具进行mbr引导,最著名的恐怕就是grub了。后面三个引导阶段是FreeBSD自有的,这是FreeBSD称之为三部曲的引导,本文仅解析磁盘分区,并不深入FreeBSD的引导,因此关于boot的详情可以参见man 8 boot。
第一部分:DOS分区
那么,奇怪的是为什么在讨论FreeBSD分区的时候,我们需要首先面对的却是DOS分区呢?原因在于,PC机上的FreeBSD运行在基于IA32的硬件之上,并且在设计时就考虑到和同一个磁盘上的其他系统共存的用户需求,比如Microsoft Windows。所以,FreeBSD不得不建立在DOS分区之上的。当然运行在非IA32体系的计算机上的FreeBSD系统并不一定使用DOS分区。
首先我们需要一个实验环境来观察后面的操作:操作系统FreeBSD7.0-release,虚拟机bochs2.3.7,虚拟磁盘大小10G,分为两个区:一个分区1G为FAT分区,另一个分区9G为BSD分区。创建虚拟磁盘的操作显示如图2:
图2: 实验用虚拟硬盘
图2告诉我们的最重要的信息是total sectors=20971440,而我们在安装*BSD时经常看到的cylinder=20805,heads=16等信息在现在较新的磁盘上已经不再重要,至于原因我们放在下面讲述。我们还可以看出这个磁盘的扇区大小为(10239.96MB/20971440扇区=512字节)。
空白磁盘添加了保留引导区之后的第一次划分光秃秃的如下图3:
图3: 磁盘的第一次划分
这时磁盘上并没有任何数据,这63个扇区的划分直到后面写入磁盘信息时才会正式建立,我们这里引用这些分区是为了文章描述的逻辑性。
OK,接下来我们正常安装FreeBSD,直到下一步,如图4:(同样的信息我们也可以在系统安装完成之后使用fdisk命令查看)
图4中显示了设备名:ad0,整个磁盘扇区大小:20971440,还有三个看起来像分区的条目。呃,这里用了“看起来像”,是因为从扇区0到扇区62结束的第一个条目,其实不是一个分区,它是磁盘的保留块,至于为什么要63个扇区而不是我们经常讲的mbr 1个扇区?原因在于磁盘开始的63个扇区保留给了mbr和扩展分区。而为什么保留的扇区是63而不是64,65呢?呃,因为一个柱面包含了63个扇区 第0个扇区确实是我们关心的mbr,而第1—62扇区,是为扩展分区保留的空间,它可以不使用。如果是这样,那么1—62扇区可以存放扩展引导代码,也可以放数据。
进一步划分:一个分区1G为FAT分区,从63扇区开始到2096639扇区结束,共(2096639−63+1) = 2096577个扇区,共2096577S · 512B = 1023KB = 1G。这个分区的分区号为Subtype = 6。另一个分区9G为FreeBSD分区,从2096640扇区开始到20971439扇区结束,共18874800个扇区,分区号为Subtype = 165。
图4: 划分磁盘DOS分区
图4中显示的Subtype也就是我们通常说的分区类型,我们会在后面的mbr实例中看到这个类型号。然而,分区类型的使用只与操作系统有关。系统挂载时,OS可以使用,也可以不使用这个类型决定目标分区系统的类型。
接下来的安装中,用户可以选择FreeBSD安装到mbr的操作类型,如图5所示。
图5: mbr引导程序选择
BootMgr对应/boot/boot0(代码在src/boot/i386/boot0/),Standard对应/boot/mbr(代码在src/boot/i386/mbr/),None当然就是不改变当前PC机安装的mbr。那么问题是:FreeBSD为什么要分两种类型的mbr?其实boot0和mbr都是安装在PC机的mbr上的,完成相同的引导功能,然而它们之间的区别在于boot0提供一种简单的分区选择功能。当系统启动时,boot0会根据分区表的内容自动检测系统上存在的磁盘分区,然后在一定计时范围内给出一个选择让用户自行选择boot0下一步引导的磁盘分区。这时可以看见屏幕上出现的所有分区列表,和它对应的选择键:F1, F2, F3等等。用户如果在这期间选择了一个分区进行引导,那么boot0自动将用户选择的分区激活为活动分区并进行加载。当计时超出之后,boot0将默认选择分区表中记录的活动分区进行引导。这样一来,如果上一次用户选择了某个分区进行引导,那么下一次PC机启动的时候,默认的启动分区就是上一次用户选择的引导分区。
/boot/mbr的功能就简单的多,只需要找到分区表里面的活动分区进行加载就完成任务。具体的代码分析参见雨丝风片的FreeBSD7.0 /sys/boot/i386/mbr/mbr.s源代码分析。
需要注意的是:我们这里仅仅只是引用文件系统上的对应特定文件,这并不意味着系统引导之时,就是执行的这些文件。也就是说:FreeBSD在引导过程中执行的boot0(mbr) 和后面讲述的boot1 都不是直接执行文件系统上的代码。因为在引导之时,FreeBSD的文件系统结构尚未在内存中建立。解决的办法是通过bsdlabel, boot0cfg等工具,FreeBSD直接将/boot/boot0(/boot/mbr) 和/boot/boot1 安装到磁盘的对应扇区上(需要root权限)。
图6: mbr结构,图片来自wiki
图6和图7显示了mbr的结构和分区表结构,下面祭起我们的照妖镜 -- bochs,观察有关分区的系统活动。
图7: mbr分区结构,图片来自wiki
中间插一句(等会还要继续按照我们的系统,呵呵),在整个系统安装完成之后,我们通过在bochs引导初期下断点的方式,取得图8所示的整个512字节mbr反汇编:
图8: mbr中的分区表
mbr信息我们也可以通过dd if=/dev/ad0 of=mbr.bin bs=512 count=1得到(为什么是/dev/ad0在后面解释)。我们最关心的是446—509字节表示的mbr分区表内容,每个条目16字节,共4个条目。446—462字节描述了第一个DOS分区,463—479描述了第二个DOS分区。
0x7DBE开始的16个字节依次是00 010100 06 0fffff 3f000000 c1fd1f00(注意,这里反汇编显示的是intel的little-ending序)按照图7的分区表格式,我们知道这个分区不是引导分区(0x0),分区类型是0x6 (图4中的Subtype域,下同),起始LBA在第0x3f=63 扇区,分区大小0x1ffdc1=2096577 扇区,这是一个FAT分区。继续0x7DCE开始的第二个分区,依次是80 ffffff a5 0fffff 00fe1f00 b0012001 按照图7的分区格式,这个分区是引导分区(0x80),分区类型是0xa5 (表示FreeBSD分区),起始LBA在第0x1ffe00=2096640扇区,分区大小0x12001b0=18874800 扇区,这是一个FreeBSD分区。
呵呵,是不是和我们在图4中看到的一样呢?至此,FreeBSD引导过程的DOS引导部分完成。
总结一下目前为止的DOS分区的情况,图9
图9: 简明DOS分区结构
整个第一个磁盘在FreeBSD里面表示为/dev/ad0,如果有第二个磁盘,则命名为/dev/ad1,依次类推。磁盘上的DOS分区在FreeBSD里面表示为Slice,因此第一个磁盘/dev/ad0上的第一个Slice为/dev/ad0s1,第二个Slice为/dev/ad0s2。正如9所示,/dev/ad0s1在mbr里面被表示为FAT分区,从63号扇区开始到2096639扇区结束;/dev/ad0s2在mbr里面被表示为FreeBSD分区,跨越剩下的磁盘空间。
最后做个简单的加法:
/dev/ad0s2 = /dev/ad0 + 2099640 。
这意味着
dd if=/dev/ad0s2 of=xxx bs=512 count=1
和
dd if=/dev/ad0 of=yyy bs=512 count=1 skip=2099640
完成相同的功能。
[ 本帖最后由 gvim 于 2008-6-30 16:55 编辑 ] |
评分
-
查看全部评分
|