跳转到内容
来自 Arch Linux 中文维基

为了启动 Arch Linux,必须配置一个与 Linux 兼容的引导加载程序。引导加载程序负责在初始化启动进程之前,加载好内核和 initial ramdisk。具体过程因 BIOSUEFI 系统而异,详细描述在本文和关联页面中给出。

固件类型

固件是开机时最先执行的程序。

提示:本文时常以 BIOS 和 UEFI 代称固件。

UEFI

统一可扩展固件接口(Unified Extensible Firmware Interface,UEFI)支持读取分区表和文件系统。UEFI 不从主引导记录(MBR)中启动任何引导代码(无论其是否存在),相反,UEFI 的启动过程依赖非易失性随机访问存储器(NVRAM)中的引导条目。

UEFI 规范要求支持 FAT12、FAT16 和 FAT32 文件系统(参见 UEFI 规范 2.10 版 13.3.1.1 小节),但每个符合规范的厂商可以选择添加对其它文件系统的支持;比如,苹果的固件支持 HFS+APFS 文件系统。UEFI 的一些实现方案还支持光盘的 ISO 9660 文件系统。

UEFI 会启动 EFI 应用程序,例如引导加载程序、引导管理器和 UEFI Shell 等等。这些应用程序通常以文件形式存储在 EFI 系统分区中。厂商可以将其特定文件存储在 EFI 系统分区中的 /EFI/vendor_name 文件夹下。应用程序可以通过在 NVRAM 中添加引导项或从 UEFI shell 中启动。

UEFI 规范通过兼容性支持模块(Compatibility Support Module,CSM)来支持传统 BIOS 引导。如果在 UEFI 中启用了 CSM,UEFI 会为所有驱动器生成 CSM 引导项。如果选择从某一个 CSM 引导项启动,UEFI 的 CSM 会尝试从这个磁盘的 MBR 引导代码启动。

注意:英特尔正逐渐取消对 CSM 的支持。以后也许不能再依赖此特性。[1]

BIOS

BIOS,又称基本输入输出系统(Basic Input-Output System),大多数情况下储存在主板自身的一块闪存内,独立于其它系统存储。其最早是为 IBM PC 开发,用于处理硬件初始化和启动过程。从 2010 年起已逐渐被技术上没有类似限制的 UEFI 替换。

系统初始化

系统上电时,会执行加电自检(Power-on self-test,POST)。详细信息可参考 Hugo Landau 的 Modern CPUs have a backstage cast 一文。

在 UEFI 下的情况

  1. 加电自检后,UEFI 初始化引导所需的硬件(硬盘、键盘控制器等等)。
  2. 固件读取 NVRAM 中的引导项,以决定要启动哪一个 EFI 应用程序,以及从哪启动(比如从哪一个硬盘和分区)。
    • 一个引导项可能对应的只是一块硬盘。在这种情况下,固件会寻找硬盘上的 EFI 系统分区,并尝试在后备引导路径 \EFI\BOOT\BOOTx64.EFI 处(在 IA32(32 位)UEFI 的系统上为 BOOTIA32.EFI)查找 EFI 应用程序。这就是UEFI 可引导可移除介质的工作原理。
  3. 固件启动 EFI 应用程序。

如果启用了安全启动,启动过程将会通过签名验证 EFI 二进制文件的真实性。

注意:一些 UEFI 系统只能从后备引导路径启动。

多重引导

由于每个操作系统或厂商都可以维护自己在 EFI 系统分区中的文件,同时不影响其他系统,所以 UEFI 的多重引导的原理就是启动不同的、与特定操作系统引导加载程序所对应的 EFI 应用程序。这避免了依赖一个#引导加载程序去加载另一个操作系统的链式加载机制。

另请参阅 Arch + Windows 双系统

在 BIOS 下的情况

  1. 上电自检后,BIOS 初始化引导所需的硬件(硬盘、键盘控制器等等)。
  2. BIOS 启动在“BIOS 硬盘顺序”中第一块硬盘上的前 440 字节代码(即主引导记录引导代码区域)。
  3. 引导加载程序在 MBR 引导代码的第一阶段,之后会从下列任意一处启动第二阶段代码(如果有的话):
    • MBR 之后的下一个磁盘扇区,即所谓 MBR 后间隙(post-MBR gap,仅在 MBR 分区表上有)。
    • 分区或者无分区磁盘的卷引导记录(Volume Boot Record,VBR)。
    • GRUB 特定 BIOS 引导分区(仅限 GPT 分区硬盘上的 GRUB,用于 GPT 上没有 MBR 后间隙的情况)
  4. 真正的#引导加载程序启动。
  5. 随后,引导加载程序通过链式加载或直接加载操作系统内核的方式加载操作系统。

引导加载程序

引导加载程序(Boot Loader,又称引导加载器、启动加载器或启动引导器)是由计算机固件(BIOSUEFI)启动的软件。它负责用想要的内核参数加载内核和其它外置 initramfs 映像。

