CentOS6 启动流程

概述

  理解操作系统开机引导和启动过程对于配置操作系统和解决相关启动问题是至关重要的。本文结合互联网上各类资料,做一些总结,希望对大家有一些帮助。启动流程总的划分可以分为4个阶段

  • POST加电自检
  • 引导装载程序(GRUB)
  • 内核(kernel)初始化
  • 系统第一个进程初始化

1.POST加电自检

  Power-On-Self-Test,加电自检,是BIOS功能的一个主要部分。负责完成对CPU、主板、内存、硬盘子系统、显示子系统、串并行接口、键盘等硬件情况的检测。

  BIOS 上电自检确认硬件的基本功能正常,然后产生一个 BIOS 中断[3] INT 13H,该中断指向某个接入的可引导设备的引导扇区。它所找到的包含有效的引导记录的第一个引导扇区将被装载到内存中,并且控制权也将从引导扇区转移到此段代码。BIOS的任务就完成了,此后将系统启动的控制权移交到MBR部分的代码。

  引导扇区是引导加载器真正的第一阶段。大多数 Linux 发行版本使用的引导加载器有三种:GRUB、GRUB2 和 LILO。GRUB2 是最新的,也是相对于其他老的同类程序使用最广泛的。

2.引导装载程序(Bootloader)

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

GRUB(全称是 GRand Unified BootLoader),是一个用于计算机寻找操作系统内核并加载其到内存的智能程序

GRUB主要包含三个阶段:

1)stage1

  stage1是直接被写入到MBR中去的,这样机器一启动检测完硬件后,就将控制权交给了GRUB的代码。也就是上图所看到的前446个字节空间中存放的是stage1的代码。

  由于引导记录必须非常的小,它不可能非常智能,且不能理解文件系统结构。因此阶段 1 的唯一功能就是定位并加载阶段 1.5 的代码。为了完成此任务,阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。在加载阶段 1.5 代码进入内存后,控制权将由阶段 1 转移到阶段 1.5。

2)stage1.5

  阶段 1.5 的代码必须位于引导记录与设备第一个分区之间的位置。因为有更大的存储空间用于阶段 1.5,且该空间足够容纳一些通用的文件系统驱动程序,如标准的 EXT 和其它的 Linux 文件系统,如 FAT 和 NTFS 等。

3)stage2

  GRUB 阶段 2 所有的文件都已存放于 /boot/grub目录及其几个子目录之下。该阶段没有一个类似于阶段 1 与阶段 1.5 的镜像文件。

  GRUB 阶段 2 的主要功能是根据/boot/grub/grub.conf定位和加载 Linux 内核到内存中,并转移控制权到内核。内核的相关文件位于 /boot 目录下,这些内核文件可以通过其文件名进行识别,其文件名均带有前缀 vmlinuz。你可以列出 /boot 目录中的内容来查看操作系统中当前已经安装的内核。

  默认情况下,GRUB 提供了一个已安装内核的预引导菜单,其中包括问题诊断菜单(recuse)以及恢复菜单(如果配置已经设置恢复镜像)。

阶段 2 加载选定的内核到内存中,并转移控制权到内核代码。

3.kernel初始化

  内核文件都是以一种自解压的压缩格式存储以节省空间,它与一个初始化的内存映像和存储设备映射表都存储于 /boot 目录之下。

  initrd(Initial RAM Disk),它在stage2这个步骤就被拷贝到了内存中,这个文件是在安装系统时产生的,是一个临时的根文件系统(rootfs)。因为Kernel为了精简,只保留了最基本的模块,因此,Kernel上并没有各种硬件的驱动程序,也就无法识rootfs所在的设备,故产生了initrd这个文件,该文件装载了必要的驱动模块,当Kernel启动时,可以从initrd文件中装载驱动模块,直到挂载真正的rootfs,然后将initrd从内存中移除。

  Kernel会以只读方式挂载根文件系统,当根文件系统被挂载后,开始装载第一个进程(用户空间的进程),执行/sbin/init,之后就将控制权交接给了init程序。

  • 探测可识别到的所有硬件设备
  • 加载硬件驱动程序(借助于ramdisk加载驱动)
  • 以只读方式挂载根文件系统
  • 运行用户空间的第一个应用程序:/sbin/init

4.初始化系统

1)/etc/inittab

内核被加载后,第一个运行的程序便是/sbin/init,该文件会读取/etc/inittab文件(CentOS7已经不再使用),并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级,其设定形式是“:id:5:initdefault:”,这就表明Linux需要运行在等级5上。

2) /etc/rc.d/rc.sysinit

执行系统初始化脚本(/etc/rc.d/rc.sysinit),对系统进行基本的配置,以读写方式挂载根文件系统及其它文件系统,到此系统算是基本运行起来了,后面需要进行运行级别的确定及相应服务的启动。

(1)获取网络环境与主机类型。首先会读取网络环境设置文件"/etc/sysconfig/network",获取主机名称与默认网关等网络环境。

(2)测试与载入内存设备/proc及usb设备/sys。除了/proc外,系统会主动检测是否有usb设备,并主动加载usb驱动,尝试载入usb文件系统。

(3)决定是否启动SELinux。

(4)接口设备的检测与即插即用(pnp)参数的测试。

(5)用户自定义模块的加载。用户可以再"/etc/sysconfig/modules/*.modules"加入自定义的模块,此时会加载到系统中。

(6)加载核心的相关设置。按"/etc/sysctl.conf"这个文件的设置值配置功能。

(7)设置系统时间(clock)。

(8)设置终端的控制台的字形。

(9)设置raid及LVM等硬盘功能。

(10)以方式查看检验磁盘文件系统。

