16 引导过程简介 #
    引导 Linux 系统涉及不同组件和任务。固件和硬件初始化过程(取决于计算机的体系结构)完成后,引导加载程序 GRUB 2 会启动内核。在此之后,引导过程由操作系统控制,并由 systemd 处理。systemd 会提供一组“目标”,用于引导与日常使用、维护或紧急情况相关的配置。
   
16.1 术语 #
本章使用的术语可能存在歧义。为了理解本章中术语的用法,请阅读以下定义:
- init
- 有两个不同的进程通常命名为 “init”: - 用于挂载根文件系统的 - initramfs进程
- 从实际根文件系统执行且用于启动其他所有进程的操作系统进程 
 - 在这两种情况下, - systemd程序都会处理此任务。首先会从- initramfs执行此进程,以挂载根文件系统。挂载成功后,此进程将作为初始进程从根文件系统重新执行。为了避免混淆这两个- systemd进程,我们将第一个进程称为 init on initramfs,将第二个进程称为 systemd。
- 
initrd/initramfs
- initrd(初始 RAM 磁盘)是一个映像文件,内含将由内核加载并作为临时根文件系统从- /dev/ram挂载的根文件系统映像。挂载此文件系统需要使用文件系统驱动程序。- 从内核 2.6.13 开始,initrd 已由 - initramfs(初始 RAM 文件系统)取代,后者无需文件系统驱动程序即可挂载。SUSE Linux Enterprise Server 只使用- initramfs。但是,由于- initramfs作为- /boot/initrd存储,因此通常将其称为 “initrd”。本章只使用名称- initramfs。
16.2 Linux 引导进程 #
Linux 引导进程包括多个阶段,每个阶段由一个不同组件来代表:
16.2.1 初始化和引导加载程序阶段 #
在初始化阶段,将设置计算机的硬件并准备好设备。此过程因硬件体系结构而异。
SUSE Linux Enterprise Server 在所有体系结构中都使用引导加载程序 GRUB 2。根据体系结构和固件,启动 GRUB 2 引导加载程序的过程可能包括多个步骤。引导加载程序的用途是加载内核以及基于 RAM 的初始文件系统 (initramfs)。有关 GRUB 2 的详细信息,请参见第 18 章 “引导加载程序 GRUB 2”。
16.2.1.1 AArch64 和 AMD64/Intel 64 上的初始化和引导加载程序阶段 #
在打开计算机之后,BIOS 或 UEFI 将初始化屏幕和键盘并测试主内存。直到这一阶段,计算机不访问任何大容量存储媒体。随后,将从 CMOS 值加载有关当前日期、时间和最重要的外设的信息。识别引导媒体及其几何尺寸之后,系统控制权将从 BIOS/UEFI 转到引导加载程序。
     在装配传统 BIOS 的计算机上,只能加载引导磁盘的第一个 512 字节物理数据扇区(主引导记录,MBR)中的代码。只有极少量的 GRUB 2 代码能够挂载 MBR。引导加载程序的唯一作用就是从 MBR 与第一个分区(MBR 分区表)之间的间隙处,或是从 BIOS 引导分区(GPT 分区表)加载包含文件系统驱动程序的 GRUB 2 核心映像。此映像包含文件系统驱动程序,因此能够访问根文件系统中的 /boot。/boot 包含 GRUB 2 核心的附加模块以及内核和 initramfs 映像。获取此分区的访问权限后,GRUB 2 会将内核和 initramfs 映像加载到内存中,并将控制权交给内核。
    
     从包含已加密分区 /boot 的加密文件系统引导 BIOS 系统时,需要输入解密口令两次。第一次是为了让 GRUB 2 解密 /boot,第二次是让 systemd 挂载加密的卷。
    
     在装配 UEFI 的计算机上,引导过程比装配传统 BIOS 的计算机要简单得多。固件能够读取包含 GPT 分区表的磁盘的 FAT 格式化系统分区。此 EFI 系统分区(在运行的系统中挂载为 /boot/efi)可提供足够的空间,用于存储由固件直接加载和执行的完备 GRUB 2。
    
如果 BIOS/UEFI 支持网络引导,则也可以配置提供引导加载程序的引导服务器。然后,可以通过 PXE 引导系统。BIOS/UEFI 充当引导加载程序。它会从引导服务器获取引导映像并启动系统,而不受本地硬盘的影响。
16.2.1.2 IBM Z 上的初始化和引导加载程序阶段 #
     在 IBM Z 上,必须通过名为 zipl(z 初始程序加载)的引导加载程序初始化引导进程。尽管 zipl 支持从多个文件系统读取数据,但不支持 SLE 默认文件系统 (Btrfs) 或者从快照引导。因此,SUSE Linux Enterprise Server 使用两阶段的引导过程来确保引导时完全支持 Btrfs:
    