在 UEFI 的情况下,内核本身可以由 UEFI 使用 EFI boot stub英语EFI boot stub 直接启动。要在引导前编辑内核参数,仍可以使用单独的引导加载程序或引导管理器。使用 32 位 IA32 UEFI 固件的系统需要使用支持混合启动模式的引导加载程序。

警告:引导加载程序必须能够访问通常位于 /boot 目录下的内核和 initramfs 映像,否则 Arch 系统将无法引导。也就是说,引导加载器必须支持从块设备、堆叠块设备(LVM、RAID、dm-crypt、LUKS 等)开始,到内核和 initramfs 映像所在文件系统为止的一切功能。

Since almost no boot loader supports such stacked block devices and since file systems can introduce new features which may not yet be supported by any boot loader (e.g. archlinux/packaging/packages/grub#7 , FS#79857, FS#59047, FS#58137, FS#51879, FS#46856, FS#38750, FS#21733 and fscrypt encrypted directories), using a separate /boot partition with a universally supported file system, such as FAT32, is oftentimes more feasible.

功能比较

注意:
  • 由于 GPT 是 UEFI 规范的一部分,因此所有的 UEFI 引导加载程序都支持 GPT 磁盘。在 BIOS 上使用 GPT 磁盘是可行的,可以使用 Hybrid MBR 的“混合引导(hybrid booting)”,或者使用新的纯 GPT 协议。但是这个协议可能在某些 BIOS 实现上会出问题,详情请参考 Rodsbooks
  • 作为 UEFI 规范的一部分,所有 UEFI 引导加载程序都支持安全启动,但有可能会存在一些限制。
名称 固件 分区表 多重引导 文件系统 注意
BIOS UEFI MBR GPT
Clover 可扩展2,5 可以在过时 BIOS 系统上模拟 UEFI。
EFI boot stub英语EFI boot stub 1 继承自固件2 内核是有效的 EFI 可执行文件,可直接从 UEFI 或其它 UEFI 引导加载器启动。
GRUB 3 内置 支持 RAID,LUKS(Argon2 PBKDFs 除外)和 LVM(但是不支持精简配置卷)。平台相关限制请参考 GRUB
Limine 3 有限
rEFInd 4 可扩展2,5 支持自动检测内核和参数,无需明确配置,并支持快速启动[2]
Syslinux 部分1 部分 有限 不支持某些文件系统功能。
只能访问自身所处的文件系统。
systemd-boot 3 手动 4 可扩展2,5 无法从 ESP 或扩展引导加载程序分区(XBOOTLDR)以外的分区启动二进制文件。
支持自动检测放入 esp/EFI/Linux/统一内核映像
统一内核映像 3 继承自固件2 systemd-stub(7)、内核、initramfs、内核命令行打包而成的 EFI 可执行文件,可直接从 UEFI 固件或另一个引导加载程序加载。
GRUB Legacy 有限 停止开发,转为 GRUB
LILO 部分 有限 因为局限性(如与 Btrfs、GPT 和 RAID 搭配使用时)已停止开发
  1. 虽然二进制文件可以被签名用于安全启动,但它不会进行后续验证,从而破坏了信任链。
  2. 文件系统支持是从固件继承的。UEFI 规范要求支持 FAT12,FAT16 和 FAT32 文件系统,但厂商可选择添加对其他文件系统的支持。比如说,苹果 Mac 中的固件支持 HFS+ 文件系统。如果固件提供在启动时加载 UEFI 驱动程序的接口,则可以通过加载文件系统驱动程序(需单独获取)的方式添加对其他文件系统的支持。
  3. 支持混合模式启动,即可以在 32 位 IA32 UEFI 固件上启动 64 位 x86_64 Linux 内核
  4. 一种启动管理器。它只能启动其他的 EFI 应用程序,例如,使用 CONFIG_EFI_STUB=y 参数编译的 Linux 内核映像和 Windows Boot Manager bootmgfw.efi
  5. 支持加载 UEFI 文件系统驱动

另请参见维基百科:引导加载程序比较

内核

引导加载器会启动包含内核vmlinux 映像

内核是操作系统的核心。它运行于一个叫内核空间的底层上,负责机器硬件和应用程序之间的交流。在继续进入用户空间前,内核会首先执行硬件枚举和初始化。具体细节请参考zhwp:内核zhwp:Linux内核

initramfs

initramfs(初始内存文件系统,initial RAM file system)映像是一个 cpio 存档文件。Initramfs 映像可通过 mkinitcpiodracutbooster 生成,并是 Arch 推荐的设置早期用户空间的工具。

#引导加载程序加载内核和可能存在的 initramfs(初始 RAM 文件系统)文件、并启动内核之后,内核将 initramfs 档案展开到(当时为空的)rootfs(初始根文件系统,比如 ramfs 或 tmpfs)。在内核构建过程中嵌入内核二进制文件的 initramfs 被首先提取,然后提取可能存在的外部 initramfs 文件。因此,外部 initramfs 中的文件会覆盖嵌入式 initramfs 中具有相同名称的文件。然后,内核执行 /init (在 rootfs 中)作为第一个进程。早期用户空间(early userspace)启动。

/ 下的根文件系统原本是一个空的 rootfs,是一个特殊的 tmpfs 或 ramfs 实例。这里就是 initramfs 会解压到的临时根文件系统。

initramfs 的功能是为早期用户空间提供必要文件,以启动晚期用户空间。它不需要包括所有可能会用到的内核模块,而只需要包括根设备需要的模块,例如 NVMe,SATA,SAS,eMMC 或 USB(从外接硬盘启动需要)和加密模块。在根切换到根文件系统后,大部分模块将在后续通过 udev 在 init 阶段加载好。

  1. 首先,内核会将其内置 initramfs 解压到临时根分区下。Arch Linux 官方支持的内核使用空白存档作为内置 initramfs,即构建内核时的默认行为。
  2. 然后,内核会按照引导加载器传递的命令行参数指定的顺序解压外置 initramfs 映像,覆盖掉之前内置 initramfs 或其它解压出来的文件。注意,可以将多个 initramfs 映像合并为一个文件,内核会按照文件内的顺序加载映像。
    1. 如果首个 initramfs 映像未经压缩,那么内核在解压后会在 /kernel/x86/microcode/ 目录查找 CPU 微码更新,并在 /kernel/firmware/acpi/ 目录查找 ACPI 表更新。
    2. 在适用的情况下,在处理完 CPU 微码和 ACPI 表更新后,内核会继续解压剩余的 initramfs 映像。

Running without initramfs

Since 6.13.8 officially supported kernels have Btrfs and Ext4 drivers built-in [3].

This makes it possible for the kernel to use a root partition with these file systems directly and load the rest of external modules needed from there. Although, there are some quirks to keep in mind:

注意:Only regular SCSI/SATA/AHCI drives have built-in modules at the moment. Other storage kinds (NVMe, USB, device mapper etc.) would not work. LVM or encryption also can not be used without initramfs as they require userspace utilities to work.

Another thing you really need initramfs for is early microcode loading. But it is not necessary to build full image for that, Arch provides microcode in separate initramfs files, which could be used independently.

If no initramfs image is provided, the kernel always contains still an empty image to start from [7]. So there should be no issues with root partition pinning.

早期用户空间

The early userspace stage, a.k.a. the initramfs stage, takes place in rootfs consisting of the files provided by the #initramfs. Early userspace starts by the kernel executing the /init binary as PID 1.

The function of early userspace is configurable, but its main purpose is to bootstrap the system to the point where it can access the root file system. This includes:

Note that the early userspace serves more than just setting up the root file system. There are tasks that can only be performed before the root file system is mounted, such as fsck and resuming from hibernation.

At the final stage of early userspace, the real root is mounted at /sysroot/ (in case of a systemd-based initramfs) or at /new_root/ (in case of a busybox-based one), and then switched to by using systemctl switch-root when using systemd-based initramfs or switch_root(8) when using busybox-based initramfs. The late userspace starts by executing the init program from the real root file system.

晚期用户空间

The startup of late userspace is executed by the init process. Arch officially uses systemd which is built on the concept of units and services, but the functionality described here largely overlaps with other init systems.

getty

init 会为每个虚拟终端(通常有六个)调用一次 getty,它会初始化终端并保护其免受未授权访问。在提供用户名和密码后,getty 会对照 /etc/passwd/etc/shadow 检查是否正确。如果正确,就接着调用 login(1)

Login

login 会根据 /etc/passwd 设置环境变量并启动用户 shell,从而为用户配置一个会话。在成功登录后,执行登录 shell 前,login 程序会显示 /etc/motdmessage of the day)的内容,你可以用它来显示服务条款以提醒用户你的本地策略,也可以显示其它提示信息。

Shell

用户的 shell 启动后,在显示命令行提示符前,通常会执行一个运行时配置文件(例如 bashrc)。如果用户账户配置为在登录时自动启动 X,那么运行时配置文件会调用 startxxinit,具体内容请参考#图形会话(Xorg)

显示管理器

这篇文章的某些内容需要扩充。

原因:该部分只提到 Xorg,缺少 Wayland 相关内容。 (在 Talk:Arch 的启动流程 中讨论)

另外,在特定虚拟终端下,init 可配置为启动显示管理器,而不是 getty。要达成该效果,需要手动启用systemd 服务文件,之后显示管理器就会启动一个图形会话。

图形会话(Xorg)

xinit 会调用用户的 xinitrc 运行时配置文件,后者一般会启动一个窗口管理器桌面环境。如果用户退出了窗口管理器,xinitstartx、shell、login 就会依此顺序中断,返回到 getty 或显示管理器。

参见