linux操作系统启动流程解析:

    CentOS系统启动流程

    boot loader:引导加载器

        在linux系统上有两种:

            Lilo

            Grub:GRand Uniform Bootloader

                在centos6(包含)之前:Grub0.x,也称为GRUB legacy

                在centos7上:Grub1.x,也称为GRUB2

        功能:提供一个可视化的菜单,允许用户选择要启动的系统或者不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核;

    kernel: 

        自身初始化:

            探测可识别到的所有硬件设备;

            加载硬件驱动程序;(有可能会借助于ramdisk加载驱动)

            以只读方式挂载根文件系统;

            运行用户空间的第一个应用程序:/sbin/init

    init程序的类型:

        SysV: init, CentOS 5

            配置文件:/etc/inittab

Upstart: init, CentOS 6

    配置文件:/etc/inittab, /etc/init/*.conf

Systemd:systemd, CentOS 7

    配置文件:/usr/lib/systemd/system, /etc/systemd/system

    ramdisk:   

        内核中的特性之一:使用缓冲和缓存来回事对磁盘上的文件访问;

        ramdisk是一个微小的根文件系统,内部存放了磁盘的驱动设备,在用户安装操作系统之后,会自动生成或者借助于工具生成磁盘类型的驱动。是存放在内存中的,在加载内核的时候,会自动搜索是否存在,若存在,则加载入内存。是一个辅助的程序,并不一定必须存在。在ramdisk上存在bin、sbin等个目录,也存在init初始化程序。

        CentOS 5: /boot/initrd-VERSION-release.img,模拟为磁盘设备

        CentOS 6: /boot/initramfs-VERSION-release.img,模拟为文件系统使用

        根切换,从这个微小的根文件系统切换为真正要使用的根文件系统。

        

        ramdisk --> ramfs

    CentOS 5: initrd,  工具程序:mkinitrd

    CentOS 6: initramfs, 工具程序:mkinitrd, dracut

    运行级别:

        /sbin/init是在系统初始化的时候完成的。设置运行级别是为了系统的维护或者运行等应用目的而进行的设定。

        运行级别共有7个级别:       

            0-6:7个级别

                0:关机

                1:单用户模式(root, 无须登录), single, 维护模式;

                2: 多用户模式,会启动网络功能,但不会启动NFS;维护模式;

                3:多用户模式,正常模式;文本界面;

                4:预留级别;可同3级别;

                5:多用户模式,正常模式;图形界面;

                6:重启

        

        切换系统的运行级别:

    init #

查看当前系统的运行级别:

    runlevel

    who -r

    配置文件/etc/inittab:      

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

    id:runlevel:action:process

action:

    wait: 切换至此级别运行一次;

    respawn:此process终止,就重新启动之;

    initdefault:设定默认运行级别;process省略;

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

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

...

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

说明:rc 0 --> 意味着读取/etc/rc.d/rc0.d/

    K*: K##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为依赖到别的服务;

            S*: S##*:##运行次序;数字越小,越先运行;数字越小的服务,通常为被依赖到的服务;

    chkconfig命令:

查看服务在所有级别的启动或关闭设定情形:

    chkconfig [--list] [name]

        添加:

            SysV的服务脚本放置于/etc/rc.d/init.d (/etc/init.d)目录下。

                服务脚本的格式:

                    在服务脚本中必须指定chkconfig: LLLL nn mm;

                        其中LLLL:表示运行的级别,就是服务在哪些运行级别下进行启动;

                        其中nn:表示服务在该级别下启动的次序;

                        其中mm:表示服务在该级别下关闭的次序;

            chkconfig --add name

删除:

    chkconfig --del name

修改指定的链接类型:

    chkconfig [--level levels] name <on|off|reset>

--level LLLL: 指定要设置的级别;省略时表示2345;

注意:正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个服务脚本,而是指向了/etc/rc.d/rc.local脚本;因此,不便或不需写为服务脚本放置于/etc/rc.d/init.d/目录,且又想开机时自动运行的命令,可直接放置于/etc/rc.d/rc.local文件中;


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

(1) 设置主机名;

(2) 设置欢迎信息;

(3) **udev和selinux; 

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

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

(6) 设置系统时钟;

(7) **swap设备;

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

(9) **lvm及software raid设备;

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

(11) 清理操作;

步骤详解:

    第一步:post加电自检

        POST(PowerOnSelfTest)首先对每一个外围设备进行检查。

    第二步:boot sequence

        也就是我们常说的BIOS,在加电自检完成之后,系统会按照一定的次序进行引导程序的查找,找到第一个引导程序即执行,不管该引导程序是否可以正常运行。若不能正常运行,也不会进行再次的查找。

    第三步:boot loader

        boot loader(引导加载器)存在于MBR(主引导记录)中。MBR由512个字节组成,前446个字节为boot loader,后64个字节为分区表相关信息,最后两字节为Magical Number。

        通过读取MBR中的boot loader以及分区的相关信息,把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核。在引导完成之后,就会进入kernel的初始化。

    第四步:kernel初始化

        在kernel初始化的时候,进行的工作主要是识别各种硬件设备,加载硬件的驱动。在识别本地磁盘的时候,可能需要借助于ramdisk,通过ramdisk加载的磁盘驱动,kernel识别本地磁盘。

        ramdisk并不是人为制作的,而是在系统启动的时候,会自动生成该文件系统。该文件系统不是必需的。

        在识别完各种硬件之后,要进行根文件系统的切换,从ramfs切换到真正我们要使用的rootfs。

        在挂载ramfs的时候,以只读方式挂载。在挂载rootfs的时候,以读写方式挂载。

        在完成内核初始化之后,就要运行用户空间内的第一个初始化程序,即/sbin/init程序。

    第五步:/sbin/init程序

        通过运行系统初始化程序,启动一个init进程,读取/etc/inittab以及/etc/init/*.conf等配置文件,设置系统的默认启动级别,运行/etc/rc.d/rc.sysinit初始化脚本,加载/etc/rc.d/rc#.d所有脚本,启动相对应的系统运行级别下的服务。最后运行/etc/rc.d/rc.local脚本,启动终端,并进入认证界面。

        注意:在centos5上只读取/etc/inittab文件;在centos6上,读取/etc/inittab以及/etc/init/*.conf文件;在centos7上systemd类型,读取/etc/lib/systemd及/etc/systemd/system。