CentOS 7.x系统启动流程(BIOS/Boot Loader/Kernel)


Linux启动流程

系统启动流程
启动流程

  1. 按下电源键,硬件主动加载BIOS硬件信息与进行自我检测,并依据设定取得第一个可开机装置;
  2. 读取并执行第一个可开机装置内MBR的Boot Loader(如grub2);
  3. 依据Boot Loader的设定加载内核,内核会开始侦测硬件与加载驱动程序;
  4. 在硬件驱动成功后,内核呼叫第一个进程(init或systemd),而后将控制权交给第一个进程。

系统启动流程

BIOS/Boot Loader/Kernel

BIOS

按下电源后,启动系统首先要加载BIOS(Basic Input Output System):

  • BIOS程序首先加载CMOS芯片(CMOS芯片保存了系统引导最基本的资料)的信息,并依据CMOS内的设定值取得主机的各项硬件配置;
  • 从CMOS处取得信息后,BIOS开始进行开机自我测试(Power-on Selt Test,POST),之后开始执行硬件侦测的初始化,并设定PnP(即插即用装置)。做完以上工作,BIOS可以定义出可开机装置的顺序,接下来开始开机装置的数据读取;
  • BIOS通过硬件的INT 13中断功能读取MBR,只要BIOS能够侦测到磁盘,BIOS就可以通过INT 13信道读取磁盘的第一个扇区MBR,即可执行Boot Loader。

总结:按下电源键后首先加载BIOS,BIOS负责自我检测以及硬件侦测,并找到第一个可开机装置,加载Boot Loader。

Boot Loader

Boot Loader(开机管理程序):因为不同的操作系统的文件系统格式不同,所以需要一个Boot Loader处理核心文件加载的问题,不同的操作系统有不同的Boot Loader。Boot Loader的功能如下:

  • 最主要的功能是识别操作系统的文件系统格式并据以加载核心到内存中执行;
  • 提供选单,用户可以选择不同的开机项目;
  • 转交给其他Boot Loader,将开机管理功能转交给其他Loader负责。

扩展:如何在同一台主机安装两个操作系统?

在这里插入图片描述
如上图所示一块硬盘,每个文件系统或分区都会保留启动块Boot Block来提供操作系统安装Boot Loader。

MBR常常被不同操作系统的Boot Loader覆盖:

  • Linux在安装时,可以选择将boot loader安装到MBR中,也可以选择不安装(如果将boot loader安装到MBR中,那么在MBR和Linux系统都有一个boot loader)。
  • Windows在安装时,会主动将MBR和boot block都装上一份boot loader。

虽然MBR只有一个,但是Boot Loader具有选单功能,可以将控制权转交给其他boot loader,因此可以加载其他boot block中的boot loader。

要额外注意的是:安装Windows和Linux双系统时,由于Windows的Boot Loader预设不具有控制权转交功能,因此要先安装Linux再安装Windows。

总结:Boot Loader负责识别操作系统文件系统类型并加载内核到内存中(提供选单和转交控制权功能)。

Kernel

Boot Loader将内核加载到内存中后,内核会自己重新检测硬件(不会使用BIOS侦测到的硬件信息),并尝试挂载根目录以加载驱动程序。

Linux核心文件会被放置在/boot目录中,并取名为/boot/vmlinuz。

[root@rhel7 ~]# ll --format=single-column -F /boot
config-3.10.0-1160.el7.x86_64                            # 此版本核心被编译时选择的功能与模块配置文件
grub/                                                    # 旧版本grub目录
grub2/                                                   # 开机管理程序grub2相关数据目录
initramfs-0-rescue-ddfe10d662ea41efaa2953aec05e3f58.img  # 救援使用的虚拟文件系统
initramfs-3.10.0-1160.el7.x86_64.img                     # 正常开机使用的虚拟文件系统
System.map-3.10.0-1160.el7.x86_64                        # 核心功能放置到内存地址的对应表
vmlinuz-0-rescue-ddfe10d662ea41efaa2953aec05e3f58*       # 救援用到的核心文件
vmlinuz-3.10.0-1160.el7.x86_64*                          # 开机用到的核心文件

