Linux 开机程序之研讨
位是否曾经对电脑整个开机的流程感到好奇呢 ? 这一次 , 我们所要讨论的主题 , 就是 Linux 从开机的一瞬间到 login 为止 ,
到底发生了什麽事情?
想必各位都知道 , 在刚开机时 , 由於 80x86 的特性 , CS ( Code Segment)这个暂存器中全部都放著 1 , 而
IP ( Instruction Pointer ) 这个暂存器中全部都放著 0 , 换句话说 , CS=FFFF 而 IP=0000 , 此时 , CPU 就依据CS 及 IP 的
值 , 到 FFFF0H 去执行那个地方所放的指令 . 这时候 , 由於FFFF0H 已经到了高位址的顶端 , 所以 , FFFF0H 这个地方 , 总
会放一个JMP 指令 , 跳到比较低的位址 . 接著 , ROM BIOS 就会作一些检查的动作像记忆体 , 键盘 等...... 并在我们俗称
的 UMB ( Upper Memory Block )之中扫描 , 看看是否有合法的 ROM 存在 ( 比如 SCSI 卡上的 ROM ) .
假如有 , 就到里面去执行一些东西 , 执行完之後再继续刚才的行程 . 到了最後 , 读取磁碟机上的第一个 sector . 在这里 ,
我假设各位由硬碟启动因此 , 就硬碟的构造而言 , 它的第一个 sector 称为 MBR ( Master BootRecord ) . 因为一个 sector
是 512 bytes , 而 MBR 这 512 bytes 可分为两个部份 , 第一个部份为 Pre-Boot 区 , 占了 446 bytes ; 第二部份是
Partition Table , 占了 66 bytes . Pre-Boot 区的作用之一 , 就是去看看那在上次的介绍中 , 我们已经看完了 rc.S 及
rc.serial 这两个 shell script . 现在 , 我们将把剩下的 shell script 再作一个介绍 .
首先还是看看全部的流程 :
init[1]
rc.S begin
rc.serial begin
rc.serial end
rc.S end <-- 上一次我们说明到这里
init[1] enter runlevel 5
rc.M begin
rc.inet1 begin
rc.inet1 end
rc.inet2 begin
rc.inet2 end
rc.font begin
rc.font end
rc.local begin
rc.local end
rc.M end
login
这次主要的部份可分为两项 : 因为 init 将会去读取 inittab , 所以 inittab 将被列为第一部份的重点 , 而第二部份就是
rc.M , rc.font , rc.local 这几个 shell script 的说明 . ( rc.inet1 , rc.inet2 这两个关於网路的shell script 将在以後
单独说明 )
好了 , 我们先从 inittab 看起吧 ! 看看上面的流程 , 在第一行 : init[1]也就是 init 这个 process 被启动之後 , 它会去
读取 /etc/inittab 这个档案以完成系统的启动 . 从这里 , 我们看到了 LINUX 的确融合了 SVR4 及 SunOS的一些特性 ,
inittab 这个档案 , 在 SunOS 系统中是不存在的 , 但是它却是SVR4 典型的档案 . init 这个 process 会依据 /etc/inittab
中所记载的内容进入不同的 run-level 并启动不同的 process . 所以 inittab 的重要性可见一斑 . 那什麽叫 run-level 呢 ?
所谓 run-level 就是系统中定义了许多不同的 level , 而系统会随著 level 的不同而去启动不同的资源 .
现在就让我们来看一下 /etc/inittab 中的内容 :
在 /etc/inittab 这个档案中 , 每一列是一个进入点 , 假如我们仔细观察每一列的话 , 那我们就会很容易的发现 ,
/etc/inittab 的每一列可以被 " : " 这个字元分成好几个栏位 . 这几个栏位的格式如下 :
id:runlevels:action:process
而它们代表的意义分别如下 :
id : 由两个独特的字元所组成的辨示符号 , 在比较新的 UNIX 系统中 , 已不受只能有两个字元的限制 .
runlevels : 指出下面一个栏位中的 action 以及 下下个栏位中的 process会在那些 runlevel 中被执行 . 这一栏的合法值
有 0,1,2...6 s 以及 S . 而在正常的启动程序之後 , Superuser 可以使用telinit 这个指令来改变系统的 runlevel . 又因
在 LINUX 中, runlevel 的预设值是 5 ( 等一下就会看到 ) 所以 , 只有那些每一列中 runlevel 那栏有 5 这个值的 , 後面的
process才会被启动 . 所以 , 我们就可以想像的到 : " 由於系统的runlevel 不同 , 所起动的 process 也不尽相同 , 所以系
统起动的资源在每个不同的 runlevel 就会有差异存在 .
action : 这个栏位有一点复杂 , 在这个栏位中记录著 init 在启动相对应的process 时 , 对 process 所采取的动作 , 而
合法的动作有下面几项:
initdefault : 指出系统在启动时 , 预设进入的 run-level 值 ,比如说 , 我? 强梢栽?/etc/inittab 中找到下面这一列
id:5:initdefault:
很明显的 , 系统将在启动时 , 进入 runlevel 为 5的模式 . 当然 , 你可以把 5 改成 6 试试看 , 如果你改成了 6 , 那将
会执行 /etc/rc.d/rc.6 , 也就是 run xdm . xdm 在以後有机会的话 , 将为各位介绍 ......
sysinit : 在系统起动时 , 这个 process 会被执行 . 而所有 process 前的 action 中有 boot 及 bootwait 的 process ,
必须等到这些 action 为 sysinit 的 process 执行完之後它们才能够执行 .
wait : 在起动一个 process 之後 , 若要再起动