(11)进行磁盘配额quota的转换。

(12)重新以读取模式载入系统磁盘。

(13)启动quota功能。

(14)启动系统随机数设备(产生随机数功能)。

(15)清楚启动过程中的临时文件。

(16)将启动信息加载到"/var/log/dmesg"文件中。

3) /etc/rc.d/rc脚本

3)执行/etc/rc.d/rc脚本。该文件定义了服务启动的顺序是先K后S,而具体的每个运行级别的服务状态是放在/etc/rc.d/rc.d(=0~6)目录下,所有的文件均是指向/etc/init.d下相应文件的符号链接。rc.sysinit通过分析/etc/inittab文件来确定系统的启动级别,然后才去执行/etc/rc.d/rc*.d下的文件。

/etc/init.d-> /etc/rc.d/init.d

/etc/rc ->/etc/rc.d/rc

/etc/rc.d ->/etc/rc.d/rc.d

/etc/rc.local-> /etc/rc.d/rc.local

/etc/rc.sysinit-> /etc/rc.d/rc.sysinit

也就是说,/etc目录下的init.d、rc、rc*.d、rc.local和rc.sysinit均是指向/etc/rc.d目录下相应文件和文件夹的符号链接。我们以启动级别3为例来简要说明一下。

/etc/rc.d/rc3.d目录,该目录下的内容全部都是以 S 或 K 开头的链接文件,都链接到"/etc/rc.d/init.d"目录下的各种shell脚本。S表示的是启动时需要start的服务内容,K表示关机时需要关闭的服务内容。/etc/rc.d/rc.d中的系统服务会在系统后台启动,如果要对某个运行级别中的服务进行更具体的定制,通过chkconfig命令来操作,或者通过setup、ntsys、system-config-services来进行定制。如果我们需要自己增加启动的内容,可以在init.d目录中增加相关的shell脚本,然后在rc.d目录中建立链接文件指向该shell脚本。这些shell脚本的启动或结束顺序是由S或K字母后面的数字决定,数字越小的脚本越先执行。例如,/etc/rc.d/rc3.d /S01sysstat就比/etc/rc.d/rc3.d /S99local先执行。

4)/etc/rc.d/rc.local

执行用户自定义引导程序/etc/rc.d/rc.local。其实当执行/etc/rc.d/rc3.d/S99local时,它就是在执行/etc/rc.d/rc.local。S99local是指向rc.local的符号链接。就是一般来说,自定义的程序不需要执行上面所说的繁琐的建立shell增加链接文件的步骤,只需要将命令放在rc.local里面就可以了,这个shell脚本就是保留给用户自定义启动内容的。

5) /sbin/mingetty

完成了系统所有的启动任务后,linux会启动终端或X-Window来等待用户登录。tty1,tty2,tty3...这表示在运行等级1,2,3,4的时候,都会执行"/sbin/mingetty",而且执行了6个,所以linux会有6个纯文本终端,mingetty就是启动终端的命令。

CentOS6 启动流程总结

  • 1.POST:通电自检,获取第一个启动设备
  • 2.读取第一个启动设备MBR的引导加载程序(grub)的启动信息
  • 3.加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备(ramdisk)
  • 4.启动init进程,依据inittab文件设定运行级别 (inittab用于定义默认运行级别)
  • 5.init进程,执行/etc/rc.d/rc.sysinit文件
  • 6.分别执行/etc/init/rcS.conf、/etc/init/rc.conf、/etc/init/start-ttys.confl来调用命令执行/etc/rc#.d/文件里面定义的是各种服务的启动脚本,可以ls查看,S开头代表开机启动的服务,K开头的是关机要执行的任务。#代表数字,一个数字代表一个运行级别,共7个运行级别,这里就不多说了
  • 7.执行/etc/rc.d/rc.local
  • 8.执行/sbin/mingetty程序,等待用户登录

    CentOS7 启动流程

CentOS7启动主要特点

CentOS7 的启动流程主要步骤没有很大的区别,主要是CentOS7开始,GRUB开始采用GRUB2版本,原来的init程序,改为了systemd,因此详细解释一下systemd后的启动流程

systemd新特性:

  • 系统引导时实现服务并行启动
  • 按需启动守护进程
  • 自动化的服务依赖关系管理
  • 同时采用socket式与D-Bus总线式激活服务
  • 系统状态快照

CentOS7 启动流程

  • UEFi或BIOS初始化,运行POST开机自检,选择启动设备
  • 引导导装载程序, centos7是grub2,加载装载程序的配置文件:/etc/grub.d/ /etc/default/grub /boot/grub2/grub.cfg

  • 加载initramfs驱动模块,加载内核选项,内核初始化,从initramfs根文件系统切换到磁盘根目录,centos7使用systemd代替init

  • systemd执行默认target配置。centos7表面有“运行级别”这个概念,实际是为了兼容以前的系统,每个所谓“运行级别”都有对应的软连接指向,默认的启动级别/etc/systemd/system/default.target,根据它的指向可以找到系统要进入到哪个模式。
  • systemd执行sysinit.target
  • systemd启动multi-user.target下的本机与服务器服务
  • systemd执行multi-user.target下面的/etc/rc.d/rc.local
  • systemd执行multi-user.target下的getty.target及登录服务

### Centos5、Centos6、Centos7服务启动的区别

Sysvinit技术:按照一定顺序执行——>启动太慢。(Centos5)

Upstart技术:Upstart对rc.sysinit脚本做了大量的优化,缩短了系统初始化的启动时间。(Centos6)

Systemd技术:克服sysvinit固有的缺点,采用并行技术,提高系统的启动速度(RedHat7,CentOS7,Ubuntu15等)

总结和经验