- zipl从- /boot/zipl分区引导,该分区可格式化为 Ext2、Ext3、Ext4 或 XFS 文件系统。此分区包含一个极简的内核,以及一个加载到内存中的 initramfs。initramfs 包含 Btrfs 驱动程序(及其他组件)和引导加载程序 GRUB 2。内核是使用参数- initgrub(告知要启动 GRUB 2)启动的。
- 内核会挂载根文件系统,使 - /boot可访问。现在,将从 initramfs 启动 GRUB 2。GRUB 从- /boot/grub2/grub.cfg读取其配置,并从- /boot加载最终的内核和 initramfs。现在,将通过 Kexec 加载新内核。
16.2.2 内核阶段 #
    引导加载程序转交系统控制权后,所有体系结构中的引导过程都是相同的。引导加载程序会将内核和基于 RAM 的初始文件系统 (initramfs) 都加载到内存中,而内核将接管控制权。
   
    内核确立内存管理权限并检测到 CPU 类型及其功能后,会初始化硬件,并从内存中挂载通过 initramfs 加载的临时根文件系统。
   
16.2.2.1 initramfs 文件 #
initramfs(初始 RAM 文件系统)是一个小型 cpio 存档,可由内核加载到 RAM 磁盘中。它位于 /boot/initrd 中。可以使用名为 dracut 的工具创建该文件,有关详细信息,请参见 man 8 dracut。
    
initramfs 提供了一个极简的 Linux 环境,可用于在挂载实际根文件系统之前执行程序。这个最小的 Linux 环境由 BIOS 或 UEFI 例程载入内存,而且除了需要足够的内存外没有特定的硬件要求。initramfs 存档必须始终提供一个名为 init 的可执行文件,该文件执行根文件系统上的 systemd 守护程序,使引导进程得以继续。
    
     在能够挂载根文件系统并启动操作系统之前,内核需要相应的驱动程序来访问根文件系统所在的设备。这些驱动程序可能包括用于特定类型硬盘的特殊驱动程序,甚至还可能包括访问网络文件系统所需的网络驱动程序。根文件系统所需的模块由 initramfs 上的 init 加载。加载模块后,udev 将为 initramfs 提供所需的设备。在引导过程的后面,更改根文件系统之后需要重新生成设备。可以使用 systemd 单元 systemd-udev-trigger.service 来实现此目的。
    
16.2.2.1.1 重新生成 initramfs #
      由于 initramfs 包含多个驱动程序,因此,每当其中某个驱动程序有新版本发布时,都需要更新 initramfs。在安装包含驱动程序更新的软件包时可以自动完成这种更新。YaST 或 zypper 通过显示用于生成 initramfs 的命令的输出来告知您此状况。但在某些情况下,您需要手动重新生成 initramfs:
     
