当前位置: 首页 > 文档资料 > systemd 中文手册 >

bootup 中文手册

优质
小牛编辑
145浏览
2023-12-01

名称

bootup — 系统启动流程

描述

在系统启动过程中要涉及多个不同的组件。按下电源按钮后,首先BIOS/UEFI做最基本的硬件自检与初始化,然后加载预设/手动选择的磁盘/网络上的引导加载器(例如GRUB2),引导加载器进一步从磁盘/网络上加载操作系统内核(例如Linux)。对于Linux来说,内核将会(可选的)解压一个initrd(initial RAM disk)镜像(可以用dracut(8)之类的工具生成),并执行由"rdinit="内核引导选项指定的init程序(例如systemd(1))以寻找并挂载根文件系统。完成根文件系统的挂载之后,内核启动由"init="内核引导选项指定的init程序(例如systemd(1))以接管系统的控制权。该init程序将会负责检测所有其他的硬件设备、挂载必要的文件系统、启动所有必要的服务,等等。

关机时,init程序将会停止所有服务、卸载所有文件系统、(可选的)返回initrd环境卸载根文件系统,最后关闭电源。

其他有关系统启动流程的信息可以参考boot(7) 手册。

常规启动流程

当成功挂载了"root="内核引导选项指定的根文件系统之后,内核将启动由"init="内核引导选项指定的init程序,从这个时间点开始,即进入了"常规启动流程":检测硬件设备并加载驱动、挂载必要的文件系统、启动所有必要的服务,等等。对于systemd(1)系统来说,上述"init程序"就是 systemd 进程,而整个"常规启动流程"也以几个特殊的 target 单元(详见systemd.target(5))作为节点,被划分为几个阶段性步骤。在每个阶段性步骤内部,任务是高度并行的,所以无法准确预测同一阶段内单元的先后顺序,但是不同阶段之间的先后顺序总是固定的。

当启动系统时,systemd 将会以 default.target 为启动目标,借助单元之间环环相扣的依赖关系,即可完成"常规启动流程"。 default.target 通常只是一个指向graphical.target(图形界面) 或multi-user.target(文本控制台) 的软连接。为了强制启动流程的规范性以及提高单元的并行性,预先定义了一些具有特定含义的 target 单元。详见systemd.special(7) 手册。

下面的图表解释了这些具有特定含义的 target 单元之间的依赖关系以及各自在启动流程中的位置。图中的箭头表示了单元之间的依赖关系与先后顺序,整个图表按照自上而下的时间顺序执行。

local-fs-pre.target   |   v
 (各个 mounts 与       (各个 swap      (各个加密块设备
 fsck services……)      devices……)         devices……)          (各个底层服务:      (各个底层虚拟   |                  |                  |              udevd, tmpfiles,    文件系统 mounts:   v                  v                  v              random seed,        mqueue, configfs,
  local-fs.target      swap.target     cryptsetup.target          sysctl, ……)      debugfs, ……)   |                  |                  |                    |                    |   \__________________|_________________ | ___________________|____________________/                                        \|/                                         v                                  sysinit.target                                         |    ____________________________________/|\________________________________________   /                  |                  |                    |                    \   |                  |                  |                    |                    |   v                  v                  |                    v                    v(各个               (各个                |                  (各个           rescue.servicetimers……)           paths……)               |               sockets……)                |   |                  |                  |                    |                    v   v                  v                  |                    v              rescue.target
   timers.target      paths.target             |             sockets.target   .                  |                  |                    |   .                  \_________________ | ___________________/   .................................... \|/                                         v                                   basic.target                                         |    ____________________________________/|                                 emergency.service   /                  |                  |                                         |   |                  |                  |                                         v   v                  v                  v                                 emergency.target display-        (图形界面所必需    (各个系统服务)
 manager.service      的各个系统服务)          |   |                  |                  |   |                  |                  v   |                  |           multi-user.target   |                  |                  |   \_________________ | _________________/                     \|/                      v            graphical.target

斜体标识的目标单元经常被用作启动目标。有两种方法可以指定启动目标:(1)使用systemd.unit= 内核引导选项(参见systemd(1));(2)使用 default.target 软连接。

因为 timers.target 以异步方式包含在basic.target 中,所以 timer 单元可以依赖于在 basic.target之后才启动的服务。

