在系统启动时,先是由硬件读取引导磁盘的第一个扇区,并执行从那得到的代码。
在已分区的硬盘中,其第一个扇区上包含了主引导记录和分区表,还有一个程序称为Minix系统主引导程序,
这个程序将自身定位到一个内存区域,然后装入并执行活动分区(在分区表中记录)的第一个扇区(注意与前面的第一个扇区是不同的),
这样控制权就传递到这个引导扇区了。
但Minix3引导扇区是怎样写入硬盘的呢?这个工作由installboot.c来完成。可以看看它的代码:
//位于installboot.c中的main函数入口
int main(int argc, char **argv)
{
if (argc < 2) usage();
if (argc >= 4 && isoption(argv[1], "-image")) {
make_image(argv[2], argv + 3);
} else
if (argc == 3 && isoption(argv[1], "-extract")) {
extract_image(argv[2]);
} else
if (argc >= 5 && isoption(argv[1], "-device")) {
make_bootable(FS, argv[2], argv[3], argv[4], argv + 5);
} else
if (argc >= 6 && isoption(argv[1], "-boot")) {
make_bootable(BOOT, argv[2], argv[3], argv[4], argv + 5);
} else
if ((4 <= argc && argc <= 6) && isoption(argv[1], "-master")) {
install_master(argv[2], argv[3], argv + 4);
} else {
usage();
}
exit(0);
}
再看看install_master函数的声明:
void install_master(char *device, char *masterboot, char **guide)
/* Booting a hard disk is a two stage process: The master bootstrap in sector
* 0 loads the bootstrap from sector 0 of the active partition which in turn
* starts the operating system. This code installs such a master bootstrap
* on a hard disk.*/
程序installboot 能使Minix3找到boot程序,而boot则是Minix3的次级装入程序。同时boot作为一个监控程序,
它语序用户改变、设置和保存不同的参数。Minix3保留每个硬盘设备的前1kb作为一个引导块,但其中只有
512字节的扇区被rom引导程序或主引导扇区装入,另外的512字节可以用来保存设置信息。
--------------------------------------------------------------------------------------------------------------------------------
接下来,在Minix3启动之前还需做一些工作。
1.在加载镜像时,引导程序从镜像中读取镜像的属性,如它被编译为运行在16位机还是32位机上的。
2.Minix3镜像组件的头文件a.out被抽取为引导内存空间的一个数组,其基地址被传递给内核。(这个a.out我一直没弄懂是个啥)
3.保存当前监控程序运行到的地址到栈中,这样当Minix3结束时,控制权将重新返回到引导监控程序。
关于第三点Minix3具体是怎样做的,从下面的代可以看到:
08841 !*===========================================================================*
08842 !* monitor *
08843 !*===========================================================================*
08844 ! PUBLIC void monitor();
08845 ! Return to the monitor.
08846
08847 _monitor:
08848 mov esp, (_mon_sp) ! restore monitor stackpointer
08849 o16 mov dx, SS_SELECTOR ! monitor data segment
08850 mov ds, dx
08851 mov es, dx
08852 mov fs, dx
08853 mov gs, dx
08854 mov ss, dx
08855 pop edi
08856 pop esi
08857 pop ebp
08858 o16 retf ! return to the monitor
由此可以看出,我们可以把Minix3看成是一个例程,由boot(也可以看成是一个函数)来调用它,当Minix3例程执行完毕时再返回到boot调用它的地方,如下图所示:
以上是个人的理解,有误之处请留言指出。