Linux内核学习篇一:引导启动

对于Linux内核启动问题总是一知半解,今天正好趁着学习课本的机会,写一下自己的体会,尽量通俗易懂,方便日后翻看。好了进入正题~~~~~

首先需要明确一下几点:
1.引导程序也属于Linux内核的一部分,而不是独立于内核的,所以我们通常所说的“内核 = 引导 + 操作系统”。
1.Linux系统自身想要启动是无法实现的,所以必须要借助引导(软件程序+硬件设备)才行。
2.Linux的引导启动过程采用的是“多级”方式,不是“一个”程序或者部件就能完成的,而且还有固定的顺序。

下面按照引导启动的顺序依次进行介绍:BIOS -> bootsect.s -> bootsetup.s + system -> main.c

1.一级引导 -----BIOS
关于引导程序,我们以前经常听说的是“BIOS”,也就是(basic input-output system)。BIOS是第一个启动的设备,上电后“自动”启动,所以也是我们第一个要介绍的。BIOS 通常被写入一块 ROM 芯片连接在主板上,注意这里BIOS是写在“ROM”里的,所以说是不可通过编程更改的。为什么呢?

这里说一下我的理解,BIOS一个独立的部件,它有自己的硬件和软件,而且都是“写死的”,只要开机时按下了电源,BIOS就是第一个被启动的部件。那它做什么?它会立刻去启动设备的第一个扇区去取东西。(启动设备是什么?就是存放操作系统的设备,U盘、硬盘、软盘都可以作为启动设备,就看你的操作系统放在哪里了^_^)

这样的好处就是,开发者只需要把他的内核放到第一扇区就可以了。无论你是用的Windows/Linux/Mac系统,只要放在第一扇区,就一定能保证被读到,只能说很省心!(当然,BIOS还负责一些上电以后的自检工作,这可不感兴趣可以不深入研究了~)

2.二级引导 -----bootsect.s
好了,我们按照规则把内核放在了第一扇区,BIOS怎么读呢?是把内核全部都读出来吗?显然是不可能的,因为太耗时间而且内存也没有那么大的空间把系统全读进来。此时BIOS做的工作只是把内核中的“bootsect.s”程序读到了内存中,读到了内存的0x7c00这个地址上,bootsect.s一共只有512Bytes。(注意,这里.s是汇编文件,而bootsect.s就是一段汇编程序,它是一个可以执行的二级引导程序)

bootsect.s非常的狡猾,当它执行时,它不满足于待在0x7c00处,它将自己偷偷的移动到了0x90000处。所以bootsect.s在内存里的位置就是0x90000 ~ 0x901FF ,一共512Bytes。(有同学会问了,这时候BIOS干嘛去了,回答是BIOS将bootsect.s读出来就完成了它的使命,以后就没它的工作了)

bootsect.s移动了位置后,就开始执行了,执行主要完成两个工作:1)将bootsetup读到内存0x90200处。2)将system模块读到内存0x10000处。

3.三级引导 -----bootsetup.s / system模块
到了这里,bootsect.s也完成它的使命了。下面就交给bootsetup.s和system模块了。

1)bootsetup.s也是一段汇编程序,主要负责读取系统的一些数据。然后它做了一件很忘恩负义的事情,就是把这些读取来的数据保存在了0x90000 ~ 0x901FF,也就是将bootsect.s覆盖了bootsetup.s的位置是在0x90200 ~ 0x909FF , 一共2KBytes

2)system模块主要保存了大量的系统信息和变量。system模块的位置是在0x10000 ~ 0x8FFFF,一共512KBytes。system这里也很狡猾,它也偷偷的移动了自己的位置,怎么移动的呢?从0x10000 ~ 0x8FFFF 移动到了 0x00000 ~ 0x7FFFF。还是保持了512KByte长度不变。为什么要移动呢?因为你有没有感觉到0x00000这个移动后的起始地址很特殊呢?哈哈~因为全是0,这个好处就是如果操作系统去读取system模块中的数据时,完全不需要转换,也就是不需要加“偏移量”,比如要读取0x00F03处的数据,如果按照没移动之前的地址,那读取的位置是0x00F03 + 0x10000 = 0x10F03,而移动后,直接可以将0x00F03送到寄存器里去取。看到了没?移动后的地址不需要转换了,多省事~

4.系统常态运行 ------ main.c
经过了三级引导的处理,引导过程也算是结束了,程序会最终调用/init/main.c文件,执行main()函数,进入了正常的操作系统运行状态。

下图是书本上对启动过程内存的使用情况。非常直观~
横轴:时间        纵轴:内存(堆栈)
Linux内核学习篇一:引导启动_第1张图片
如果你要问为什么内存中地址高的反而在上面,那我推荐可以看一下“操作系统”->"堆栈-----操作系统方面"的介绍^_^


引导过程为什么这么复杂?
首先,无论是嵌入式设备还是PC,内部都是很复杂的,像上文中介绍的引导过程其实是省略了很多寄存器存取的过程。所以将引导过程分级处理,分割为各个环节,便于设计和维护,这让我想到了软件设计中的高内聚低耦合原理+_+。(如果想仔细研究引导过程,可以参见书本。。。)

你可能感兴趣的:(Linux,Kernel)