内核会查找init进程,有默认几个init路径,最后发现/sbin/init存在,于是执行/sbin/init,这个init实际上是init.sysvinit的软链接。
init.sysvinit读取/etc/inittab
# /etc/inittab: init(8) configuration.
# $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $
# The default runlevel.
id:5:initdefault:
# Boot-time system configuration/initialization script.
# This is run first except when booting in emergency (-b) mode.
si::sysinit:/etc/init.d/rcS
# What to do in single-user mode.
~~:S:wait:/sbin/sulogin
# /etc/init.d executes the S and K scripts upon change
# of runlevel.
#
# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
l0:0:wait:/etc/init.d/rc 0
l1:1:wait:/etc/init.d/rc 1
l2:2:wait:/etc/init.d/rc 2
l3:3:wait:/etc/init.d/rc 3
l4:4:wait:/etc/init.d/rc 4
l5:5:wait:/etc/init.d/rc 5
l6:6:wait:/etc/init.d/rc 6
# Normally not reached, but fallthrough in case of emergency.
z6:6:respawn:/sbin/sulogin
O0:12345:respawn:/sbin/getty -L 115200 ttyO0
# /sbin/getty invocations for the runlevels.
#
# The "id" field MUST be the same as the last
# characters of the device (after "tty").
#
# Format:
# :::
#
1:12345:respawn:/sbin/getty 38400 tty1
根据LFS中的介绍,现在运行级别为5,我们就认为是正常运行的级别就行了。
0: 关闭计算机
1: 单用户模式
2: 无网络多用户模式
3: 有网络多用户模式
4: 保留作自定义,否则同运行级 3
5: 同运行级 4,一般用于图形界面(GUI)登录(如 X的 xdm 或 KDE的 kdm)
6: 重启动计算机
开机执行了5个程序/脚本:
/etc/init.d/rcS /**/
~~:S:wait:/sbin/sulogin /**/
/etc/init.d/rc 5
O0:12345:respawn:/sbin/getty -L 115200 ttyO0
/sbin/getty 38400 tty1
sulogin需要输入用户名和密码,如果想改成自动登录可参考:
http://blog.csdn.net/swliao/article/details/5989203
/etc/init.d/rcS将运行级别提升到S级别,设置PATH并且导入 /etc/default/rcS 中的环境变量(初始化runlevel=S和prevlevel=N
),执行trap ":" INT QUIT TSTP,使得Ctrl+C不会退出当前控制台,只会退出子shell。,最后一步是执行exec /etc/init.d/rc S
(注意inittab里后面还会执行一次/etc/init.d/rc 5)
/etc/init.d/rcS内容:
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022 /*设置对文件默认的操作权限,比如新建一个文件时*/
export PATH runlevel prevlevel
# Make sure proc is mounted
#
[ -d "/proc/1" ] || mount /proc
#
# Source defaults.
#
. /etc/default/rcS
#
# Trap CTRL-C &c only in this shell so we can interrupt subprocesses.
#
trap ":" INT QUIT TSTP
#
# Call all parts in order.
#
exec /etc/init.d/rc S
重点来了,/etc/init.d/rc 根据运行级别,使用for循环启动/etc/rcX.d中的所有链接的脚本(服务),按序号可以从 00 到 99(数字越小执行的越早)。
因此,关机的时候运行级别是0,自然是执行rc0.d目录下的脚本。
那么为什么先执行/etc/init.d/rc S,然后执行/etc/init.d/rc 5呢? 目前猜测是因为先执行/etc/init.d/rc S,初始化一些变量,后面执行/etc/init.d/rc 5时可以根据变量值显示启动进度。
最后补充一下logo和进度条的实现:
logo和进度条的启动服务是rcS.d/S00psplash.sh实现的,实际上是init.d/pspsplash.sh
#!/bin/sh
### BEGIN INIT INFO
# Provides: psplash
# Required-Start:
# Required-Stop:
# Default-Start: S
# Default-Stop:
### END INIT INFO
read CMDLINE < /proc/cmdline
for x in $CMDLINE; do
case $x in
psplash=false)
echo "Boot splashscreen disabled"
exit 0;
;;
esac
done
export TMPDIR=/mnt/.psplash
mount tmpfs -t tmpfs $TMPDIR -o,size=40k
rotation=0
if [ -e /etc/rotation ]; then
read rotation < /etc/rotation
fi
/usr/bin/psplash --angle $rotation &
psplash服务启动后,在rcS里就会根据已启动的进程计数,输出进度条。
开机进度条:
if [ -e /mnt/.psplash/psplash_fifo ]; then
echo "PROGRESS $progress" > /mnt/.psplash/psplash_fifo
fi
开机背景logo:
if [ "x$runlevel" != "xS" ] && [ ! -x /etc/rc${runlevel}.d/S??xserver-nodm ]; then
if type psplash-write >/dev/null 2>&1; then
TMPDIR=/mnt/.psplash psplash-write "QUIT" || true
umount· -l /mnt/.psplash
fi
fi
type命令用于判断命令是否是内部命令,其实这里是判断logo程序是否存在。
阅读(2678) | 评论(0) | 转发(0) |