Linux内核启动过程分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、Linux内核启动协议
阅读文档\linux-2.6.35\Documentation\x86\boot.txt
传统支持Image和zImage内核的启动装载内存布局(2.4以前的内核装载就是这样的布局):
| |
0A0000 +------------------------+
| Reserved for BIOS | Do not use. Reserved for BIOS EBDA.
09A000 +------------------------+
| Command line |
| Stack/heap | For use by the kernel real-mode code.
098000 +------------------------+
| Kernel setup | The kernel real-mode code.
090200 +------------------------+
| Kernel boot sector | The kernel legacy boot sector.
090000 +------------------------+
| Protected-mode kernel | The bulk of the kernel image.
010000 +------------------------+
| Boot loader | <- Boot sector entry point 0000:7C00
001000 +------------------------+
| Reserved for MBR/BIOS |
000800 +------------------------+
| Typically used by MBR |
000600 +------------------------+
| BIOS use only |
000000 +------------------------+
当使用bzImage时,保护模式的内核会被重定位到0x1000000(高端内存),内核实模式的代码(boot sector,setup和stack/heap)会被编译成可重定位到0x100000与低端内存底端之间的任何地址处。不幸的是,在2.00和2.01版的引导协议中,0x90000+的内存区域仍然被使用在内核的内部。2.02版的引导协议解决了这个问题。boot loader应该使BIOS 的12h中断调用来检查低端内存中还有多少内存可用。
人们都希望“内存上限”,即boot loader触及的低端内存最高处的指针,尽可能地低,因为一些新的BIOS开始分配一些相当大的内存,所谓的扩展BIOS数据域,几乎快接近低端内存的最高处了。
不幸的是,如果BIOS 12h中断报告说内存的数量太小了,则boot loader除了报告一个错误给用户外,什么也不会做。因此,boot loader应该被设计成占用尽可能少的低端内存。对zImage和以前的bzImage,这要求数据能被写到x090000段,boot loader应该确保不会使用0x9A000指针以上的内存;很多BIOS在这个指针以上会终止。
对一个引导协议>=2.02的现代bzImage内核,其内存布局使用以下格式:| Protected-mode kernel |
100000 +------------------------+
| I/O memory hole |
0A0000 +------------------------+
| Reserved for BIOS | Leave as much as possible unused
~ ~
| Command line | (Can also be below the X+10000 mark)
X+10000 +------------------------+
| Stack/heap | For use by the kernel real-mode code.
X+08000 +------------------------+
| Kernel setup | The kernel real-mode code.
| Kernel boot sector | The kernel legacy boot sector.
X +------------------------+
| Boot loader | <- Boot sector entry point 0000:7C00
001000 +------------------------+
| Reserved for MBR/BIOS |
000800 +------------------------+
| Typically used by MBR |
000600 +------------------------+
| BIOS use only |
000000 +------------------------+
这里程序段地址是由grub的大小来决定的。地址X应该在bootloader所允许的范围内尽可能地低。
2、BIOS POST过程
传统意义上,由于CPU加电之后,CPU只能访问ROM或者RAM里的数据,而这个时候是没有计算机操作系统的,所以需要有一段程序能够完成加载存储在非易失性存储介质(比如硬盘)上的操作系统到RAM中的功能。这段程序存储在ROM里,BIOS就是这类程序中的一种。对于BIOS,主要由两家制造商制造,驻留在主板的ROM里。有了BIOS,硬件制造商可以只需要关注硬件而不需要关注软件。BIOS的服务程序,是通过调用中断服务程序来实现的。BIOS加载bootloader程序,Bootloader也可以通过BIOS提供的中断,向BIOS
获取系统的信息。整个过程如下:
(1)电源启动时钟发生器并在总线上产生一个#POWERGOOD的中断。
(2)产生CPU的RESET中断(此时CPU处于8086工作模式)。
(3)进入BIOS POST代码处:%ds=%es=%fs=%gs=%ss=0,%cs=0xFFFF0000,%eip = 0x0000FFF0 (ROM BIOS POST code,指令指针eip,数据段寄存器ds,代码段寄存器cs)。
(4)在中断无效状态下执行所有POST检查。
(5)在地址0初始化中断向量表IVT。
(6)0x19中断:以启动设备号为参数调用BIOS启动装载程序。这个程序从启动设备(硬盘)的0扇面1扇区读取数据到内存物理地址0x7C00处开始装载。这个0扇面1扇区称为Boot sector(引导扇区),共512字节,也称为MBR。
就是说,CPU 在BIOS 的入口(CS:IP=FFFF:0000)处执行BIOS的汇编程序,BIOS 程序功能有系统硬件的检测,提供中断访问接口以访问硬件。而后被BIOS程序通过中断
0x19调用磁盘MBR上的bootloader程序,将bootloader程序加载到ox7c00处,而后跳转到0x7c00,这样,位于0x7c00处的bootloader程序,就可以执行了。
从BIOS执行MBR中的bootloader程序开始,就是linux的代码在做的事情了。
3、Bootloader过程
bootloader程序是为计算机加载(load)计算机操作系统的。boot(引导)是bootstrap 的简写,bootstrap是引导指令的意思。bootloader程序通常位于硬盘上,被BIOS调用,用于加载内核。在PC机上常见的bootloader主要有grub、lilo、syslinux等。
GRUB(GRand Unified Bootloader)是当前linux诸多发行版本默认的引导程序。嵌入式