Linux 从开机到加电执行 main 函数之前的过程 #
flowchart LR bootsect[执行 bootsect]--> setup[执行 setup]--> head[执行 head.s]--> main[main 函数]
1.1 启动 BIOS,准备中断向量表和中断服务程序 #
- 加电时,内存 RAM 是空的
- BIOS 负责把操作系统内核程序加载到内存中
具体过程:
- 靠硬件完成,将 CPU 的硬件逻辑设计为加电瞬间 CS:IP 指向 0xFFFF0, 即 BIOS 程序入口地址。
- BIOS 在内存中建立中断向量表和中断服务程序。利用中断,才能加载内核程序。
1.2 加载内核程序 #
- 产生
int 0x19
中断,找到并加载启动扇区,从而bootsecct
程序被拷贝到内存。BIOS 负责找到并加载第一扇区,与具体的Linux内核无关,即两头约定 + 定位识别。
bootsecct
程序复制自身到另一个地方,并调整CS:IP、DS(数据段寄存器)、ES(附加段寄存器)、SS(栈基址寄存器)+SP(栈顶指针).意味着从现在起,操作系统已经不需要完全依赖BIOS,可以按照自己的意志进行内存规划和程序执行。
- 执行
int 0x13
中断,加载setup
程序。- 需要传参给中断服务程序,包括指定的扇区和加载的内存信息等;
- 通过几个通用寄存器来实现传参,非函数调用
- 加载
system
系统内核程序 - 开始执行
setup
程序,读取机器系统数据,放在原bootsect
程序所在的部分内存区域。
1.3 转变为32位模式,为调用 main
函数做准备
#
- 将
system
系统内核程序复制到0x00000
的位置- 这个位置本来放的是
BIOS
建立的中断向量表和BIOS数据区,相当于废掉了BIOS
提供的实模式下的中断服务程序; - 同时收回寿命结束的内存空间;
- 让内核代码占据内存物理地址最开始、最天然、最有利的位置。
- 这一过程是在关中断的状态下进行。
- 这个位置本来放的是
- 初始化两个表:
- GDT(全局描述符表) + GDTR
- IDT(中断描述符表) + IDTR
- 打开
A20
,实现32位寻址 - 对 中断控制芯片
8259A
重新编程