initrd(Initial RAM Disk) 启动流程

在initrd内部,也可以将 systemd 用作init程序(由"rdinit="内核引导选项指定)。

此时initrd.target 将是默认目标。initrd内部启动流程的上半部分与前一小节 basic.target 之前的部分完全相同。随后的启动流程将以 initrd.target 为目标(如下图所示)。 在挂载任何文件系统之前(也就是在启动 local-fs-pre.target 之前),systemd-hibernate-resume@.service 将会首先完成启动,以检查系统是要从先前的休眠状态中恢复,还是要执行常规的启动流程。在检查完成之前,将不会挂载任何文件系统。 当根文件系统设备可用时,将到达initd-root-device.target 目标。如果成功的将根文件系统挂载到/sysroot 目录,那么sysroot.mount 单元将被启动,然后进一步到达initrd-root-fs.target 目标。initrd-parse-etc.service 将会分析/sysroot/etc/fstab 文件以挂载/usr (若需要)与带有 x-initrd.mount 标记的挂载点。所有这些挂载点都将被挂载到 /sysroot 之下,然后流程到达initrd-fs.target 目标。再接下来initrd-cleanup.service 将会使用 systemctl --no-block isolate 命令启动initrd-switch-root.target 目标。因为 isolate 表示立即停止所有在新的目标单元中不需要的进程,所以此动作实际上是为接下来切换根目录做预先的准备(也就是清理环境)。最后,启动 initrd-switch-root.service 服务,将系统的根目录切换至/sysroot 目录。

                              (之前的流程与上一小节完全相同)                                         :                                         v                                   basic.target                                         |                                 emergency.service                  ______________________/|                                         |                 /                       |                                         v                 |            initrd-root-device.target                    emergency.target                 |                       |                 |                       v                 |                  sysroot.mount                 |                       |                 |                       v                 |             initrd-root-fs.target                 |                       |                 |                       v                 v            initrd-parse-etc.service        (各个自定义的                    |       initrd services……)                v                 |            (sysroot-usr.mount 以及                 |             fstab 中带有 x-initrd.mount                 |               标记的各个挂载点)                 |                       |                 |                       v                 |                initrd-fs.target                 \______________________ |                                        \|                                         v                                    initrd.target                                         |                                         v                               initrd-cleanup.service                    (使用 isolates 启动 initrd-switch-root.target)                                         |                                         v                  ______________________/|                 /                       v                 |        initrd-udevadm-cleanup-db.service                 v                       |        (各个自定义的                    |       initrd services……)                |                 \______________________ |                                        \|                                         v                             initrd-switch-root.target                                         |                                         v                             initrd-switch-root.service                                         |                                         v                               切换到主机上的操作系统

关机流程

systemd 系统在关机时同样遵循固定的流程,具体如下图所示:

 (与所有系统服务互斥)    (与所有文件系统 mounts, swaps, cryptsetup devices 互斥)      |                                             |      v                                             v shutdown.target                                 umount.target      |                                             |      \____________________________________   ______/                                           \ /                                            |                                            v                                  (各个底层 services)                                            |                                            |                                            v                                      final.target                                            |                                            |      _____________________________________/ \_________________________________     /                         |                        |                      \     |                         |                        |                      |     v                         v                        v                      v
systemd-reboot.service   systemd-poweroff.service   systemd-halt.service   systemd-kexec.service     |                         |                        |                      |     v                         v                        v                      vreboot.target             poweroff.target            halt.target           kexec.target

斜体标识的目标单元经常被用作关机目标。

注意,systemd-halt.service(8),systemd-reboot.service, systemd-poweroff.service,systemd-kexec.service 会将系统与 systemd(PID=1)带入关机流程的第二个阶段(由 systemd-shutdown 执行),也就是不再考虑任何服务与单元等概念,只用一种简单粗暴的方式卸载所有文件系统、杀死所有进程、释放所有资源。一般来说,在第一阶段结束时,常规应用都已终止、常规资源都已释放,第二阶段只是一个兜底的安全网,那些在第一阶段基于单元的关闭流程中(见前文)未能结束的进程将被强制终止、未能释放的资源将被强制释放。

参见

systemd(1),boot(7),systemd.special(7),systemd.target(5),systemd-halt.service(8),dracut(8)