6.1 总体功能
- BIOS执行某些系统的检测,并在物理地址0处开始初始化中断向量
- BIOS启动设备的第一个扇区将bootsect.s读入内存绝对地址0x7C00处,并跳转到这个地方
- bootsect.s程序开始执行,并将自己移动到0x90000位置处,并把setup.s代码读入到内存0x90200中,同时把system模块被读入到从内存地址0x10000开始处
- setup.s函数执行,将system模块移动到物理内存起始位置处
- head.s加载IDT、GDT以及LDT,最终调用init/main.c中的main()程序
- 内核代码运行起来,还需要一个基本的文件系统
6.2 bootsect.s程序
6.2.1 功能描述
- 将自己移动到内存绝对地址0x90000开始处并继续执行
- 把从磁盘第2个扇区开始的4个扇区的setup模块加载到内存
- 将system模块加载到内存0x10000开始的地方
6.2.2 代码注释
6.2.3 其他信息
6.2.3.1 Linux0.11硬盘设备号
6.2.3.2 从硬盘启动系统
- 系统上电后,可启动硬盘的第1个扇区会被BIOS加载到内核0x7c00处并开始执行
- 该程序会首先把自己向下移动到内存0x600处
- 然后根据MBR中分区表信息所知名活动分区中的第1个扇区加载到内存0x7c00处,然后开始执行
6.3 setup.s程序
6.3.1 功能描述
- 利用ROM BIOS中断读取机器系统数据,并将这些数据保存到0x90000开始的位置
- setup程序将system模块从0x10000-0x8ffff整块向下移动到内存绝对地址0x00000处
- 加载idtr和gdtr,开启A20地址线,重新设置两个中断控制芯片8259A,将硬件中断号重新设置为0x20 - 0x2f
- 设置CPU的控制期存器CR0,从而进入32位保护模式运行
- 跳转到system模块的head.s程序运行
6.3.2 代码注释
6.3.3 其他信息
6.3.3.1 当前内存映像
6.3.3.2 BIOS视频终端0x10
6.3.3.3 硬盘基本参数表(“INT 0x41”)
6.3.3.4 A20地址线问题
6.3.3.5 8259A终端控制器的编程方法
-
IRR外接外设的中断信号线;
-
IMR来控制IRR上的哪根中断线被屏蔽,也就是不送入到PR中
-
当有多个中断送去到PR中,那么PR通过解析向CPU发送一个具有最高优先级INT信号
-
CPU则会在执行完当前的一条指令之后向8259A发送一个INTA来相应中断信号
-
8359A在收到这个相应信号之后就会把所选出的最高优先级中断请求保存到ISR中,与此同时,IRR中的对应比特位被复位
-
CPU会想8259A发出第2个INTA脉冲信号,该信号用于通知8259A送出中断号
-
最后就是ISR中的位如何清除的问题
- 自动结束中断的8259A会在发出第2个INTA脉冲信号后,自动清除ISR
- 非自动结束中断的8259A需要CPU向其发送一个结束中断的命令以复位ISR中的比特位
6.4 head.s程序
6.4.1 功能描述
- 采用的是AT&T的汇编语言格式,因此赋值方向是从左到右
- 功能是加载各个数据段寄存器,重新设置中断描述符表idt,共256项,并使各个表项均指向一个只报错误的哑中断子程序ignore_int
- 重新设置全局段描述符表gdt,并将gdt表放在内存内核代码比较合理的地方
- 检测A20地址线是否真的开启,未开启则进入死循环
- 测试PC机是否含有数学协处理器芯片,并在CR0中设置相应的标志位
- 设置管理内存的分页处理机制,将页目录表放在绝对物理地址0开始处
- 最后,head.s程序利用返回指令将预先放置在堆栈中的/init/main.c程序的入口地址弹出,去运行main()程序