本文主要解析MINIX中引导程序的源文件bootblock.s(1.4版本),而文章从http://www.os-forum.com/minix/boot/bootblock.php中参考了大量资料,也非常感谢作者(被参考文章)的大量注释。当是由于原作的解析是在于对代码的注释,没有很系统的折分和系统的讲解代码的工作原理。基于这个原因,作者(被参考文章)在注释中留了一些疑问;所以我决定从宏观上来讲解代码,这样能够更清楚的看清原理(不会太过于陷入细节而忽略原理),也解答了注释留下的疑问。
基于尊重和鼓励原创,如要转帖,请注明原处,谢谢。
如果对本文有任何疑问或纠正,欢迎留言,我会第一时间尽快的解答和修改。
这里我提供下bootblock.s(1.4版本)的源代码: http://www.cppblog.com/alister/archive/2011/03/07/bootblock-1_4_s.html
首先,根据源代码的结构,可以转化为如下图示:
![](http://www.cppblog.com/images/cppblog_com/alister/bootblock_uncategorize.jpg)
其中实线是顺序运行或跳转指令(jmp,jl,jg...)。这里sectors和addresses没有与其他代码进行跳转,而是其他代码引用sectors和addresses区域内的数据。
接下来,按照功能性来把这些散块聚集成一个个大类。
第一分类是:boot,next,floppy和success。
第二分类是:winchester,loadboot,load,read和done。
第三分类是:error,prnum,digit和print。
第四分类是:hang。
第五分类是:sectors。
第六分类是:addresses。
现在我们把这六个分类构成图来看下分类与分类之间的依赖关系,如下图所示:
![](http://www.cppblog.com/images/cppblog_com/alister/bootblock_uncategorize_edited.jpg)
按照功能性分类后,接下来讲揭开这些分类之间的依赖关系,其中依赖关系由箭头上的黑色数字标注;但在揭开之前先把各分类的功能简述一下。
第一分类:在这个类中,首先在boot处检测加载驱动器是软盘还是硬盘,若是软盘就通过读取最后一个扇区来确认软盘的类型:1.44M,1.2M或720K/360K;从1.44M开始往后检测。
第二分类:在这个类中,首先在wincester处加载第一个扇区(从分区表处),接下来后面是加载扇区到内存处并最终跳到BOOTOFF:BOOTSEG。
第三分类:在这个类中,主要是把ah中的错误代码打印到标准输出处(显示器)。
第四分类:这个类主要就是进入死机状态。
第五分类:这里保存了软盘三种种类的扇区数。(数据区)
第六分类:这里保存了下个分区的开始扇区处。(数据区)
现在我已经把每个分类的大概功能都概述完毕,接着我要开始说明分类与分类之间的依赖关系。
1:第一分类与第二分类的关系;当软盘的类型被确定后就会跳到第二分类中加载扇区。
2:第二分类与第二分类的关系;这里根据第六分类里保存的开始扇区处加载扇区并且直到所有扇区已加载完毕才跳出循环。
3:第二分类与第三分类的关系;若在第二分类中加载扇区失败,将会跳到第三分类处打印错误代码。
4:第三分类与第四分类的关系;当在第三分类中打印完错误代码后,就跳到第四分类处。(进入死机状态)
5:第四分类与第四分类的关系;这个主要是进入死循环,也就是死机状态。
本人的讲解也到此为止,读者可以去阅览http://www.os-forum.com/minix/boot/bootblock.php里详细注释,我就不在这里列出来。虽然原文是英文,但还是很好懂的。如果认为有翻译的必要就请在下面留言吧,我会根据人数的多少来决定是否有这个必要。