1.总体过程概述
- 我们都知道,计算机是一个
取指执行
的机器,那么打开电源后,计算机所执行的第一句指令是什么呢?
计算机进行取值的时候,要根据CS:IP
这两个寄存器的内容来寻找。所以我们要关注这两个寄存器所指向的内容。而这是由硬件设计者所决定的。
- 我们所讨论的Linux0.11是基于
x86
的,刚开机时,CPU处于实模式,其中CS=0xFFFF,IP=0x0000。- 此时它寻找的地址就是
0xFFFF0(ROM BIOS的映射区)
,就是基本的BIOS程序,这段程序会检查我们的RAM,键盘,显示器等设备,之后将磁盘0磁道0
扇区的内容读入到0x7c00
处。并设置CS=0x07c0,IP=0x0000。
- 而磁盘0扇区0中存放着
512字节
的信息,它就是操作系统所要执行的第一个程序。(即bootsect.s)
- 引导扇区代码bootsect.s的作用:把自己移动到内存绝对地址0x90000(576KB)处,并把启动设备中后2KB字节代码(
setup.s
)读入到内存0x90200处,而内核的其它部分(system模块
)则被读入到内存地址0x10000(64KB)处。 - setup.s:当bootsect执行完成后,会跳转到setup.s的模块开始执行,
它是一个操作系统的加载程序
,主要作用是利用ROM BIOS中断读取机器系统数据,并将这些数据保存到0x90000
开始的位置(覆盖掉了bootsect程序所在的地方)。然后setup将system模块整体向下移动到内存绝对地址0x0000处,并加载了中断描述符表寄存器(idtr)
和全局描述符表寄存器(gdtr)
,进入保护模式,并跳转到system模块最前面部分的head.s - head.s:它是system模块最前面的部分,主要功能是
加载各个数据段寄存器,重新设置中断描述符表idt
,并使各个表均指向ignore_int。并设置了内存的分页处理机制,然后利用返回指令将预先放置在堆栈中的/init/main.c程序的入口地址弹出,去运行main()程序。
整个过程可以用下面这张图来展示:
下面我们详细的了解下这几个程序的内容。
2.bootsect.s
- 这是我们所要执行的第一段程序,我们通过讨论它的一些重要源代码来深入的里了解这段程序到底做了什么事情。
- 这是第一部分代码:
- 从start开始看起,它首先设置了ds寄存器的值为
0x07c0
,es寄存器的值为0x9000
。这两个都是段寄存器。cx通用寄存器的值为256
,si和di寄存器的值都为0.- si是源变址寄存器,di是目的变址寄存器,它们一般与数据段寄存器DS联用,但是在串处理指令中,si和di作为隐藏的源变址和目的变址寄存器,此时si和ds联用,di和es联用。
- rep:将重复执行下面的语句,直到寄存器cx为0
- movw:
将ds:si的内容送至es:di,是复制过去,原来的代码还在。</