从开机到main函数总共要执行三步,目的是为了完成从启动盘加载操作系统程序,完成main函数执行前的准备工作。
一、启动BIOS,准备实模式下的中断向量表和中断服务程序。
二、从启动盘加载操作系统到内存。
三、为执行32位的main做过度工作。

一、启动BIOS,准备实模式下的中断向量表和中断服务程序。
(打开电源CPU进入实模式------>>开机寻址CS:IP=0xFFFF0------>>检查ROM,键盘,显示器,软硬盘)
1.1、BIOS启动原理
计算机的运行始终都是由程序控制的。但是在上电的一瞬间,计算机的RAM什么都没有。启动盘里有操作系统,但是CPU的逻辑电路被设计的只能运行内存中的程序,没有直接从硬盘中运行操作系统。所以想要运行操作系统,必须把启动盘的操作系统加载到内存(RAM)中。
PS:RAM中什么程序也没有的时候,是BIOS来完成加载启动盘的操作系统的任务。
PS:BIOS(Basic Input/Output System)即基本输入输出系统。
从计算机底层机制上看,在开机上电的一瞬间,内存没有任何程序,无法人为执行BIOS程序,所以无法用软件的办法来实现。为了解决这个启动问题,Inter将所有的8086系统的CPU硬件都设置为加电进入16位实模式状态。然后将硬件逻辑设计为强行将CS的值设置为0xF000,IP的值为0xFFF0,这样CS:IP指向0xFFFF0这个位置,也就是BIOS的地址范围。BIOS程序的人口地址是0XFFFF0,也就是说,BIOS程序的第一条指令就是在这个位置。
PS:cs:代码段段地址。ip:将要执行的下一条指令的地址cs
10h+ip指向下一条要执行的指令所为的内存单元的起始位置。

1.2、BIOS在内存中加载中断向量表和中断服务程序。
BIOS程序被固化在计算机主板的一块很小的ROM芯片里。 BISO程序在内存最开始的位置(0x00000)用1kb的内存空间(0x00000~0x003FF)构建中断向量表。紧接着它的位置用256字节的内存空间构建数据区
(0x00400~0x004FF),并在大约57KB以后的位置(0x0E05B)加载了8KB左右的与中断向量表相应的若干中断服务程序。

二、从启动盘加载操作系统到内存。
(将磁盘的0磁道0扇区读到第一个扇区(512字节)到0x7c00处(引导扇区)------>>跳转到引导程序(设置CS:IP=0x7c00))
上述已经完成boot操作前准备工作。现在执行boot操作,把启动盘的操作系统加载到内存。这个步骤分成三部分实现。第一批由BIOS中断int 0x19把第一扇区bootsect的内容加载到内存。第二批,第三批在bootsect的指挥下,分别把其后的4个扇区和随后的240个扇区的内容加载至内存。
2.1 加载第一部分内核代码——引导程序
经历一系列的BISO代码,由于我们把软盘作为启动设备,会让CPU接到一个int 0x19的中断向量。中断向量把CPU指向0x0E6F2,这个位置也就是int 0x19相对应的中断服务程序的入口地址。这个中断服务程序的作用是把软盘第一扇区中的程序(512B)加载到内存的指定位置。这个int 0x19中断向量所指向的中断服务程序,即启动加载服务程序,将软驱0号磁头对应的盘面的0磁道1扇区的内容复制至内存0x07C00处。这个扇区的内容就是Linux 0.11的引导程序,也就是我们的启动扇区(bootsector),第一批代码bootsect已经从软盘载入计算机的内存了。
PS:启动设备信息被设置在CMOS中(互补金属氧化物半导体64B-128B).用来存储实时钟和硬件配置信息。
2.2 加载第二部分内核代码,
BIOS已经把bootsect引导程序载入内存了,现在它的作用就是把第二批和第三批程序陆续加载到内存中。为了把第二批和第三批加载到内存的适当位置,bootsect首先做的工作就是规划内存。
(1)内存规划
这些源代码作用:对后续操作涉及的内存位置进行设置,包括加载的setup程序扇区数(SETUPLEN)以及被加载到的
位置(SETUPSEG);启动扇区被BIOS加载的位置(BOOTSEG)及将要被加载到的位置(INTSEG);内核(kernel)被

加载的位置(SYSSEG)、内核的末尾位置(ENDSEG)及根文件系统设备号(ROOT_DEV)。设置这些位置为了确保将
要载入的内存的代码与以及载入内存的代码及数据各在其位,互不覆盖。
(2)复制bootsect
加载setup这个程序,要使用BIOS提供的int 0x13中断向量所指向的中断服务程序(也就是磁盘服务程序)来完成。
(3)将setup程序加载到内存中。
加载setup这个程序,要使用BIOS提供的int 0x13中断向量所指向的中断服务程序(也就是磁盘服务程序)来完成。
Int 0x19和int 0x13的中断服务不同:
int 0x19中断向量所指向的启动加载服务程序是BIOS执行,而int 0x13的中断服务程序是Linux操作系统自身的启动代码bootsect执行的。
init 0x19的中断服务程序只负责把软盘第一扇区的代码加载到0x07C00位置,而int 0x13的中断服务程序则可以根据设计者的意图把指定扇区代码加载到内存的指定位置。
2.3 加载第三部分内核代码——system
加载第三批代码还是使用BIOS提供的int 0x13中断,bootsect程序】执行的第三批程序的载入工作,即将系统模块载入内存。
bootsect借BIOS中断int 0x13,将240个扇区的system模块加载进内存,加载工作主要是由bootsect调用read_it子程序完成,这个子程序将软盘第六扇区开始的约240个扇区的system模块加载至内存的SYSSEG(0x10000)处往后的120KB空间中。
由于长时间操作软盘,所以需要对软盘设备进行更多的监控,对读盘结果不断地进行检测。因此read_it后续的调用步骤比较多,但读盘工资最终由0x13对应的中断服务程序完成。到此为止,第三批程序加载完毕。整个操作系统代码已经全部加载到内存。还有一点小事,就是再次确定根设备号。
bootsect程序的任务都已经完成,下面要执行第二批程序,setup程序加载的位置:
setup执行的第一件事就是利用BIOS提供的中断服务程序从设备上提取内核运行所需的机器系统数据。包括光标位置、显示页面数据、并从中断0x41和0x46向量值所指的内存地址处获得硬盘参数表1、硬盘参数表2,把腿毛存放在0x9000:0x0080和0x9000:0x0090处。这些机器系统数据被加载到内存0x90000~0x901FC。BIOS提取的机器系统数据将覆盖bootsect程序所在的部位区域。这些数据由于是要留用的,所以在他们失去价值之前,一定不能被覆盖掉。