[关闭]
@myecho 2017-09-11T22:27:47.000000Z 字数 935 阅读 821

第一讲启动过程分析

linux内核笔记


BIOS

实模式内存寻址空间
0XFFFFF=20个1=10^20=1KK=1M
我们可以看到连接到南桥(北桥连接cpu、内存等,南桥连接显卡等外设,现在南桥和北桥已经合并)上的BIOS通过硬件映射的方式将BIOS程序代码映射到内存空间OXFE000到0XFFFFF的地址空间。
而CS:IP的地址段在通电的时候就被设定为BIOS的程序代码起始处0XFFFF0,实际上由硬件决定的。
BIOS的主要任务包括检测外设、设置中断向量表以及中断服务程序。参考sea-BIOS程序(https://www.seabios.org/SeaBIOS)。
操作系统写入的地址都是线性地址,经过MMU转换地址成为实际的物理地址,而编辑器实际上解析应用程序时处理的是线性地址。
实模式下内存分布
而在保护模式下的中断向量表与之不同,通过IDTR指明其存储位置,后边还会说明。

加载程序代码

加载bootsect.s

加载bootsect.s过程
软盘上的第一个扇区并不是值得.s后缀的这个文件,而是被写入的可执行文件的代码,只有第一个扇区被写入启动代码的存储文件才算是启动盘,无论是机械硬盘、SSD还是U盘都有类似的机制。
加载过程
其中0X07C00是一个约定好了的地址,可以方便将操作系统和BISO进行解耦。

加载setup

  1. bootsect.s划分的内存分布
    其中setup的程序代码占据了软盘上紧接着bootsect.s的4个扇区。
  2. 复制自身到0X90000(INITSEG) 处,然后jmp到go处,避免循环执行复制逻辑
    避免重复执行复制逻辑
  3. 调整数据段的位置
    要理解正常的可执行代码分布为:代码区+静态数据区+堆+栈 其中堆和栈对向增长,可以增强利用率,如果栈不由高地址向低地址增长,则无法设定栈的起点。
  4. 调用int 0x13中断加载setup可执行代码
    具体加载过程
    我们可以观察到此时SS:SP的位置为OX9FF00,这与setup的起始位置还有很大的距离,即便setup加载进来后,系统仍然有足够的内存空间用来执行数据压栈操作,而且在启动部分,要压栈的数据毕竟也是有限的。

加载system模块

具体加载过程

setup开始运行

这里要注意内存的使用总是随着操作系统的运行而不断发生覆盖和改变的,例如上边setup运行过程中覆盖了bootsect.s复制后的内存区域。

后边就是实模式向保护模式的转变了,包括关中断、移动system代码到0X00000处,以及执行Main函数等。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注