# -F或--classify 在执行文件、目录、Socket、符号连接、管道名称后面,各自加上识别符
     执行文件 *
     目录 /
     Socket =
     符号链接 @
     管道 |

Linux核心可以动态加载核心模块(驱动程序),核心模块放置在/lib/modules/目录中(SATA、SCSI等磁盘装置的驱动程序通常都是以模块的形式存在)。

[root@rhel7 ~]# ls /lib/modules/3.10.0-1160.el7.x86_64/
build              modules.builtin      modules.modesetting  source
extra              modules.builtin.bin  modules.networking   updates
kernel             modules.dep          modules.order        vdso
modules.alias      modules.dep.bin      modules.softdep      weak-updates
modules.alias.bin  modules.devname      modules.symbols
modules.block      modules.drm          modules.symbols.bin

BIOS-SYSTEMD
出现问题:驱动程序作为核心模块放置在磁盘根目录中,所以开机过程中,核心必须挂载根目录才能够读取核心模块,从而加载驱动程序。但是此时核心并不认识磁盘,需要加载磁盘驱动程序后才能挂载根目录。由此出现矛盾。

解决措施:通过虚拟文件系统(Initial RAM Disk)处理该问题。正常开机时使用的虚拟文件系统的文件名一般是/boot/initramfs或/boot/initrd。

  • 虚拟文件系统可以通过Boot Loader和内核一起被加载到内存中,虚拟文件系统在内存中被解压缩并仿真成一个根目录。
  • 该仿真根目录在内存中的文件系统能够提供一支可执行的程序,内核可以通过该程序来加载开机过程中所需要的核心模块(通常为文件系统和磁盘的驱动程序)。
  • 加载驱动程序完成后,将根文件系统以只读方式挂载,并挂载到真正的根目录文件系统,而后释放该虚拟文件系统,同时调用第一个进程,进入系统初始化阶段。

注意:RHEL 6 虚拟文件系统为initrd,呼叫第一个进程init;RHEL 7 虚拟文件系统initramfs,呼叫第一个进程systemd。

总结:内核自行检测所有硬件信息,通过搜索虚拟文件系统挂载的仿真根目录来加载必要的驱动程序和核心模块,主机硬件准备就绪后,核心呼叫第一个进程,并转移控制权。

System V / Systemd

System V 启动流程

System V启动流程
通过执行系统初始化脚本/etc/rc.d/rc.sysinit初始化用户环境。

  • 设置主机名;
  • 设置欢迎信息;
  • 激活UDEV和SeLinux;
  • 挂载/etc/fstab文件定义的所有文件系统;
  • 检测根文件系统,并以读写方式重新挂载根文件系统(内核加载阶段只读挂载);
  • 设置系统时钟;
  • 根据/etc/sysctl.conf文件设置内核参数;
  • 激活LVM及RAID设备;
  • 激活SWAP设备;
  • 加载额外设备的驱动程序(内核只加载根文件系统的驱动程序);
  • 清理操作;

通过/etc/inittab文件确定运行级别,之后将运行级别传入/etc/init/rc.conf文件中,/etc/init/rc.conf调用/etc/rc.d/rc $RUNLEVEL。

[root@rhel6 ~]# cat /etc/inittab  
...
id:5:initdefault:

[root@rhel6 ~]# cat /etc/init/rc.conf
...
export RUNLEVEL
console output
exec /etc/rc.d/rc $RUNLEVEL

