第4章 系统初始化
当你想要运行程序时,你需要把程序的文件名敲入shell—或者更为流行的,在如GNOME或
者KDE等之类桌面环境中点击相应的图标,这样就能将其装载进内核并运行。但是,首先
必须有其他的软件来装载并运行内核;这通常是诸如LOADLIN或者LILO之类的内核引导程
序。更进一步说,我们还需要其他的软件来装载运行内核引导程序—称之“内核引导程序
的引导程序”,而且看起来似乎运行内核引导程序的引导程序也需要内核引导程序的引导
程序的引导程序,等等,这个过程是无限的。
这个无限循环的过程必然最终在某个地方终止,这就是硬件。因此,在最低的层次上,启
动系统的第一步是从硬件中获得帮助。该硬件总是运行一些短小的内置程序—软件,但是
这些软件是被固化在只读存储器中,存储在已知地址中。因此,在这种情况下就不需要软
件引导程序了—它能够运行更大更复杂的程序,直到内核自身装载成功为止。按照这种方
式,系统自己的引导过程(bootstrap)会引发系统的启动,当然这只是术语“系统引导
(booting)”的一个比喻。虽然不同体系结构的引导过程的具体细节差异很大,但是它
们的原则都基本相同。
前面的工作都完成以后,内核就已经成功装载了。随后内核可以初始化自身以及系统的其
他部分。
本章首先将简单介绍基于x86 PC机的典型自启动方式,接着回顾一下每一步工作在什么时
机发生,最后我们还要介绍的是内核的相应部分。
4.1 引导PC机
4.1 引导PC机
本节简要介绍x86 PC是如何引导的。本节的目的不是让你精通PC是怎样引导的(这超出了
本书的范围),而是向你展示特定体系结构一般的引导方式,为下文中的内核初始化进行
铺垫。
首先,机器中的每个CPU都要自行初始化,接着可能要用几分之一秒的时间来执行自测试
。在多处理器的系统中,这个过程会更复杂些—但是实际上也并不多。在双处理器的
Pentium系统中,一个CPU总是作为主CPU存在,另外一个CPU则是辅CPU。主CPU执行启动过
程中的剩余工作,随后内核才会激活辅CPU。在多处理器的Pentium Pro系统中,CPU必须
根据Intel定义的算法“抢夺标志”来动态决定由哪个CPU启动系统。取得标志的CPU启动
系统,随后内核激活其他的CPU。无论是哪种情况,启动程序的剩余部分只与一个CPU有关
。这样,在随后的一段时间内,我们可以认为该系统中只有一个CPU是可用的,而不考虑
其他的CPU,或者说这些CPU被暂时隐藏了。另一方面,内核还需要明确地激活所有其他的
CPU—这一点你可以在本章后续部分看到。
接下来,CPU从0xfffffff0地址单元中取得指令并执行,这个地址非常接近于32位CPU的最
后可用的地址。因为大多数PC都没有4GB的RAM,所以通常在这个地址上并没有实际内存。
内存硬件可以虚拟使用它。对那些确实有4GB内存的机器来说,它们也只是仅仅损失了供
BIOS使用的顶端地址空间末尾的少量内存(实际上BIOS在这里只保留了64K的空间—这种
损失在4GB的机器中是可以忽略的)。
该地址单元中存储的指令是一条跳转指令,这条指令跳转到基本输入输出系统(BIOS)代
码的首部。BIOS内置在主板中,它主要负责控制系统的启动。请注意CPU实际上并不真正
关心BIOS是否存在,这样就使得在诸如用户定制的嵌入系统之类的非PC体系结构的计算机
中使用Intel的CPU成为可能。CPU执行在目标地址中发现的任何指令,在这里使用跳转指
令转移到BIOS只是PC体系结构的一部分(实际上,跳转指令自己是BIOS的一部分,但是这
不是考虑这个问题的最方便的方法)。
BIOS使用内置的规则来选择启动设备。通常情况下,这些规则是可以改变的,方法是在启
动过程开始时按下一个键(例如,在我的系统中是Del键)并通过一些菜单选项浏览选择
。但是,通常的过程是BIOS首先试图从软盘启动,如果失败了,就再试图从主硬盘上启动
。如果又失败了,就再试图从CD-ROM上启动。为了使问题更具体,这里讨论的情况假定是
最普通的,也就是启动设备是硬盘。
从这种启动设备上启动,BIOS读取第一个扇区的信息—首512个字节,称之为主引导记录
(MBR)。接下来发生的内容有赖于Linux是怎样在系统上安装的。为使讨论形象具体,我
们假定LILO是内核的载入程序。在典型的设置中,BIOS检测MBR中的关键数字(为了确认
该数据段的确是MBR),并在MBR中检测引导扇区的位置。这一扇区包含了LILO的开始部分
,然后BIOS将其装入内存,开始执行。
注意我们现在已经实现了从硬件和内置软件的范围到实际软件范围的转变,从有形范围到
无形范围,也就是说从你可以接触的部分到不可接触的部分。
下面就是LILO的责任了。它把自己其余的部分装载进来,在磁盘上找到配置数据,这些数
据指明从什么地方可以得到内核,启动时要通过什么选项。LILO接着装载内核到内存并跳
转到内核。
通常,内核以压缩形式存储,只有少量足以完成解压缩任务的指令,也就是自解压可执行
文件,是以非压缩形式存储的。因此,内核的下一步工作是自解压缩内核镜像。到这里,
内核就已经完成了装载的过程。
下面是对所进行步骤的简要描述:
1) CPU初始化自身,接着在固定位置执行一条指令。
2) 这条指令跳转到BIOS中。
3) BIOS找到启动设备并获取MBR,该MBR指向LILO。
4) BIOS装载并把控制权转交给LILO。
5) LILO装载压缩内核。
6) 压缩内核自解压,并把控制权转交给解压的内核。
正如你所见到的,引导过程每一步都将你带入更大量更复杂的代码块中,一直到最后成功
地运行了内核为止。
依赖于你计算层次的方式,CPU成为内核引导程序的引导程序的引导程序的引导程序(CPU
装载BIOS,BIOS装载LILO,LILO装载压缩内核,压缩内核装载解压内核;但是你可以考虑
是否这些步骤都满足引导程序的定义)。