CentOS 6系统启动流程

Linux系统的组成

内核+根文件系统
内核功能:
    进程管理、内存管理、文件系统管理、网络管理、安全功能、驱动程序

运行中的系统环境可分为两层:内核空间、用户空间
    用户空间:应用程序(进程或线程)
    内核空间:内核代码(系统调用)

内核设计流派:
    单内核设计:把所有功能集成与同一个程序
        Linux
    微内核设计:每种功能使用一个单独的子系统实现
        Windows,Solaris

    Linux内核特定:
        支持模块化:.ko(Kernel Object)
        支持模块运行时动态装载或卸载

        组成部分:
            核心文件:/boot/vmlinuz-VERSION-release
            ramdisk:
                CentOS 5:/boot/initrd-VERSION-release.img
                CentOS 6,7:/boot/initramfs-VERSION-release.img
            模块文件:/lib/modules/VERSION-release

CentOS系统启动流程

整体来说系统启动分为以下几个过程:

%ZZ(2}_)I(VCNDFP$47J1F0.png

1.加电自检

步骤1:通过BIOS(Basic Input Output System)即基本输入输出系统来检测硬件设备是否存在且运行正常,如:CPU、内存、硬盘,如果有异常情况,BIOS自检阶段会报错,从而导致系统无法启动
步骤2:去读BIOS启动顺序当中的第一个可引导设备(例如硬盘)的第一个扇区(MBR 512字节),然后执行里面的代码,实际上这里BIOS并不关心启动设备第一个扇区中是什么内容,它只是负责读取该扇区内容、并执行

2.Boot Loader

 我们首先来了解一下MBR,它是Master Boot Record的缩写。硬盘的0柱面、0磁头、1扇区称为主引导扇区。它由三个部分组成,主引导程序(Bootloader)、 硬盘分区表DPT(Disk Partition table)和硬盘有效标志(55AA)
 Boot loader:引导加载器
    Windows:ntloader
    Linux:LILO、GRUB

我们以GRUB为例来分析整个过程:
    Boot loader的主要功能是功能丰富,提供菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的特定空间中,解压、展开,并把系统控制权移交给内核。存放于MBR的前446bytes当中,但是446bytes容纳这么多功能,显然是很难得,因此,将Boot loader程序分为三个阶段来运行:
        stage1:存放于MBR的前446bytes当中,负责引导stage2
        stage1.5:在MBR之后的扇区中存放,让stage1中的bootloader能识别stage2所在的分区上的文件系统
        stage2:通过Bootloader加载所有配置文件及相关的环境参数信息,这些配置文件及相关的环境参数存放于磁盘分区上的/boot/grub目录下

3.加载kernel

在Bootloader开始读取操作系统内核文件后,接下来会将内核文件解压缩后装载到内存当中,然后根据内核提供的功能开始测试与加载各个设备(CPU、硬盘、网卡等)。
通过ramdisk来加载设备的驱动程序
    ramdisk:
        能够通过bootloader程序将其加载到内存当中,然后这个文件会被加压缩并且在内存中模拟一个根文件系统,这个根文件系统能够提供一个可运行的程序,通过该程序加载在启动过程当中所需要的核心模块。
    CentOS 5:initrd,工具程序:mkinitrd
    CentOS 6:initramfs,工具程序:mkinitrd,dracut
        mkinitrd initramfs-KERNEL-VERSION.img KERNEL-VERSION

Boot loader可以加载kernel以initrd,然后在内存中让initrd解压缩成根目录,然后内核可以在这个虚拟的根文件系统上加载和是的驱动程序,来加载硬盘等设备,之后释放虚拟的根文件系统,并以只读方式挂载磁盘上真实的根文件系统,之后启动/sbin/init程序

内核空间启动过程

POST --> BootSequence(BIOS) --> BootLoader(MBR) --> kernel(ramdisk) --> rootfs(readonly) --> /sbin/init

4.启动用户空间第一个执行程序/sbin/init

init程序
    CentOS 5:采用Sys V,配置文件为/etc/inittab
    CentOS 6:采用Upstart方式,特点是守护进程间的通信依赖于D-Bus进行,因此,可基本实现类似并行启动;
        配置文件:/etc/inittab、/etc/init/*.conf
    CentOS 7:采用systemd方式,服务只有在第一次被访问到时才会真正启动起来,因此,启动过程非常之快
        配置文件:/usr/lib/systemd/system, /etc/systemd/system

运行级别:为了系统的运行或维护等目的而设定的机制
    0:关机,shutdown
    1:单用户模式(single),root用户,无须认证可直接登录
    2:多用户模式,会启用网络功能,但不会启用nfs,维护模式
    3:正常模式,多用户,全功能,文本界面,通常用于服务器
    4:预留级别
    5:正常模式,多用户,全功能,图形界面操作,一般用于个人
    6:重启,reboot

    默认级别:3,5
    级别切换:init #
    级别查看:who -r或runlevel

在内核、硬件及驱动信息加载完毕后,内核会呼叫用户空间中的第一个执行程序/sbin/init,是所有进程的父进程,init程序主要功能是对系统进行初始化:

    1.首先会去读取配置文件/etc/inittab、/etc/init/*.conf
        /etc/inittab文件格式
            id:一个任务的标识符
            runlevels:在哪些级别下运行此任务#,##,可以为空,表示所有级别
            action:在什么条件下运行此任务
            process:任务

        action:
            wait:切换至此级别运行一次
            respawn:此process终止,就重新启动之
            initdefault:默认运行级别;process省略
            sysinit:设定系统初始方式,此处一般指为/etc/rc.d/rc.sysinit

    2.根据以上配置文件当中所定义运行级别以及参数去执行/etc/rc.d/rc.sysinit进行系统的初始化,/etc/rc.d/rc.sysinit所做的事情主要以下几点
        (1)根据配置文件中的设定来配置主机名(去读/etc/sysconfig/network文件中HOSTNAME进行)
        (2)打印文本欢迎信息
        (3)挂载所有定义在/etc/fstab文件中的文件系统
        (4)激活swap设备
        (5)激活SELinux和udev
        (6)检测根文件系统,并实现以读写方式重新挂载
        (7)设置系统时钟
        (8)根据/etc/sysctl.conf文件设定内核参数的值
        (9)激活LVM和RAID设备
        (10)加载额外的设备驱动程序
        (11)清理操作

    3.根据默认运行级别执行/etc/rc.d/rc脚本
        /etc/rc.d/rc脚本根据默认运行级别去启动或关闭/etc/rc.d/rc#.d目录下的所有脚本
            K*:要停止的服务;k##*,优先级,数字越小,越是优先关闭;依赖的服务先关闭,而后关闭被依赖的
            S*:要启动的服务;S##*,优先级,数字越小,越是优先启动,被依赖的服务先启动,而依赖的服务后启动
        rc脚本:接受一个运行级别数字为参数
            /etc/init.d/*(/etc/rc.d/init.d/*)脚本执行方式
                # /etc/init.d/SRV_SCRIPT {start|stop|restart|status}
                # service SRV_SCRIPT {start|stop|restart|status}

            chkconfig命令:管控/etc/init.d目录下每个脚本在各级别下的启动或关闭状态
                查看:chkconfig --list [NAME]
                添加:chkconfig --add SRV_NAME
                    能被添加至服务脚本定义格式之一:
                        #!/bin/bash
                        #
                        # chkconfig: LLL NN NN
                        # description:
                删除:chkconfig --del SRV_NAME
                修改指定的连接类型:
                    chkconfig [--level LEVELS] name <one|off|reset>
                        --level LEVELS:指定要控制的运行级别,默认为2345
    4.执行/etc/rc.d/rc.local脚本
        正常级别下,最后启动的一个服务S99local没有连接至/etc/init.d/下的某脚本,而是链接至了/etc/rc.d/rc.local脚本;因此,不便或不需写为服务脚本的程序期望能开机自动运行时,直接放置于此脚本文件中即可
    5.在完成系统所有先关服务启动之后,接下来Linux就会启动终端或者是X Window来向用户提供登录界面
        根据/etc/init/tty.conf文件中的配置启动一个应用程序-----login
        如果默认运行级别为5,会启动一个图形虚拟终端,附加X应用程序

用户空间的启动流程:/sbin/init

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

系统启动流程简要总结

POST加电自检 --> Boot Sequence(BIOS) --> Boot Loader(GRUB) --> kernel(ramfs) --> rootfs(readonly) --> switchroot --> /sbin/init --> (/etc/inittab, /etc/init/*.conf) --> 设定默认运行级别 --> 初始化系统脚本(/etc/rc.d/rc.sysinit) --> 关闭或启动对应级别下的服务(/etc/rc.d/rc#.d/) --> 启动终端程序

原创文章,作者:zhai796898,如若转载,请注明出处:http://www.178linux.com/46531