Linux的引导启动程序

本文详细介绍了Linux系统的启动过程,从加电开始,经历BIOS初始化、加载启动扇区到内存,执行内核引导程序,再到保护模式的设置及模块加载等关键步骤。

离上一篇日志很长时间了,中间当然是因为过年,事情很多,书没看多少,现在有时间了,再发一篇笔记存档,是关于系统启动过程的:

 

一切从加电开始。加电以后,所有的寄存器清0,只有CS寄存器为全1,于是指针指向了0xffff:0, 这个地址是 ROM-BIOS地址, 在此放置和程序开始做的事情是执行一些系统检测,并在物理地址0处开始初始化中断向量,这个时候初始化的中断向量,就是在上一篇日志中打印“Hello”的那个中断,也是以后要被操作系统覆盖的中断向量。然后,将可启动设备的0扇区加载到内存0x7c00处,并跳转到这个程序开始执行。

 

放到0x7c00处的程序就是内核中的 /boot/bootsect.s, 它由BIOS读入后马上掌握了CPU的控制权,此时它做的第一件事就是把自己移动 到0x90000处,(至于这个问题我不知道是为什么,有人说是为了向下兼容,但我还找不到证据)然后把启动设备中后2k的字节代码,也就是 boot/setup.s读入到内存0x90200处,然后用BIOS中断取当前启动引导盘的参数,同时在屏幕上显示“loading”,

而其他的system模块,包括head.s, 也在此时加载到内存的0x10000处。到此为止,启动模块的三个文件 bootsect.s, ,setup.s,  head.s和system模块都已经进入内存了,只是他们的位置还不对,接下来要调整一下位置,并做下一步的工作。下一步的工作是在setup程序中执行的,此时bootsect程序已经完成了自己的历史使命,并在不久的将来被覆盖掉。

 

下来进入setup, 在这个程序中,首先利用ROM-BIOS中断读机器系统数据,并把这些数据保存到0x90000的位置,先前那战功卓著而可怜的bootsect程序就这样无情地被覆盖掉了。然后,setup程序会把system模块向下移动,由原来的0x10000移动到内存开始的0x0000处,现在先前使用的bios中断也被无情的覆盖掉了。接着加载中断描述符表寄存器和全书描述符表寄存器,开启A20地址总线, 重新设置中断控制芯片, 将硬件中断号重新设置, 最后设置CPU控制寄存器 CR0, 从而进入32位保护模式,并跳转到head.s 中。

 

接下来是head.s 程序。加载各个数据寄存器, 重新设置中断描述符表IDT, 一共256项,使所有的项都指向一个只报告错误的哑中断子程序 ignore_int, 然后又重新设置全局描述符表gdt, 接着检测A20是否开启, 设置管理内存的分页机制, 转去执行 /init/main.c 中的 main程序。

 

以上就是Linux启动的大致过程。看赵炯的书上还讲到了一点,也是上一篇日志留下的一个关子,如果是硬盘启动的话,会是什么样子的呢?

答案是:如果是硬盘启动的话,在第一步中,不是bootsect.s 被加载到0x7c00处,而是MBR,其中的程序可能会是grub, LILO等,会首先把自己下移到0x600处,然后根据MBR中的分区信息指明的引导扇区——也就是第一个扇区,加载到07c00处,然后开始执行。

 

最后想说一点,本来画个图就很好理解,上次袁泉师兄做过一个动画,有时间我拿过来贴上吧。不过我还是想有时间了自己画一个图,更清楚一些。下一次我想记录一下自己看于渊书中有关保护模式的一些收获,现在还有些不清楚的地方,弄清楚了就写上来。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值