打开PC的电源,BIOS开机自检,按BIOS中设置的启动设备(通常是硬盘)启动,接着启动设备上安装的引导程序lilo或grub开始引导Linux,Linux首先进行内核的引导,接下来执行init程序,init程序调用了rc.sysinit和rc等程序,rc.sysinit和rc当完成系统初始化和运行服务的任务后,返回init;init启动了mingetty后,打开了终端供用户登录系统,用户登录成功后进入了Shell,这样就完成了从开机到登录的整个启动过程。
init进程起来后,系统启动的控制权移交给init进程。
/sbin/init进程是所有进程的父进程,当init起来之后,它首先会读取配置文件/etc/inittab,进行以下工作:
1)执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,到此系统基本算运行起来了,后面需要进行运行级别的确定及相应服务的启动;
2)确定启动后进入的运行级别;
3)执行/etc/rc.d/rc,该文件定义了服务启动的顺序是先K后S,而具体的每个运行级别的服务状态是放在/etc/rc.d/rcn.d(n=0~6)目录下,所有的文件均链接至/etc/init.d下的相应文件。
4)/etc/rc.d/rc$RUNLEVEL # $RUNLEVEL为缺省的运行模式
5) /etc/rc.d/rc.local
6)启动虚拟终端/sbin/mingetty
7)在运行级别5上运行X
这时呈现给用户的就是最终的登录界面。
至此,系统启动过程完毕。
说明:
系统启动运行级别的概念以及服务的定制方法;
当initrd 可以正常检测和装载之后,最后的工作就基本上由操作系统来进行了。当系统的init进程起来之后系统启动的控制权移交给init进程。
/sbin/init 进程是所有进程的父进程,当init起来之后,它首先会读取配置文件/etc/inittab,进行以下工作:
1)执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,后面需要进行运行级别的确定及相应服务的启动,(从这个角度可以看出如果要定义系统的init动作,需要修改/etc/rc.d/rc.sysinit脚本)。它的主要工作有:配置selinux,系统时钟,内核参数(/etc/sysctl.conf),hostname,启用wap分区,根文件系统的检查和二次挂载(读写),激活RAID和LVM设备,启用磁盘quota检查并挂载其它文件系统。
2)通过对/etc/inittab文件
[[email protected] etc]# cat inittab # inittab is only used by upstart for the default runlevel. # # ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM. # # System initialization is started by /etc/init/rcS.conf # # Individual runlevels are started by /etc/init/rc.conf # # Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf # # Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf, # with configuration in /etc/sysconfig/init. # # For information on how to write upstart event handlers, or how # upstart works, see init(5), init(8), and initctl(8). # # Default runlevel. The runlevels used 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) # id:5:initdefault:
[[email protected] init]# cat rc.conf # rc - System V runlevel compatibility # # This task runs the old sysv-rc runlevel scripts. It # is usually started by the telinit compatibility wrapper. # # Do not edit this file directly. If you want to change the behaviour, # please create a file rc.override and put your changes there. start on runlevel [0123456] stop on runlevel [!$RUNLEVEL] task export RUNLEVEL console output exec /etc/rc.d/rc $RUNLEVEL [[email protected]sky init]#
[[email protected] ~]# cat /etc/rc.d/rc #! /bin/bash # # rc This file is responsible for starting/stopping # services when the runlevel changes. # # Original Author: # Miquel van Smoorenburg, <[email protected]nl.mugnet.org> # set -m # check a file to be a correct runlevel script check_runlevel () { # Check if the file exists at all. [ -x "$1" ] || return 1 is_ignored_file "$1" && return 1 return 0 } # Now find out what the current and what the previous runlevel are. argv1="$1" set $(/sbin/runlevel) runlevel=$2 previous=$1 export runlevel previous . /etc/init.d/functions export CONSOLETYPE do_confirm="no" if [ -f /var/run/confirm ]; then do_confirm="yes" fi UPSTART= [ -x /sbin/initctl ] && UPSTART=yes # See if we want to be in user confirmation mode if [ "$previous" = "N" ]; then if [ "$do_confirm" = "yes" ]; then echo $"Entering interactive startup" else echo $"Entering non-interactive startup" fi fi # Get first argument. Set new runlevel to this argument. [ -n "$argv1" ] && runlevel="$argv1" # Is there an rc directory for this new runlevel? [ -d /etc/rc$runlevel.d ] || exit 0 # Set language, vc settings once to avoid doing it for every init script # through functions if [ -f /etc/sysconfig/i18n -a -z "${NOLOCALE:-}" ] ; then . /etc/profile.d/lang.sh 2>/dev/null export LANGSH_SOURCED=1 fi # First, run the KILL scripts. for i in /etc/rc$runlevel.d/K* ; do # Check if the subsystem is already up. subsys=${i#/etc/rc$runlevel.d/K??} [ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] || continue check_runlevel "$i" || continue # Bring the subsystem down. [ -n "$UPSTART" ] && initctl emit --quiet stopping JOB=$subsys $i stop [ -n "$UPSTART" ] && initctl emit --quiet stopped JOB=$subsys done # Now run the START scripts. for i in /etc/rc$runlevel.d/S* ; do # Check if the subsystem is already up. subsys=${i#/etc/rc$runlevel.d/S??} [ -f /var/lock/subsys/$subsys ] && continue [ -f /var/lock/subsys/$subsys.init ] && continue check_runlevel "$i" || continue # If we‘re in confirmation mode, get user confirmation if [ "$do_confirm" = "yes" ]; then confirm $subsys rc=$? if [ "$rc" = "1" ]; then continue elif [ "$rc" = "2" ]; then do_confirm="no" fi fi update_boot_stage "$subsys" # Bring the subsystem up. [ -n "$UPSTART" ] && initctl emit --quiet starting JOB=$subsys if [ "$subsys" = "halt" -o "$subsys" = "reboot" ]; then export LC_ALL=C exec $i start fi $i start [ -n "$UPSTART" ] && initctl emit --quiet started JOB=$subsys done [ "$do_confirm" = "yes" ] && rm -f /var/run/confirm exit 0 [[email protected] ~]#
[[email protected] rc5.d]# pwd /etc/rc5.d [[email protected] rc5.d]# ls K01smartd K61nfs-rdma K89netconsole S10network S24nfslock S55sshd K02oddjobd K69rpcsvcgssd K89rdisc S11auditd S24rpcgssd S70spice-vdagentd K05wdaemon K73winbind K92pppoe-server S11portreserve S25blk-availability S80postfix K10psacct K74ntpd K95firstboot S12rsyslog S25cups S82abrt-ccpp K10saslauthd K75ntpdate K95rdma S13cpuspeed S25netfs S82abrtd K15htcacheclean K75quota_nld K99rngd S13irqbalance S26acpid S90crond K15httpd K76ypbind S01sysstat S13rpcbind S26haldaemon S95atd K50dnsmasq K84wpa_supplicant S02lvm2-monitor S15mdmonitor S26udev-post S99certmonger K50kdump K87restorecond S08ip6tables S22messagebus S28autofs S99local K60nfs K88sssd S08iptables S23NetworkManager S50bluetooth [[email protected] rc5.d]#