第一步:POST 加电自检(Powered On Self-Test)

通过主板上集成RAM中的BIOS程序实现POST
主板上的ROM:CMOS:主板上的一块可读写的并行或串行FLASH芯片,是用来保存BIOS的硬件配置和用户对某些参数的设定。(BIOS设置程序一般都被厂商整合在芯片中,因此BIOS设置有时也被叫做CMOS设置。)
BIOS:Basic Input and Output System
通过BIOS可以设置按次序查找各引导设备,第一个有引导程序的设备即为本次启动要用到的设备.
CentOS 6系统启动流程详解_系统



第二步:加载运行bootloader
bootloader:引导加载器(程序)
Windows中使用的bootloader是:ntloader
Linux:LILO(LIinux LOader)
    GRUB:Grand Uniform Bootloader
           GRUB 0.X:Grub Legacy(CentOS 6中使用)
           GRUB 1.X:Grub2   (CentOS 7中使用)

CentOS 6系统启动流程详解_系统_02                            
功能:提供一个菜单,允许用户选择要启动的系统或不同的内核版本; 把用户选定的内核装载到RAM中的特定空间中,解压、展开,而后把系统控制权移交给内核.

CentOS 6系统启动流程详解_系统_03

ext系列及GPT系列的文件系统的bootloader都在MBR中的前446个字节,MBR为该磁盘的第一个扇区(1st stage),共512字节。        
MBR:Master Boot Record
前446bytes:bootloader
然后64bytes:fat (GPT文件系统中不同)
2bytes:55AA (分区表有效性标识)
加载运行GRUB共可分为三步
1st stage:
Partition:filesystem driver, 1.5 stage
Partition:/boot/grub, 2nd stage

GRUB运行详细过程可以查看我的另一篇博客:


第三步:加载内核
1,内核加载完成后自身初始化
2,探测可识别到的所有硬件设备;
3,加载硬件驱动程序;(有可能会借助于ramdisk加载驱动,ramdisk文件需要和内核放在同一分区,如果需要用到,需要在前一步grub中指定其位置,如果内核编译时已经将硬件设备的驱动程序编译进内核了,就不需要ramdisk了)

注:有关ramdisk可以查看我的另一篇博客:


第四步:以只读方式挂载根文件系统


第五步:切换根(switchroot)


第六步:运行用户空间的第一个应用程序:/sbin/init,实现系统初始化,然后设置系统运行级别。

/sbin/init/通过它的配置文件定义了其运行的流程
配置文件:/etc/inittab和/etc/init/目录下所有以.conf结尾的文件。


/etc/inittab:仅被用于定义默认运行级别(CentOS 6中)

CentOS 6系统启动流程详解_系统_04

注意:在CentOS 5中此文件不是仅用于定义系统默认运行级别。还用于定义其系统初始化及之后的流程

例如:id:3:initdefault: 
    si::sysinit:/etc/rc.d/rc.sysinit(设定系统初始化方式)
   l0:0:wait:/etc/rc.d/rc  0
    l1:1:wait:/etc/rc.d/rc  1(等到运行级别为1时启动或关闭/etc/rc.d/rc3.d/目录下的服务脚本所控制服务)
    …………
    l6:6:wait:/etc/rc.d/rc  6

具体请查看CentOS 5系列中的配置文件/etc/inittab

                           

此配置文件设置方式:

每行定义一种action以及与之对应的process

格式   id:runlevels:action:process    (共四个字段,以:隔开)   
                    
第一个字段:id:一个任务的标识符;
第二个字段:runlevels:在哪些级别启动此任务;#,###,也可以为空,表示所有级别;
第三个字段:action:在什么条件下启动此任务;
第四个字段:process:任务;
                            
action种类:
      wait:等待切换至此任务所在的级别时执行一次;
      respawn:一旦此任务终止,就自动重新启动之;
      initdefault:设定默认运行级别;此时,process省略;
      sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit脚本;


/etc/init/目录下所有以.conf结尾的文件 :定义系统初始化及之后的流程   

CentOS 6系统启动流程详解_启动流程_05


运行流程:

首先读取/etc/init/rcS.conf配置文件,此配置文件共定义完成两个功能
1.实现系统初始化
CentOS 6系统启动流程详解_系统_06


通过运行系统初始化脚本实现系统初始化
系统初始化脚本:/etc/rc.d/rc.sysinit


CentOS 6系统启动流程详解_启动流程_07

其功能:(1) 设置主机名;
    (2) 设置欢迎信息;
    (3) 激活udev和selinux;
    (4) 挂载/etc/fstab文件中定义的所有文件系统; 
    (5) 检测根文件系统,并以读写方式重新挂载根文件系统; 
    (6) 设置系统时钟; 
    (7) 根据/etc/sysctl.conf文件来设置内核参数;
    (8) 激活lvm及软raid设备;
    (9) 激活swap设备;
    (10) 加载额外设备的驱动程序;
    (11) 清理操作; 

2.定义系统运行级别

CentOS 6系统启动流程详解_启动流程_08
注意:(如果在第二步grub中没有指定,而且grub的配置文件中也没有设置系统运行级别此参数的话,系统运行级别会按照/etc/inittab配置文件中设置的定义)

