1. 功能描述
操作系统加载程序,位于磁盘引导扇区后面,即第2个扇区开始,占据4个扇区。它利用BIOS中断读取机器系统数据,并将这些数据保存在0x90000开始的位置(覆盖掉bootsect所在的地方),所取得的参数与保留的内存位置见表。
扩展内存是因为实模式只能识别1MB(2^20)大小内存。
然后将system模块从0x10000~0x8ffff(当时认为内核模块system不会超过512KB)整块下移到内存绝对地址0x00000处。然后加载IDTR和GDTR(GDTR大小6字节,其中限长设置成limit=2048,每个描述符8字节,所以可以有256个;IDTR大小6字节,因为CPU要求进入保护模式之前必须设置,所以限长和地址都先设为0),开启A20地址线,重新设置两个中断控制芯片8259A,将硬件中断号重新设置为0x20~0x2f。最后设置CR0,进入32位保护模式,并跳转到system最前面的head.s继续执行。
为了让head.s在32位保护模式中运行,在本程序中临时设置了IDT和GDT,并在GDT中设置了当前内核代码段的描述符和数据段的描述符。下面在head.s中会根据内核的需要重新设置。
另外,setup.S在215~566行识别机器中使用的显示卡类别。如果使用的是VGA显卡,那么检查下显卡是否支持超过25行X80列的扩展显示模式(或显示方式)。所谓显示模式是指ROM BIOS中断int 0x10的功能0(ah=0x00)设置屏幕显示信息的方法,其中al寄存器中的输入参数即是要设置的显示模式或显示方式号。通常将IBM PC刚推出时所能设置的几种显示模式成为标准显示模式,而后面添加的称为扩展显示模式。例如ATL显卡除了支持标准显示模式,还支持扩展显示模式号0x23、0x33,即还能使用132列X25行和132列X44行两种显示模式在屏幕上显示信息。在VGA、SVGA刚出现,这些扩展模式均由显卡上的BIOS支持。若识别出一块已知类型的显示卡,程序就会向用户提供选择分辨率的机会。但这段程序涉及很多显示卡特有的端口信息,所以程序比较复杂。不过与内核运行关系不大,可以跳过不看。
2. 代码注释
3. 其他信息
3.1 当前内存映像
setup.s执行结束后,系统模块system被移动到物理地址0x0000开始处,从0x90000开始处则放置内核会使用的一些系统基本参数,如图。
此时临时GDT有三个描述符,第一个NULL不用,另外两个是代码段描述符和数据段描述符。它们都指向系统模块起始处,即物理地址0x0000处。这样当setup.S中执行最后一条指令“jmp 0,8”(193行)就会跳到head.s开始处继续执行。“8”是段选择符,指定所需使用的描述符,此处指GDT中代码段描述符(1000,刚好是代码段描述符索引位置),“0”是代码段中偏移值。
3.2 BIOS视频中断0x10
BIOS中视频中断调用功能如下。
3.3 硬盘基本参数表(“INT 0x41”)
中断向量表中,int 0x41的中断向量位置(4X0x41=0x0000:0x0104)存放的并不是中断程序的地址,而是第一个硬盘的基本参数表。对于100%兼容的BIOS,这里存放的是硬盘参数表阵列的首地址F000h:E401h。第二个硬盘的基本参数表入口地址存放于int 0x46中断向量位置处。参数见表。
3.4 A20地址线问题
为了能够访问和使用1MB以上的物理内存,我们需要首先开启A20地址线。
3.5 8259A中断控制器的编程方法
(1)8259A工作原理
这里说明8259A工作原理,然后详细说明8259A芯片编程方法以及Linux内核对其设置的工作方式。
PC/AT使用两片8259A可编程控制器(PIC)芯片,可管理15级中断向量。从芯片的INT引脚连到主芯片的IR2引脚。主芯片端口基地址0x20,从芯片0xA0。逻辑框图如下。
具体内容见书内容