Arch boot process (简体中文)
为了启动 Arch Linux,必须配置一个与 Linux 兼容的引导加载程序。引导加载程序负责在初始化启动进程之前,加载好内核和 initial ramdisk。具体过程因 BIOS 和 UEFI 系统而异,详细描述在本文和关联页面中给出。
固件类型
BIOS
BIOS,又称基本输入输出系统(Basic Input-Output System),是系统开启时最先运行的程序(固件)。大多数情况下它储存在主板自身的一块闪存内,独立于其他系统存储。
UEFI
统一可扩展固件界面(Unified Extensible Firmware Interface,UEFI)支持读取分区表和文件系统。UEFI 不从主引导记录(MBR)中启动加任何引导代码(无论其是否存在),相反,UEFI 的启动过程依赖非易失性随机访问存储器(NVRAM)中的引导条目。
UEFI 规范要求支持 FAT12、FAT16 和 FAT32 文件系统(参见 UEFI 规范 2.8 版本,第 13.3.1.1 小节),但每个符合条件的厂商可以选择添加对其他文件系统的支持;比如,苹果公司(Apple)的 Mac 支持(并默认使用)他们自己的 HFS+ 文件系统驱动程序。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 引导代码启动。
系统初始化
在 BIOS 下的情况
- 系统开启,执行上电自检(Power-on self-test,POST)。
- 上电自检后,BIOS 初始化引导所需的硬件(硬盘、键盘控制器等等)。
- BIOS 启动在“BIOS 硬盘顺序”中第一块硬盘上的前 440 字节代码(即主引导记录引导代码区域)。
- 引导加载程序在 MBR 引导代码的第一阶段,之后会从下列任意一处启动第二阶段代码(如果有的话):
- 实际引导加载程序启动。
- 引导加载程序之后通过链式加载或直接加载操作系统内核的方式加载一个操作系统。
在 UEFI 下的情况
- 系统开启,执行上电自检(Power-on self-test,POST)。
- 上电自检后,UEFI 初始化引导所需的硬件(硬盘、键盘控制器等等)。
- 固件读取 NVRAM 中的引导项,以决定要启动哪一个 EFI 应用程序,以及从哪启动(比如从哪一个硬盘和分区)。
- 一个引导项可能对应的只是一块硬盘。在这种情况下,固件会寻找硬盘上的 EFI 系统分区,并尝试在后备引导路径
\EFI\BOOT\BOOTx64.EFI
处(在带 IA32(32 位)UEFI 的系统上为BOOTIA32.EFI
)查找 EFI 应用程序。这就是可引导 UEFI 可移动媒体的工作原理。
- 一个引导项可能对应的只是一块硬盘。在这种情况下,固件会寻找硬盘上的 EFI 系统分区,并尝试在后备引导路径
- 固件启动 EFI 应用程序。
如果启用了安全启动,启动过程将会通过签名验证 EDI 二进制文件的真实性。
UEFI 中的多重引导
因为每个操作系统或厂商都可以维护自己在 EFI 系统分区中的文件,同时不影响其他系统,所以 UEFI 的多重引导的机理就是启动不同的与特定操作系统引导加载程序所对应的 EFI 应用程序。这避免了依赖一个引导加载程序去加载另一个操作系统的链式加载机制。
另请参阅与 Windows 系统双引导。
引导加载程序
引导加载程序(Boot Loader,又称引导加载器、启动加载器或启动引导器)是由计算机固件(BIOS 或 UEFI)启动的软件。它负责用想要的内核参数加载内核,并根据配置文件初始化 RAM 磁盘。在 UEFI 的情况下,内核本身可以由 UEFI 使用 EFI boot stub 直接启动。要在引导前编辑内核参数,仍可以使用单独的引导加载程序或引导管理器。
/boot
路径。这意味着它必须要支持从块设备、堆叠块设备(LVM、RAID、dm-crypt、LUKS 等)开始,到内核和 initramfs 映像所在文件系统为止的一切功能。功能比较
- 由于 GPT 是 UEFI 规范的一部分,因此所有的 UEFI 引导加载程序都支持 GPT 磁盘。在 BIOS上 使用 GPT 磁盘是可行的,可以使用 Hybrid MBR 的混合引导(hybird booting),或者使用新的纯 GPT 协议。但是这个协议可能在某些 BIOS 实现上会出问题,详情请参考 Rodsbooks。
- 在文件系统支持中提到的“加密”指的是文件系统级加密,和块级别加密没有任何关系。
名称 | 固件 | 分区表 | 多重启动 | 文件系统 | 注意 | ||||||
---|---|---|---|---|---|---|---|---|---|---|---|
BIOS | UEFI | MBR | GPT | Btrfs | ext4 | ReiserFS | VFAT | XFS | |||
EFISTUB | – | 是 | 是 | 是 | – | – | – | – | 继承自固件1 | – | 内核会变为 EFI 可执行文件以被从 UEFI 固件或者其他引导加载程序加载。 |
Clover | 模拟 UEFI | 是 | 是 | 是 | 是2 | 否 | 不支持加密 | 否 | 继承自固件1 | 否 | 修改版的 rEFIt 分支,用来运行黑苹果(运行在非苹果硬件上的 macOS)。 |
GRUB | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 是 | 在 BIOS/GPT 配置下需要一个 BIOS 引导分区。 支持 RAID、LUKS1 和 LVM(但是不支持精简配置卷)。 |
Limine | 是 | 是 | 是 | 是 | 是 | 否 | 不支持加密 | 否 | 是 | 否 | |
rEFInd | 否 | 是 | 是 | 是 | 是2 | 不支持加密 | 不支持加密 | 不支持尾部压缩(tail-packing)功能 | 继承自固件1 | 否 | 支持自动检测内核和参数,无需明确配置,并支持快速启动(fastboot)[2]。 |
Syslinux | 是 | 部分支持 | 是 | 是 | 部分支持 | 不支持:多设备卷、压缩和加密 | 不支持加密 | 否 | 是 | 仅限 MBR;不支持稀疏索引节点(sparse inodes) | 不支持某些文件系统功能。[3] 没有文件系统驱动[4],只能够访问自身所处的文件系统。 |
systemd-boot | 否 | 是 | 仅限手动安装 | 是 | 是2 | 否 | 否 | 否 | 继承自固件1 | 否 | 无法从 ESP 或扩展引导加载程序分区 (XBOOTLDR) 以外的分区启动二进制文件。 |
GRUB Legacy | 是 | 否 | 是 | 否 | 是 | 否 | 否 | 是 | 是 | 仅 XFS v4 | 停止开发,转为 GRUB。 |
LILO | 是 | 否 | 是 | 否 | 是 | 否 | 不支持加密 | 是 | 是 | 是 | 因为局限性(如与 Btrfs、GPT 和 RAID 搭配使用时)已停止开发。 |
- 文件系统支持是从固件继承的。UEFI 规范要求支持 FAT12,FAT16 和 FAT32 文件系统[5],但厂商可选择添加对其他文件系统的支持。比如说,苹果公司的 Mac 中的固件支持 HFS+ 文件系统。如果固件提供在启动时加载 UEFI 驱动程序的接口,则可以通过加载文件系统驱动程序(需单独获取)的方式添加对其他文件系统的支持。
- 一种启动管理器。它只能启动其他的 EFI 应用程序,例如,使用
CONFIG_EFI_STUB=y
参数编译的 Linux 内核映像和 Windows 中的bootmgfw.efi
。
另请参见维基百科:引导加载程序比较。
内核
内核是操作系统的核心。它运行于一个叫「内核空间」的底层上,负责机器硬件和应用程序之间的交流。为了尽可能充分地压榨 CPU 性能,内核使用调度器,通过一定的优先级算法将 CPU 按照时间动态的分配给各个程序。让我们感觉就像所有程序都在同时使用 CPU 一样。
initramfs
在 boot loader(启动引导器)加载 kernel 和可用的 initramfs 文件,并执行 kernel 之后,kernel 将 initramfs(初始RAM文件系统)压缩包解压缩到(然后清空)rootfs(初始根文件系统,特别是ramfs或tmpfs)。首先提取的 initramfs 是在 kernel 构建过程中嵌入 kernel 二进制Update translation.的 initramfs,然后提取可用的外部 initramfs 文件。因此,外部 initramfs 中的文件会覆盖嵌入式 initramfs 中具有相同名称的文件。然后, kernel 执行 /init
(在rootfs中)作为第一个进程。early userspace开始。
Arch Linux 对内置的 initramfs 使用一个空的存档(在构建Linux时是默认的)。有关外部 initramfs 的更多信息和 Arch 特定的信息,请参见 mkinitcpio。
initramfs 之所以存在,是为了帮系统访问真正的根文件系统(参见 Arch filesystem hierarchy (简体中文))。也就是说,那些硬件 IDE, SCSI, SATA, USB/FW 所要求的 kernel 模块,如果并没有内置在 kernel 里,就会被 initramfs 负责加载。一旦通过 udev (简体中文) 之类的程序或脚本加载好模块,启动流程才会继续下去。所以,initramfs 只要有能够让系统访问真实根文件系统的模块就可以了,不用尽可能地包含一切模块。当然,其它真正有用的模块之后会在 init 流程中被 udev 加载好。
Init 流程
在「早期用户空间」的最终环节里,真正的根文件系统被挂载好后,就会替换掉原来的伪根文件系统。接着 /sbin/init
被执行,同样也替换掉原来的 /init
进程。Arch 御用的 init 就是 systemd (简体中文).
Getty
init 为每一个 虚拟终端 调用 getty,前者一般有六个,每个虚拟终端都会初始化 tty 并请求输入用户名和密码。当在某虚拟终端输入用户名和密码后,其 getty 会通过 /etc/passwd
检查是否正确,如果正确,就接着调用 login, 此外 getty 也可能会改启动一个显示管理器。
显示管理器
显示管理器, 可以配置为代替原来的 getty 登录命令行提示符。
为了在引导后自动初始化显示管理器,必须通过systemd手动启用服务单元。 有关启用和启动服务单元的更多信息,请参见systemd#使用单元。
Login
所谓的 login 程序会为用户启动一个设置了环境变量的「会话」,接着根据 /etc/passwd
的配置启动用户专用 shell。
在成功登录后,刚刚启动登录 shell 之前,login 程序显示 /etc/motd (message of the day) 。在这里,您可以显示服务条款,以提醒用户您的本地政策或您想告诉他们的任何内容。
Shell
一旦用户专用的 shell 启动了,它会在显示命令行提示符前,执行一个「有可执行性的配置文件」,比如 .bashrc. 如果用户有设定了 Start X at login, 原来那个「有可执行性的配置文件」会调用 startx or xinit.
GUI、 xinit 或者 wayland
xinit 也会调用用户的 .xinitrc 这个「有可执行性的配置文件」,后者一般用来启动一个 窗口管理器。如果用户退出了窗口管理器、xinit、 startx 和 shell login 就会先后中断,返回到 getty.