运行级别的意义:为了系统的运行或维护等目的而设定的机制;
0-6:7个级别;  0:关机, shutdown
           1:单用户模式(single user),root用户,无须认证;维护模式;
           2、多用户模式(multi user),会启动网络功能,但不会启动NFS;维护模式;
           3、多用户模式(mutli user),完全功能模式;文本界面;
           4、预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
           5、多用户模式(multi user), 完全功能模式,图形界面;
           6、重启,reboot
                        
默认级别:3, 5
                    
级别切换命令:init #
级别查看命令:
who -r

runlevel 

示例:

CentOS 6系统启动流程详解_启动流程_09


第七步:按照定义的系统运行级别关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务。


在CentOS 5和6中,系统服务都被设计为一个单独的服务脚本,可以通过运行这些脚本来管理系统服务。


这些服务脚本都在/etc/rc.d/init.d/目录下。

CentOS 6系统启动流程详解_系统_10

服务脚本的运行方式:


1.脚本路径加一个执行参数
# /etc/rc.d/init.d/SRV_SCRIPT  {start|stop|restart|status}
# /etc/init.d/SRV_SCRIPT  {start|stop|restart|status}
/etc/init.d是/etc/rc.d/init.d目录的软链接
CentOS 6系统启动流程详解_系统_11

2.service命令
命令格式:                                        
# service  SRV_SCRIPT   {start|stop|restart|status}


在/etc/rc.d/目录下面有7个rc#.d格式的子目录(#为0-6的整数,对应着七个系统运行级别)

CentOS 6系统启动流程详解_启动流程_12

这些目录下面各有很多K##SCRIPT-NAME和S##SCRIPT-NAME的软链接文件,
其链接对象都是/etc/rc.d/init.d/目录下同SCRIPT-NAME的服务脚本文件。


CentOS 6系统启动流程详解_启动流程_13


CentOS 5和6中对单个运行级别的服务环境的配置和系统运行中级别切换后的服务环境配置正是基于以上基础实现的。


单个运行级别的服务环境的配置流程:


1.读取/etc/init/rc.cof这个配置文件CentOS 6系统启动流程详解_系统_14


配置文件中通过运行/etc/rc.d/rc这个脚本来实现单个运行级别的系统服务环境配置,在运行的同时传递了一个位置参数 $RUNLEVEL,这个参数就是上一步中已经定义过了的系统运行级别。(注意:系统运行中级别切换后的服务环境配置也是通过此脚本实现)


CentOS 6系统启动流程详解_启动流程_15
/etc/rc.d/rc这个脚本执行会按照给定的位置参数($RUNLEVEL)运行对应的/etc/rc.d/rc#.d/目录下的那些K和S开头的脚本。其运行方式是先依次运行以K开头的脚本,顺序是##从小到大,运行时会传递一个执行参数stop。之后再依次运行以S开头的脚本,顺序是##从小到大,运行时会传递一个执行参数start。(注:这只简要说明,具体执行方式请参照/etc/rc.d/rc脚本代码)

因此:K表示是该系统级别要停止的服务;##表示优先级,数字越小,越是优先关闭,所以若这个服务依赖于其它服务就应该设置为先关闭,而被其它服务所依赖的服务应该设置为后关闭。

S表示该系统级别要启动的服务;##表示优先级,数字越小,越是优先启动;所以若被其它服务所依赖的服务应该设置为先启动,而这个服务依赖于其它服务就应该设置为后启动。(##为00-99)


对系统服务的管理可以通过chkconfig命令实现

chkconfig命令:管控/etc/rc.d/init.d/rc.d/下面每个服务脚本在各级别下的启动或关闭状态

使用格式
查看:chkconfig  --list   [name]

CentOS 6系统启动流程详解_系统_16


修改指定的链接类型:chkconfig  [--level  LEVELS]  name  <on|off|reset>
--level LEVELS:指定要控制的级别;默认为2,3,4,5

CentOS 6系统启动流程详解_启动流程_17                                        
添加:chkconfig  --add  name
删除:chkconfig  --del  name(只是删除了服务脚本的那些软链接)

因此如果想增加一个系统服务,可以先写一个服务脚本,放到/etc/rc.d/init.d/目录下,再通过chkconfig命令实现。

能被添加的服务的脚本定义格式之一:
#!/bin/bash
#
# chkconfig: LLL  NN NN
# description:  



注意:在rc2.d,rc3.d,rc4.d,rc5.d中都有一个S99local软链接,即这是几个级别中最后一个启动的系统服务。

CentOS 6系统启动流程详解_启动流程_18可以看到它链接的并不是/etc/rc.d/init.d/目录下面的服务脚本,而是/etc/rc.d/rc.local这个脚本。

CentOS 6系统启动流程详解_系统_19
从脚本注释中可以看出其功用

因此,如果希望一些程序能开机自动运行时,又想写服务脚本,可以直接写入这个脚本中实现。


第八步:启动终端
读取/etc/init/start-ttys.conf这个配置文件,完成启动终端的流程。其中会判定,如果运行级别为5的话,在启动tty1-6之后会再启动图像终端。

CentOS 6系统启动流程详解_启动流程_20


自此,系统启动完成。


注:第六到八步,都是init程序通过配置文件实现。