也许你想知道,为什么boot2
是在
boot0
之后,而不是在boot1之后。事实上,
也有一个512字节的文件boot1
存放在目录
/boot
里,那是用来从一张软盘引导系统的。
从软盘引导时,boot1
起着
boot0
对硬盘引导相同的作用:它找到
boot2
并运行之。
你可能已经看到有一文件/boot/mbr
。
这是boot0
的简化版本。
mbr
中的代码不会显示菜单让用户选择,
而只是简单的引导被标志的分区。
实现boot2
的代码存放在目录
sys/boot/i386/boot2/
里,对应的可执行文件在
/boot
里。在/boot
里的文件
boot0
和boot2
不会在引导过程中使用,
只有boot0cfg这样的工具才会使用它们。
boot0
的内容应在MBR中才能生效。
boot2
位于可引导的FreeBSD分区的开始。
这些位置不受文件系统控制,所以它们不可用ls
之类的命令查看。
boot2
的主要任务是装载文件
/boot/loader
,那是引导过程的第三阶段。
在boot2
中的代码不能使用诸如
open()
和read()
之类的例程函数,因为内核还没有被加载。而应当扫描硬盘,
读取文件系统结构,找到文件/boot/loader
,
用BIOS的功能将它读入内存,然后从其入口点开始执行之。
除此之外,boot2
还可提示用户进行选择,
loader可以从其它磁盘、系统单元、分区装载。
boot2
的二进制代码用特殊的方式产生:
这个Makefile片断表明btxld(8)被用来链接二进制代码。
BTX表示引导扩展器(BooT eXtender)是给程序(称为客户(client)
提供保护模式环境、并与客户程序相链接的一段代码。所以
boot2
是一个BTX客户,使用BTX提供的服务。
工具btxld是链接器, 它将两个二进制代码链接在一起。btxld(8)和ld(1) 的区别是ld通常将两个目标文件 链接成一个动态链接库或可执行文件,而btxld 则将一个目标文件与BTX链接起来,产生适合于放在分区首部的二进制代码, 以实现系统引导。
boot0
执行跳转至BTX的入口点。
然后,BTX将处理器切换至保护模式,并准备一个简单的环境,
然后调用客户。这个环境包括:
虚拟8086模式。这意味着BTX是虚拟8086的监视程序。 实模式指令,如pushf, popf, cli, sti, if,均可被客户调用。
建立中断描述符表(Interrupt Descriptor Table, IDT), 使得所有的硬件中断可被缺省的BIOS程序处理。 建立中断0x30,这是系统调用关口。
两个系统调用exec
和
exit
的定义如下:
BTX建立全局描述符表(Global Descriptor Table, GDT):
客户的代码和数据始于地址MEM_USR(0xa000),选择符(selector)
SEL_UCODE指向客户的数据段。选择符 SEL_UCODE 拥有第3级描述符权限
(Descriptor Privilege Level, DPL),这是最低级权限。但是
INT 0x30
指令的处理程序存储于另一个段里,
这个段的选择符SEL_SCODE (supervisor code)由有着管理级权限。
正如代码建立IDT(中断描述符表)时进行的操作那样:
所以,当客户调用 __exec()
时,代码将被以最高权限执行。
这使得内核可以修改保护模式数据结构,如分页表(page tables)、全局描述符表(GDT)、
中断描述符表(IDT)等。
boot2
定义了一个重要的数据结构:
struct bootinfo
。这个结构由
boot2
初始化,然后被转送到loader,之后又被转入内核。
这个结构的部分项目由boot2
设定,其余的由loader设定。
这个结构中的信息包括内核文件名、BIOS提供的硬盘柱面/磁头/扇区数目信息、
BIOS提供的引导设备的驱动器编号,可用的物理内存大小,envp
指针(环境指针)等。定义如下:
boot2
进入一个循环等待用户输入,然后调用
load()
。如果用户不做任何输入,循环将在一段时间后结束,
load()
将会装载缺省文件(/boot/loader
)。
函数 ino_t lookup(char *filename)
和
int xfsread(ino_t inode, void *buf, size_t nbyte)
用来将文件内容读入内存。/boot/loader
是一个ELF格式二进制文件,
不过它的头部被换成了a.out格式中的struct exec
结构。
load()
扫描loader的ELF头部,装载/boot/loader
至内存,然后跳转至入口执行之:
本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读
文档,如不能解决再联系
<questions@FreeBSD.org>.
关于本文档的问题请发信联系
<doc@FreeBSD.org>.