由于Minix引导过程不属于操作系统,《操作系统设计与实现》一书中没有对其进行详细的分析和说明。Andrew Swartzbaugh 和 Brent Johnson 的网站对引导过程所涉及的六个代码文件进行了详细的分析。
我觉得有必要对其进行一些翻译,以利于进一步的学习。正如网站上说的,通过阅读6个文件的代码,不仅可以了解Minix的引导过程,而且对于理解操作系统中的汇编语言也很有帮助。
本文的代码来自Minix当前的最新版本2.0.4。其中一些部分与2.0.0版有所不同。
当系统启动时,硬件将软盘或硬盘的第一个扇区载入到内存的LOADOFF位置,这实际上是ROM BIOS的工作,与操作系统无关。
对于Minix,第一次载入的程序可能是 masterboot.s 或者 bootblock.s。
对于有分区的硬盘,它的第一个扇区是MBR(master boot record),其中包含有代码和分区表。
如果分区里有子分区,则在分区的第一个扇区也有MBR。MBR也可以被拷贝到软盘的第一个扇区。
masterboot.s 就存放在MBR中。
如果 masterboot.s 被载入,它的任务就是找到引导分区(或软盘),
从而加载该分区(或软盘)的第一个扇区并跳转至该处运行。
在引导分区或软盘的第一个扇区存放有Minix的初级引导程序,即 bootblock.s。
它同样是被加载到LOADOFF位置,它的任务是将boot monitor(Minix的次级引导程序)加载到内存,
并将控制转给boot monitor。
boot monitor由(boothead.s,boot.c,bootimage.c,rawfs.c)四个文件组成。
boot monitor的主要任务是加载Minix或其他操作系统。
boothead.s是boot monitor的入口,并提供一些底层支持(主要是调用BIOS中断)。
当bootblock.s跳转到boot monitor,boothead的代码就开始执行。
这些代码确定内存布局,处理器类型(286,386,486等),当前显示模式以及被加载的设备,
并最终调用函数 boot() (在boot.c中)。
boothead.s还提供了退出monior,确定设备参数,在盘中读写数据,从键盘和屏幕读写字符的函数。
跳转到Minix的代码(包括从实模式转到保护模式)也在boothead.s中。
boot.c提供monitor中的高层函数。
其中最高层的是 boot()。boot() 调用函数 initialize() (同样在boot.c中)。
initialize()转移boot monitor并将它从传递给内核的内存表中删去(以防内核覆盖boot monitor)。
boot()接下来调用下列函数:
1) get_parameters()(在boot.c中)设置一些环境变量和函数并从bootparams扇区(引导分区的第二个扇区)中读取一些参数的值。
2) r_super()(在rawfs.c中)证实系统是minix文件系统并确定文件系统的参数。
在这两个函数返回后系统将执行用户输入的命令,其中最重要的命令是boot。
bootimage.c的主要函数是 bootminix(),当用户输入boot命令时将调用此函数。
bootminix()调用下列函数:
1) select_image()在盘中找到所需的内核镜像。
2) exec_image()将内核镜像加载到内存,然后调用minix()(在boothead.s)转到保护模式(如果内核在保护模式中编译)并跳至内核。
当操作系统返回boot monitor时(如用户使用shutdown命令),bootminix()返回。
以上的文件都存放在/usr/src/boot文件夹中。该文件夹中还有一些提供辅助功能的函数:
如果内核镜像所在的硬盘存在minix文件系统,在引导过程中必定要涉及文件系统的相关操作。
在操作系统的文件系统模块还无法使用的情况下,引导程序必须提供一系列函数以实现对文件系统的操作。
这些函数被集中放在 rawfs.c 中。
installboot.c 不属于引导程序。
它的功能是将引导程序和内核写入磁盘并使其可引导。
--
原文链接: http://minix.blog.sohu.com/1002304.html
|