FreeBSD操作系统的boot2阶段( 二 )


mov %ax,(%di)# 设置处理程序偏移量
mov %dh,0x2(%di)# 设置处理程序选择符
mov %dl,0x5(%di)# 设置 P:DPL:type
add $0x4,%ax# 下一个中断处理程序所以,当客户调用 __exec()时,代码将被以最高权限执行 。这使得内核可以修改保护模式数据结构,如分页表(page tables)、全局描述符表(GDT)、中断描述符表(IDT)等 。
boot2 定义了一个重要的数据结构:struct bootinfo 。这个结构由 boot2 初始化,然后被转送到loader,之后又被转入内核 。这个结构的部分项目由boot2设定,其余的由loader设定 。这个结构中的信息包括内核文件名、BIOS提供的硬盘柱面/磁头/扇区数目信息、BIOS提供的引导设备的驱动器编号,可用的物理内存大小,envp指针(环境指针)等 。定义如下:
/usr/include/Machine/bootinfo.h
struct bootinfo {
u_int32_tbi_version;
u_int32_tbi_kernelname; /* 用一个字节表示 * */
u_int32_tbi_nfs_diskless;/* struct nfs_diskless * */
/* 以上为常备项 */
#define bi_endcommonbi_n_bios_used
u_int32_tbi_n_bios_used;
u_int32_tbi_bios_geom[N_BIOS_GEOM];
u_int32_tbi_size;
u_int8_tbi_memsizes_valid;
u_int8_tbi_bios_dev;/* 引导设备的BIOS单元编号 */
u_int8_tbi_pad[2];
u_int32_tbi_basemem;
u_int32_tbi_extmem;
u_int32_tbi_symtab; /* struct symtab * */
u_int32_tbi_esymtab; /* struct symtab * */
/* 以下项目仅高级bootloader提供 */
u_int32_tbi_kernend; /* 内核空间末端 */
u_int32_tbi_envp;/* 环境 */
u_int32_tbi_modulep; /* 预装载的模块 */
};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至内存,然后跳转至入口执行之:
【FreeBSD操作系统的boot2阶段】sys/boot/i386/boot2/boot2.c:
__exec((CADdr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dev_maj[dsk.type], 0, dsk.slice, dsk.unit, dsk.part),
0, 0, 0, VTOP(&bootinfo));

推荐阅读