使用内核:linux0.11
参考文档:linux内核设计的艺术 英文名:The Art of Linux Kernel Design
一、
开机加电的一瞬间,内存中什么都没有,CPU只能执行内存中的东西,所以只有把硬盘(软盘)中的操作系统
程序加载到内存中,BIOS可以将操作系统程序加载到内存中,而BIOS又是如何启动的?
Intel 80x86系列CPU可以在16位 实模式和32位 保护模式运行,为了兼容,硬件设计为加电进入16位实模式运行,同时CPU加电强行将CS(代码段寄存器)设为0xFFFF,IP(指令指针寄存器)为0x0000,CS:IP为0xFFFF0,这个地址即BIOS,BIOS存于ROM,断电不丢
解释:
IP指令指针寄存器,存在于CPU中,记录将要执行的指令在代码段内的偏移地址,与CS组合即为要执行的指令的内存地址。实模式为绝对地址IP为16位,保护模式为线性地址,IP为32位,32位下IP叫EIP
二、个人理解:CS指向内存区域(内存被划分为几个区域)IP为这个区域的偏移
三、利用中断服务程序把系统内核从硬盘(软盘)加载到内存随着BIOS程序的执行,BIOS会检测显卡、内存等。有一项对启动操作系统至关重要的工作,BIOS会在内存中建立中断向量表和中断服务程序,256个中断向量,每个向量两个字节是CS的值,两个字节是IP的值因此占用1KB的内存空间(0x0000~0x003FF)构建中断向量表,并在紧挨着它的位置用256字节的内存空间构建BIOS数据区(0x00400~0x004FF),在大约56KB以后的位置(0x0E2CE)加载8KB左右的与中断向量表对应的若干中断服务程序
0x0 中断向量表 0x003FF 0x00400 BIOS数据区 0x004FF 0x0E2CE 中断服务程序(8K左右) 0x0FFFE 按照 中断类型号 从小到大的顺序存储对应的中断向量,总共存储256个中断向量。在 中断响应 过程中,CPU通过从接口电路获取的 中断类型号 (中断向量号)计算对应中断向量在表中的位置,并从中断向量表中获取中断向量,将程序流程转向 中断服务程序 的入口地址。
正式将软硬盘中断操作系统服务程序加载到内存,Linux0.11分三批加载代码
1.加载第一部分代码——引导程序(bootsect)(软盘中的第一个扇区)
BIOS中断 int 0x19把第一扇区bootsect加载到内存
计算机硬件体系结构的设计与BIOS联手操作,让CPU接收一个int 0x19的中断,查表得到中断服务程序入口地址,该程序的作用
就是把软盘第一个扇区中的512B加载到内存中(0x7C00),该扇区就是Linux0.11中的bootsect.s,这是上电开始后,内存中第一次
有了Linux的代码
2.加载第二部分代码——setup(软盘中的第2到第5个扇区)
1)为了加载第二第三批代码,bootsect要先规划内存
2)接下来bootsect启动程序将它自身(512B)从内存0x07C00(BOOTSEG)复制到0x90000(INITSEG)
3)借助BIOS提供的 int 0x13中断来加载setup这个程序,加载到内存的SETUPSEG(0x90200)
![]()
3.加载第三部分代码——system模块(软盘中的240个扇区)
同样借助BIOS提供的 int 0x13中断,将system模块加载至内存的SYSSEG(0X10000)的120KB4.启动setup程序
至此,bootsect任务完成,通过jmpi 0,SETUPSEG跳转至setup程序的加载位置, setup的作用是获取及其系统数据为以后main函数执行时发挥作用
四、开始向32位模式转变,从实模式到保护模式的转变
(打开32位寻址空间、打开保护模式、建立保护模式下的中断响应机制、建立内存分页机制)
1.关中断,将CPU的标志寄存器(EFLAGS)中断允许标志(IF)置0(关掉BIOS的那些中断,建立自己新的 中断)
2.setup将0x10000的内核程序拷贝到0x00000
3.创建两个表,中断描述附表和全局描述附表
GDT 全局描述附表 可理解为所有进程的总目录表,用于完成进程中各段的寻址,现场保护与现场恢复
GDTR GDT可放到内存任何位置,GDTR就是寻找GDT的寄存器IDT 中断描述附表 中断服务程序的入口地址,类似实模式下的中断向量表IDTR 同GDTR4.打开 A20, 从此变为32位,32根地址线寻址