System V init启动过程
概括地讲,Linux/Unix系统一般有两种不同的初始化启动方式.
大多数发行套件的Linux使用了与System V init相仿的init也就是Sys V init,它比传统的BSD system init更容易且更加灵活。
System V init的主要思想是定义了不同的"运行级别(runlevel)"。通过配置文件/etc/inittab定义了系统引导时的运行级别, 进入或者切换到一个运行级别时做什么。每个运行级别对应于一个子目录/etc/rc.d/rcX.d。
每个rcX.d目录中都是一些以S或K开头的文件链接。这些链接指向的脚本都 可以接收start和stop参数,S开头的链接会传入start参数,一般是开启一项服务,K会传入stop参数,一般是停止某服务。
以下是一个大致的System V init过程:
(1)init 过程执行的第一个脚本是 /etc/rc.d/rc.sysinit,它主要做在各个运行级别中进行初始化工作,包括: 启动交换分区;检查磁盘;设置主机名;检查并挂载文件系统;加载并初始化硬件模块.
(2)执行缺省的运行级别模式。 这一步的内容主要在/etc/inittab中体现, inittab文件会告诉init进程要进入什么运行级别,以及在哪里可以找到该运行级别的配置文件.
(3)执行/etc/rc.d/rc.local脚本文件。 这也是init过程中执行的最后一个脚本文件,所以用户可以在这个文件中添加一些需要在登录之前执行的命令.
(4)执行/bin/login程序
System V init只是一种模式,每个系统初始化都有差异,但大体上不会相差太多。如busybox执行的第一个启动脚本就是/etc/init.d/rcS,而且不可以改变,与上面讲的不同。
由下内容可以看出,最先执行的是/etc/rc.d/init.d/rc文件,给这个文件传入的参数是一个数字,rc会由传入的数字合成rcX.d目录的路径,然后执行其中的所有脚本链接。当然这只是一部分功能。
# Begin /etc/inittab id:3:initdefault: si::sysinit:/etc/rc.d/init.d/rc sysinit #可以设定初始化脚本 l0:0:wait:/etc/rc.d/init.d/rc 0 l1:S1:wait:/etc/rc.d/init.d/rc 1 l2:2:wait:/etc/rc.d/init.d/rc 2 ... ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now su:S016:once:/sbin/sulogin 1:2345:respawn:/sbin/agetty tty1 9600 2:2345:respawn:/sbin/agetty tty2 9600 ... # End /etc/inittab
只是一部分,有删减。
. ├── fstab ├── inittab ├── inputrc ├── profile ├── rc.d │ ├── init.d │ │ ├── checkfs │ │ ├── cleanfs ... │ │ ├── modules │ │ ├── mountfs │ │ ├── mountkernfs │ │ ├── network │ │ ├── rc #when boot, run. │ │ ├── reboot ... │ ├── rc0.d │ │ ├── K80network -> ../init.d/network │ │ ├── K90sysklogd -> ../init.d/sysklogd │ │ ├── S60sendsignals -> ../init.d/sendsignals │ │ ├── S70mountfs -> ../init.d/mountfs │ │ ├── S80swap -> ../init.d/swap │ │ ├── S90localnet -> ../init.d/localnet │ │ └── S99halt -> ../init.d/halt │ ├── rc1.d │ │ ├── K80network -> ../init.d/network │ │ └── K90sysklogd -> ../init.d/sysklogd │ ├── rc2.d │ │ ├── K80network -> ../init.d/network │ │ └── K90sysklogd -> ../init.d/sysklogd │ ├── rc3.d │ │ ├── S10sysklogd -> ../init.d/sysklogd │ │ └── S20network -> ../init.d/network │ ├── rc4.d │ │ ├── S10sysklogd -> ../init.d/sysklogd │ │ └── S20network -> ../init.d/network │ ├── rc5.d │ │ ├── S10sysklogd -> ../init.d/sysklogd │ │ └── S20network -> ../init.d/network │ ├── rc6.d │ │ ├── K80network -> ../init.d/network │ │ ├── K90sysklogd -> ../init.d/sysklogd │ │ ├── S60sendsignals -> ../init.d/sendsignals │ │ ├── S70mountfs -> ../init.d/mountfs │ │ ├── S80swap -> ../init.d/swap │ │ ├── S90localnet -> ../init.d/localnet │ │ └── S99reboot -> ../init.d/reboot │ └── rcsysinit.d │ ├── S00mountkernfs -> ../init.d/mountkernfs │ ├── S02consolelog -> ../init.d/consolelog │ ├── S05modules -> ../init.d/modules ... ├── udev │ ├── rules.d │ │ └── 55-lfs.rules │ └── udev.conf └── vimrc
#!/bin/sh . /etc/sysconfig/rc . ${rc_functions} . /etc/sysconfig/network case "${1}" in start) # Start all network interfaces for file in ${network_devices}/ifconfig.* do interface=${file##*/ifconfig.} # skip if $file is * (because nothing was found) if [ "${interface}" = "*" ] then continue fi IN_BOOT=1 ${network_devices}/ifup ${interface} done ;; stop) # Reverse list FILES="" for file in ${network_devices}/ifconfig.* do FILES="${file} ${FILES}" done # Stop all network interfaces for file in ${FILES} do interface=${file##*/ifconfig.} # skip if $file is * (because nothing was found) if [ "${interface}" = "*" ] then continue fi IN_BOOT=1 ${network_devices}/ifdown ${interface} done ;; restart) ${0} stop sleep 1 ${0} start ;; *) echo "Usage: ${0} {start|stop|restart}" exit 1 ;; esac # End /etc/rc.d/init.d/network