计算机只是一些冰冷的机器,加载了操作系统后,它才有了灵魂。如何让计算机加载上操作系统就是我们将要说的。我们要把操作系统要加载到内存,为什么是内存,不能直接从硬盘里运行操作系统吗?不能,因为CPU被设计成只能执行内存中的程序,所以像硬盘这种辅存里的程序要运行起来,第一件事就是把它加载到内存中来,操作系统也不例外。
计算机在我们按下电源后,要完成自举,就是它要把自己运行起来。它分为三步,我们今天先来讲它的第一步。从前文我们可以知道,自举的工作之一就是把操作系统的代码加载,计算机的电源接上后,主板上的BIOS(基本输入输出系统)就会开始工作,BIOS是一个很小巧的程序。具体的工作是这样的:文章来源:https://www.toymoban.com/news/detail-518187.html
- 电源接上时,Intel所有80x86 CPU的逻辑电路进入16位实模式运行,这个模式下物理地址与逻辑地址都是一模一样的,这些地址都是绝对地址。加电时,CPU的CS、IP寄存器分别被强制设置成0xF000、0xFFF0,CS是段寄存器,IP是指令指针地址,即指令在段内的偏移地址,CS:IP组合就指向了将要执行的指令的内存地址。0xF000:0xFFF0组合后的绝对地址是0xFFFF0,它个地址是BIOS程序的入口地址,此时BIOS并不在内存中,而在BIOS芯片上,BIOS是固化在芯片上的程序。所以在按下电源后,CPU被强制设置指向BIOS程序的入口。
- BIOS开始执行,它在内存最开始的位置构建中断向量表,就是在内存最开始的地方,初始化256个中断向量,每个向量占4个字节,其中两个字节是CS的值,另外两个字节是IP的值。每个向量都指向一个具体的中断服务程序,然后从第一个向量指向的内存地址开始加载中断服务程序,在中断向量和中断服务程序之间有一段空内存,它用于放置BIOS程序执行时会用到的数据,这些数据就从中断向量后面开始设置。这些位置的设置都需要BIOS程序员提前考虑好。
- 在继续说之前,我们来回忆一下,在开机时,马上按Del键,可以进入BIOS设置界面,设置启动盘,为什么要设置启动盘呢?因为上面有我们的引导程序(bootsect),也就是如果你设置的驱动盘没有引导程序,那系统肯定是无法加载的,硬盘的第一个扇区上有引导程序的盘才真正叫启动盘,这个扇区也叫启动扇区。言归正传,现在计算机的硬件体系联合BIOS,让CPU收到一个int 0x19中断,CPU收到后,会立刻在中断向量表中查找到int 0x19中断向量,然后用中断向量的值设置CS:IP,使其指向对应的中断服务程序入口,它就是“启动加载服务程序”的入口。CPU开始执行这个服务程序加载启动盘的第一扇区中的程序,启动加载服务程序中管加载启动盘的第一扇区里的东西,至于里面有没有引导程序(bootsect),它是不管的。(一个扇区的大小是512B)启动加载服务程序会把引导程序加载到指定的位置,这个位置是BIOS预先设计好的,与操作系统本身没有关系,具体的位置是0x07C00.这个引导程序属于Linux操作系统本身的一部分,操作系统在这之后在内存的布局都将由这个引导程序来开始。
- 当BIOS把引导程序(bootsect)加载到内存0x07C00这个位置后,很快就会设置CS:IP,指向0x07C00,也就是说开始执行引导程序的代码。从这里开始有操作系统本身的代码的执行。这里要特别注意,我们必须非常清楚操作系统该如何规划内存的使用,这与用高级语言写应用程序是非常不同的,高级语言的内存规划有编译器帮忙做看护,操作系统可没有这些。所以要非常仔细。譬如说,引导程序执行时所涉及的要加载setup程序的扇区数,setup加载到内存的位置,引导程序本身要移动到新的内存位置、内核加载到内存的位置等等都要预先规则好内存,写死在代码上。引导程序开始执行后,第一件事就是将自己移动到一个新的内存位置,这个位置是操作系统自己规划的,这是操作系统的开始自己规划内存了。在linux 0.11中,具体的移动位置是从0x07C00移动到0x90000,引导程序执行自己的代码移动自己,所以说它的代码的设计 还是很巧妙的。更巧的是,在完成移动后,它巧妙地跳到了执行复制的代码的后面,继续执行后面的代码,而不是死循环。执行后面的代码会向CPU发出int 0x13中断,这个中断会使用“磁盘服务程序”来完成加载第一扇区后的四个扇区的setup程序到内存的工作。int 0x19启动服务程序与int 0x13磁盘服务程序是有区别的,前者只负责把启动盘第一扇区加载到0x07C00这个位置,后者则可以根据设计者的意图将指定扇区的代码加载到内存指定的位置。所以引导程序在向CPU发出int 0x13这个中断时,会事先设置好指定的扇区数、加载到内存的位置,这些参数都是写在代码中的。setup程序在linux 0.11中会被加载到0x90200,这个位置刚好在bootsect引导程序之后。
- 引导程序在加载完setup程序后,它会被继续执行,再向CPU发出int 0x13中断,再次启动磁盘服务程序去加载第5个扇区之后的240扇区里的程序,它是system模块,磁盘服务程序执行使用的参数,如扇区数量、内存加载位置都在bootsect代码中预先指定好的。对于Linux 0.11来说,到此就已经将整个操作系统的代码全部加载入内存了。当引导程序在最尾会将CS:IP设置指向setup程序的位置0x90200,即是说,setup程序将接着引导程序继续执行。
setup程序的执行将涉及向32位模式的转变,为执行main函数做准备。我们在下一篇文章再做介绍。文章来源地址https://www.toymoban.com/news/detail-518187.html
到了这里,关于Linux如何被启动(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!