📄 00000001.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER> <BR> <BR> Linux 开机程序之研讨(1) <BR> CCCA 资工86 许景华 <BR> <BR> <BR> 各位是否曾经对电脑整个开机的流程感到好奇呢 ? 这一次 , 我们所要讨论的 <BR> 主题 , 就是 Linux 从开机的一瞬间到 login 为止 , 到底发生了什麽事情 ? <BR> <BR> 想必各位都知道 , 在刚开机时 , 由於 80x86 的特性 , CS ( Code Segment ) <BR> 这个暂存器中全部都放著 1 , 而 IP ( Instruction Pointer ) 这个暂存器 <BR> 中全部都放著 0 , 换句话说 , CS=FFFF 而 IP=0000 , 此时 , CPU 就依据 <BR> CS 及 IP 的值 , 到 FFFF0H 去执行那个地方所放的指令 . 这时候 , 由於 <BR> FFFF0H 已经到了高位址的顶端 , 所以 , FFFF0H 这个地方 , 总是会放一个 <BR> JMP 指令 , 跳到比较低的位址 . 接著 , ROM BIOS 就会作一些检查的动作 <BR> 像记忆体 , 键盘 等...... 并在我们俗称的 UMB ( Upper Memory Block ) <BR> 之中扫描 , 看看是否有合法的 ROM 存在 ( 比如 SCSI 卡上的 ROM ) . <BR> 假如有 , 就到里面去执行一些东西 , 执行完之後再继续刚才的行程 . 到了 <BR> 最後 , 读取磁碟机上的第一个 sector . 在这里 , 我假设各位由硬碟启动 <BR> 因此 , 就硬碟的构造而言 , 它的第一个 sector 称为 MBR ( Master Boot <BR> Record ) . 因为一个 sector 是 512 bytes , 而 MBR 这 512 bytes 可分 <BR> 为两个部份 , 第一个部份为 Pre-Boot 区 , 占了 446 bytes ; 第二部份 <BR> 是 Partition Table , 占了 66 bytes . Pre-Boot 区的作用之一 , 就是 <BR> 去看看那个 Partition 被标成 Active , 然後去读那个 Partition 的 Boot <BR> 区 . <BR> <BR> 在 Linux 的启动方面 , 一般人最常把 LILO 放在 MBR 或 Superblock <BR> 假如你把 LILO 放在 MBR , 那很明显的 , 当读取到 MBR 的时候 , LILO <BR> 就被执行 , 此时 , 你的萤幕上会出现 boot: 接著 , 就进行 Load Kernel <BR> 的动作 . 在另一方面来说 , 假如你把 LILO 安装在 Superblock , 通常你 <BR> 还会有一个管理开机的程式 , 也许是住在 MBR ( 像 OSBS ) 或者是放在一 <BR> 个单独的 Partition ( 像 OS/2 的 Boot Manager ) . 再由这个管理开机 <BR> 的程式去读取 LILO , 进而做 Load Kernel 的动作 . <BR> <BR> 好了 , 到了目前为止 , 我们已经讲到 Load Kernel 的动作 . Kernel 被 <BR> load 到 memory 中之後 , 接著进行一连串 probe 周边的动作 , 像串联埠 <BR> 并联埠 , 软碟 , 音效卡 , 硬碟 , 光碟机 等 ...... 接著 mount root <BR> partition . 在这之後 , kernel 会起动 init 这个 process . init 这 <BR> 个 process 的 PID 为 1 , 它是所有 process 的祖先 . <BR> <BR> 接下来呢 ? 系统就开始执行 /rc.d/rc.S , 在这里 , 我们暂时打住 , <BR> 先对大概的 initialization script 执行的顺序作一个浏览 , 请看下面 <BR> 的流程 : <BR> <BR> init[1] <BR> rc.S begin <--- 目前我们已经讲到这里 <BR> rc.serial begin <BR> rc.serial end <BR> rc.S end <BR> init[1] enter runlevel 5 <BR> rc.M begin <BR> rc.inet1 begin <BR> rc.inet1 end <BR> rc.inet2 begin <BR> rc.inet2 end <BR> rc.font begin <BR> rc.font end <BR> rc.local begin <BR> rc.local end <BR> rc.M end <BR> login <BR> <BR> 上面的流程清楚的指出 , 在 rc.S 这个 shell script 中 , 会去执行 rc.serial <BR> 接著再执行 rc.M , rc.M 中又包含了 rc.inet1 , rc.inet2 , rc.font , rc.local <BR> 最後执行 login . 在下面的内容中 , 将为各位介绍这几个 shell script <BR> 从下面开始 , 凡是每一列之前有一个 # 的 , 为原来 shell script 中的注解 <BR> 有两个 # 的 , 为笔者加上的注解 , 当然啦 , 没有任何 # 的为 shell script <BR> 的内容 , 而对命令或内容的解释 , 一律都写在命令或内容的前面 . <BR> 首先由 rc.S 开始 : <BR> <BR>***************************** rc.S ********************************** <BR> <BR>#!/bin/sh <BR># <BR># /etc/rc <BR># <BR># These commands are executed at boot time by init(8). <BR># User customization should go in /etc/rc.local. <BR> <BR>echo '======== rc.S is running ! System Initializing Now !!! ========' <BR>PATH=/sbin:/usr/sbin:/bin:/usr/bin <BR> <BR>## 打开所有 swap ! 下面 /sbin/swapon -a 的意思是 : 使得 /etc/fstab 中被记录 <BR>## 成 swap 的 device 全部启动 . <BR> <BR>/sbin/swapon -a <BR> <BR> <BR>## 喔 ! 下面这个指令 update 就很重要了 , 它负责每隔一段固定的时间 , 就将 <BR>## buffer 中的资料 , 利用 sync 写回磁碟机上 , 并将 superblock 做 update <BR>## 的动作 . 使用 ps 这个指令看看有那些 process , 就可看到 update 还有一个 <BR>## bdflush , 这两个 process 都是必然要存在的 , 可不要随便砍掉 , 要不然 , <BR>## 万一系统 crash 了 , 那磁碟机里面的资料就不是最新的了 ...... <BR> <BR>/sbin/update & <BR> <BR> <BR>## 利用 echo -n >> 制造一个档案 , 并用 rm -f 这个档案来测试 root partition <BR>## 是不是 read-only 或者是可读写 <BR> <BR>READWRITE=no <BR>if echo -n >> "Testing filesystem status"; then <BR> rm -f "Testing filesystem status" <BR> READWRITE=yes <BR>fi <BR> <BR> <BR>## 假如 root partition 是 read-only 就作 fsck 的动作 , 假如不是 read-only <BR>## 而是 read-write 的话 , 就做下面 else 之後的动作 <BR> <BR>if [ ! $READWRITE = yes ]; then <BR> ## 利用 fsck 做检查及修复档案系统的工作 , 後面接的两个参数 -A , -a . <BR> ## -A 的意思是 : fsck 会依据 /etc/fstab 中的记录 , 去检查所有的档案 <BR> ## 系统 ; 而 -a 就是 auto 的意思 , 当 fsck 有修复的动作时 , 它不会问 <BR> ## 你问题 , 而直接修复 . <BR> <BR> /sbin/fsck -A -a <BR> <BR> <BR> ## 假如 fsck 有 error , [ $? -gt 1 ] 括号里面的意思是 : 若上个命令的 <BR> ## 传回值大於 1 , 而上个命令就是 fsck . 让我们看看 fsck 的传回值 : <BR> ## 0 - No errors <BR> ## 1 - File system errors corrected <BR> ## 2 - File system errors corrected, system should <BR> ## be rebooted if file system was mounted <BR> ## 4 - File system errors left uncorrected <BR> ## 8 - Operational error <BR> ## 16 - Usage or syntax error <BR> ## 128 - Shared library error <BR> ## 很明显的 , 若有任何错误产生的话 , 那 fsck 的传回值都大於 1 . 其实 <BR> ## 就我的观点认为 , 应该写成 if [ $? -ge 1 ] 比较好 . 既然有错呢 , 系统 <BR> ## 应该就要跳至单人模式 , 在单人模式中主要就是 /etc/rc.d/rc.K <BR> ## 中的两件事 : 关掉 swap 及 卸下所有的档案系统 , 而最後重新 login . <BR> ## 一般正常的情况下 , if 下面这一大段是不会执行的 , 而会跳至下面 <BR> ## 标有 ************************* Normal 1 ************************* 处 <BR> <BR> if [ $? -gt 1 ] ; then <BR> echo <BR> echo <BR> echo "**************************************" <BR> echo "fsck returned error code - REBOOT NOW!" <BR> echo "**************************************" <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -