16.1 启动引导器

FreeBSD 的启动过程分为五个核心阶段:固件初始化(BIOS 或 UEFI)→ 引导加载程序(boot0/boot1/boot2)→ loader 引导 → 内核初始化 → 用户空间初始化,其中 loader 阶段通过 loader.conf 实现参数化配置。本节解析启动流程并说明 loader.conf 的关键配置项。

FreeBSD 启动过程概述

FreeBSD 的启动过程是一个多阶段的有序流程,从硬件加电自检(POST)开始,经过固件初始化、引导加载程序执行、内核加载,最终进入用户空间初始化。loader 是引导加载过程的最终阶段。

FreeBSD 的启动过程可分为以下阶段:

  1. POST(加电自检):计算机加电后,CPU 首先执行固件(BIOS 或 UEFI)中的初始化代码,完成硬件自检和基本设备配置。

  2. 固件引导阶段:POST 完成后,固件根据启动顺序定位启动设备。

  • 在 BIOS 模式下,固件读取磁盘主引导记录(MBR)或卷引导记录(VBR)中的引导代码;

  • 在 UEFI 模式下,固件从 EFI 系统分区(ESP)加载 EFI 应用程序。FreeBSD 的 UEFI 引导程序位于 /EFI/freebsd/loader.efi

  1. 引导加载程序阶段(Boot Loader):FreeBSD 的引导加载程序分为四个阶段(在 BIOS 模式下为 boot0/boot1/boot2/loader,在 UEFI 模式下为 loader.efi)。其中 boot0 为阶段 0(引导管理器),boot1boot2 为阶段 1 和阶段 2,loader 为阶段 3。最终阶段的 loader(8) 是一个交互式引导加载程序,它读取 /boot/loader.conf 配置文件,加载内核和模块,随后将控制权转移给内核。

  2. 内核初始化阶段:内核加载后,首先探测硬件并初始化设备,此后挂载根文件系统,启动 init(8) 进程。init(8) 始终是内核启动的第一个用户空间进程,其进程 ID(PID)始终为 1。

init(8) 信号参数(BSD init 不使用 System V 运行级别机制):

信号
动作

SIGUSR1

停机

SIGUSR2

停机并关闭电源(需硬件支持)

SIGWINCH

停机、关闭电源后再重新开机(需硬件支持)

SIGTERM

终止多用户操作,进入单用户模式

SIGINT

终止全部进程并重新启动系统

SIGTSTP

阻止进一步登录(reboot(8) 和 halt(8) 在关机前发送此信号以阻止新登录)

SIGHUP

重新读取 ttys(5) 文件

注意

如果安全级别启用过早(大于 1),可能妨碍 fsck(8) 修复不一致的文件系统。建议在 /etc/rc 末尾设置安全级别。在 Jail 中运行 init(8) 时,安全级别按 Jail 独立设置,不影响宿主系统。

  1. 用户空间初始化阶段:init(8) 读取 /etc/rc 脚本,该脚本根据 /etc/rc.conf 的配置启动系统服务,最终将系统带入多用户模式。

FreeBSD 在传统引导(BIOS + MBR)下的启动过程

引导管理器(Boot Manager,阶段 0)

boot0cfg 仅适用于 BIOS/MBR 启动模式,不适用于 UEFI 系统(UEFI 使用 efibootmgr(8))。

MBR 中的引导管理器代码有时称作启动过程的阶段 0。默认情况下,FreeBSD 使用 boot0 引导管理器。

FreeBSD 安装程序安装的 MBR 基于 /boot/boot0。由于 MBR 末尾的分区表和 0x55AA 标识符的限制,boot0 的大小和功能限制在 446 字节。

技巧

在 MBR 的末端还有一个值为 0x55AA、大小为两个字节的扇区标记(Sector Marker)的签名字段。该字段通常还标注了扩展启动记录(EBR, Extended Boot Record)和启动扇区(boot sector)的结束。

如果安装了 boot0 和多个操作系统,启动时将显示类似以下消息:

参考文献

阶段 1 和阶段 2

从概念上讲,阶段 1 和阶段 2 是同一程序在同一磁盘区域上的组成部分。受限于空间,它们分为两个部分,但始终一起安装。

它们由 FreeBSD 安装程序从 /boot/boot 复制而来。

这两个阶段位于文件系统之外,在启动分区的第一个磁道中,从第一个扇区开始。这是 boot0 或其他引导管理器查找后续启动程序的位置。

阶段 1 的 boot1 因其 512 字节的大小限制而非常简单。它对 FreeBSD bsdlabel(存储分区信息)的了解仅足以找到并执行 boot2。

阶段 2 的 boot2 稍微复杂一些,它能够识别 FreeBSD 文件系统,找到其中的文件。它提供了简单的界面,用于选择要运行的内核或加载器。它运行 loader,后者更加复杂,能够读取引导配置文件。如果在阶段 2 中断启动过程,将显示以下交互式屏幕:

阶段 3(loader)

loader 是阶段 3 引导过程的最后阶段。它位于文件系统上,通常为 /boot/loader

loader 提供一种交互式配置方式,使用内置命令集,并辅以更强大的解释程序,该程序具备更复杂的命令集。自 FreeBSD 12.0 起,默认脚本解释器为 Lua(此前为 Forth),同时保留 Simple 解释器以支持纯内置命令。

初始化时,loader 将探测控制台和磁盘,并确定从哪块磁盘启动。它将相应地设置变量,并启动一个解释程序,用户可以通过脚本或交互方式传递命令。

随后 loader 读取 /boot/loader.rc,该文件默认读取 /boot/defaults/loader.conf(为变量设置合理的默认值)和 /boot/loader.conf(用于本地更改这些变量)。loader.rc 再根据这些变量加载选定的模块和内核。

最后,默认情况下,loader 等待用户按键 10 秒,若无中断则启动内核。若用户中断此过程,将看到支持命令集操作的提示符,用户可在其中调整变量、卸载所有模块、加载模块,随后启动或重启。

loader 常用内置命令如下:

命令
说明

autoboot seconds

在给定的时间跨度(秒)内如果没有被中断,则继续启动内核。它显示倒计时,默认时间跨度为 10 秒。

boot [-options] [kernelname]

立即启动内核,可以使用任何指定的选项或内核名称。

boot-conf

根据指定变量(最常用的是 kernel)重新进行自动模块配置。仅在先使用 unload 更改变量后此命令才有意义。

help [topic]

显示从 /boot/loader.help 读取的帮助消息。

include filename

读取指定文件并逐行解释。错误会立即中断文件的引入。

load [-t type] filename

加载内核、内核模块或给定类型的文件。

ls [-l] [path]

显示给定路径中的文件列表。

lsdev [-v]

列出所有可能加载模块的设备。

lsmod [-v]

显示已加载的模块。

more filename

显示指定文件,在每页暂停。

reboot

立即重启系统。

set variableset variable=value

设置指定的环境变量。

unload

移除所有已加载的模块。

以下是若干 loader 使用的实际示例。

以单用户模式启动常用内核:

卸载常用内核和模块,随后加载之前的内核或指定的其他内核:

使用 /boot/kernel/kernel 引用安装时附带的默认内核,或使用 /boot/kernel.old/kernel 引用系统升级或配置自定义内核之前安装的先前内核。

使用以下命令加载常用模块与另一个内核。注意此时无需指定模块的完整路径:

加载自动化内核配置脚本:

最后阶段

内核经 loader 或 boot2 加载后(boot2 可绕过 loader 直接加载内核),内核会检查启动标志并根据需要调整其行为。常用的启动标志如下:

选项
说明

-a

在内核初始化期间,询问要挂载为根文件系统的设备。

-C

从 CDROM 启动根文件系统。

-s

启动进入单用户模式。

-v

在内核启动期间输出更详细的信息。

有关其他启动标志的更多信息,请参阅 boot(8)。

内核完成启动后,将控制权传递给用户进程 init(8),该进程位于 /sbin/init,或 loader 中 init_path 变量指定的程序路径。这是启动过程的最后阶段。

启动序列确保系统中可用的文件系统是一致的。如果 UFS 文件系统不一致,并且 fsck 无法修复不一致之处,init 会将系统降级到单用户模式,以便系统管理员直接解决问题。如果文件系统正常,系统将启动进入多用户模式。

单用户模式

用户使用 -s 启动或在 loader 中设置 boot_single 变量,即可指定单用户模式。也可以在多用户模式下运行 shutdown now 进入单用户模式。进入单用户模式后将显示以下内容:

如果用户按回车键,系统将进入默认的 POSIX Shell。要指定不同的 Shell,请输入 Shell 的完整路径。

单用户模式通常用于修复因文件系统不一致或启动配置文件错误而无法启动的系统。它也可用于在不知道 root 密码时重置 root 密码。由于单用户模式提示符提供了对系统及其配置文件的完全本地访问,方能进行这些操作。此模式下没有网络。

虽然单用户模式对修复系统颇具实用价值,但除非系统位于物理安全的位置,否则将构成安全风险。默认情况下,任何能够获得系统物理访问权限的用户启动进入单用户模式后都将拥有系统的完全控制权。

多用户模式

如果 init 发现文件系统正常,或者用户在单用户模式下完成操作并输入 exit 离开单用户模式,则系统进入多用户模式,启动系统的资源配置。

资源配置系统从 /etc/defaults/rc.conf 文件读取默认配置,从 /etc/rc.conf 文件读取系统特定的配置。随后挂载 /etc/fstab 中列出的文件系统,并启动网络服务、系统守护进程,以及本地安装软件包的启动脚本。

有关资源配置系统的更多信息,请参阅 rc(8) 并检查 /etc/rc.d 目录中的脚本。

关机过程

使用 shutdown(8) 执行受控关机时,init(8) 将尝试运行脚本 /etc/rc.shutdown,此后向所有进程发送 TERM 信号,随后向任何未及时终止的进程发送 KILL 信号。

loader.conf 的功能定位与文件结构

loader.conf 是 FreeBSD 系统引导过程中的核心配置文件,参见 loader.conf(5)。该文件在引导加载程序 loader(8) 阶段读取,用于指定要启动的内核、传递给内核的参数以及需要加载的附加模块,同时可设置 loader(8) 支持的所有变量。

loader.conf(5) 相关的文件结构如下:

loader.conf 是系统启动配置的核心文件,位于 /boot/loader.conf。写入此处的配置比 rc.conf 文件更早生效,但不当配置可能会妨碍系统正常启动。

注意

不建议直接修改 /boot/defaults/loader.conf 文件。如需自定义配置,应使用 /boot/loader.conf 文件或 /boot/loader.conf.local 文件来扩展本地配置。其中 /boot/loader.conf.local 文件优先级最高,专门用于机器特定设置。

ZFS 标准安装场景下的 loader.conf 配置内容

ZFS 标准安装方案中,/boot/loader.conf 文件通常包含以下配置内容(以 15.0-RELEASE 为例):

该文件由 bsdinstall(8) 安装程序在系统安装过程中自动写入。具体而言,usr.sbin/bsdinstall/scripts/zfsboot 脚本会分别写入 kern.geom.label.disk_ident.enable="0"kern.geom.label.gptid.enable="0"zfs_enable="YES" 这三行配置。因此在使用 ZFS 标准安装方案的系统中,这三行即是 /boot/loader.conf 文件的全部初始内容。

默认配置文件的内容结构与说明

默认配置文件位于源代码中的 stand/defaults/loader.conf。以下内容基于版本 loader.conf.5: “console” setting does not document multi-value possiblity

配置引导选择界面的等待时间

引导选择界面的等待时间由 autoboot_delay 参数控制,该参数定义系统自动启动默认内核前等待用户干预的时间。

