程序的执行一般来说,都是要加载到内存中才能运行。操作系统实际上也只是一个运行的程序,只不过职责有别于其他的程序,所以操作系统也必须加载到内存中才能够运行。
本文章基于x86架构的CPU
上电之后,计算机的启动流程
-
上电启动后,CPU会处于16位运行的实模式,不能使用分页机制,此时只有1MB内存可以使用,没有特权级
- 你可能会有这样的疑问:现在基本上32位的x86架构CPU都很少了,为什么CPU启动后会运行在16位的工作模式下? 实际上,我一开始也是有这样的疑问。但实际上刚进入32位的时代时,有着大量的16位程序,为了兼容这些程序(就像现在还有一堆32位程序一样),Intel就这样做了,一直到现在。(不过我听说Intel有打算对x86进行简化,并且命名为x86s,有兴趣的可以了解一下)
-
之后CPU会跳转到BIOS的入口(地址为0xFFFF0)开始执行BIOS程序
-
BIOS会对各种硬件进行自检,并保存一些配置数据到特定的内存地址处(如硬盘的数量)
-
根据配置的启动顺序(光驱、U盘、硬盘等),加载引导代码运行。例如,硬盘启动时,会将硬盘的第1扇区读取到0x7c00处并跳转到该地址进行运行。
- 熟悉重装系统的小伙伴们是不是对引导盘的作用了解更多了呢?
-
引导代码对操作系统的运行初始环境进行配置,并操作系统加载到内存中
-
跳转到操作系统运行
如何将操作系统加载到内存
在启动流程的第4步,我们提到了BIOS会将磁盘的第1个扇区(实际上这些忽略和简化了一些细节,例如硬盘细节和多分区的情况)加载到0x7c00处。
在这一步之前,BIOS其实会检查第1个扇区的最后两个字节是否是0x55,0xaa。我们称这两个字节为引导标志,BIOS正是通过引导标志来判断存在第1扇区的内容是否为引导程序。
下面这个图是实模式中的内存分配:
为什么要有引导
首先就是BIOS只把第1扇区加载到内存中,而一个扇区存放的字节数并不多,只有512字节。绝大多数的操作系统需要的内存远不止有只有512字节大小。所以我们必须采用引导程序对操作系统(?)进行加载。
但有一个问题,引导程序是用来加载数据的,但是由于引导程序最多只有510字节,不可能承担一些比较繁重的工作,所以使用引导程序把操作系统加载到内存也是不太现实的。
loader
那怎么解决这个问题呢?于是又有了一种思路,让引导程序去加载另一个程序"loader",而loader可以使用的空间就远远大于510个字节了。
所以我们就可以使用loader来对操作系统进行加载,如果操作系统大小比较小的话,也可以直接16位模式下的loader进行加载(可以使用BIOS中断,也比较方便)。如果操作系统比较大的话,就不能这样做了,必须在32位的模式下进行加载,否则无法使用1MB以上的内存区域。
至此,操作系统被加载到了内存中,并且CPU的控制权也从BIOS交给了内核。
总结一下:
加载步骤简单的来说就是:
-
BIOS判断磁盘第1个扇区最后两个字节是否为0x55、0xaa,若是,则加载到0x7c00处。
-
引导程序加载loader程序,并且跳转到loader程序。
-
由loader程序负责进行加载操作系统之前的一些准备工作,并且把操作系统进行加载。
希望我的文章能让你得到收获。