- 由于更换硬件而需添加驱动程序
- 如果需要更换硬件(例如硬盘),并且引导时此硬件需要内核中存在不同的驱动程序,则您必须更新 - initramfs文件。- 打开或创建 - /etc/dracut.conf.d/10-DRIVER.conf,并添加如下一行内容(请注意前导空格):- force_drivers+=" DRIVER1 " - 用驱动程序的模块名称替换 DRIVER1。如果您需要添加多个驱动程序,请将其全部列出并以空格分隔: - force_drivers+=" DRIVER1 DRIVER2 " 
- 将系统目录移到 RAID 或 LVM
- 每次您要将正在运行的系统中的交换文件或系统目录(例如 - /usr)移到 RAID 或逻辑卷时,都需要创建包含软件 RAID 或 LVM 驱动程序支持的- initramfs。- 为此,请在 - /etc/fstab中创建相关的项,并挂载新项(例如,使用- mount -a和/或- swapon -a)。
- 将磁盘添加到包含根文件系统的 LVM 组或 Btrfs RAID
- 每当您要在包含根文件系统的逻辑卷组或者 Btrfs RAID 中添加(或去除)磁盘时,都需要创建一个支持扩容的卷的 - initramfs。请按照过程 16.1 “生成 initramfs”中的说明操作。
- 更改内核变量
- 如果您在 - sysctl界面中通过编辑相关文件(- /etc/sysctl.conf或- /etc/sysctl.d/*.conf)更改了内核变量的值,系统下次重引导时,这项更改将会丢失。即使您在运行时使用- sysctl --system加载这些值,更改也不会保存到- initramfs文件中。您需要根据过程 16.1 “生成 initramfs”中所述更新该文件。
          下面的过程中的所有命令都需要以 root 用户身份执行。
        
- 进入 - /boot目录:- #cd /boot
- 使用 - dracut生成一个新- initramfs文件(以您选择的文件名替换 MY_INITRAMFS):- #dracut MY_INITRAMFS- 或者,可以运行 - dracut -fFILENAME 来替换现有的 init 文件。
- (如果在上一步中运行了 - dracut -f,请跳过此步骤。)基于您在上一步中创建的- initramfs文件创建指向- initrd的符号链接:- #ln -sf MY_INITRAMFS- initrd
- 在 IBM Z 体系结构中,另外还需运行 - grub2-install。
16.2.3 Init on initramfs 阶段 #
    由内核从 initramfs 挂载的临时根文件系统包含可执行文件 systemd(下面称作 init on initramfs,另请参见第 16.1 节 “术语”)。此程序执行挂载正确根文件系统所需的全部操作。它为所需的文件系统提供内核功能,并为使用 udev 的大量存储控制器提供设备驱动程序。
   
initramfs 上的 init 的主要用途是为挂载和访问真实根文件系统完成准备工作。根据您的系统配置的不同,initramfs 上的 init 负责以下任务。
   
- 加载内核模块
- 根据硬件配置的不同,可能需要一些特殊的驱动程序来访问计算机的硬件组件(最重要的组件是硬盘)。要访问最终的根文件系统,内核需要加载适当的文件系统驱动程序。 
- 提供块特殊文件
- 内核根据加载的模块生成设备事件。 - udev会处理这些事件,并在- /dev中的 RAM 文件系统上生成所需的特殊块文件。没有这些特殊文件,文件系统和其他设备将不可访问。
- 管理 RAID 和 LVM 设置
- 如果将系统配置为在 RAID 或 LVM 下保存根文件文件系统,则 - initramfs上的- init将设置 LVM 或 RAID 以支持以后对根文件系统的访问。
- 管理网络配置
- 如果将系统配置为使用通过网络挂载的根文件系统(通过 NFS 挂载),则 - init必须确保加载了正确的网络驱动程序,并且这些驱动程序设置为允许访问根文件系统。- 如果文件系统驻留在一个联网的块设备(如 iSCSI 或 SAN)上,则与存储服务器的连接也由 - initramfs上的- init设置。SUSE Linux Enterprise Server 支持在主要目标不可用的情况下从次要 iSCSI 目标引导。有关 iSCSI 引导目标配置的更多细节,请参见第 15.3.1 节 “使用 YaST 配置 iSCSI 发起端”。
如果根文件系统无法从引导环境中挂载,则必须先对其进行检查和修复,才能继续引导。如果文件系统为 Ext3 和 Ext4,文件系统检查程序将会自动启动。如果是 XFS 和 Btrfs 文件系统,则不会自动开始修复过程,而是向用户显示有关可用于修复文件系统的选项的信息。成功修复文件系统后,退出引导环境将会使系统重试挂载根文件系统。如果挂载成功,将正常继续引导。
16.2.3.1 安装过程中的 init on initramfs 阶段 #
     如果在安装过程的初始引导阶段调用 init on initramfs,它要执行的任务将与上述任务不同。安装系统也不会从 initramfs 启动 systemd — 这些任务由 linuxrc 执行。
    
- 查找安装媒体
- 当您启动安装过程时,计算机会加载一个安装内核以及一个包含 YaST 安装程序的特殊 - init。YaST 安装程序正在 RAM 文件系统中运行,它需要知道安装媒体的位置,才能访问安装媒体以安装操作系统。
- 启动硬件识别并加载适当的内核模块
- 如第 16.2.2.1 节 “ - initramfs文件”中所述,引导过程从最少的一组驱动程序(可在大多数硬件配置中使用)开始。在 AArch64、POWER 和 AMD64/Intel 64 计算机上,- linuxrc会启动初始硬件扫描进程,以确定适合您的硬件配置的驱动程序集。在 IBM Z 上,需要提供驱动程序及其参数的列表(例如,通过 linuxrc 或 parmfile 提供)。- 这些驱动程序用于生成引导系统所需的自定义 - initramfs。如果引导时不需要这些模块,但冷插拔时需要,您可以使用- systemd加载这些模块。有关详细信息,请参见第 19.6.4 节 “加载内核模块”。
- 加载安装系统
- 系统在正确识别硬件后会加载相应的驱动程序。 - udev程序会创建特殊的设备文件,- linuxrc使用 YaST 安装程序启动安装系统。
- 启动 YaST
- 最后, - linuxrc会启动 YaST,后者会启动软件包安装和系统配置。
16.2.4 systemd 阶段 #
    找到“实际的”根文件系统后,对其进行错误检查并挂载。如果挂载成功,系统会清理 initramfs 并执行根文件系统上的 systemd 守护程序。systemd 是 Linux 的系统和服务管理器。它是作为 PID 1 启动的父进程,充当用于启动和维护用户空间服务的 init 系统。有关详细信息,请参见 第 19 章 “systemd 守护程序”。