内核级别启动流程



POST-->BootSequence(BIOS)—>Bootloader(MBR)-->Kernel

程序启动流程

第一步post:加电自检,检查各种硬件设备是否存在。

第二步)Boot Sequence:当硬件自检完成后,BIOS会在按次序查找各引导设备,第一个有MBR的设备即为本次启动要用到的设备。找到有MBR的设备之后,控制权就交给MBR中位于前446字节的Bootloader进行下一步。

第三步)Bootloader:MBR中的前446字节存放着Bootloader,在早期的Linux发行版中,Bootloader一直采用LILO,LILO曾经是Linux发行版中主流的Bootloader,但是它不能引导1024柱面以后的分区,大大限制了操作空间,所以现如今的Linux发行版中的Bootloader都使用了GRUB,它有更好的接口和界面,而且能为用户提供交互式接口,使用配置更加灵活方便。之后Bootloader将用户选择要启动的内核装载到内存中解压展开,之后控制权就交给内核进行下一步。

第四步)kernel:内核接到控制权后完成自身初始化-->探测可识别到的所有硬件设备-->加载硬件驱动程序(有可能借助于ramdisk加载驱动)-->以只读方式挂载根文件系统-->运行用户空间的第一个程序:/sbin/init



用户级别



设置默认运行级别 --> 运行系统初始化脚本,完成系统初始化 --> 关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务--> 设置登录终端 [--> 启动图形终端]

(CentOS5 init程序 :SysV init)



         用户级别启动流程

init程序启动任务



/sbin/init程序启动后会读取配置文件:/etc/inittab

配置文件中定义了各种任务,每行定义一种action以及与之对应的process

  id:runlevels:actions:process

  id:一个任务的标识符;

         runlevels:在哪些级别启动此任务;#,###,也可以为空,表示所有级别。

                          action:在什么条件下启动此任务。

                                          process:任务;


    action:

           wait:等待切换至此任务所在的级别时执行一次;

           respawn:一旦此任务终止,就自动重新启动之;

           initdefault:设定默认运行级别,此时,process省略

           sysinit:设定系统初始化方式,此处一般为指定/etc/rc.d/rc.sysinit脚本;

第一步:设置默认运行级别



CentOS6中在/etc/inittab文件中设置默认运行级别:

1

第二步:运行系统初始化脚本,完成系统初始化



系统初始化脚本文件:/etc/rc.d/rc.sysinit

1

         (1)设置主机名;

        (2)设置欢迎信息;

   (3)激活udev和selinux;

         (4)挂载/etc/fstab文件中定义的所有文件系统;

         (5)检测根文件系统;,并以读写方式重新挂载根文件系统;

         (6)设置系统时钟;

         (7)根据/etc/sysctl.conf文件来设置内核参数;

         (8)激活lvm及软raid设备;

         (9)激活swap设备;

         (10)加载额外设备的驱动程序;

         (11)清理操作;