/etc/rc.d/rc 接受传递的参数$runlevel,之后读取/etc/rc$runlevel.d/K*和/etc/rc$runlevel.d/S*所有文件(这些文件都是链接文件,它们链接到了/etc/init.d/*目录下的各个程序),按照优先级启动和关闭相应脚本。

[root@rhel6 ~]# ls /etc/rc.d/
init.d  rc  rc0.d  rc1.d  rc2.d  rc3.d  rc4.d  rc5.d  rc6.d  rc.local  rc.sysinit
[root@rhel6 ~]# ls /etc/rc.d/rc5.d/
K01smartd        K60nfs             S01sysstat       S20kdump             S50bluetooth
K02oddjobd       K69rpcsvcgssd      S02lvm2-monitor  S22messagebus        S55sshd
K05wdaemon       K73winbind         S08ip6tables     S23NetworkManager    S58ntpd
...
[root@rhel6 ~]# ll /etc/rc.d/rc5.d/
total 0
lrwxrwxrwx. 1 root root 16 May  1 19:08 K01smartd -> ../init.d/smartd
  • K*:要停止的服务,K##*,优先级,数字越小,越优先关闭,依赖的服务先关闭,然后再关闭被依赖的。
  • S*:要启动的服务,S##*,优先级,数字越小,越是优先启动,被依赖的服务先启动,而依赖的服务后启动。

启动和关闭/etc/rc.d/rc.local中的程序。因此有什么希望系统开机就做的动作,可以写入/etc/rc.d/rc.local文件中。

[root@rhel6 ~]# cat /etc/rc.local 
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

Systemd启动流程

在正常进入Linux操作环境的情况下,取得/etc/systemd/system/default.target 的预设操作界面设定为graphical.target。

[root@rhel7 ~]# ll /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 36 Sep 11 17:23 /etc/systemd/system/default.target -> /lib/systemd/system/graphical.target

通过/usr/lib/systemd/system/graphical.target配置文件发现Requires和Wants信息

systemd会去找两个地方的设定:

  • /etc/systemd/system/graphical.target.wants/ :使用者设定加载的unit
  • /usr/lib/systemd/system/graphical.target.wants/:系统默认加载的unit
[root@rhel7 ~]# cat /usr/lib/systemd/system/graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target                # graphical.target必须在multi-user.target完成后才能够进行
Wants=display-manager.service             # 进行完graphical.target之后,还得启动display-manager.service才行
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes

通过/usr/lib/systemd/system/multi-user.target配置文件查看multi-user.target执行完毕所需操作

systemd会去找两个地方的设定:

  • /etc/systemd/system/multi-user.target.wants/:使用者设定加载的unit
  • /usr/lib/systemd/system/multi-user.target.wants/:系统默认加载的unit
[root@rhel7 ~]# cat /usr/lib/systemd/system/multi-user.target
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target                     # multi-user.target必须在=basic.target完成后才能够进行
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes

通过/usr/lib/systemd/system/basic.target配置文件查看basic.target执行完毕操作

systemd会去找两个地方的设定:

  • /etc/systemd/system/basic.target.wants/:使用者设定加载的unit
  • /usr/lib/systemd/system/basic.target.wants/:系统默认加载的unit
[root@rhel7 ~]# cat /usr/lib/systemd/system/basic.target

[Unit]
Description=Basic System
Documentation=man:systemd.special(7)

Requires=sysinit.target                 # basic.target必须在sysinit.target执行之后才能进行
After=sysinit.target
Wants=sockets.target timers.target paths.target slices.target
After=sockets.target paths.target slices.target

可以通过systemctl list-dependencies graphical.target查看系统服务启动的流程,这就是systemd呼叫所需要的服务的流程。

[root@rhel7 basic.target.wants]# systemctl list-dependencies graphical.target
graphical.target
● ├─accounts-daemon.service
● ├─gdm.service
● ├─initial-setup-reconfiguration.service
● ├─network.service
● ├─rtkit-daemon.service
● ├─systemd-readahead-collect.service
● ├─systemd-readahead-replay.service
● ├─systemd-update-utmp-runlevel.service
● ├─udisks2.service
● └─multi-user.target
●   ├─abrt-ccpp.service
●   ├─abrt-oops.service
●   ├─abrt-vmcore.service
...

简略分析 systemctl list-dependencies graphical.target所输出的相依性服务,基本CentOS 7.x的systemd开机流程大约是:

  • local-fs.target+swap.target:主要在挂载本机/etc/fstab里所规范的文件系统与相关的内存置换空间
  • sysinit.target:主要侦测硬件,加载所需要的核心模块等动作
  • basic.target:加载主要的外围硬件驱动程序与防火墙相关任务
  • multi-user.target:其他一般系统或网络服务的加载
  • graphical.target:图形界面相关等其他服务的加载

SystemV 和 Systemd

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值