要调整等待时间,编辑 /boot/loader.conf 文件并新增以下条目:

参数说明:2 表示设置系统启动自动引导延迟为 2 秒。

精简启动输出信息

精简系统启动输出信息可从多个层面着手:引导器层面减少内核加载信息,服务启动阶段关闭状态提示,网络配置中优化等待逻辑。

如下图所示,设置后可看到 FreeBSD 启动 Logo。

FreeBSD 启动 Logo

参考文献

控制台屏幕保护程序的配置与应用

默认情况下,控制台驱动程序在屏幕空闲时不会执行任何特殊处理。若显示器需长时间保持开启并处于空闲状态,应启用屏幕保护程序以防止烧屏。

使用 bsdconfig 配置屏幕保护程序

可以通过 bsdconfig 工具配置屏幕保护程序:

执行命令后,将显示如下界面:

菜单
说明

1 None Disable the screensaver

1 无 禁用屏幕保护程序

2 Blank Blank screen

2 空白 显示空白屏幕

3 Beastie “BSD Daemon” animated screen saver (graphics)

3 Beastie “BSD Daemon”动画屏幕保护程序(图形)

4 Daemon “BSD Daemon” animated screen saver (text)

4 Daemon “BSD Daemon”动画屏幕保护程序(文字)

5 Dragon Dragon screensaver (graphics)

5 龙 动画屏幕保护程序(图形)

6 Fade Fade out effect screen saver

6 淡出 屏幕保护程序淡出效果

7 Fire Flames effect screen saver

7 火焰 火焰效果屏幕保护程序

8 Green “Green” power saving mode (if supported by monitor)

8 绿色“绿色”省电模式(如果显示器支持)

9 Logo FreeBSD “logo” animated screen saver (graphics)

9 标志 FreeBSD“logo”动画屏幕保护程序(图形)

a Rain Rain drops screen saver

a 雨滴 雨滴屏幕保护程序

b Snake Draw a FreeBSD “snake” on your screen

b 蛇 在屏幕上绘制 FreeBSD“蛇”

c Star A “twinkling stars” effect

c 星星 闪烁星星效果

d Warp A “stars warping” effect

d 扭曲 星星扭曲效果

Timeout Set the screen saver timeout interval

超时 设置屏幕保护程序超时时间

选择屏保样式:在主菜单中选择 7 Console,随后选择 5 Saver Configure the screen saver,此处选择 3 Beastie "BSD Daemon" animated screen saver (graphics)

设定屏幕超时时间:在主菜单中选择 7 Console,随后选择 5 Saver Configure the screen saver,再选择 Timeout Set the screen saver timeout interval,单位是秒。

手动写入配置

也可通过手动编辑配置文件以设置屏幕保护程序。编辑 /etc/rc.conf 文件,添加以下配置:

可选的屏幕保护程序模块如下:

可以自定义引导加载程序的 Logo 以定制系统启动界面。默认有以下几种 Logo 可选:

Logo 名称
说明

fbsdbw

FreeBSD 黑白 Logo

beastie

小恶魔彩色 Logo

beastiebw

小恶魔黑白 Logo

orb

UEFI 下彩色 Orb Logo

orbbw

默认黑白 Orb Logo

none

无 Logo

fbsdbw 为例,在 /boot/loader.conf 文件中写入:

重启后效果如下:

fbsdbw
beastie
beastiebw
orb
orbbw
none

参考文献

课后习题

  1. 修改 autoboot_delay 为 0 并启用 boot_mute,对比两次系统启动的输出差异,分析引导器在用户体验与调试需求之间的设计权衡。

  2. 查阅 /boot/loader.conf.d/ 目录的加载机制源代码,创建一个自定义配置文件并验证其与主配置文件的优先级关系,分析分散配置设计对系统管理的影响。

  3. 自定义一张 BMP 格式的启动 Logo,替代默认 Logo 并记录加载过程与格式要求。

最后更新于