第三步:关闭对应级别下需要停止的服务,启动对应级别下需要开启的服务



         1)有些服务我们需要在开机启动时自动关闭或开启,这些服务脚本都存放在/etc/init.d/*(/etc/rc.d/init.d/*)中。

                  1

         启动或关闭这些脚本的方法:# /etc/init.d/SRV_SCRIPT{start|stop|restart|status}

                                                     # /service SRV_SCRIPT {start|stop|restart|status}

 

但在各级别启动后要逐个启动或关闭这些脚本太过麻烦,为了方便管理这些服务的启动,我们需要一个统一的接口,这个接口就是rc服务脚本。我们可以通过管控这些服务脚本达到开机启动各种服务的目的。

 

 

            2) 在/etc/rc.d目录下存放了运行于各级别的rc脚本


1

    (如图所示每个运行级别下都有自己的要运行的rc脚本)


                        rc脚本:接受一个运行级别数字为参数

                             l0:0:wait:/etc/rc.d/rc 0 表示启动或关闭/etc/rc.d/rc0.d/目录下的服务脚本所控制的服务

                             l0:1:wait:/etc/rc.d/rc 1

                             l0:2:wait:/etc/rc.d/rc 2

                                …….

                             l0:6:wait:/etc/rc.d/rc 6

K*:要停止的服务;K##*,优先级,数字越小,越是优先关闭,有依赖关系的服务先关闭,而后关闭被依赖的服务。

S*:要启动的服务;S##*,优先级,数字越小,越是优先启动;被依赖的服务先启动,而后启动有依赖关系的服务。

而我们需要在系统的各级别中启动或者关闭这些服务,在系统初始化脚本运行完成后就会给rc脚本传递运行级别参数,从而就能统一关闭并开启该级别下的所有服务脚本,这样就不用逐个操作服务脚本,只需要管控一个rc脚本就能达到关闭或启动该级别下所有服务脚本的效果,但我们还要给这些rc脚本创建它所要关闭和开启的服务,这时就需要在/etc/rc.d/rc#.d这些各级别中运行的rc脚本中创建init.d目录下各服务脚本的符号连接,以S开头表示开机启动,K开头表示开机关闭。当系统读取完系统初始化脚本之后会运行相应运行级别下的rc脚本,先把该级别rc脚本中以K开头的服务关闭,再把以S开头的服务开启。

                      1

                    1  

        现在我们就需要解决怎么为这些脚本创建这些可以自动启动和关闭的符号连接。


              3)我们可以使用chkconfig命令来管控/etc/init.d/*下的各服务脚本在/etc/rc.d/rc#.d各级别下的开启或关闭

                   ①查看脚本:chkconfig --list[name](可以看出该服务脚本名称和在哪些运行级别是开启和在那些运行级别下是关闭的)

                     1



        ②添加服务脚本:chkconfig --add name

              能被添加的服务脚本定义格式:

                  #!/bin/bash

                  #

                  #chkconfig:LL NN NN(LL表示在那些级别是启动的,第一个NN是启动级别数字,第二个NN是关闭级别数字)

                  #description

                1

        如图所示,表示该服务脚本被添加后自动在345级别中运行。0126级别中自动关闭

        

              ③修改指定的链接类型:(只在当前系统有效,重启后无效)

                 chkconfig [--level LEVELS] name <on|off|restart>

                     --level LEVELS:指定要控制的级别;默认为2345;

(该操作的目的就是在相应运行级别下的rc脚本中创建要开机启动和关闭的服务脚本的符号链接。)

    (注:在/etc/rc.d/目录下会有一个rc.local文件,是为了在开机最后一步中运行一次,当我们不便写脚本或者不需要写服务脚本但又期望改程序开机启动时,直接放置于此脚本文件即可。   )    

 



第四步:定义各级别下的虚拟终端(可省略)



          tty1:2345:respawn:/usr/sbin/mingetty tty1      
             ... ...      
            tty6:2345:respawn:/usr/sbin/mingetty tty6   
                                (1)mingetty会调用login程序;      
                                (2)打开虚拟终端的程序除了mingetty之外,还有诸如getty等


    

到此为止系统就被启动起来,提供给用户交互式的图形界面或文本界面,用户键入用户名和密码就能使用该操作系统了。



 

CentOS6:

           init程序:upstart风格,但依然为/sbin/init,其配置文件为:/etc/init/*.conf,/etc/inittab(仅用于设置默认运行级别)

           1

如上图所示,在CentOS6中只不过把配置文件切割成了不同的以.conf结尾的配置文件片段中,每个文件控制一种配置内容。

     rcS.conf:系统初始化脚本。rc.d:启动或关闭各种服务。start-ttys.d:启动哪些终端。

CentOS7:

                init程序:systemd,配置文件:/usr/lib/systemd/system/*,  /etc/systemd/system/*        
                完全兼容SysV脚本机制;因此,service命令依然可用;

                 不过,建议使用systemctl命令来控制服务;        
                 # systemctl  {start|stop|restart|status}  name[.service]

(CentOS7中init启动的时候,所有服务默认是不启动的,当启动后第一次访问的时候再启动这些服务)