3.2 安装双系统(后安装 FreeBSD)
本节以 FreeBSD-14.2-RELEASE-amd64-disc1.iso 为例,演示在已预装 Windows 11 24H2 的 UEFI 设备上追加安装 FreeBSD 双系统,重点处理 ESP 分区空间与引导管理。
技巧
本节示例要求先安装其他操作系统(如 Windows),再安装 FreeBSD,请遵循此操作顺序。
3.2.1 简单方法(无需众多数据集)
首先介绍一种相对简单的安装方法。
注意
按照本部分所述方法,使用 ZFS 时,只会创建一个存储池
zroot(zpool),并在其中创建一个直接挂载到 / 的数据集root。与自动安装不同,系统不会创建zroot/ROOT/default及众多数据集。可以在安装后创建数据集并替换,但若希望初始布局就与自动安装相同,请跳转至本节“Shell 分区”部分。
使用简单方法安装 FreeBSD,按照以下步骤操作。
首先需要在硬盘上为 FreeBSD 预留空间。因为在典型的 Windows 安装中,最后一个分区(本例为 nda0p4)通常是恢复分区,不适合用来安装系统,为 FreeBSD 预留的空间不一定位于硬盘末尾,中间位置亦可。
分区完成后,在 FreeBSD 下查看磁盘分区情况,结果如下:
# gpart show
=> 34 419430333 nda0 GPT (200G)
34 2014 - free - (1.0M)
2048 204800 1 efi (100M) # EFI 分区
206848 32768 2 ms-reserved (16M) # MSR 分区
239616 207992832 3 ms-basic-data (99G) # 此为 C 盘(NTFS 数据分区)。此处已为其后的 FreeBSD 预留了约 100G 空间。
417947648 1478656 4 ms-recovery (722M) # 恢复分区
419426304 4063 - free - (100G)应关闭安全启动和快速启动。安全启动会阻止未签名的引导加载程序运行,而 FreeBSD 的引导加载程序目前未被微软签名,因此必须关闭安全启动。快速启动会使 Windows 在关机时处于特殊的休眠状态,导致其他系统无法正常访问 NTFS 分区。也可通过 Windows 设置 → 更新与安全 → 恢复 → 高级启动,选择从 U 盘设备启动,随后正常引导 FreeBSD 安装程序,直至进入分区选择界面。

此处选择 Manual。
技巧
实际上此处调用的是软件
sade(sysadmins disk editor,系统管理员磁盘编辑器),bsdconfig中的分区模块亦调用此工具。
此处可查看硬盘分区情况。图中仅有一块硬盘,包含一个 300 MB 的 EFI 系统分区、一个 16 MB 的 MSR 分区、一个 64 GB 的 Windows 系统分区(即 C 盘)以及未显示的空闲空间。直接选择 Create(创建)。

此处在第一行输入分区类型(即下方会列出的 Filesystem type)。如需添加 swap 分区,请在此步骤首先添加,因为分区会从空闲空间的开头或结尾分配,后续添加则难以控制分区大小,先添加 swap 可以更好地控制其位置。添加 UFS 或 ZFS 分区时,需在 Mountpoint 处填写 /,表示将该分区挂载到根目录。Label 是 FreeBSD 的卷标(gptlabel),用于识别分区,可根据需要填写或留空。此处使用 ZFS,不添加 swap 分区,并且填入卷标 zroot。

使用 Tab 键 将焦点移动到 OK,然后按回车键确认。

此处会警告 ZFS 分区可能无法启动,但实际测试表明可以正常启动。这个警告是安装程序的通用提示,不适用于 UEFI 环境下的配置。选择 Yes 忽略此警告:

注意
请将 Windows 创建的 300 MB EFI 系统分区的挂载点设置为 /boot/efi,这样 FreeBSD 就能正确找到并使用已有的 EFI 分区,避免创建多个 EFI 分区带来的混乱。
选择 Finish(完成)

选择 Commit(确认)

之后会进入正常安装流程。安装完成后,列出系统中所有 ZFS 池及其状态:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
root 534M 130G 534M none进入系统后可以看到,仅有一个 root 数据集。可手动将数据集调整为自动安装的布局,也可以参照下文在安装时进入 Shell 进行分区。
3.2.2 Shell 分区
此时仍停留在分区选择界面,选择 Shell:

