1. BIOS自检
计算机在接通电源之后首先由BIOS 进行POST自检,然后依据BIOS内设置的引导顺序从硬盘、软盘或CDROM 中读入引导块。Linux 系统是从BIOS 中的地址0xFFFF0 处开始引导的。BIOS的第1 个步骤是加电POST 自检。POST的工作是对硬件进行检测。BIOS的第2个步骤是进行本地设备的枚举和初始化。BIOS由两部分组成:POST 代码和运行时的服务。当POST 完成之后,它被从内存中清理出来,但是BIOS 运行时服务依然保留在内存中,目标操作系统可以使用这些服务。
BIOS运行时会按照CMOS的设置定义的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备甚至是USB 闪存。通常,Linux 系统都是从硬盘上引导的,其中主引导记录(MBR)中包含主引导加载程序。MBR 是一个512字节大小的扇区,位于磁盘上的第一个扇区(0 道0柱面1 扇区)。当MBR被加载到RAM 中之后,BIOS 就会将控制权交给MBR。
如果要查看MBR的内容,用户需要以root用户的身份运行如下命令:
#dd if=/dev/hda of=mbr.bin bs=512 count=1
读入了1+0 个块
输出了 1+0 个块
#od -xa mbr.bin
0000000 48eb 1090 d08e 00bc b8b0 0000 d88e c08e
k H dle dle so P nul | ? nul ack 9 nul stx s $ j ! ack nul
0000040 be00 07be 0438 0b75 c683 8110 fefe 7507
nul > > bel 8 eot u vt etx F dle soh ~ ~ bel u
0000060 ebf3 b416 b002 bb01 7c00 80b2 748a 0203
s k syn 4 stx 0 soh ; nul | 2 nul nl t etx stx
0000100 0080 8000 e441 0000 0800 80fa 80ca 53ea
nul nul nul nul A d nul nul nul bs z nul J nul j S
0000120 007c 3100 8ec0 8ed8 bcd0 2000 a0fb 7c40
| nul nul 1 @ so X so P y } h 4 soh v B nul
0000160 5474 41b4 aabb cd55 5a13 7252 8149 55fb
t T 4 A ; * U M dc3 Z R r I soh { U
0000200 75aa a043 7c41 c084 0575 e183 7401 6637
* u C sp A | eot @ u enq etx a soh t 7 f
0000220 4c8b be10 7c05 44c6 01ff 8b66 441e c77c
vt L dle > enq | F D del soh f vt rs D | G
0000240 1004 c700 0244 0001 8966 085c 44c7 0006
eot dle nul G D stx soh nul f ht \ bs G D ack nul
0000260 6670 c031 4489 6604 4489 b40c cd42 7213
p f 1 @ ht D eot f ht D ff 4 B M dc3 r
0000300 bb05 7000 7deb 08b4 13cd 0a73 c2f6 0f80
enq ; nul p k } 4 bs M dc3 s nl v B nul si
…………………………………………………………………
它从/dev/hda(第一个IDE盘)上读取前512个字节的内容,并将其写入mbr.bin 文件中。od 命令会以十六进制和ASCII码格式打印这个二进制文件的内容。
2 启动GRUB/LILO
GRUB 和LILO 都是引导加载程序。引导加载程序用于引导操作系统启动。当机器引导它的操作系统时,BIOS会读取引导介质上最前面的512 字节(主引导记录)。在单一的MBR中只能存储一个操作系统的引导记录,所以当需要多个操作系统时就会出现问题,需要更灵活的引导加载程序。
所有引导加载程序都以类似的方式工作,满足共同的目的,但LILO 和GRUB 之间也有很多不同之处:
这些守护进程启动完毕,rc程序也就执行完了,然后又将返回init继续下一步。
3.执行/etc/ec.d/rc.local
RHEL 4中的运行模式2、3、5都把/etc/rc.d/rc.local做为初始化脚本中的最后一个,所以用户可以自己在这个文件中添加一些需要在其他初始化工作之后、登录之前执行的命令。在维护Linux 系统时一般会遇到需要系统管理员对开机或者关机命令脚本进行修改的情况。如果所做的修改只在引导开机的时候起作用,并且改动不大的话,可以考虑简单地编辑一下/etc/rc.d/rc.local脚本。这个命令脚本程序是在引导过程的最后一步被执行的。
6. 执行/bin/login程序
login 程序会提示使用者输入账号及密码,接着编码并确认密码的正确性,如果账号与密码相符,则为使用者初始化环境,并将控制权交给shell,即等待用户登录。
login 会接收mingetty传来的用户名作为用户名参数,然后login 会对用户名进行分析。如果用户名不是root,且存在/etc/nologin文件,login将输出nologin 文件的内容,然后退出。这通常用来在系统维护时防止非root 用户登录。只有在/etc/securetty 中登记了的终端才允许root 用户登录,如果不存在这个文件,则root 可以在任何终端上登录。/etc/usertty 文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。
在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的其他信息,比如:主目录是什么、使用何种shell。如果没有指定主目录,则将主目录默认设置为根目录;如果没有指定shell,则将shell 类型默认设置为/bin/bash。
login 程序成功后,会向对应的终端再输出最近一次登录的信息(在/var/log/lastlog 中有记录),并检查用户是否有新邮件(在/usr/spool/mail/的对应用户名目录下),然后开始设置各种环境变量。对于bash 来说,系统首先寻找/etc/profile 脚本文件并执行它;然后如果用户的主目录中存.bash_profile 文件,就执行它,在这些文件中又可能调用了其他配置文件,所有的配置文件执行后,各种环境变量也设好了,这时会出现大家熟悉的命令行提示符,至此整个启动过程就结束了。
图1 所示为整个Linux 系统的启动过程。
init 进程
init 是Linux 系统执行的第一个进程,进程ID 为1,是系统所有进程的起点,主要用来执行一些开机初始化脚本和监视进程。Linux 系统在完成核内引导以后就开始运行init程序,init 程序需要读取配置文件/etc/inittab。inittab 是一个不可执行的文本文件,它由若干行命令所组成。在RHEL 4 系统中,inittab配置文件的内容如下所示。
#
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg,
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
//表示当前缺省运行级别为5,启动系统进入图形化界面
id:5:initdefault:
//启动时自动执行/etc/rc.d/rc.sysinit 脚本
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
//当运行级别为5 时,以5为参数运行/etc/rc.d/rc脚本,init 将等待其返回
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
//在启动过程中允许按[CTRL+ALT+DELETE]重启系统
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
//在运行级别2、3、4、5 上以ttyX 为参数执行/sbin/mingetty 程序,打开ttyX 终端用于用户登录,如果
进程退出则再次运行mingetty 程序
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
//在级别5 上运行xdm程序,提供xdm 图形方式登录界面,并在退出时重新执行
# Run xdm in runlevel 5
x:5:respawn:/etc/X11/prefdm -nodaemon
inittab配置文件每行的基本格式如下。
id:runlevels:action:process
其中某些部分可以为空,下面我们逐一介绍。
1.id
1~2个字符,配置行的惟一标识,在配置文件中不能重复。
2.runlevels
配置行适用的运行级别,在这里可填入多个运行级别,比如12345或者35等。
Linux 有7个运行级别。