概括地讲,Linux/Unix系统一般有两种不同的初始化启动方式.
1) BSD system init
2) System V init
大多数发行套件的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,而且不可以改变,与上面讲的不同。
LFS文件系统初始化示例
inittab文件
由下内容可以看出,最先执行的是/etc/rc.d/init.d/rc文件,给这个文件传入的参数是一个数字,rc会由传入的数字合成rcX.d目录的路径,然后执行其中的所有脚本链接。当然这只是一部分功能。
# Begin /etc/inittab
id:3:initdefault:
<em><strong>si::sysinit:/etc/rc.d/init.d/rc sysinit</strong></em>#可以设定初始化脚本
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
etc目录结构
只是一部分,有删减。
.
├── fstab
├── <em>inittab</em>
├── 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
network脚本
#!/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
LINUX系统的初始化可以分为两部分:内核部分和init程序部分。内核主要完成系统的硬件检测和初始化,init程序则主要完成系统的各项配置。主要流程是:CPU自身初始化-->加载BIOS-->BIOS加载内核引导程序(也就是ubuntu我们常说的GRUB)-->内核引导程序加载内核映像(这里的内核代码是压缩过的)-->内核映像获得CPU控制权并开始工作-->内核映像自己解压缩,开始运行init/main.c中的start_kernel()函数,这时候内核就启动了,系统初始化,系统的父进程init进程执行起来了,这时候整个系统初始化完毕,接下来只是调用一些UI界面的进程执行。
这是我的一点浅陋简介,希望对你有所帮助,谢谢!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)