之后将进入终端(TTY):

执行以下命令。
3.2.2.1 加载 ZFS 内核模块
ZFS 支持并不在内核中,而是作为可加载模块提供。
默认的安装镜像可能未启用 ZFS,因此还需要加载 ZFS 内核模块:
# kldload zfs可通过 kldstat 验证模块是否已成功加载。
3.2.2.2 配置 ZFS 对齐方式(仅影响新创建的硬盘分区)
强制 ZFS 文件系统使用 4K 对齐,这样可以更好地适配现代硬盘的物理扇区大小,提高读写性能:
# sysctl vfs.zfs.vdev.min_auto_ashift=12
vfs.zfs.vdev.min_auto_ashift: 9 -> 12技巧
参数
12表示 2^12 = 4096 字节(4 KB)的扇区大小。默认参数(可通过命令sysctl vfs.zfs.vdev.min_auto_ashift查看)是9,即 2^9 = 512 字节,这是传统硬盘的扇区大小。
思考题
如果使用 NVMe 硬盘,新装系统(UEFI+GPT,无 freebsd-boot 分区)的默认参数通常为 12。但 4K 对齐究竟对齐的对象是什么?因为 SSD 并无传统机械硬盘的物理扇区概念。
3.2.2.3 创建交换分区
在 nda0 磁盘上创建 4 GB、4K 对齐的 FreeBSD 交换分区,并标记为 swap:
# gpart add -a 4k -l swap -s 4G -t freebsd-swap nda0选项说明:
-t指定类型-l指定卷标-s指定大小-a指定对齐
请注意根据实际情况替换 nda0 为实际硬盘编号。
3.2.2.4 创建 ZFS 分区
在 nda0 磁盘上创建 4K 对齐的 FreeBSD ZFS 分区,并标记为 zroot:
# gpart add -a 4k -l zroot -t freebsd-zfs nda0上面的设置将使用全部空余空间,请注意替换 nda0 为实际硬盘编号。
3.2.2.4.1 查看分区情况
显示系统磁盘分区情况:
# gpart show
=> 34 419430333 nda0 GPT (200G)
34 2014 - free - (1.0M)
2048 204800 1 efi (100M)
206848 32768 2 ms-reserved (16M)
239616 207992832 3 ms-basic-data (99G)
208232448 8388608 5 freebsd-swap (4.0G)
216621056 201326592 6 freebsd-zfs (96G)
417947648 1478656 4 ms-recovery (722M)
419426304 4063 - free - (2.0M)3.2.2.5 挂载临时文件系统准备安装
挂载一个临时文件系统(tmpfs),如此可在内存中临时存储安装过程中需要的文件,避免频繁写入磁盘:
# mount -t tmpfs tmpfs /mnt3.2.2.6 创建 ZFS 池
创建 ZFS 池 zroot:
# zpool create -f -o altroot=/mnt -O compress=lz4 -O atime=off -m none zroot /dev/gpt/zroot该命令将设置 zroot 池的挂载点为 /mnt,启用 LZ4 压缩以节省空间并提高读写性能,关闭访问时间记录以减少磁盘写入。
选项说明如下:
-o altroot=/mnt将其临时挂载至 /mnt;-O compress=lz4启用 lz4 压缩(可换为 zstd 等);-O atime=off关闭访问时间记录;-m none不设置挂载点;- /dev/gpt/zroot 为刚创建的分区。
可通过 zpool status zroot 验证池的健康状态。
3.2.2.7 创建 ZFS 数据集
以下数据集的设置参照 FreeBSD 源代码中的 usr.sbin/bsdinstall/scripts/zfsboot 创建。FreeBSD 本身持续演进,不同版本间的 ZFS 数据集也有所差异。读者创建数据集时若希望创建与默认安装相同的数据集结构,应参照对应分支的 usr.sbin/bsdinstall/scripts/zfsboot 文件。
- 创建根数据集
# zfs create -o mountpoint=none zroot/ROOT将创建数据集 zroot/ROOT,不设置挂载点(mountpoint=none)。
此类无具体挂载点的数据集通常作为系统根数据集的容器,其下将创建具体用于挂载的子数据集或起到排除作用。
- 创建默认根数据集
# zfs create -o mountpoint=/ zroot/ROOT/default将创建数据集 zroot/ROOT/default,将其挂载到根目录 /。此数据集将作为系统的默认根文件系统。
- 创建 /home 数据集
# zfs create -o mountpoint=/home zroot/home将创建数据集 zroot/home,并将其挂载到 /home,通常用于存储用户主目录。
- 创建 /tmp 数据集
# zfs create -o mountpoint=/tmp -o exec=on -o setuid=off zroot/tmp创建数据集 zroot/tmp,并将其挂载到 /tmp,允许执行文件(exec=on),但禁用 setuid(setuid=off)防止该目录中的文件使用 setuid 提升权限。
- 创建
zroot/usr数据集
# zfs create -o mountpoint=/usr -o canmount=off zroot/usr将创建 zroot/usr 数据集,设置 canmount=off 即禁止自动挂载,如此可将相关的子数据集组织在一起,但不会单独挂载这个父数据集。
- 创建 /usr/ports 数据集
# zfs create -o setuid=off zroot/usr/ports将创建 /usr/ports 数据集,禁用 setuid(setuid=off)。
- 创建 /usr/src 数据集
# zfs create zroot/usr/src将创建 /usr/src 数据集。
- 创建 /var 数据集
# zfs create -o mountpoint=/var -o canmount=off zroot/var将创建 /var 数据集,设置 canmount=off 意味着不会自动挂载。
- 创建 /var/audit 数据集
# zfs create -o exec=off -o setuid=off zroot/var/audit将创建 /var/audit 数据集,禁用执行(exec=off),同时禁用 setuid(setuid=off)。
- 创建 /var/crash 数据集
# zfs create -o exec=off -o setuid=off zroot/var/crash将创建 /var/crash 数据集,禁用执行(exec=off),同时禁用 setuid(setuid=off)。
- 创建 /var/log 数据集
# zfs create -o exec=off -o setuid=off zroot/var/log将创建 /var/log 数据集,禁用执行(exec=off),同时禁用 setuid(setuid=off)。
- 创建 /var/tmp 数据集
# zfs create -o setuid=off zroot/var/tmp将创建 /var/tmp 数据集,同时禁用 setuid(setuid=off)。
- 创建 /var/mail 数据集
# zfs create -o atime=on zroot/var/mail将创建 zroot/var/mail 数据集,并启用访问时间记录(atime=on),通常用于存放邮件数据,因为邮件程序可能需要知道文件的最后访问时间。
技巧
上述参数参考自 bsdinstall(8) 的默认配置。安装后,也可通过命令
zfs get exec,setuid,mountpoint查看相关属性。具体代码位于 usr.sbin/bsdinstall/scripts/zfsboot。
相关文件结构:
zroot/
├── ROOT/
│ └── default/ # 挂载到 /(根文件系统)
├── home/ # 挂载到 /home(用户主目录)
├── tmp/ # 挂载到 /tmp(临时文件)
├── usr/
│ ├── ports/ # 挂载到 /usr/ports(Ports 树)
│ └── src/ # 挂载到 /usr/src(系统源代码)
└── var/
├── audit/ # 挂载到 /var/audit(审计日志)
├── crash/ # 挂载到 /var/crash(系统崩溃转储)
├── log/ # 挂载到 /var/log(系统日志)
├── mail/ # 挂载到 /var/mail(邮件存储)
└── tmp/ # 挂载到 /var/tmp(持久化临时文件)3.2.2.8 修改文件夹权限
将 /mnt/tmp 和 /mnt/var/tmp 的权限设置为 1777(粘滞位),以确保临时目录权限正确,这样任何用户都可以在这些目录中创建文件,但只能删除自己创建的文件:
# chmod 1777 /mnt/tmp # 设置 /mnt/tmp 目录为粘滞位,可读写
# chmod 1777 /mnt/var/tmp # 设置 /mnt/var/tmp 目录为粘滞位,可读写3.2.2.9 配置交换分区到 fstab
将交换分区 /dev/nda0p5 添加到临时的 fstab 文件,如此系统启动时即可自动挂载这个交换分区:
# printf "/dev/nda0p5\tnone\tswap\tsw\t0\t0\n" >> /tmp/bsdinstall_etc/fstab注意将 /dev/nda0p5 替换为实际的交换分区设备名,可使用 gpart show nda0 命令确认。
技巧
\t是制表符(Tab)的转义字符(意味着按一下 Tab 键),用于对齐字段,使用空格也可以达到相同效果。也可使用ee /tmp/bsdinstall_etc/fstab命令手动编辑该文件并写入如下格式的行:sh/dev/nda0p5 none swap sw 0 0下同。
3.2.2.10 设置启动项与 UEFI
- 设置 ZFS 池的引导文件系统(bootfs)为
zroot/ROOT/default,如此系统启动时会自动从这个数据集引导:
# zpool set bootfs=zroot/ROOT/default zroot- 要求系统在启动时启用 ZFS 服务。
# printf 'zfs_enable="YES"\n' >> /tmp/bsdinstall_etc/rc.conf\n 代表 Unix/Linux 系统中的换行符。
Windows 文本文件的行尾通常是 \r\n(回车 + 换行)。
此命令效果等同于使用 ee /tmp/bsdinstall_etc/rc.conf 编辑该文件并添加一行 zfs_enable="YES"。
- 挂载现有的 EFI 系统分区,以便在其中添加 FreeBSD 的启动文件:
# mount -t msdosfs /dev/nda0p1 /media注意将 /dev/nda0p1 替换为实际的 EFI 分区设备名。
- 在 EFI 系统分区中为 FreeBSD 创建启动目录
# mkdir -p /media/efi/freebsd- 将 FreeBSD 的 EFI 启动文件复制到启动目录
# cp /boot/loader.efi /media/efi/freebsd/- 使用
efibootmgr工具向主板 UEFI 固件添加启动项FreeBSD,这样开机时便能在 UEFI 启动菜单中看到 FreeBSD 选项。
# efibootmgr --create --activate --label "FreeBSD" --loader "/media/efi/freebsd/loader.efi"- 卸载 EFI 系统分区
# umount /media目录结构:
/
├── boot/
│ └── loader.efi # FreeBSD EFI 引导加载程序
├── tmp/
│ └── bsdinstall_etc/
│ ├── fstab # 临时 fstab 配置
│ └── rc.conf # 临时 rc.conf 配置
└── media/
└── efi/
└── freebsd/
└── loader.efi # 复制到 EFI 分区的引导加载程序- 退出 Shell
# exit安装程序将自动继续后续流程。
3.2.2.11 完成
至此,已手动创建了一套与自动安装程序基本相同的 ZFS 数据集结构(自动安装通常还会创建独立的 /home/用户名 数据集,此处未包含)。
显示安装后系统的 ZFS 文件系统状态:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
zroot 921M 91.6G 96K none
zroot/ROOT 919M 91.6G 96K none
zroot/ROOT/default 919M 91.6G 919M /
zroot/home 128K 91.6G 128K /home
zroot/tmp 104K 91.6G 104K /tmp
zroot/usr 288K 91.6G 96K /usr
zroot/usr/ports 96K 91.6G 96K /usr/ports
zroot/usr/src 96K 91.6G 96K /usr/src
zroot/var 636K 91.6G 96K /var
zroot/var/audit 96K 91.6G 96K /var/audit
zroot/var/crash 96K 91.6G 96K /var/crash
zroot/var/log 156K 91.6G 156K /var/log
zroot/var/mail 96K 91.6G 96K /var/mail
zroot/var/tmp 96K 91.6G 96K /var/tmp3.2.3 参考文献
- Stanislas. How to manually install FreeBSD on a remote server (with UFS, ZFS, encryption...)[EB/OL]. (2018-12)[2026-03-26]. https://stanislas.blog/2018/12/how-to-install-freebsd-server/. 提供了 FreeBSD 手动安装的完整技术指南,包括 UFS、ZFS 等文件系统配置方法。
- FreeBSD Project. RootOnZFS/GPTZFSBoot[EB/OL]. [2026-03-26]. https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot. 详细介绍了 FreeBSD 在 GPT 分区表上的 ZFS 根文件系统配置方法。
- FreeBSD Project. bsdinstall(8) -- system installer[EB/OL]. [2026-04-17]. https://man.freebsd.org/cgi/man.cgi?query=bsdinstall&sektion=8. FreeBSD 系统安装程序手册页。