# FreeBSD 从入门到跑路

![🎉 欢迎来到 BSD 的世界！](/files/A5vGDHB7aIVlwrFBdyyW)

🎉 欢迎来到 BSD（Berkeley Software Distribution, 伯克利软件**发行版**）的世界！！！

FreeBSD 项目赓续了计算机系统研究小组（Computer Systems Research Group, CSRG）的未竟事业。FreeBSD 是一款真正自由（Liberty）的 **操作系统**，在这云谲波诡的世界中仍然坚守 BSD UNIX 哲学——**恪守古老的法则，追寻真正的自由**。

## 内容提要

本书是一本关于 FreeBSD 操作系统的开源研究著作。

[~~FreeBSD 项目即将归档（Archived）~~，为了保护我们心爱的操作系统……我们能做的事情就是，写一本书！](https://www.bilibili.com/bangumi/media/md3068)（化用 Love Live! School Idol Project\[Z]. 日本: SUNRISE, 2013-01-06. 中的经典口号）

“入门”本是一种快乐，“跑路”亦是一种豁达。“本乘兴而行，兴尽而反，何必 FreeBSD 邪！”（化用晋书·王羲之传附王徽之传\[M]//房玄龄.晋书.北京:中华书局,1996）

> **注意**
>
> 现在为你呈现的是第四版（开发版本），已有章节虽经审阅和修订，但仍非最终版本。开发版本的章节结构并不稳定，**不建议**将任何章、节添加为书签，可能很快便会失效。

## 关于 FreeBSD 中文社区

![微信公众号](/files/yp8xx1l75lWRUX9L4mWG)

微信公众号：bsdcn2018

* FreeBSD 中文社区主要联系方式为 QQ 群：[787969044](https://qm.qq.com/q/cX5mpJ36gg)

![FreeBSD 中文社区 QQ 群](/files/uMCsOy4saO4vpnfMvtyY)

* 微信群：受微信平台限制，需先加入 QQ 群，再联系群主获取新鲜的入群二维码。
* Discord：<https://discord.gg/j7VhWrhp3e>（需代理，可通过网页端访问）
* Telegram 群组：<https://t.me/oh_my_BSD>（需代理）

## 电子文档

本书提供 PDF 和 EPUB 两种格式的电子文档：

* PDF（适用于印刷及桌面端离线阅读）下载地址：<https://docs.bsdcn.org/bsdbook.pdf> ![PDF 文件状态](https://img.shields.io/website?url=https%3A%2F%2Fdocs.bsdcn.org%2Fbsdbook.pdf\&up_message=%E6%96%87%E4%BB%B6%E5%8F%AF%E7%94%A8\&down_message=%E6%96%87%E4%BB%B6%E4%B8%8D%E5%8F%AF%E7%94%A8\&style=for-the-badge\&label=%E6%96%87%E6%A1%A3%E7%8A%B6%E6%80%81)
* EPUB（适用于移动端离线阅读）下载地址：<https://docs.bsdcn.org/bsdbook.epub> ![EPUB 文件状态](https://img.shields.io/website?url=https%3A%2F%2Fdocs.bsdcn.org%2Fbsdbook.epub\&up_message=%E6%96%87%E4%BB%B6%E5%8F%AF%E7%94%A8\&down_message=%E6%96%87%E4%BB%B6%E4%B8%8D%E5%8F%AF%E7%94%A8\&style=for-the-badge\&label=%E6%96%87%E6%A1%A3%E7%8A%B6%E6%80%81)

电子文档内容与网页版实时同步，随 Git 提交更新，文件名保持不变。

移动端建议使用 [微信读书](https://play.google.com/store/apps/details?id=com.tencent.weread\&hl=zh) 阅读 EPUB 文档，桌面端建议使用 [CAJViewer 9](https://cajviewer.cnki.net/download.html)。

电子书由 [safreya](https://github.com/safreya) 开发的 [GitBook PDF/EPUB 导出工具](https://github.com/FreeBSD-Ask/gitbook-pdf-export) 提供支持，该工具可将 GitBook 项目转换为 PDF 和 EPUB 格式的文档。

## 部署地址

本书通过三个子域名提供访问服务，各域名使用不同网站架构：

* <https://book.bsdcn.org>
* <https://docs.bsdcn.org>
* <https://doc.bsdcn.org>（境内访问速度较佳）

FreeBSD 中文社区未通过其他域名部署本书，唯一官方域名为 `bsdcn.org`。

## 意见反馈

受编者水平所限，书中难免存在疏漏与错误。

如遇内容问题或网站技术问题，请发送邮件至 ykla <yklaxds@gmail.com>。关于内容问题，也可以通过 GitHub 提交 PR，入口位于桌面端网页当前页面的右下角或底部左下角。

FreeBSD 中文社区相关问题，请加入 QQ 群后联系群主。

请确保您遵循 [FreeBSD 中文社区行为规范（CoC）](https://docs.bsdcn.org/CODE_OF_CONDUCT)。

留言功能需使用 GitHub 账户登录，评论将公开至 GitHub 存储库 [Handbook-giscus-discussions](https://github.com/FreeBSD-Ask/Handbook-giscus-discussions) 的 Discussions 板块，可前往该位置管理历史留言。

## 目标与方向

在既有基础上逐步实现中文社区的《FreeBSD 操作系统设计与实现》。

## 捐赠

请优先考虑向 FreeBSD 基金会捐赠。

![捐赠 FreeBSD 基金会](/files/I7mxWpSZ6B8K44aBrtMO)

[前往捐赠 FreeBSD 基金会](https://freebsdfoundation.org/donate-to-freebsd-foundation/)

支付方式支持：万事达品牌借记卡、VISA 信用卡（可通过 Amazon Pay 或 Google Pay）。

Microsoft Rewards 是微软必应搜索提供的积分计划。可通过 Microsoft Rewards 积分 [捐赠 FreeBSD 基金会](https://rewards.bing.com/redeem/000999036000?causeId=840-841545163&\&PC=EMMX01)。同方式也可以 [捐赠 NetBSD 基金会](https://rewards.bing.com/redeem/000999036000?causeId=840-134134071\&PC=EMMX01)。

## 贡献者

![贡献者](https://contrib.nn.ci/api?no_bot=true\&repo=FreeBSD-Ask/FreeBSD-Ask)

## 授权协议与法律声明

本书部分内容参考、翻译或改写自 FreeBSD 文档项目，原著版权归属于 The FreeBSD Project。许可证如下：

```
Copyright 1994-2026 The FreeBSD Project.

Redistribution and use in source (AsciiDoc) and 'compiled' forms (HTML, PDF,
EPUB and so forth) with or without modification, are permitted provided that
the following conditions are met:

1. Redistributions of source code (AsciiDoc) must retain the above copyright
   notice, this list of conditions and the following disclaimer as the first
   lines of this file unmodified.

2. Redistributions in compiled form (converted to PDF, EPUB and other formats)
   must reproduce the above copyright notice, this list of conditions and the
   following disclaimer in the documentation and/or other materials provided
   with the distribution.

THIS DOCUMENTATION IS PROVIDED BY THE FREEBSD DOCUMENTATION PROJECT "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE FREEBSD DOCUMENTATION PROJECT BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

作为项目目标的一部分，我们将尽快完整重写此部分直接转引自手册的内容。

除特别注明外，本书中的文字、图表等内容依据 [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) 协议发布。您无需精确标注章节出处，仅标注项目主页即可。

[![License: CC BY 4.0](https://img.shields.io/badge/License-CC_BY_4.0-orange.svg)](https://creativecommons.org/licenses/by/4.0/)

书中所有代码示例依据 [BSD 2 条款许可](https://opensource.org/license/bsd-2-clause) 发布。

[![License: BSD 2 Clause](https://img.shields.io/badge/License-BSD--2--Clause-EB0028.svg)](https://opensource.org/license/bsd-2-clause)

本作品引用的第三方商标、服务标志、商品外观及版权材料，其相关权利均由各自权利人持有。前述引用仅为说明、评论或教学之目的。

如认为本作品存在侵权情形，请通过电子邮件 ykla <yklaxds@gmail.com> 联系。

## 项目历史

《FreeBSD 从入门到跑路》始于 2021 年 3 月 14 日，其原型可追溯至 ykla 于 2020 年 12 月 31 日发表的文章《FreeBSD 艺术科学哲学导论》。

## 统计信息

自 2022 年 6 月 1 日以降，本书的访问情况如下：

| 指标     | 统计数据      |
| ------ | --------- |
| 用户总数   | 72,134 位  |
| 会话数    | 123,963 次 |
| 浏览次数   | 697,914 次 |
| 平均会话时长 | 7 分 4 秒   |

![总用户数](https://img.shields.io/badge/%E6%80%BB%E7%94%A8%E6%88%B7%E6%95%B0-72,134-green) ![会话数](https://img.shields.io/badge/%E4%BC%9A%E8%AF%9D%E6%95%B0-123,963-orange) ![浏览次数](https://img.shields.io/badge/%E6%B5%8F%E8%A7%88%E6%AC%A1%E6%95%B0-697,914-blue) ![平均会话时长](https://img.shields.io/badge/%E5%B9%B3%E5%9D%87%E4%BC%9A%E8%AF%9D%E6%97%B6%E9%95%BF-7min4s-purple)

以上统计信息由 [Google Analytics](https://analytics.google.com/) 提供。

***

![GitHub 存储库状态图](https://repobeats.axiom.co/api/embed/0268f0741b1257dd58a7489442bd7829d2670313.svg)

以上图表由 [Repobeats analytics image](https://repobeats.axiom.co/) 提供。

***

文档总字数：95.92 万字；

统计时间：2026-08-09 14:00:47（北京时间）

与上周相比：+653 字（+0.07%）

与上月相比：+3461 字（+0.36%）

## ⭐ 图

[<picture><source srcset="https://api.star-history.com/chart?repos=FreeBSD-Ask/FreeBSD-Ask&#x26;type=date&#x26;theme=dark&#x26;legend=top-left&#x26;sealed_token=m4veCu3-50Wb7qK0-YeYJKjFj34xrgYZkPf5Ulj9xhD2JSvGokY40UGIvabwLZLyZcLpfUDO9Fofznig3228xRTTln79uKGwBIB-9imIqabfi3cmwINO0A" media="(prefers-color-scheme: dark)"><img src="https://api.star-history.com/chart?repos=FreeBSD-Ask/FreeBSD-Ask&#x26;type=date&#x26;legend=top-left&#x26;sealed_token=m4veCu3-50Wb7qK0-YeYJKjFj34xrgYZkPf5Ulj9xhD2JSvGokY40UGIvabwLZLyZcLpfUDO9Fofznig3228xRTTln79uKGwBIB-9imIqabfi3cmwINO0A" alt="⭐ 图"></picture>](https://www.star-history.com/?repos=FreeBSD-Ask%2FFreeBSD-Ask\&type=date\&legend=top-left)

若本书对您有所帮助，欢迎为 [GitHub 项目存储库](https://github.com/FreeBSD-Ask/FreeBSD-Ask) 加星标 ⭐。


# 编辑日志

## 2026 年第三季度

* 2026.8.15
  * <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296052> 修复 KDE 6 Wayland 无法登录的 Bug
* 2026.7.2
  * 格式清理（空格、大小写统一、统一格式）

## 2026 年第二季度

* 2026.6.27
  * 目录结构调整
* 2026.6.25
  * 从迁移指南中拆分出“第 3 章 BSD 文化与 BSD 发行版概论”
* 2026.6.24
  * X11 的归 X11、Wayland 的归 Wayland
  * 为全书增补 Mermaid 图
* 2026.6.22
  * “10.2 KDE 6 桌面环境（Wayland 会话）”新增“通过 Ly 启动桌面”
  * 使用 Port **www/code-server** 重新整理“22.1 code-server 和 clangd 开发环境”

***

* 2025.4.21-2026.6.22
  * 《FreeBSD 从入门到跑路》第三版完成（TAG 2026.6.22）

***

* 2026.6.14
  * 更新“5.5 基于 Apple M1 和 VMware Fusion Pro 安装 FreeBSD”到 VMware Fusion Pro 26H1
  * 更新“5.4 基于 Apple M1 和 Parallels Desktop 安装 FreeBSD”到 Parallels Desktop 26.3.3
* 2026.6.13
  * 全面调整章节结构
* 2026.6.12
  * “16.8 OpenSSH”中的“SSH 和 SCP 客户端”移动到“5.1 Windows 用户迁移指南”
  * “26.1 数据库概论”增补 PostgreSQL 对应语法，由自动程序测试通过所有语法
  * “22.2-22.4”由自动程序测试通过所有语法
  * “16.8 OpenSSH”新增“tmux”
  * 从“7.3 使用 PkgBase 更新 FreeBSD”拆分出“7.3 使用 PkgBase 转换基本系统”“7.4 使用 ZFS 启动环境更新 FreeBSD”“20.7 更新 OpenZFS 版本”
* 2026.6.11
  * 使全书符合最佳实践，标记不符合生产环境的行为
  * 废除冗余的 A/B 组 shell，环境变量一律改用用户分级方法
  * “27.4 vsftpd”：使用基本系统内置的 openssl 取代 apache24
  * 完全重写并从手册增补更新：“28.3 网络文件系统（NFS）”
* 2026.6.10
  * “14.1 Godot 开源游戏引擎”新增“项目演示”
  * “28.2 Samba 文件共享”更新到 samba4.23
  * 更新“3.1 安装前的准备工作”
* 2026.6.9
  * 从“14.3 我的世界（Minecraft）”拆分出“14.2 我的世界（Minecraft）服务器”
  * “16.13 NTP 时间同步与时区”：增补“NTP 配置文件”
  * 把若干列表适当地转换为表格便于阅读
  * 新增“14.5 R 语言”
  * 从手册增补更新“8.2 基础网络管理”，新增“别名地址”
  * 从手册增补更新“8.8 网桥”
  * 从手册增补更新“8.9 链路聚合与故障转移”，注意：示例 1. 使用交换机进行 LACP 聚合无法测试，需要交换机支持。后续再重写。
  * 从手册增补更新“8.10 VLAN”，后续再重写
* 2026.6.8
  * “16.13 NTP 时间同步与时区”删除“Cron 任务中的时区”，内容不正确。FreeBSD 的 Cron 不支持此项，这是 Linux 才有的变量。
* 2026.6.7
  * 删除“14.5 科研和专业计算”中直接引用的维基百科等内容
  * 删除“7.1 系统更新检测”，对于 KDE 无用，且不具有实际价值
* 2026.6.5
  * 移除“4.5 基于 Apple M1 和 UTM 安装 FreeBSD”。
    * 参见 <https://reviews.freebsd.org/D55012> 和 [Bug 283646 - x11-drivers/xf86-video-scfb: startx fails: (EE) scfb(0): scfb\_mmap: Invalid argument](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=283646)
  * 删除“14.1 Ren'Py 视觉小说引擎”，Port 已经被移除，且实用性不强，类似游戏较少，且目前的例子（心跳文学社！）不合适
    * 提交 [Bug 295539 games/renpy: Maybe need update to 8.x.y not deprecate](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295539)
* 2026.6.4
  * 完全重写“13.5 Slackware Linux 兼容层”
  * 新增“23.2 厚 Jail（Thick Jail）”
* 2026.6.3
  * 完全重写：“13.3 Ubuntu/Debian 兼容层”，更新到 Ubuntu 26.04 LTS、Debian 13
  * 新增 Kali Linux 兼容层
  * 删除“13.6 openSUSE 兼容层”，因为全面启用了 SELinux，不被支持
  * 完全重写：“13.6 Gentoo Linux 兼容层”，更新到 2026.6.1 版本（自动构建）
* 2026.6.2
  * “13.2 Rocky Linux 兼容层”：完全重写“通过 Shell 脚本安装 Rocky Linux 10 兼容层”，现在直接引用 WSL 兼容层
* 2026.6.1
  * 新增章节“第 7 章 FreeBSD 系统更新”，拆分自其他章节
  * 提交 [Port lang/python version display incorrect, should use Mk/bsd.default-versions.mk #659](https://github.com/FreshPorts/freshports/issues/659)
* 2026.5.31
  * 通过手册增补更新“19.8 ZFS 调优”
  * 通过手册增补更新“10.7 文档查看器”
* 2026.5.30
  * 第 16 章“存储与文件系统管理”改名为“存储管理”
  * “17.1 Windows 文件系统”：完全重写“NTFS 文件系统”
  * 第 16 章新增章节：USB 存储设备、虚拟内存盘
  * 拆分“16.1 UFS 文件系统”到第 18 章“UFS 文件系统”（新增18.2 添加 UFS 磁盘）
  * 拆分“18.11 加密磁盘分区”
  * 新增第 17 章“其他文件系统”，由第 16 章“存储与文件系统管理”拆分而来
* 2026.5.29
  * 新增“加密磁盘分区”
  * “9.8 LXDE”作为附录合并到“9.6 LXQt”
  * 新增“11.2 特定语言的区域配置”
  * 完全重写：“20.1 Jail 基础”（使用手册增补更新）
  * 完全重写：“16.3 Linux 文件系统”中的“EXT 系列文件系统”
  * “16.4 Windows 文件系统”新增“exFAT 文件系统”
  * 新增“16.5 macOS 文件系统”
* 2026.5.28
  * 从“12.8 Linux Jail”拆分出第 21 章 Linux Jail
  * 新增 10.8 摄像头
  * 删除 20.2 Jail 系统更新，待重写
* 2026.5.26
  * 近 2 个月从 FreeBSD 合并了一些内容，标志着本书基本成为 Handbook 的超集。可以说，目前 Handbook 已经完全失去价值。
* 2026.5.25
  * 更新“11.11 WPS Office（Linux 版）”中的“基于 Rocky Linux 兼容层（FreeBSD Port）”
  * “27.4 Python 开发环境”新增“通过 uv 管理 Python”
  * 从“1.4 FreeBSD 导论”拆分出第二章 FreeBSD 导论和“1.4 什么是 FreeBSD”
* 2026.5.24
  * 更新“6.1 基础网络”中的“通过 ifconfig 命令识别网络适配器”
  * 更新“21.4 MySQL”到 MySQL 8.4
  * 提交 [Bug 295539 - games/renpy: Maybe need update to 8.x.y not deprecate](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295539)
  * 提交 [Bug 295538 - java/intellij-ultimate: Please move it to java/intellij](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295538)
  * 完全重写：“27.2 Java 开发环境”
  * 完全重写：“27.3 Qt 开发环境”
  * 完整重写：“27.5 Rust 开发环境”
  * 更新“27.6 Go 开发环境”
  * 更新“27.7 Node.js 开发环境”
  * 更新“27.10 使用 IDA Pro 调试 FreeBSD”到 IDA Pro 9.3
  * 将“通用嵌入式开发环境”拆分为“STM32 开发环境”“乐鑫（Espressif）开发环境”“Arduino 开发环境”
  * 重写“26.7 STM32 开发环境”中的“安装 STM32CubeMX”
  * 完整重写：“26.9 Arduino 开发环境”
  * 提交 [Bug 295543 - devel/arduino18 not work with openjdk25 but work on openjdk8](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295543)
  * 更新：“2.5 使用 Hyper-V 安装 FreeBSD”
* 2026.5.23
  * 删除“8.10 Hyprland”，无法复现，缺乏文档维护
  * 完全重写：“2.4 使用 VirtualBox 安装 FreeBSD”
* 2026.5.22
  * 从“23.1 FTP 服务器”拆分出第 22 章：文件传输协议（FTP）
  * 删除“21.4 MySQL 5.x 系列”，过时且不可用
  * 独立“27.6 Go 开发环境”
  * 使用手册增补更新“20.4 在 FreeBSD 上安装 VirtualBox”
* 2026.5.21
  * 从“16.1 ZFS 历史与现实”拆分出“16.2 ZFS 特性和术语”
  * 新增“17.1 信息安全概述”
  * 更正“17.7 OpenSSL”
* 2026.5.20
  * 新增“4.3 macOS 用户迁移指南”
* 2026.5.19
  * 非理论章节删除课后习题
  * “1.5 乔治·贝克莱（George Berkeley）与 BSD 的命名渊源”与“1.6 加州大学伯克利分校与“要有光”（Fiat Lux）”合并为“1.5 乔治·贝克莱（George Berkeley）与 BSD 文化传统”
  * 新增“1.6 其他 BSD 发行版概述”
* 2026.5.18
  * 删除：8.9 bspwm，原因：无法复现，存在逻辑错误
  * 如果 CDE 维护者未在 2027 年 1 月前接纳中文补丁，将移除 CDE。参见 [#2157](https://github.com/FreeBSD-Ask/FreeBSD-Ask/pull/2157)。
* 2026.5.17
  * 新增：“14.11 系统日志管理”
* 2026.5.16
  * 审核全书 Port 是否有效清理失效软件
* 2026.5.15
  * 增补重写：“11.1 Linux 兼容层架构”
  * 通过参考文献和 FreeBSD man 对全书进行事实核查
  * 进一步去欧化汉语
* 2026.5.13
  * 增补重写：“第 16 章 ZFS”
* 2026.5.11
  * 新增：“13.1 人工智能概述”
  * 新增：“13.2 大模型本地部署”
* 2026.5.10
  * 从“7.2 Intel 和 AMD 显卡驱动配置”拆分出“7.1 显卡驱动概述”“7.3 AMD 显卡驱动”
  * 依据手册结构重组第 16 章
* 2026.5.8
  * 增补重写：“17.6 blocklistd”，大部分功能测试通过
  * 原“6.2 TCP/IP 协议栈”重命名为“6.2 高级网络管理”
  * 增补重写：“6.2 高级网络管理”
  * 格式化全文，使之书面化
  * “4.6 shell 配置”合并入“4.5 shell 基础”
* 2026.5.6
  * 增补重写：“9.1 ZFS 历史与现实”
  * 增补重写：“5.3 管理 FreeBSD 中的服务”
  * 增补重写：“5.9 Cron 和 Periodic”
  * 增补重写：“5.10 sysctl 工具”
  * 增补重写：“14.2 声卡配置”
  * 增补重写：“5.11 NTP 时间同步与时区”
  * 增补重写：“5.8 设备资源提示文件（device.hints）”
  * 增补重写：“19.4 Samba 文件共享”
  * 将附录 1 两篇附录还原至原有路径
  * 审阅全书汉语欧化现象
  * 新增：“17.1 防火墙概述”
* 2026.5.3
  * 新增：“18.2 资源限制”
  * 新增：“18.3 安全等级”
  * 新增：“18.4 安全事件审计”
  * 新增：“18.5 OpenSSL”
  * 新增：“18.6 入侵检测系统（IDS）”
  * 新增：“18.7 第三方漏洞与安全公告”
  * 完全重写：“4.3 系统目录结构”
  * 新增：“27.7 构建定制内核”
  * 新增：“24.10 DTrace”
  * “8.1 UFS 文件系统”新增“UFS 文件系统快照”“UFS 文件系统磁盘配额”
  * 增补重写：“5.6 OpenSSH”
  * 增补重写：“权限提升工具（sudo、doas 等）”
  * 新增“18.1 账户认证安全”
* 2026.4.30
  * 新增：18.6 零配置网络（mDNS/DNS-SD）
* 2026.4.28
  * 使用手册增补 5-7 章
* 2026.4.27
  * 使用手册增补前言、1-4 章
  * 更新 7.3 Clash for FreeBSD
* 2026.4.23
  * 独立“UEFI/BIOS 注解（AMI BIOS）”
  * 独立非 FreeBSD 的其他 BSD 章节
  * 移除与 FreeBSD 无关的文学故事
* 2026.4.21
  * 调整全书结构，使之自下而上。去手册化、博客化
* 2026.4.20
  * 对查重有问题的计算机网络、防火墙中部分小节予以删除
  * 拆分附录 Ⅰ 关系型数据库基础到 19.4 MySQL 8.x 系列
  * 拆分附录 Ⅰ 计算机网络到 14.1 网络基础配置
  * 独立附录 Ⅰ 计算机系统结构中的“microSD 卡参数简介”
  * 附录 Ⅰ 计算机系统结构中的其他内容予以删除
  * 其他附录目次依次递减
* 2026.4.19
  * 审阅全书术语、错别字
  * 增补全书参考文献
  * 核查全书事实
* 2026.4.8
  * 删除赘余的人称和表达
  * 润色以符合出版物要求
* 2026.4.5
  * 格式化全书
* 2026.4.3
  * 规范全书参考文献
* 2026.4.1
  * 校对全书

## 2026 年第一季度

* 2026.3.31
  * 校对 1.1-8.6 节
* 2026.3.29
  * 删除“21.5 Deepin 兼容层”，已经失效且难以增补
  * 审阅全书在线的参考文献，确保其可访问性
  * 根据术语在线 <https://www.termonline.cn/> 平台审定全书术语
* 2026.3.28
  * 标准化全书的参考文献
  * 标准化全书的图片描述部分
  * 消除 markdownlint 报错，使 markdown 标准化
* 2026.3.24
  * 进一步审阅全书
* 2026.3.22
  * 为全书补全目录结构图
* 2026.3.21
  * 为所有参考资料作注解
  * 为全书增补课后习题
* 2026.3.19
  * 全面修订所有章节，旨在靠近专业出版物
* 2026.3.18
  * 全面修订第 1 章，旨在靠近专业出版物
* 2026.3.11
  * 将“13.1 启动引导器及配置文件（loader.conf）”中“TTY 中文控制台”移动到“8.7 系统字体替换”
  * 截至今天，本书导出的 PDF 文档为 2026 页
* 2026.3.10
  * “13.1 启动引导器及配置文件（loader.conf）”新增“loader.conf 系统启动配置信息”
  * 新增“13.8 设备资源提示文件（device.hints）”
  * “13.2 管理 FreeBSD 中的服务”易名为“13.2 init.rc 服务”，非 rc 服务部分拆分到下面章节
  * “13.2 init.rc 服务”：完全重写
  * 新增“13.9 crontab 及定时任务文件（periodic.conf）”
  * 新增“13.10 内核状态默认配置文件（sysctl.conf）”
* 2026.3.9
  * “4.10 系统目录结构”合并入“4.1 Windows 用户迁移指南”，内容重合
  * “13.4 SSH 配置和相关工具”新增“附录：OpenSSH 服务端配置详解”
* 2026.3.8
  * 新增“18.5 嵌入式开发”
* 2026.3.3
  * 删除《16.2 MinIO 对象存储服务》，原因：由于上游不再维护，将其从 Ports 删除
* 2026.3.2
  * 将“22.4 LLVM / Clang 概述”合并入“22.15 在 FreeBSD 上开发 C/C++”，成为“22.4 在 FreeBSD 上开发 C/C++”
  * 将“22.2 如何开发一个 Port”“22.14 利用脚本自动生成 BSD libc 库文本”合并入“22.3 如何参与 FreeBSD 开发”
  * 将“20.1 Ren’Py 和 Godot 游戏引擎”拆分为“20.1 Ren’Py 视觉小说引擎”“20.2 Godot 开源游戏引擎”
  * 将“18.1 树莓派简介（Raspberry Pi）”合并入“18.2 配置树莓派中 FreeBSD”
  * 将“1.1 操作系统的历程与开源往事”拆分为“1.1 什么是 UNIX？”“1.2 GNU 操作系统和自由软件运动”和“1.3 Linux 与类 UNIX”
  * 更新“绪论”
  * 全面调整章节结构
* 2026.3.1
  * 新增“22.15 在 FreeBSD 上开发 C/C++”
  * “4.6 文本编辑器”新增“Emacs 编辑器、Vim”
  * 将“22.7 Python 和 VS Code”中的 VS Code 章节拆分至“22.15 在 FreeBSD 上开发 C/C++”
* 2026.2.28
  * 新增“3.13 基于 Apple M1 和 UTM 安装 FreeBSD”
  * “20.2 我的世界（Minecraft）”新增“Prism Launcher 启动器”
  * 将“5.3 gitup 的用法”作删除处理。原因：缺乏实质性维护近 2 年。
  * 删除“21.5 基于 archlinux-pacman 的 Arch Linux 兼容层（拟删除）”。原因：存在 Bug 287690 [sysutils/pacman: The archlinux flavor cannot be built or installed.](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287690) 无法得到解决
  * 删除“6.10 Budgie（拟删除）”，原因：欠缺维护，存在 [Bug 289898 x11/budgie: After logging in with LightDM, it crashes and then shows a black screen](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289898) 无法得到解决
  * 将“附录：登录界面主题”从“6.3 KDE 6（X11 会话）”彻底删除，因为软件源中仅存在 Port x11-themes/sddm-freebsd-black-theme，且无人维护，存在 [x11-themes/sddm-freebsd-black-theme incompatible with SDDM 0.21.0 (Qt6 greeter)](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=293449) 的问题无法得到解决
  * 注意到 Lumina 实际上不存在任何维护者，且长期未更新，删除。
  * 删除“7.5 Window Maker”，Bug 较多，基本无法使用
  * 删除“7.6 Fluxbox”，Bug 较多，基本无法使用
  * “第 7 章 窗口管理器”剩余内容迁移到“第 6 章 桌面环境”，
  * “第 7 章 窗口管理器”易名为“第 7 章 人工智能（AI）”
  * 将“22.4 C/C++ 环境的配置”拆分为“vim 编程环境配置”“22.4 LLVM / Clang 概述”
* 2026.2.18
  * “21.2 通过 FreeBSD Ports 安装 Rocky Linux 兼容层”新增“Rocky Linux 版本号概述”
  * 根据 <https://reviews.freebsd.org/D55303> 以及 <https://cgit.freebsd.org/src/commit/?id=62fba0054d9eb2303116f54be1f9bc0e7b75cc15>，目前 FreeBSD 16-CURRENT 中的 ee 编辑器已经引入 UTF-8 支持，如中文。本地测试通过
* 2026.2.15
  * “4.2 Linux 用户迁移指南”新增：“理解 FreeBSD 并非发行版而是操作系统”
* 2026.2.14
  * 完全重写“5.2 更换 FreeBSD 软件源”
* 2026.2.4
  * 删除“10.4 配置 OpenVPN”，无实质性内容
* 2026.2.3
  * 在“24.1 FreeBSD 内核选项概述”中新增“CURRENT 中的调试功能”
* 2026.1.27
  * “23.5 Swap 分区”增补重要警告“在内存压力极高的系统上，无论 swap 空间剩余多少，使用 zvol 作为 swap 设备都可能导致系统锁死。”
  * 根据上游文档增补“23.5 Swap 分区”中“使用 ZFS 卷充当 Swap”
* 2026.1.19
  * 增补“6.2 NVIDIA 显卡驱动”，在台式机 3060 显卡上实际测试
  * 为其余链接添加部分存档
* 2026.1.18
  * 引入归档 CI，同时为其余链接添加部分存档
* 2026.1.17
  * “26.2 安装 OpenBSD”新增“OpenBSD 自动分区的源代码分析”
* 2026.1.16
  * 让这流变的网络世界找到归属：为全书的主要外部链接添加互联网档案馆的备份链接。由于有些项目大都部署了反 AI 且通常没有抓取必要，故跳过了 bug 报告、man 手册、FreshPorts。FreeBSD 论坛本身会失效，且已经发生了多次。这种行为已经预设了互联网档案馆本身不会失效，但是这种想法也是不可靠的，可是也许这是一个平衡。大部分内容包括项目本身，实质上也没有这种存档的意义和必要性。
* 2026.1.11
  * 增补重排“2.1 安装前的准备工作”
* 2026.1.10
  * 为 Web 端和电子文档添加封面图片
* 2026.1.7
  * 移除“小说：《大教堂与集市》”，难以重写，实际意义不大
  * 新增“小说：《青其正色》”
* 2026.1.6
  * 改正全书若干事实错误
* 2026.1.4
  * 新增“3.12 阿里云轻量应用服务器安装 FreeBSD（UEFI 和 GPT 分区表）”
  * 审阅“26.1 OpenBSD 概述”
  * 审阅“27.1 NetBSD 概述”
  * 将 book 代码块内等字体调整使用 IBM Plex Mono
  * 本项目新增镜像站 <https://doc.bsdcn.org>，境内访问速度较佳，注意域名是 `doc`，没有 `s`。
* 2026.1.2
  * “4.2 Linux 用户迁移指南”新增“何以成为 GNU/Linux 发行版”
  * 21、22：改正若干事实错误
  * 1-10：增补若干注释
* 2026.1.1
  * 将许可证日期更新到 2026
  * “第 21 章 Linux 二进制兼容层”：改正若干事实错误
  * “4.2 Linux 用户迁移指南”新增“附录：各大 GNU/Linux 发行版对比”

## 2025 年第四季度

* 2025.12.31
  * 16-17：改正若干事实错误
  * 初步审阅“附录 Ⅳ 文学故事”
  * 将“存储设备基础”和“总线接口与协议”合并入“计算机系统结构”
* 2025.12.30
  * 1-15 章：改正若干事实错误
* 2025.12.29
  * 审阅“FreeBSD 桌面发行版评述”
  * 审阅“BSD 许可证概览”
  * “附录 Ⅳ 文学故事”修正若干字词错误
  * 将“FreeBSD 13/14 安装指南”迁移到“2.3 FreeBSD 13 和 14 安装指南（基于 amd64 架构）”，其他章节编号依次递增
  * 粗略审阅“附录 Ⅲ UEFI/BIOS 基础（基于 AMI BIOS）”
* 2025.12.28
  * 审阅“附录 Ⅰ 计算机概论”
  * “附录 Ⅲ UEFI/BIOS 基础（基于 AMI BIOS）”：修正若干事实错误
* 2025.12.27
  * 审阅“第 24 章 FreeBSD 内核”
  * 审阅“第 26 章 OpenBSD 入门”
  * 审阅“第 27 章 NetBSD 入门”
  * 审阅“DragonFly BSD 导论”
  * 审阅“TwinCAT/BSD 导论”
  * 审阅“FreeBSD 兼容的网络适配器”
  * 将“UEFI/BIOS 基础（基于 AMI BIOS）”拆分到“附录 Ⅲ UEFI/BIOS 基础（基于 AMI BIOS）”，其他附录编号依次递增
* 2025.12.26
  * 23-附录 Ⅲ：修正若干事实错误
  * 审阅“第 23 章 存储与文件系统管理”
  * 审阅“第 25 章 ZFS 文件系统”
* 2025.12.25
  * 1-16 章：修正若干事实错误
  * 审阅“第 20 章 游戏、科学计算和专业工具”
  * 审阅“第 21 章 Linux 二进制兼容层”
  * 审阅“第 22 章 开发生态与贡献社区”
  * 审阅“术语表”
  * 审阅“参考书目”
* 2025.12.24
  * 审阅“第 14 章 网络管理”
  * 审阅“第 15 章 防火墙”
  * 审阅“第 16 章 服务器”
  * 审阅“第 17 章 Web 服务器和监控平台”
  * 审阅“第 18 章 FreeBSD 与嵌入式平台”
  * 审阅“第 19 章 数据库管理”
* 2025.12.23
  * 审阅“第 11 章 Jail”
  * 审阅“第 12 章 虚拟化和容器”
  * 审阅“第 13 章 系统管理”
  * “4-6”章再增补
* 2025.12.22
  * 审阅“第 6 章 桌面环境”
  * 审阅“第 7 章 窗口管理器”
  * 审阅“第 8 章 本地化——i18n/L10n”
  * 审阅“第 9 章 多媒体和外部设备”
  * 审阅“第 10 章 代理服务器”
* 2025.12.21
  * 审阅“第 3 章 FreeBSD 高级安装”
  * 审阅“第 4 章 FreeBSD 基础”
  * 审阅“第 5 章 软件管理和系统升级”
* 2025.12.20
  * 审阅“第 1 章 FreeBSD 初见”（旨在使其更靠近正式出版物的标准，去手册化）
  * 审阅“第 2 章 安装 FreeBSD”
  * 审阅“前言”
* 2025.12.17
  * “参考书目”：压缩表格列数、新增 3 本 oracle 参考书、将不建议阅读重写为谨慎阅读、增补王波部分
* 2025.12.16
  * 增补“致读者：解放思想，回归本真，高扬人道主义，不走苦难哲学的邪路”
* 2025.12.14
  * 新增“13.7 用户分级与资源配额（login.conf）”。
    * 根据编纂发现，提交 [Bug 291649 Submitted – COPYRIGHT in login classes/login.conf(5) does not work](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291649)
* 2025.12.13
  * 重写“7.2 IceWM”
  * “10.3 Mihomo（Clash）”新增“RC 脚本”。已向 Ports 维护者发出请求合并（[Bug 291295 - net/mihomo: Add rc.conf and some Post-installation](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291295)），但未予回应。
  * 将“4.10 文件系统的挂载和卸载”“4.11 磁盘结构”合并到“4.10 文件系统基础”
  * 将“4.12 目录结构”拆分到“4.11 系统目录结构”和“24.6 FreeBSD 源代码目录结构”
  * 根据编纂发现，增补 [Bug 236786 FreeBSD -.iso files not support written to USB drive](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236786)
* 2025.12.8
  * “5.1 FreeBSD 镜像站现状”新增“拒绝开放的可能性原因分析”
* 2025.12.7
  * 完全重写：“25.5 更新 ZFS 的 zpool”
  * 完全重写：“5.7 使用 freebsd-update 更新 FreeBSD”。注：在使用 freebsd-update 从 14.3 或更低版本更新时，必须先更新到最新的补丁版本再升级大版本。否则会失败。方法：`freebsd-update fetch && freebsd-update install` 参见 <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289769> 和 <https://www.freebsd.org/releases/15.0R/installation/#upgrade-binary>
* 2025.12.6
  * 将“5.9 使用 pkgbase 更新 FreeBSD”完全重写为“5.9 使用 ZFS 启动环境更新 FreeBSD 并实现多版本共存”
* 2025.12.5
  * 新增 ZFS 脚本，可用于查看、创建、删除、恢复 ZFS 快照。[FreeBSD-Ask/zfs-snap 项目地址](https://github.com/FreeBSD-Ask/zfs-snap)
  * 同时将 ZFS 脚本部署到了 <https://docs.bsdcn.org/zfs.sh>，方便直接 `fetch` 下载使用
  * “25.4 ZFS 启动环境”新增“附录：多版本/系统共存的 ZFS 版本问题”
* 2025.12.4
  * “9.4 触摸板与键鼠”新增“附录：解决 15.0 及更高版本键鼠无法驱动”
* 2025.12.3
  * 改进“7.4 Hyprland”格式，修正启动命令为 `dbus-run-session Hyprland`，声明其不支持在任何虚拟机及 NVIDIA GPU 上运行
* 2025.11.30
  * 将不具有实质性内容的“第 25 章 TwinCAT/BSD 入门”压缩到附录 Ⅱ“TwinCAT/BSD 导论”
  * 将“23.2 ZFS 文件系统”拆分为“第 25 章 ZFS 文件系统”
  * 将“23.3 磁盘扩容和分区调整”中的 ZFS 部分拆分到“第 25 章 ZFS 文件系统”，原有章节调整为“23.3 UFS 文件系统”
  * “24.2 机器相关的内核选项”引入“powerpc（32/64 位）机器相关配置”“64 位 RISC-V 机器相关配置”“arm64（aarch64）机器相关配置”
  * 新增“24.4 GENERIC 内核选项（amd64）”
  * “24.1 FreeBSD 内核选项概述”新增“附录：man config(5) 中文”“附录：man device.hints(5) 中文”
  * 将“22.15 在 Linux 上构建 FreeBSD”移动到“第 24 章 FreeBSD 内核”
  * 将“2.1-2.9”压缩归档至附录 Ⅱ“FreeBSD 13/14 安装指南”
  * 新增“2.2 安装 FreeBSD 15”
* 2025.11.29
  * “24.3 机器无关的内核选项”引入 100%
  * 修复“21.7 Gentoo Linux 兼容层”。15.0-RELEASE 测试通过。
  * “21.4 ArchLinux 兼容层（基于 ArchLinux bootstrap）”：解决了因沙盒导致的下载错误。
    * 现在的 Archlinux 兼容层构建完成 chroot 后看似卡住，其实是 bash 一行完全无显示，正常输入仍能使用。
    * 似乎无法通过 pacman 再安装 fakeroot-tcp，转为 aur，目前陷入了先有鸡还是先有蛋的悖论，但此问题优先级不高，需要先解决上面一条。
* 2025.11.28
  * 增补“致读者”
  * “24.3 机器无关的内核选项”引入 85%（按行数计）
* 2025.11.27
  * “24.3 机器无关的内核选项”引入 82%（按行数计）
  * docs：新增段落首行缩进两个字符以符合排版
* 2025.11.26
  * 全面重写“致读者”
  * “24.3 机器无关的内核选项”引入 75%（按行数计）
    * 根据编纂发现，提交 [Fix typos and unify Realtek terminology](https://github.com/freebsd/freebsd-src/pull/1901)
* 2025.11.25
  * “24.3 机器无关的内核选项”引入 69%（按行数计）
    * 根据编纂发现，提交 [NOTES: Fix a typo in a comments](https://github.com/freebsd/freebsd-src/pull/1899)
    * 根据编纂发现，提交 [NOTES: Remove duplicate options KCSAN entries](https://github.com/freebsd/freebsd-src/pull/1900)
  * 由于内容不足以构成一章，将“第 24 章 DragonFly BSD 入门”压缩到附录 Ⅱ“DragonFly BSD 导论”
  * 新增“第 24 章 FreeBSD 内核”，将“22.16 FreeBSD 内核配置选项”分别拆分为：
    * 24.1 FreeBSD 内核选项概述
    * 24.2 机器相关的内核选项（amd64）
    * 24.3 机器无关的内核选项
  * 修复 mu-lu CI
* 2025.11.24
  * “22.16 FreeBSD 内核配置选项”引入 56%（按行数计）
* 2025.11.23
  * “22.16 FreeBSD 内核配置选项”引入 40%（按行数计）
  * 引入 RSS 订阅源 <https://docs.bsdcn.org/feed.rss>
* 2025.11.22
  * 新增“22.16 FreeBSD 内核配置选项”，引入 i386/amd64 机器相关的内核选项
  * “参考文献”新增“《Solaris 性能与工具》”
* 2025.11.21
  * “5.4 使用 pkg 管理二进制包”重写“使用 pkg 安装软件”
* 2025.11.17
  * “4.1 Windows 用户迁移指南”新增“深入阅读”
  * FreeBSD 安装镜像缺乏 kmod 的离线包，提交 [Bug 291052 - Request to offline-distribute kernel modules and pkg(8) repositories in iso and img images.](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=291052)
* 2025.11.14
  * “3.3 使用 Virtual Box 安装 FreeBSD”增补“网络设置”
  * Port [net/wutil](https://www.freshports.org/net/wutil) 测试失败，提交 issue [wutil: no wpa ctrl interface on default path, provide --ctrl-interface: No error: 0](https://github.com/MainKt/wutil/issues/2)
  * “6.3 KDE6（X11）”新增“附录：解决开机时总是自动打开特定程序”
* 2025.11.13
  * CSP 配置错误，已经移除
  * docs 新增 giscus 评论功能
* 2025.11.12
  * “23.2 ZFS 文件系统”新增“ZFS 历史”
  * “27.1 NetBSD 概述”新增“NetBSD 上的 ZFS”
* 2025.11.9
  * 除特别注明外，本书的文字、图表等内容依据 CC BY 4.0 协议发布。书中所有代码示例依据 BSD 二条款许可发布。
  * 移除“12.5 无线网络环境下使用 bhyve”与“12.2 使用 bhyve 安装 Windows 11（vm-bhyve）”的“可选配置”章节。引用不符合规范
  * 将上面移除的内容涉及的 wiki 全部翻译，并放在 [vm-bhyve Wiki](https://book.bsdcn.org/wen-zhang/wen-zhang/vm-bhyve)
* 2025.11.8
  * 由于 FreeBSD 的默认 ESP 不符合 UEFI 规范，提交 [Bug 290857 - bsdinstall: The ESP on FreeBSD Should Be FAT32 Instead of FAT16: D28897 Is Actually Ineffective](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=290857)
* 2025.11.5
  * “26.5 桌面和其他软件”新增故障排除，解决“KDE 无声音”
  * 增补贡献指南
* 2025.11.4
  * “10.3 Mihomo（Clash）”新增“Clash for FreeBSD”
* 2025.11.1
  * 将 docs 的配色调整接近 book
  * 将 SRI 引入 docs
  * 将 CSP 引入 docs
* 2025.10.30
  * 将 book 的代码块也调整使用“霞鹜文楷”
  * 将 docs 和 book 的 bold 字重的字体调整为 noto sc
  * 为 docs 添加了行号
* 2025.10.29
  * 将 <https://docs.bsdcn.org>（以后称 docs） 整体字体切换到“霞鹜文楷”
  * 将 <https://book.bsdcn.org> （以后称 book）整体字体切换到“霞鹜文楷”
  * <https://docs.bsdcn.org> 现在可以用鼠标点开图片浏览大图了
* 2025.10.28
  * 注意：必须为子模块指定一个分支 `git submodule add -b main --force https://github.com/FreeBSD-Ask/FreeBSD-Ask docs`，否则会出现很多奇怪的问题。
  * 使“从 SUMMARY.md 更新目录”绕过必须 PR 的规则
  * 使“🔗 更新提交进度”绕过必须 PR 的规则
  * 引入“🔗 更新谷歌分析”，用于在首页实时（每日更新）显示“📈 统计信息”
  * 引入“🔗 更新提交进度”，用于在首页显示项目进度
* 2025.10.27
  * 修复 <https://docs.bsdcn.org> 镜像站首页显示为目录的问题
* 2025.10.26
  * 添加一个进度徽章，用以显示第三版进度
* 2025.10.24
  * “5.2 更换 FreeBSD 软件源”新增“理解 quarterly 季度分支”
  * “5.5 使用 Ports 以源代码方式安装软件”新增“Ports 与 Port 概述”
  * 在若干位置增补警告，告诫读者应尽量使用生产版本（RELEASE）
* 2025.10.23
  * NetBSD “27.4 桌面和中文环境常用软件”新增“在 VMware 中安装”
* 2025.10.19
  * 新增“2.11 将 U 盘启动盘恢复为普通 U 盘（基于 Windows）”
* 2025.10.14
  * “6.3 KDE6（X11）”新增“最小化 KDE 桌面安装方案”
* 2025.10.11
  * “6.1 Intel 和 AMD 显卡驱动”：明确目前 AMD 显卡驱动存在故障，预计在 15.0 RELEASE 发布前修复；
  * “6.1 Intel 和 AMD 显卡驱动”：明确目前 FreeBSD 移植的 drm 尚不支持 Intel DG2 Arc 显卡（如 Arc A770），预计在 15.1 RELEASE 前得到支持。
* 2025.10.10
  * “6.1 Intel 和 AMD 显卡驱动”重写“显卡支持情况”
  * 提交 [Bug 290122 - graphics/drm-latest-kmod：and related DRM ports missing CONFLICTS\_INSTALL entries](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=290122)
* 2025.10.6
  * “1.1 操作系统的历程：UNIX、BSD 和 Linux”：新增“附录：自由软件与开源软件语境下的典型误解与思想偏差探析”
* 2025.10.1
  * 非技术性问题及与社区无关话题、纯粹私人聊天及情感讨论等事宜恕不回复，如有这方面需求请咨询专业人士，其他需求欢迎加群讨论。

## 2025 年第三季度

* 2025.9.30
  * “4.9 sudo 和 doas”新增“sudo-rs”
  * 由于 Bug 287690 [sysutils/pacman: The archlinux flavor cannot be built or installed.](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287690)，本文暂不可用，若在六个月内（2026-04-01 日前）未得到解决将删除“21.5 ArchLinux 兼容层（基于 archlinux-pacman）”。
  * budgie 主要维护者 Olivier Duchateau 继续更新了，但无法正常登录桌面。Bug 289898 [x11/budgie: After logging in with LightDM, it crashes and then shows a black screen.](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289898)。若在六个月内（2026-04-01 日前）未得到解决将删除“6.10 Budgie”。
  * “19.1 PostgreSQL”更新至“PostgreSQL 18”
* 2025.9.28
  * 2025 FreeBSD 社区调查报告.pdf <https://www.alipan.com/s/6vUR7W6xfpC> 提取码: nq19 点击链接保存，或者复制本段内容，打开「阿里云盘」APP，无需下载极速在线查看，视频原画倍速播放。
  * 上面是中文版本，原文在 [这](https://freebsdfoundation.org/wp-content/uploads/2025/09/FreeBSD-2025-Community-Survey-Report-Final.pdf)。
* 2025.9.27
  * 针对 fwget 工具无法为 RTL8125 2.5GbE 以太网卡安装驱动的问题提交：[Bug 289862 - fwget(8) does not support Realtek Ethernet (RTL8125 2.5GbE, realtek-re-kmod) despite packages being available](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289862)。
* 2025.9.23
  * 在安装过程中直接引入 video 组。
  * 切勿使用 freebsd-update 升级至 15.0-ALPHA3 版本。该操作会在安装 libsys 之前先安装新版 libc，从而导致系统损坏。我们将修复 freebsd-update 以确保按正确顺序安装库文件，但在相关补丁（及相应的勘误通知）发布之前，此升级方式暂不可用。—— Colin Percival FreeBSD 发布工程负责人& EC2 平台维护者。参见：003244\[EB/OL]. \[2026-03-26]. <https://lists.freebsd.org/archives/freebsd-stable/2025-September/003244.html>.
* 2025.9.22
  * 如果普通用户没有被加入到 video 组（wheel 还不够），那么在 KDE 的设置中，“关于此系统”中的“显卡驱动”将永远显示为“llvmpipe”。且 Wayland 下普通用户将无权调用 GPU。
  * “6.3 KDE6（X11）”新增“附录：展开任务栏图标”
  * 完全重写“6.16 KDE6（Wayland）”
* 2025.9.19
  * “1.2 FreeBSD 导论”——“选择 FreeBSD 的技术性原因”新增“安全原因”
* 2025.9.15
  * 新增“22.15 在 Ubuntu 上构建 FreeBSD”
* 2025.9.10
  * 重写“9.1 音频设备配置”
  * 新增“6.16 KDE6（Wayland）”
* 2025.8.31
  * 目前将无线电（Wi-Fi）区域码设置为 `CN NONE`（`create_args_wlan0="country CN regdomain NONE"`）是不正确的，因为 FreeBSD 的文件缺乏维护，实际上会导致无法协商到 Wi-Fi 5（FreeBSD 为 VHT40），速率始终是 11a，不是应有的 11ac；并且对于 DFS，配置也不正确。已提交 Bug 报告至 [Missing CN regulatory domain and 11ac/DFS support in regdomain.xml](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289202)。临时解决方案：如果你的信道 > 48，需要专门在 **/etc/rc.conf** 中修改或写入 `create_args_wlan0="country HR regdomain ETSI"`；如果你的信道 <= 48，且存在 `create_args_wlan0="country CN regdomain NONE"`，请将其删除，因为默认的 FCC US 配置可支持其 Wi-Fi 5 协议。经过测试，即使是 Wi-Fi 6 路由器，开启 WPA3、160MHz，也是受支持的。按照以上临时方案配置，Intel AX200 网卡在 FreeBSD 14.3-RELEASE 上可成功协商至 11ac。
  * 因 budgie 主要维护者 Olivier Duchateau 称已对此项目不感兴趣，放弃维护。且无人主动维护，目前核心组件 Port `sysutils/budgie-control-center` [被标记为](https://www.freshports.org/sysutils/budgie-control-center/) `broken`（破损）。考虑在日后删除 6.10 Budgie。如果 6 个月内仍未得到修复将建议上游删除此项目，并从本书中移除此节。
* 2025.8.24
  * 新增：“12.5 无线网络环境下使用 bhyve”
  * “4.2 Linux 用户迁移指南”新增“历史”
* 2025.8.20
  * 新增“3.10 云服务器安装 FreeBSD（基于 KVM、QEMU 等平台）”
* 2025.8.18
  * “2.1 安装前的准备工作”新增：最高硬件支持
* 2025.8.17
  * 3.9 云服务器安装 FreeBSD（基于腾讯云轻量云）：测试了多种替代方案均失败
* 2025.8.14
  * 将“1.2 欢迎来到 FreeBSD”“1.3 关于 FreeBSD 项目”合并为“1.2 FreeBSD 导论”，原有章节从标题看不知道是作何用的
  * 将“窗口管理器”“FreeBSD 高级安装”前置便于使用
* 2025.8.13
  * 增补 2.2 使用 bsdinstall 开始安装：补充有关 ACPI 的警告、引入 bsdinstall 介绍
  * 将本书的组织结构、本书中使用的一些约定合并入绪论
  * 合并三篇序言到前言
* 2025.8.7
  * 重写：本书的组织结构
* 2025.7.31
  * 新增：附录 2 UEFI/BIOS 注解（基于 AMI BIOS）
* 2025.7.30
  * 之前 KDE 在 Wayland 下，启动后桌面右键单击黑屏的问题已得到解决。参见 <https://old.reddit.com/r/freebsd/comments/1m9popo/kde_mini_review/n5dv1uk/> 和 <https://github.com/freebsd/freebsd-ports/pull/431>。目前已安装的只需要 `make reinstall` Port `graphics/qt6-wayland` 和 `/x11/plasma6-layer-shell-qt` 即可。或者等几天通过 `pkg upgrade`、安装后也应该不会有黑屏问题了。
* 2025.7.23
  * 恢复书名《FreeBSD 从入门到跑路》
* 2025.7.7
  * 17.7 OpenList 新增：本机存储的多属主权限管理
  * 17.7 OpenList 新增：影视刮削
* 2025.7.6
  * 新增：17.7 OpenList
  * 6.2 Fcitx 输入法框架：已经将安装 RIME 中州韵输入法（可选）作为独立子节，并强调了 chinese/rime-essay 的必要性
  * 20.1 Renpy 游戏与 Godot 游戏：删除五分钟游戏。都是些桌面自带的游戏，列举无意义
  * 新增：20.4 Steam
* 2025.7.5
  * 重写：6.6 QQ（Linux 版）。在所有兼容层中，Fcitx5 输入法框架均测试通过，可以正常输入汉字
* 2025.7.4
  * 新增：6.11 Wine

## 2025 年第二季度

* 2025.6.24
  * FreeBSD 14.3 的 Wi-Fi country select 有问题。选哪个都是这个报错：`Error while applying chosen settings (unknown regdomain Expected eval: Use: not found)` 参见：Bug 287538 - Installer error on setting regdomain\[EB/OL]. \[2026-03-26]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287538>。替代方法是手动写，参照无线网络章节。
* 2025.6.23
  * 3.6 文本编辑器新增：microsoft-edit
* 2025.6.21
  * 格式化：第 21.5 节 ArchLinux 兼容层（基于 archlinux-pacman）
  * 为镜像站 <https://docs.bsdcn.org/> 添加了自动序号
  * 重写：22.7 Python 和 VS Code：Python
  * 本书更名为《FreeBSD 操作系统研究导论》
* 2025.6.20
  * 第 1.2 节 欢迎来到 FreeBSD：完全重写“为什么选择 FreeBSD”，去除有关 Linux 的描述
* 2025.6.19
  * 调整目录结构
  * 第 19.1 节 PostgreSQL：将 PostgreSQL 更新到 17
  * 第 19.2 节 pgAdmin4 更新到 pgadmin4-9.0
  * 第 23.7 节 ZFS 磁盘加解密合并入 FreeBSD 安装章节
* 2025.6.17
  * 增加一个术语表放在附录
  * 调整目录结构
  * 新增：在 FreeBSD 上安装 VirtualBox
* 2025.6.16
  * 将第 1.2 节 FreeBSD 简史合并入：第 1.2 节 关于 FreeBSD 项目
  * 第 8.2 节 用户和基本账户管理新增：账户类型
  * 将参考书目独立出来放在附录
* 2025.6.15
  * 计划全面重写 FreeBSD 手册
* 2025.6.14
  * 重新引入：[贡献指南与开放任务](/contributing)
* 2025.6.13
  * 第 1.1 节 操作系统的历程：UNIX、Unix-like、Linux & FreeBSD 重写：什么是 Linux？
  * 第 1.1 节 操作系统的历程：UNIX、Unix-like、Linux & FreeBSD 新增：GNU 与自由软件运动
  * 第 6.6 节 视频播放器新增：附录：直接在 TTY 播放视频（mpv）
* 2025.6.12
  * 第 4.3 节 GNOME：欢迎来到 Gnome 47
* 2025.6.10
  * 第 26.3 节 配置 OpenBSD 重写：doas
  * 第 26.1 节 OpenBSD 概述新增：其他专注于安全的 BSD 系统
  * 第 26.1 节 OpenBSD 概述新增：OpenBSD IPSEC 协议栈 FBI 后门事件
* 2025.6.9
  * 第 26.1 节 OpenBSD 概述新增：机遇与挑战、语录摘选
* 2025.6.8
  * 第 1.1 节 操作系统的历程：UNIX、Unix-like、Linux & FreeBSD 新增：草稿：二十一世纪的 Unix 哲学观
  * 第 1.1 节 操作系统的历程：UNIX、Unix-like、Linux & FreeBSD 增补：UNIX 之船：FreeBSD 是不是 UNIX？
  * 第 4.1 节 显卡驱动（英特尔、AMD）新增：AMD 视频硬解
* 2025.6.7
  * 根据调查问卷恢复一部分文学故事
* 2025.6.6
  * 第 2.3 节 UNIX 基础（新手入门版本）新增：Windows 与 Unix 字符编码的差异
  * 第 2.3 节 UNIX 基础（新手入门版本）新增：Windows 与 Unix 时间设置的差异
  * 第 2.4 节 命令行基础（新手入门版本）：新增“你并不孤单”
* 2025.6.4
  * 第 2.3 节 UNIX 基础（新手入门版本）新增：Windows 与 Unix 换行符/回车之差异，还需要补充编码差异、时区差异等
* 2025.5.30
  * 新增：第 1.7 节 BSD 许可证概览
* 2025.5.23
  * 新增：第 10.3 节 Podman
* 2025.5.17
  * 删除“第 21.2 节 Linux 兼容层——基于 CentOS（FreeBSD Port）”，过时
* 2025.5.16
  * 录制视频 [FreeBSD 14.2 基础安装配置教程](https://www.bilibili.com/video/BV1STExzEEhh)
* 2025.5.12
  * 移除“第 4.18 节 KDE6”中的“基于 Wayland”，可能存在错误
* 2025.5.9
  * 重写：第 22.8 节 Rust/Go 环境的配置
  * 此分支转为社区版本，去除 ykla 个人观点，保留中立内容。该分支转为社区维护，欢迎 PR。
* 2025.5.8
  * 第 2.4 节 命令行基础（新手入门版本）：新增“`vi` 编辑器基本用法”
* 2025.5.6
  * 从“第 2.2 节 FreeBSD 安装图解”拆分出“第 2.1 节 安装前准备（新手入门版本）”
* 2025.5.5
  * 测试“第 22.4 节 C/C++ 环境的配置”
  * 重写“第 4.5 节 Xfce”
  * UNIX 基础（新手入门版本）：新增“大小写敏感”
* 2025.5.2
  * 新增“第 2.3 节 UNIX 基础”
* 2025.4.29
  * 引入 GitHub Action“🔗 检查 Markdown 图片引用”。用以核查图片使用情况
  * 重写“第 5.4 节 五笔输入法”
* 2025.4.28
  * 第 26 章 OpenBSD：更新至 OpenBSD 7.7
  * 将“第 8.2 节 添加用户”合并入“第 8.2 节 用户与组”
  * 重写“第 8.2 节 用户与组”
  * 移除部分来自网络且未经验证的可能不可靠的内容
  * 重写“第 5.4 节 五笔输入法”，注意最后一部分未测试。
  * 重新排版：第 5.1 节 本地化环境变量
  * “第 13.4 节 SSH 配置与相关工具”：删除思考题，删除关于 OpenSSH 版本的描述，因为已经过时。
  * 今天总计清理出了 5 页 A4 纸的篇幅
  * “第 14.1 节 TCP 堆栈”新增“使用 RACK 栈”
* 2025.4.25
  * 重新更名为《FreeBSD 从入门到追忆》
  * 重写“第 6.3 节 打印机”
* 2025.4.24
  * 第 4.2 节 显卡驱动（NVIDIA）：完全重写
* 2025.4.22
  * 《FreeBSD 从入门到跑路》恢复旧名《FreeBSD 艺术科学哲学导论》
  * 第 5.2 节 Fcitx 输入法框架：重新排版
  * 从“第 4.1 节 显卡驱动”拆分出“第 4.1 节 显卡驱动（英特尔、AMD）”“第 4.2 节 显卡驱动（NVIDIA）”
  * 第 9.3 节 使用 Qjail 管理 Jail：重新排版
  * 由于电子邮件长期被忽视，今日分别致国际信函给“FreeBSD 基金会”（RD664821800CN）和“OpenBSD 基金会”（RD664821795CN），反馈目前的捐款渠道不畅之问题，以及呼吁关注中国大陆地区等
* 2025.4.21
  * “第 5.6 节 QQ（Linux 版）”新增：解决 fcitx 中文输入法在 QQ 中不能使用的问题

***

* 2024.8.1-2025.4.20
  * 《FreeBSD 从入门到跑路》第二版完成（TAG 2025.4.20）

***

* 2025.4.20
  * 格式化全书
  * 对全书初版重写达 100%
* 2025.4.19
  * 第 4 章 桌面环境：新增软件解释
  * 对全书删除冗余，重新排版
* 2025.4.18
  * “第 2.2 节 命令行基础（新手入门版本）”新增：关机、重启、`&&`、`||`
* 2025.4.17
  * 重写：第 16.7 节 Samba 服务器中的安装 Samba 部分，其余部分无条件测试
  * 重写：第 16.6 节 rsync 同步服务
* 2025.4.16
  * 格式化：第 14.2 节 Wi-Fi
  * “第 27.4 节 桌面与中文环境常用软件”：重写引入：KDE 4。因为物理机测试成功。
  * 从“第 1.1 节 操作系统的历程：UNIX、Unix-like、Linux & FreeBSD”拆分出“第 1.2 节 FreeBSD 简史”
  * 重写：第 2.6 节 云服务器安装 FreeBSD（基于腾讯云轻量云）
  * 拆分序言
  * 引入 GitHub Action：🔗 从 SUMMARY.md 更新一级标题。用于检查 SUMMARY 标题和对应文件的一级标题的符合情况
* 2025.4.15
  * 格式化：第 5.6 节 QQ（Linux 版）
  * 第 4.20 节 远程桌面：删除剩余的“VNC 与 RDP（XRDP）对比”部分
* 2025.4.14
  * 目前对全书初版已重写 96.57%（按 Commit 数）
  * 格式化“第 11.5 章 MySQL 数据库”
  * 删减占用篇幅较大的无用图片
* 2025.4.13
  * “第 16.5 节 WildFly”测试基本成功，但是注意补丁仍未合并到主线，详见 [Bug 285956 - java/wildfly: service start fail, illegal group name](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=285956)。
  * 新增“第 24.3 节 配置 DragonFly BSD”
  * 重写“第 24.2 节 安装 DragonFly BSD”
* 2025.4.11
  * 通过段落间距调整，PDF 页数从 1209 到 1084，减少了 10.34% 的页面占用。
* 2025.4.10
  * 测试、改写“第 2.8 节 手动安装双系统（后安装 FreeBSD）”
  * NetBSD 10.1 在 VMware 虚拟机中无论 UEFI 与否，进入 kde 4 都会黑屏。
* 2025.4.9
  * 使用 <https://gist.github.com/ykla/adf011fea43f5f4b91aa6f065ac09da2> 对全书过长（> 30 行）的代码块整理。
  * 孤行控制，删除冗余。
  * 从 1238 页到 1209 页，减少了 2.34% 的无效页面。
* 2025.4.8
  * “第 27.2 节 NetBSD 安装图解”更新至 NetBSD 10.1
  * “桌面与中文环境常用软件”更新至 NetBSD 10.1
  * “桌面与中文环境常用软件”新增输入法
  * “桌面与中文环境常用软件”新增中文环境
  * NetBSD KDE 4 UEFI 下测试失败，还是黑屏，报错见 <https://gnats.netbsd.org/57554>
  * “第 16.5 节 Wildfly”测试失败，见 [Bug 285956 - java/wildfly: service start fail, illegal group name](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=285956)
* 2025.4.7
  * 全译现有所有安装后说明
  * 从 [2024.8-3533 次](https://github.com/FreeBSD-Ask/FreeBSD-Ask/commit/c4d657fb586f91e9f8664ee1181a2711f7350d17) 开始，目前对全书初版已重写 94%（按 Commit 数），下同
  * 删除“第 11.3 节 散热器、风扇、鼓风机”，可能包含错误内容
* 2025.4.6
  * “第 17.8 节 PostgreSQL 与 pgAdmin4”新增“深入 PostgreSQL 服务管理”
  * “第 4.21 节 FreeBSD 桌面发行版”补图
* 2025.4.5
  * 初步重写第 15.4 节 ipfirewall（IPFW）
  * 格式化第 15.2 节 PF
  * 格式化第 15.3 节 IPFilter（IPF）
  * 新增“第 4.21 节 FreeBSD 桌面发行版”
* 2025.4.4
  * 从各个章节拆分出“第 6 章 多媒体与外设”
  * 格式化“第 5.1 节 输入法与环境变量”
  * 格式化“第 21.12 节 Linux 兼容层与 Jail”
  * mihomo（原 Clash），需要重写相关章节，我们需要一个 GUI 界面！
* 2025.4.3
  * 从“第 20.1 节 游戏”拆分出“第 20.6 节 我的世界（Minecraft）”
  * 将“第 20.2 节 音视频播放器与剪辑”拆分为“第 20.2 节 音频播放器”“第 20.3 节 视频播放器”“第 20.4 节 音视频剪辑与图像处理”、
  * 测试“第 20.5 节 科研与专业工具”，并新增“Calibre 文档管理（epub、mobi、azw3 等格式）”
  * “第 20.5 节 科研与专业工具”补图
  * “第 20.1 节 游戏”：重写“Renpy 游戏”
* 2025.4.2
  * 测试“第 20.2 节 音视频播放器”：尝试播放电视剧《人民公仆》、尝试播放动漫《败犬女主太多了！》，测试通过
* 2025.4.1
  * <https://mirrors.aliyun.com/freebsd-pkg/> 看起来早就失去同步。还是 2 月我提交 kmod 源以前的内容，故不写入

## 2025 年第一季度

* 2025.3.31
  * 将镜像站点迁移至 <https://docs.bsdcn.org/>
* 2025.3.30
  * 部署了镜像站点，临时位于 <https://freebsd-ask.github.io>，使用 VitePress
* 2025.3.29
  * 从现在起每天在 GitHub release 生成一个 PDF 文档
  * 生成新的 Windows 24H2 字体包用于 GitHub Actions
  * 重写 PDF 导出工具
* 2025.3.27
  * “第 16.1 节 FTP 服务器”新增“vsftpd”
  * 引入 GitHub Actions：🔗 从 SUMMARY.md 更新目录
  * 引入 GitHub Actions：🔗 检查 SUMMARY.md 目录
  * 引入 GitHub Actions：🔗 创建并发布 PDF 文档，从现在起每 5 天在 GitHub release 生成一个 PDF 文档
* 2025.3.26
  * 重写“Pure-FTPd（基于 MySQL）”
  * 重写“ProFTPD（基于 MySQL）”
  * “第 2.2 节 命令行基础（新手入门版本）”新增“UNIX 与 Windows 文件名规范之差异”
* 2025.3.25
  * 新增“第 15.5 节 Fail2Ban（基于 IPFW、PF、IPF）”
  * “第 12.2 节 FreeBSD EFI 引导管理”合并入“第 12.5 节 Grub & UEFI 与 efibootmgr”
* 2025.3.24
  * 测试“第 4.2 节 安装 KDE6”，同 VMware 的虚拟显卡无兼容性问题。缩放、鼠标无缝切换均正常。注：USTC 的源可能有问题。
  * 重写“致谢”
  * 根据 [clean-master/freebsdcn](https://github.com/clean-master/freebsdcn/graphs/contributors)，将本项目的开始时间改正至 2021 年 3 月 14 日。同时明确 clean-master 清理大师的历史贡献。
  * 重写“第 4.23 节 远程桌面管理”中的“使用 FreeBSD 远程其他机器”
* 2025.3.23
  * 格式化全书。
  * 测试“第 21.4 Linux 兼容层——基于 ArchLinux bootstrap”，在 14.2 通过
  * 改正全书失效外链和图片引用
* 2025.3.22
  * “第 3.6 节 通过 DVD 安装软件”更新至 14.2。注意，使用 `bsdinstall` 通过 DVD 安装软件的方法测试失败！
  * 初步重写“第 22.0 节 如何订阅 FreeBSD 的邮件列表”
  * 调整全书章节排序、重命名全书各章节标题以符合实际内容
  * 删除“第 2.8 节 虚拟机预安装镜像（本书自制）”，已过期
  * 压缩“第 25 章 TwinCAT/BSD”
  * 删除献词、后记，无实质性内容
  * 删除“第 24.4 节 禁用 Sendmail”，已过期
  * 删除“第 5.8 节 Wine”，无实质性内容
  * “第 6.6 节 Ext 2/3/4 等文件系统”已初步重写，仍待测试
  * 删除“第 9.1 节 jail 与 docker 的比较”，无实质性内容
  * “第 14.6 节 USB 以太网卡和 USB 无线网卡”合并入“第 14.5 节 USB 网卡 & 以太网卡”
  * 删除“第 24.2 节 BSD 风格的 make/grep/sed/awk”，无实质性内容
  * 删除“第 13 章 DTrace”，无实质性内容
  * “第 12 章 FreeBSD 目录注释”合并入“第 13 章 FreeBSD 系统管理”
  * 删除“第 10.1 节 FreeBSD 安装 Virtual Box”，无实质性内容
  * “第 6.1 节 UFS”合并入“第 6.3 节 磁盘扩容”，因为无实质性内容
  * “第 1.5 节 FreeBSD 开发计划”移动至网络文章集锦
  * 删除“第 18.4 节 USB 网卡与 Wi-Fi”，与其他章节重复
  * “第 18.6 节 树莓派 5”合并入“第 18.2 节 树莓派安装 FreeBSD”，并删除了冗余输出
  * 重写“第 17.7 节 Telegraf+InfluxDB+Grafana 监控平台”
  * 重写“第 6.6 节 Linux 文件系统”
  * 初步重写“第 1.4 节 Linux 用户迁移指南”
* 2025.3.21
  * 重写“第 22.9 节 Shell”
  * 新增“第 24.3 节 bsdconfig 系统配置工具”
  * 重写“第 5.9 节 压缩与解压”
  * “第 2.1 节 命令行基础（新手入门版本）”新增“在 TTY 界面上下翻页/翻行”
  * 删除“第 22.11 节 Git”，因为无实际内容，且有用的命令已经分散在全文各个章节了
  * 重命名全书各章节标题以符合实际内容
* 2025.3.20
  * “第 11.7 节 命令行基础”移动合并到“第 2.7 节 自带文本编辑器 ee 的用法”，成为“第 2.7 节 命令行基础（新手入门版本）”，并移动至“第 2.1 节 命令行基础（新手入门版本）”
  * “第 15.1 节 网络参数配置命令”新增 **/etc/rc.conf** 相关。注意：此部分以后需要补充等价的 `ifconfig`、`route` 临时命令。
  * “第 23.4 节 引导界面”新增“屏幕保护”
  * 为 1-5 章的大部分命令补充了英文原名说明解释。
* 2025.3.19
  * “第 11.7 节 命令行基础”新增“thefuck：自动纠正错误拼写的命令”，但要注意，有权限的开发者似乎已经不再维护；
  * “第 11.7 节 命令行基础”新增命令行基础命令
  * 初步重写“第 8.4 节 用户权限”
* 2025.3.18
  * “第 6.3 节 磁盘扩容”新增“附录”
  * 将“第 1.5 节 谁在使用 FreeBSD（基金会官方版本）”“第 1.7 节 FreeBSD 特色开发项目”移动到文章集锦。因为此部分过于冗长。
  * 新增“第 11.7 节 命令行基础”
* 2025.3.9
  * “第 22.4 节 C/C++ 环境的配置”新增“vim-codefmt 代码美化”
* 2025.3.7
  * “第 5.4 节 安装 Firefox 与 Chromium”新增“Chromium 使用 Google 账号同步”
* 2025.3.4
  * 重建“第 12 章 FreeBSD 源代码分析”
* 2025.3.3
  * “第 22.5 节 Java 环境的配置”完全重写
  * “第 22.6 节 QT 环境的配置”补图
* 2025.3.2
  * 新增“第 16.10 节 Gitlab-EE”
* 2025.3.1
  * 新增“第 17.15 节 Zabbix 监控（基于 PostgreSQL）”
* 2025.2.28
  * 更新“FreeBSD 镜像站现状”
* 2025.2.26
  * 新增“第 1.9 节 加州大学伯克利分校与“Fiat Lux”（要有光）”
  * 将文学故事移动至 <https://freebsd.gitbook.io/cfc>
  * 新增“第 17.14 节 OnlyOffice（基于 PostgreSQL）”
* 2025.2.25
  * “第 17.5 节 MySQL 8.X”新增“MySQL 8.4 LTS”
  * 新增“第 17.11 节 MongoDB 80”
  * “第 23.5 节 Grub & UEFI 与 efibootmgr”新增“EFI 分区删除与重建”，但仍存在文件簇的疑问
  * 完全重写“第 17.1 节 Apache”
  * 完全重写“第 17.2 节 Nginx”
  * 完全重写“第 17.3 节 PHP 8.X”
  * 新增“第 17.12 节 Tomcat”
  * 新增“第 17.13 节 Caddy”
* 2025.2.24 “第 6.2 节 ZFS”新增“ZFS 压缩” “第 23.5 节 Grub 及其他引导”新增“UEFI 与 efibootmgr”
  * “第 3.2 节 FreeBSD 切换软件源方式”新增“kernel modules（kmods）内核模块源：面向 FreeBSD 14.2 及更高版本（不含 15.0-CURRENT）”
  * 从“第 2.10 节 手动安装双系统（先安装 FreeBSD）”拆分出“第 2.13 节 配置 rEFInd（双系统用）”
* 2025.2.23
  * 新增“后记”
* 2025.2.21
  * 新增“第 2.12 节 安装 FreeBSD——基于 Apple M1\&VMware Fusion Pro”
* 2025.2.19
  * 制作了视频教程 [《003-FreeBSD14.2 安装 KDE6》](https://www.bilibili.com/video/BV12zAYeKEej)
* 2025.2.16
  * 拆分“Git\&Linux 败局与 FreeBSD 败局”到 19.5、19.6、19.7
* 2025.2.15
  * 更新、补充“第 16.9 节 Webmin”
* 2025.2.14
  * 新增“第 17.10 节 prometheus 监控部署”
* 2025.2.13
  * 删除原 KDE6 章节，将 KDE5 章节更新为 kde6。
* 2025.2.11
  * “第 18 章 树莓派嵌入式 & RISCV”新增“第 18.9 节 Radxa X4”
  * “第 2.0 节 FreeBSD 安装图解”补图、拆分章节，补充创建普通用户的说明
* 2025.2.10
  * “第 2.0 节 FreeBSD 安装图解”新增“Auto (UFS)”
* 2025.2.3
  * “第 1.1 节 UNIX、Unix-like、Linux 和 FreeBSD 简介”新增“UNIX 与忒修斯之船”一节
* 2025.2.1
  * “第 18.6 节 RISC-V 简介”合并入“第 18.8 节 在 RISCV 开发板上安装 OpenBSD”
  * “第 2.0 节 FreeBSD 安装图解”补全菜单翻译
* 2025.1.28
  * “第 23.4 节 引导界面”新增：“调整引导界面和 TTY 分辨率”“自定义引导加载程序 Logo”
* 2025.1.21
  * 将授权协议由 BSD 协议转为 CC-BY 协议（署名 4.0 协议国际版）
* 2025.1.19
  * 更新“第 21.3 节 Linux 兼容层——基于 Ubuntu/Debian”，在 14.2 测试通过
  * “第 14.3 节 USB 网络共享（USB tethering）”完全重写
  * 完全重写“第 21.1 节 Linux 兼容层实现”
  * 图片文件名去中文化，方便编程
* 2025.1.18
  * 添加“致谢”，将“贡献者名单”移动至此独立页面
  * 添加“献词”
  * 添加“凡例”，将“序言”中非序言部分移动至此。
* 2025.1.13
  * 关闭 Issue [第 1.5 章，内容有误](https://github.com/FreeBSD-Ask/FreeBSD-Ask/issues/159)
  * 新增“第 2.11 节 Qemu 安装 RISC-V FreeBSD（基于 x86 Windows）”
  * 新增“第 4.23 节 安装 Fluxbox”
  * 新增“第 4.24 节 安装 IceWM”
  * “第 24.5 节 利用脚本自动生成 BSDlibc 库文本”：脚本更新
  * “第 8.1 节 sudo 与 doas”新增“doas”
* 2025.1.11
  * “第 4.13 节 安装 KDE6”新增“基于开发中的 Ports（需要长时间编译）”
* 2025.1.10
  * “第 2.4 节 安装 FreeBSD——基于 VMware Workstation Pro”重写“共享文件夹”
* 2025.1.9
  * “第 4.16 节 安装 CDE”补图
* 2025.1.8
  * “第 4.0 节 概述（必看）”合并入 4.1 节
  * “第 4.1 节 安装显卡驱动及 Xorg（必看）”更名为“第 4.1 节 桌面环境概述、安装显卡驱动\&Xorg”
  * “第 4.3 节 安装 Gnome”新增“一些反人类设置的调整”，补图
  * “第 4.5 节 安装 Xfce”补图
  * “第 4.6 节 安装 Cinnamon”补图
  * “第 4.8 节 安装 LXQt”补图
  * “第 4.4 节 安装 Mate”补图，删除冗余
  * 新增“第 4.14 节 安装 Budgie”
  * “第 4.7 节 安装 Lumina”补图
  * 新增“第 4.21 节 安装 LXDE”
  * 新增“第 4.22 节 安装 Window Maker”
  * “第 19.2 节 Linux 败局与 FreeBSD 败局”新增“为何不能选择 Linux 桌面操作系统？”
* 2025.1.6
  * 新增“第 2.9 节 安装 FreeBSD——基于 Apple M1\&Parallels Desktop 20”
  * 新增“第 2.10 节 手动安装双系统（先安装 FreeBSD）”
  * “第 2.9 节 安装 FreeBSD——基于 Apple M1\&Parallels Desktop 20”新增“虚拟机工具”

## 2024 年第四季度

* 2024.12.22
  * “第 2.4 节 安装 FreeBSD——基于 VMware Workstation Pro”新增“故障排除”
* 2024.12.21
  * 新增“第 10.3 节 使用 BVCP 通过网页管理 BHyve”
  * “序言”新增“存在即破烂（2025 代序）”
* 2024.12.19
  * “第 6.3 节 磁盘扩容”新增“ZFS 磁盘扩容”一节
  * “第 10.3 节 使用 bhyve 安装 Windows 11”完全重写。
  * “第 2.3 节 安装 FreeBSD——基于 Virtual Box”补充图片
  * 为第 20 章相关软件包补充 port，删除失效软件包
  * 删除无实质性内容的“第 10.1 节 虚拟化简介”
  * “第 23.3 节 FreeBSD 中文 TTY 控制台”完全重写，验证通过
  * 新增“第 4.21 节 安装 KDE6”
  * 删除“第 4.13 节 安装 Wayland （可选）”，无实质性内容
* 2024.12.18
  * “第 2.4 节 安装 FreeBSD——基于 VMware Workstation Pro”新增“配置虚拟机”
  * “第 2.0 节 FreeBSD 安装图解”还原“怎么看你的硬件支持不支持呢？”一节
  * “第 1.3 节 为什么要使用 FreeBSD”新增“诚实与可信”一节
  * 将“编撰说明”“参考资料”“贡献者名单”合并为“序言”
  * “序言”新增“2021-2024 自序”
* 2024.12.17
  * “第 2.0 节 FreeBSD 安装图解”新增“FreeBSD 镜像说明”一节
  * 将原“第 2.6 节 普通电脑下载安装哪个镜像，如何刻录镜像？”合并入“第 2.0 节 FreeBSD 安装图解”
  * 新增“第 1.8 节 谁在使用 FreeBSD？（中文社区版本）”
* 2024.12.16
  * “第 26.1 节 安装”更新至 OpenBSD 7.6
  * “第 26.4 节 桌面与其他软件”中 KDE5 在 OpenBSD 7.6 依旧测试失败，而且错误看起来更严重了
* 2024.12.14
  * 将文学故事章节 FreeBSD 相关内容重新上线
* 2024.12.4
  * 制作了视频教程《[001-Windows 11 安装 VMware17](https://www.bilibili.com/video/BV1Qji2YLEgS) 》、《[002-VMware17 安装 FreeBSD14.2](https://www.bilibili.com/video/BV1gji2YLEoC) 》《[003-FreeBSD14.2 安装 KDE5](https://www.bilibili.com/video/BV13ji2YLELM) 》、《[004-FreeBSD14.2 允许 root 登录 ssh](https://www.bilibili.com/video/BV1gji2YLE2o) 》、《[005-FreeBSD14.2 更换 pkg 源为 USTC 镜像站](https://www.bilibili.com/video/BV13ji2YLEkV) 》和《[006-FreeBSD14.2 安装 fcitx5 及其输入法](https://www.bilibili.com/video/BV13ji2YLE3m) 》。已经分别插入了对应的目录。
* 2024.12.3
  * “第 1.3 节 为什么要使用 FreeBSD”新增“旧闻：《FreeBSD 基金会收到史上最大一笔捐款》”
* 2024.11.30
  * “第 3.7 节 通过 freebsd-update 更新 FreeBSD”更新至 FreeBSD 14.2-RELEASE
  * “第 2.0 节 FreeBSD 安装图解”更新至 FreeBSD 14.2-RELEASE
  * “第 3.4 节 软件包管理器 pkg 的用法”修订“安装 pkg”一节
* 2024.11.29
  * 更新“第 1.6 节 FreeBSD 开发计划”：同步上游
* 2024.11.27
  * “第 1.2 节 BSD 与哲学家 George Berkeley”新增“贝克莱与爱因斯坦”
* 2024.11.26
  * “第 19.2 节 Linux 败局与 FreeBSD 败局”新增“Git 典型缺陷”
* 2024.11.22
  * “第 4.11 节 主题与美化”新增“系统更新提示 `freebsd-update-notify`”
  * “第 17.9 节 AList”新增“官方二进制包”
  * 更新“第 16.3 节 Nodejs 相关”
* 2024.11.17
  * “第 4.2 节 安装 KDE 5”新增“解除自动锁屏”
* 2024.11.15
  * “第 4.2 节 安装 KDE 5”新增“登录界面主题”
* 2024.11.12
  * “第 3.4 节 软件包管理器 pkg 的用法”新增“如何查找缺少的 .so（适用于 Linux 兼容层）”
  * “第 21.13 节 Linux 兼容层故障排除与配置”更新“sysctl 变量（基于 FreeBSD 14.1）”
* 2024.11.9
  * 新增一节：“第 6.8 节 自动挂载文件系统”
  * 新增一节：“第 5.10 节 FreeBSD 安装微信（Linux 版）”
  * “第 5.5 节 FreeBSD 安装金山 WPS（Linux 版）”：新增“基于 RockyLinux 兼容层（FreeBSD Port）”安装 WPS
* 2024.11.8
  * “第 1.1 节 UNIX、Unix-like、Linux 和 FreeBSD 简介”：补充“macOS/iOS 等与 BSD 的关系”
* 2024.11.7
  * “第 6.4 节 NTFS 的挂载”：新建“格式化”、挂载部分。
  * 针对“[Add new category fs for file systems](https://github.com/freebsd/freebsd-ports/pull/302)”修改
* 2024.11.2
  * “第 19.2 节 Linux 败局与 FreeBSD 败局”补充思考题
  * 新建“第 19.3 节 驳《还有人记得 Linux 之前，那个理想又骄傲的 BSD 吗？》”
  * “第 17.6 节 NextCloud——基于 PostgreSQL”补充一节：“在 nextcloud 中挂载 samba 共享”
* 2024.11.1
  * 新建一章：“第 17.6 节 NextCloud——基于 PostgreSQL”，并测试通过
* 2024.10.30
  * “第 14.5 节 以太网卡”：修正配置文件路径
  * 新增“第 0.5 节 MySQL 数据库”
* 2024.10.29
  * 将原“第 11 章更新与升级 FreeBSD”拆分到第 3 章，将原“第 0 章计算机概论”移动到第 11 章
  * “第 3.9 节 使用 pkgbase 更新 FreeBSD”补充境内镜像站，并测试通过 NJU 163 USTC
* 2024.10.28
  * “第 17.9 节 AList”：服务部分测试通过
* 2024.10.27
  * USTC、163、NJU pkg-freebsd 源基本恢复正常
  * 新增一节：“第 17.9 节 AList”
  * “第 4.16 节 安装 CDE”测试通过
* 2024.10.8
  * 同步更新“第 1.5 节 谁在使用 FreeBSD”
  * 重写“第 4.1 节 安装显卡驱动及 Xorg（必看）”
* 2024.10.7
  * USTC、163、NJU pkg-freebsd 源故障，已经反馈
  * 同步上游：“第 1.6 节 FreeBSD 开发计划”
* 2024.10.5
  * 添加贡献者“[dongdigua](https://github.com/dongdigua)”
  * “第 3.4 节 软件包管理器 pkg 的用法”：重写故障排除。
  * 新增一节：“第 2.2 节 安装 FreeBSD——基于 Hyper-V”，原章节拆分到各个子章节。
  * 将“参考资料与贡献者名单”拆分成独立的两个小节

## 2024 年第三季度

* 2024.9.30
  * “第 2.0 节 图解安装”新增“无线网卡/ Wi-Fi 设置”一节
  * 将全文的 Wi-Fi 区域码调整为 FreeBSD 参考配置文件中设定的 `country CN regdomain NONE`
  * 完全重写：“第 14.2 节 Wi-Fi”
* 2024.9.27
  * 将“第 1.2 节 FreeBSD 与哲学家 George Berkeley”中有关 FreeBSD 的内容移动至“第 1.1 节 UNIX、Unix-like、Linux 和 FreeBSD 简介”
  * 改写“第 1.2 节 BSD 与哲学家 George Berkeley”，并补充参考文献
  * 根据 FreeBSD-14.1-RELEASE 完全重写“第 2.0 节 图解安装”
* 2024.9.20
  * “第 3.5 节 使用 ports 以源代码方式安装软件”：重写 ccache 3、ccache 4 两节。测试通过。
  * 制作了 14.1-RELEASE、15.0-CURRENT 两个虚拟机镜像
  * 新建一节“第 2.9 节 虚拟机预安装镜像”
  * “第 21.10 节 RockyLinux 兼容层（FreeBSD Port）”测试通过，将 QQ 安装方法移动至 QQ 章节。
* 2024.9.19
  * 新增“第 21.10 节 RockyLinux 兼容层（FreeBSD Port）”
  * “第 6.2 节 ZFS”新增“zfs 用户级管理”
* 2024.9.18
  * “第 3.5 节 使用 ports 以源代码方式安装软件”：测试、重写 ccache、wget2 两节。
* 2024.9.14
  * 补充了几款 Windows 上的 SSH 工具
* 2024.9.13
  * 补充若干存储卡、U 盘的测试数据
* 2024.9.9
  * 将小说诗歌杂记等与 FreeBSD 无关内容下线
* 2024.9.4
  * 测试创建第 0 章，正确性待考察
  * 还原“第 0.4 节 操作系统”
  * “第 26.1 节 安装”：同步至 OpenBSD 7.5
  * “第 26.4 节 桌面与其他软件”：测试 KDE5
* 2024.9.3
  * 将原 2.7 节合并至 2.6 节
* 2024.8.29
  * “第 19.1 节 开源与苦难哲学”：根据 v2ex 增补“长衫”小节
  * “第 1.4 节 Linux 用户迁移指北”：将“各大 GNU/Linux 发行版对比”一节移动到“第 19.2 节 Linux 败局与 FreeBSD 败局”，因为此节内容对 FreeBSD 新手没有多大帮助，反而会产生诸多误解
* 2024.8.25
  * “第 18.10 节 存储卡参数简介与测试”：新增“任何速度超过 104 MB/秒的 microSD 存储卡无意义”一节
* 2024.8.22
  * “第 18 章 树莓派与 RISC-V”拆分，增加《第 18.10 节 存储卡参数简介与测试》、《第 18.11 节 总线接口与协议》、《第 18.12 节 散热器、风扇、鼓风机》
* 2024.8.21
  * “第 18.1 节 树莓派简介与配件选用”新增一节“如何测试存储卡和硬盘？”
* 2024.8.19
  * “第 1.3 节 为什么要使用 FreeBSD”：补充“选择 FreeBSD 的一句话原因——FreeBSD 能在流变的世界中寻求理想的中道”一节
  * “第 1.5 节 Linux 用户迁移指北”：补充例子，使其总体呈现客观化
  * 删除原“第 1.4 节 其他 BSD 简介”，因为和后续章节重复
* 2024.8.17
  * “第 1.5 节 Linux 用户迁移指北”：补充外链、依据、命令等，使其总体呈现客观化
  * “第 1.1 节 UNIX、Unix-like、Linux 简介”：补充外链
  * 重现全文代码高亮
  * 为编撰说明一节增加了一个 pkg、ports 用法的简单例子
* 2024.8.15
  * “第 24.1 节 BSD INIT 管理服务”完全重写
  * “第 1.2 节 FreeBSD 简史”：重写“BSD 与哲学家 George Berkeley”一节
* 2024.8.14
  * 为全文的 pkg 包补充 port 方式，以防止人们忘记 Ports，同时方便需要 Ports 的用户
  * 删除原 7.5 节，因为无实质性内容
* 2024.8.11
  * 删除原第 2.7 节 手动安装 FreeBSD，因为和原第 2.1 节 安装双系统重复
  * 第 1.2 节 FreeBSD 简史：重新校对“时间表”
* 2024.8.10
  * “第 4.12 节 远程桌面管理”：新增一节，VNC 与 RDP（XRDP）对比。整体完全重写。新增一小节“使用 Android 通过 XRDP 远程访问 FreeBSD”；新增一小节“RustDesk 中继服务器”
  * 第 16 章 服务器：基本删除了所有不存在实质性内容的小节
* 2024.8.9
  * “第 18 节”：补充扩容卡、虚标卡等信息
* 2024.8.7
  * 精简压缩第 3、10、11、12、14、17 章；删除冗余
  * 基本删除了全书所有不存在实质性内容的章节
  * “第 2.9 节 SSH 相关软件推荐与 SSH 配置”：增加了 PuTTY 的典型缺陷论证；新增一节——“mosh：移动的 shell”。完全重写一节：“WinSCP 下载”
* 2024.8.6
  * “第 18.1 节 树莓派简介”：完全重写
  * 移除兼容层相关失效链接
  * “第 18.9 节 树莓派 5”：新增一节，涉及 HAT+、总线、接口与协议、散热器、风扇等
  * 精简压缩第 1、12、14、19、20、25 章，删除冗余
* 2024.8.5
  * “第 11.3 节 通过源代码更新”：将“Git 代理设置方法”移动至此。补充了“nvi”相关信息。整体排版优化
  * “第 1.6 节 UNIX 哲学”：删除不可靠且无依据的内容及引用
    * 出于可靠性考量，本书原则上禁止引用“阮一峰（<https://www.ruanyifeng.com/>）”相关内容作为参考文献
  * “第 18.2 节 系统安装”：整体排版优化；新增存储卡挑选技巧、新增 SD 卡标准分析
* 2024.8.1
  * “第 2.4 节 安装 FreeBSD——基于 VMware Workstation Pro”：新增博通注册、登录、下载流程

***

* 2021.11.19-2024.7.31
  * 《FreeBSD 从入门到跑路》第一版（初版）完成（version-1 分支）

***

* 2024.7.9
  * “第 2.11 节 声卡与网卡设置”新增“Realtek（螃蟹卡）”
* 2024.7.6
  * ykla 回归
  * 更新“第 2.14 节 FreeBSD 硬件选择”

## 2024 年第二季度

* 2024.6.2
  * “第 20.1 节 游戏”新增“Godot 游戏”
* 2024.6.1
  * 更新兼容层相关教程
  * “第 5.7 节 安装 QQ”增补若干故障排除
* 2024.5.5
  * 引入多个 GitHub Action：主要为 Markdown 格式化
* 2024.5.3
  * “贡献说明”新增“如何使用 git 拉取本项目”

## 2024 年第一季度

* 2024.2.24
  * “第 20.2 节 音视频播放器”新增“用 MPD 播放 DSD”

## 2023 年第四季度

* 2023.12.28
  * 新增“第 2.1 节 双系统安装”
* 2023.12.3
  * 本项目暂停，ykla 暂时放弃维护
* 2023.12.2
  * “第 4.5 节 安装 Xfce”新增“软件推荐”
* 2023.11.27
  * “第 18.8 节 OpenBSD 在 RISC-V 开发板上的安装”：增加串口启动输出信息
  * “第 23.4 节 引导界面”增补 FreeBSD 精简启动输出的方法
* 2023.11.26
  * 新增“第 18.8 节 OpenBSD 在 RISC-V 开发板上的安装”
  * 格式化“第 22.12 节 安装 code-server 和 clangd”
* 2023.11.23
  * 新增“第 4.9 节 安装 bspwm”
* 2023.11.19
  * “第 6.2 节 ZFS”新增“FreeBSD on zfs 的 zpool 升级”
* 2023.11.18
  * 重写“第 22.12 节 安装 code-server 和 clangd”
* 2023.11.15
  * 新增“第 4.8 节 安装 LXQt”
* 2023.11.5
  * 增补“第 22.12 节 安装 code-server 和 clangd”
* 2023.10.14
  * 增补“第 22.12 节 安装 code-server 和 clangd”
* 2023.10.13
  * 增补“第 22.12 节 安装 code-server 和 clangd”
* 2023.10.12
  * “第 4.2 节 安装 KDE 5”中的“lightdm 登录管理器本地化语言”移动至“第 4.5 节 安装 Xfce”
  * “第 4.2 节 安装 KDE 5”新增“SDDM 中文化”

## 2023 年第三季度

* 2023.9.21
  * “第 6.2 节 ZFS”新增“复制出启动环境”
* 2023.9.20
  * “第 26.4 节 桌面与其他软件”OpenBSD 新增“KDE 5”，待测试
  * “第 26.4 节 桌面与其他软件”新增 OpenBSD 关机方法
  * 审核全书所有参考文献的有效性，真实性，并统一其格式
* 2023.9.18
  * 新增“第 18.7 节 树莓派与 OpenBSD”
* 2023.9.7
  * 增补“第 8.1 节 sudo”
* 2023.9.5
  * “第 30.13 节 Linux 兼容层与应用”新增“sysctl 变量”说明
* 2023.9.4
  * 增补“第 29.5 节 安装 Hyprland”
* 2023.9.3
  * “第 29.5 节 安装 Hyprland”补图
* 2023.9.1
  * 全书代码高亮
* 2023.8.31
  * 实质性新增“第 29.5 节 安装 Hyprland”
  * 测试全书代码高亮
* 2023.8.30
  * 为便于导出 PDF，将第 0 章合并后置到第 1 章
* 2023.8.28
  * 增补“第 7.1 节 HTTP 代理”，新增“HTTP\_PROXY 代理”
  * “第 11.2 节 通过源代码更新”新增故障排除
* 2023.8.27
  * 更新“第 1.7 节 其他 BSD 简介”
* 2023.8.26
  * 增补“第 26.5 节 桌面与其他软件”
  * 验证兼容层中输入法问题
* 2023.8.25
  * “第 30.3 节 Linux 兼容层——基于 Ubuntu/Debian”新增 Debian 12（bookworm）兼容层脚本
  * 更新全书安装图片到 FreeBSD 14.0-RELEASE
* 2023.8.20
  * “第 2.9 节 触摸板的设置”新增“关闭触摸板”
  * 增补全书兼容层相关章节
* 2023.8.18
  * “第 30.1 节 Linux 兼容层实现”增补“题外话——使用 Linux 兼容层为什么不是苦难哲学？”
  * 对来源不明的章节标注版权或发出警告
* 2023.8.17
  * 新增“第 0.9 节 谁在使用 FreeBSD”
  * 新增“第 0.10 节 FreeBSD 中文社区文章翻译表”
* 2023.8.16
  * 新增“第 0.8 节 FreeBSD 子项目”
* 2023.8.13
  * 增补“第 9.4 节 jail 更新”
  * 增补“第 9.3 节 jail 配置”
  * “第 4.2 节 安装 KDE 5”增补“lightdm 登录管理器本地化语言”
* 2023.8.12
  * 增补审阅“第 3.5 节 通过源代码 ports 方式安装软件”
  * 新增“第 18.5 节 树莓派与 Linux 兼容层”
  * “第 30.11 节 Linux 兼容层——基于 Deepin”新增“直接从 FreeBSD 的命令行运行软件”
  * “第 23.4 节 引导界面”新增“精简启动输出”
* 2023.8.8
  * “第 18.3 节 使用配置”新增“htop”“显示温度”“查看 CPU 频率”
* 2023.8.7
  * 新增“第 0.8 节 FreeBSD 中文社区文章翻译表”
  * “第 17.4 节 MySQL 5.X”，补充通过 ports 安装旧版 MySQL 软件的方法
* 2023.8.4
  * “第 18.2 节 系统安装”增补内核用户空间编译等
  * 实质性填充“第 11.2 节 通过源代码更新”
* 2023.8.3
  * 新增“第 1.7 节 FreeBSD 安全公告”
  * 增补“第 3.5 节 通过源代码 ports 方式安装软件”
* 2023.8.1
  * 新增“第 11.4 节 使用 pkgbase 更新”
  * 增补“第 18.2 节 系统安装”
* 2023.7.31
  * “第 27.3 节 桌面与其他软件”新增“xfce”“Mate”
* 2023.7.30
  * “第 18.2 节 系统安装”新增“【变通方案】FreeBSD 与树莓派 4B 8G 启动失败问题”
* 2023.7.28
  * 新增“第 19.18 节 网络安全中的主体隐私权与主体选择的自由讨论——网络安全与企业道德”
  * 新增“第 17.9 节 Telegraf+InfluxDB+Grafana 监控平台”
* 2023.7.27
  * 新增“第 19.17 节 杂记”
* 2023.7.26
  * 新增 NetBSD “第 27.1 节 安装与配置”
  * 新增 NetBSD “第 27.2 节 切换软件源与包管理器”
* 2023.7.22
  * 增补 OpenBSD “第 26.1 节 安装”，将其更新至 OpenBSD 7.3
* 2023.7.21
  * 新增“第 16.15 节 MinIO 对象存储服务”
  * 新增“第 30.11 节 Linux 兼容层——基于 Deepin”
* 2023.7.12
  * 新增“第 30.7 节 Linux 兼容层——基于 Gentoo Linux”
* 2023.7.11
  * 新增“第 30.10 节 Android 兼容层”
  * 新增“第 30.7 节 Linux 兼容层——基于 Gentoo Linux”
  * 新增“第 30.8 节 Linux 兼容层——基于 Rocky Linux”
  * 新增“第 30.9 节 Linux 兼容层——基于 Slackware Linux”
* 2023.7.9
  * 向 openSUSE 提交 [Bug 1213157 - repo http://download.opensuse.org/update/leap/15.5/oss : metadata expired](https://bugzilla.opensuse.org/show_bug.cgi?id=1213157) zypper 一直有这个警告，不知道如何消除。更新、切换软件源均不起作用。dnf 显示正常。但是不影响正常使用。
* 2023.7.8
  * 新增“第 30.6 节 Linux 兼容层——基于 openSUSE”
* 2023.7.7
  * 新增视频教程 [07-FreeBSD-ArchLinux 兼容层脚本使用说明](https://www.bilibili.com/video/BV1wg4y1w7QV/)
  * 新增视频教程 [06-FreeBSD-Ubuntu 兼容层脚本使用说明](https://www.bilibili.com/video/BV1iM4y1j7E9/)
* 2023.7.5
  * 合并全书 fcitx 相关教程到“第 5.1 节 Fcitx 输入法框架”，减少重复
  * 合并全书 ibus 相关教程到“第 5.2 节 Ibus 输入法框架”，减少重复
  * “第 5.5 节 安装 金山 WPS”删除对 Ports 中 WPS 的引用。因为无人维护。
* 2023.7.4
  * “第 1.9 节 参考资料与贡献者名单”新增若干参考文献
  * “第 1.9 节 参考资料与贡献者名单”移除鸟哥的 Linux 私房菜。不适合作为 FreeBSD 参考书目
  * “第 1.9 节 参考资料与贡献者名单”：为所有参考书目增加封面

## 2023 年第二季度

* 2023.6.24
  * 新增“第 5.0 节 输入法与环境变量”
* 2023.6.19
  * “第 1.4 节 FreeBSD 与其他操作系统”新增“时间表”
* 2023.6.18
  * 新增“第 19.15 节 吾乡何处”
* 2023.6.16
  * 新增“第 30.5 节 Linux 兼容层 —— 基于 archlinux-pacman”
* 2023.6.15
  * 新增空文件“第 30.5 节 Linux 兼容层——基于 archlinux-pacman”
  * 重写“第 22.12 节 安装 code-server 和 clangd”
* 2023.6.14
  * 新增“第 19.9 节 所谓开源哲学”
  * 新增“第 19.10 节 兔子”
  * 新增“第 19.11 节 寻道”
  * 新增“第 19.12 节 诗歌选”
  * 新增“第 19.13 节 简议道风”
  * 新增“第 19.14 节 小说——你与暗”
  * “第 30.3 节 Linux 兼容层——基于 Ubuntu/Debian”新增 Shell 安装脚本
  * “第 30.4 节 Linux 兼容层——基于 ArchLinux”新增 Shell 安装脚本
* 2023.6.12
  * freebsd.cn 镜像站永久退役。移除教程中所有对其引用链接和说明
* 2023.6.10
  * TCBSD “第 31.2 节 系统安装与基本配置”新增虚拟机安装方法，辅以图片说明
  * 新增 TCBSD “第 31.3 节 开发环境配置”
* 2023.5.26
  * 更新“第 22.12 节 安装 code-server 和 clangd”
* 2023.5.24
  * 重写“第 22.12 节 安装 code-server 和 clangd”
  * portsnap 已弃用。移除教程中所有对其引用链接和说明
* 2023.5.23
  * 新增“第 22.12 节 安装 code-server 和 clangd”
* 2023.5.21
  * 更新“第 22.7 节 Python 与 VS Code”
* 2023.5.3
  * 引入 GitHub Action：链接检查、Markdown 格式化
* 2023.4.27
  * 经过 safreya 的提醒，目前 KDE 已不需要 procfs，移除教程中所有对其引用链接和说明
* 2023.4.15
  * 经过 safreya 的提醒，移除不存在的服务项 `gnome_enable="YES"`。同时提交 PR 到了 FreeBSD 手册，[The gnome service does not exist](https://reviews.freebsd.org/D39580)
  * “第 4.8 节 root 登录桌面”增补“GDM（GNOME 显示管理器）”
* 2023.4.13
  * 更新“第 11.1 节 通过 freebsd-update 更新”

## 2023 年第一季度

* 2023.3.28
  * “第 5.7 节 安装 QQ”：删除“Linux QQ 2.x （GTK 2.0）”，已弃用
  * “第 5.7 节 安装 QQ”：更新相关教程到新版 QQ
* 2023.3.24
  * 不要选`local_unbound`，会影响 DNS，见 <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=262290>。
* 2023.3.22
  * “第 23.1 节 恢复模式与密码重置”：重写 ZFS 挂载
* 2023.3.10
  * 重写“第 3.6 节 通过 DVD 安装软件”
* 2023.3.1
  * “第 24.5 节 利用脚本自动生成 BSDlibc 库文本”新增“改进方案”
* 2023.2.21
  * 新增“第 30.1 节 Linux 兼容层实现”
  * 新增“第 30.3 节 Linux 兼容层——基于 Ubuntu/Debian”
  * 新增“第 30.4 节 Linux 兼容层——基于 ArchLinux”
  * 新增“第 30.5 节 高级教程：Linux 兼容层与 Jail”
* 2023.2.8
  * “第 14.2 节 Wi-Fi”新增“博通（Broadcom）网卡驱动”
* 2023.1.24
  * 实质性填充“第 22.3 节 如何参与 FreeBSD 协作”
* 2023.1.13
  * OpenBSD“第 26.2 节 配置”新增“挂载 Android 设备”
  * 在合适的位置引入“xdg-user-dirs”以自动创建家目录相关路径
* 2023.1.11
  * 新增视频：[安装 DragonFly BSD 6.4](https://www.bilibili.com/video/BV1BM41187pD/)
* 2023.1.9
  * “第 5.7 节 安装 QQ”新增“Linux QQ 3.x（electron）【可选：基于 ArchLinux 兼容层】”
* 2023.1.8
  * 新增“第 9.6 节 使用 qjail 管理 jail”
  * “第 5.5 节 Linux 兼容层”新增“Gentoo Linux 兼容层”
* 2023.1.7
  * “第 5.5 节 Linux 兼容层”新增“安装 Windows 11 字体【可选。自制包，打包同时兼容与低版本 Ubuntu】”
* 2023.1.5
  * “第 5.5 节 Linux 兼容层”新增“ArchLinux 兼容层”
* 2023.1.4
  * 实质性填充“第 22.4 节 C/C++ 环境的配置”

## 2022 年第四季度

* 2022.12.31
  * 实现 PDF 文档导出
  * 实质性填充“第 22.6 节 Qt 环境的配置”
* 2022.12.30
  * “第 5.7 节 安装 QQ”新增“Linux QQ 3.x（electron）”
  * “第 5.5 节 Linux 兼容层”新增“缺失 .so 文件”的故障排除
* 2022.12.7
  * “第 11.1 节 通过 freebsd-update 更新”新增“查看 FreeBSD 版本”
* 2022.11.24
  * 新增“贡献指南”
  * 新增“CoC”
* 2022.11.11
  * “第一节 Fcitx 输入法框架”新增 KDE5 下的安装方法
* 2022.11.6
  * 新增 GitHub Action：Markdown 链接检查
* 2022.10.28
  * 实质性测试“第五节 使用 bhyve 安装 Windows 11”
* 2022.10.21
  * 在全书移除北京交通大学开源镜像站。不可用。
* 2022.10.15
  * 新增“第五节 使用 bhyve 安装 Windows 11”
* 2022.10.12
  * 新增“第〇节 如何订阅 FreeBSD 邮件列表”
* 2022.10.6
  * 实质性填充“第二节 安装 CDE”

## 2022 年第三季度

* 2022.9.20
  * 新增树莓派“第三节 使用配置”
  * 新增“第三节 安装 Awesome”
  * 新增“第三节 PHP 8.X”

## 2022 年第二季度

* 2022.6.23
  * 新增“第七节 小说——FreeBSD 从入门到跑路”
  * 重写“第九节 参考资料与贡献者名单”
* 2022.6.21
  * 重写“第三节 FreeBSD 的不足之处”
* 2022.6.17
  * “第二节 ZFS”新增 ZFS 快照
* 2022.6.16
  * 实质性填充“第八节 远程桌面管理”中的“XRDP”
* 2022.6.13
  * 将网站部署到 <https://book.bsdcn.org>
* 2022.6.9
  * 实质性填充“第十三节 WildFly”
* 2022.6.3
  * 实质性填充“第二节 V2Ray”
* 2022.5.27
  * “第一节 三种虚拟机与 FreeBSD 版本比较”增加阿里云相关故障排除
  * 增补“参考书目”
* 2022.5.26
  * 增补“第一节 什么是 UNIX”
  * 增补“第三节 什么是 Linux”
* 2022.5.21
  * 重写“第四节 FreeBSD 与其他操作系统”
* 2022.5.20
  * “第二节 配置”增补 OpenBSD
* 2022.5.3
  * 实质性填充“第一节 安装 i3wm”
  * 增补“第八节 Rust/Go 环境的配置”
* 2022.4.1
  * 增补“第七节 常用软件 与 SSH 配置”

## 2022 年第一季度

* 2022.3.28
  * 重写“第一节 FTP 服务器”
* 2022.3.25
  * 实质性填充“第三节 FreeBSD 的不足之处”
  * “第八节 物理机安装与硬件选配”新增“网卡推荐”
* 2022.3.22
  * 实质性填充“第一节 FTP 服务器”
* 2022.3.21
  * 重写“第三节 安装 Gnome”
  * 增补“第二节 Wi-Fi”
  * 增补“第九节 物理机下显卡的配置”
* 2022.3.19
  * 新增“第三节 Node.js 相关”
* 2022.3.4
  * 增补“第三节 安装 Gnome”
  * 实质性填充“第十三节 无线蓝牙鼠标的设置”
* 2022.3.3
  * 增补 FreeBSD“第〇章 图解安装”
* 2022.3.2
  * 增补“第三节 FreeBSD 13.0 安装——基于 VMware Workstation Pro 16”
* 2022.2.9
  * 实质性填充“第一节 FTP 服务器”
* 2022.2.5
  * 增补“第二节 FreeBSD 切换软件源方式”
* 2022.1.28
  * “第一节 三种虚拟机与 FreeBSD 版本比较”新增“Hyper-V”
* 2022.1.24
  * “第三节 安装 Gnome 3”新增输入法
* 2022.1.21
  * 实质性填充“第七节 Python 与 VS Code”
* 2022.1.7
  * 重写“第六节 root 登录桌面”
  * 重写“第四节 安装 Mate 桌面”
  * 重写“第五节 安装 Xfce”
  * 增补“第一节 Fcitx 输入法框架”
  * 增补“第六节 物理机安装与硬件选配”
* 2022.1.4
  * 增补“第九节 声卡与网卡设置”

## 2021 年第四季度

* 2021.12.31
  * 增补“第二节 FreeBSD 13.0 安装——基于 VirtualBox”网络相关
  * 增补“两种虚拟机与 FreeBSD 版本比较”
* 2021.12.30
  * 增补“第三节 FreeBSD 13.0 安装——基于 VMware Workstation Pro 15”
* 2021.12.21
  * “第八节 Linux 用户迁移指北”新增“命令对比”
* 2021.12.18
  * 实质性填充“第七节 安装 QQ”
  * 实质性增补“第二节 FreeBSD 切换软件源方式”
  * 实质性增补“第二节 Nginx”
  * 新增“第八节 PostgreSQL 与 pgAdmin4”
* 2021.12.15
  * 实质性填充“第七节 Samba 服务器”
  * 实质性填充 OpenBSD“第一节 安装”
  * 实质性填充 OpenBSD“第二节 配置”
  * 实质性填充 OpenBSD“第三节 切换软件源”
  * 实质性填充 OpenBSD“第五节 桌面与其他软件”
* 2021.12.14
  * 实质性填充 DragonFly BSD“第〇节 概述”
* 2021.12.13
  * 实质性填充“第一节 恢复模式与密码重置”
  * 实质性填充“第四节 ee 用法及网络配置”
* 2021.12.12
  * 重写“第三节 磁盘扩容”
  * 实质性填充“第四节 Firefox 与 Chromium 安装”
  * 实质性新增 FreeBSD“第〇章 图解安装”
  * 实质性填充“第八节 PostgreSQL”
  * 实质性填充“第五节 MySQL 8.X”
  * 实质性填充“第四节 MySQL 5.X”
  * 实质性填充“第一节 Apache”
* 2021.12.9
  * 新增“第五节 操作系统”
* 2021.12.8
  * 实质性增补“第一节 游戏”
* 2021.12.6
  * 实质性增补“第六节 Ext 2/3/4 等文件系统”
* 2021.12.3
  * “第八节 Rust/Go 环境的配置”新增“Golang 官方打包（不建议）”
* 2021.12.1
  * 实质性增补“第十节 压缩与解压”
* 2021.11.27
  * 实质性增补“第四节 教育”
* 2021.11.26
  * 实质性增补“第五节 科研与专业工具”
  * 实质性增补“第八节 Rust 环境的配置”
* 2021.11.20
  * 实质性增补“第七节 主题与美化”
  * 重写“第四节 安装 Mate 桌面”
  * 引入众多文章
* 2021.11.19
  * 第一次提交，添加许可证和 README.md 文件

## 2021 年第三季度

《FreeBSD 从入门到跑路》项目持续迭代。

## 2021 年第二季度

《FreeBSD 从入门到跑路》项目在 [clean-master/freebsdcn](https://github.com/clean-master/freebsdcn) 更新。

## 2021 年第一季度

* 2021.3.15
  * ykla 在翌日凌晨完成了教程的初步整理与发布，此后主要维护者始终是 ykla
* 2021.3.14
  * 《FreeBSD 从入门到跑路》肇始于 2021 年 3 月 14 日（依据 [clean-master/freebsdcn](https://github.com/clean-master/freebsdcn/graphs/contributors) 项目的创建时间分析），由 FreeBSD 中文社区 [clean-master 清理大师](https://github.com/clean-master) 发起

## 2020 年第四季度

* 2020.12.31
  * 《FreeBSD 从入门到跑路》的原型最早可追溯至 2020 年 12 月 31 日由 ykla 发布的帖子《FreeBSD 艺术科学哲学导论》


# 贡献指南与开放任务

## 贡献指南概述

若您希望将教程收录至本书，可通过以下方式提交：

* 若您熟悉 GitHub 操作，可点击桌面端网页右侧的“编辑此页”按钮进入项目编辑。本项目采用 Markdown 语法配合 GitBook 平台，易于上手（具体操作详见项目 WiKi）。
* 若上述方式存在困难，您也可发送 PDF、Word 或 TXT 格式的文档至电子邮箱 `yklaxds@gmail.com`（我们将在 3 个工作日内回复。如果没有收到回复，请更换邮箱再次发送或提交 issue）。如果有视频教程，建议上传至各大云盘并提供分享链接。

本书现收录以下类型的内容：

* 一切与 FreeBSD 相关及各种体系架构的教程。您既可以扩充现有教程，也可以创建新的章节。
* 下方的 ToDo 列表或 GitHub Project 中的任务。
* 您也可以在文学故事章节分享您与 BSD 的故事及个人心得体会。

### 基本原则与方法论

#### 基本原则

* 内容应尽可能详尽且基础，勿假定读者具备任何使用背景
* 介绍大型软件（如 IDE、Java）时，请注明软件版本号
* **引用应注重权威性、时效性与准确性。优先采用原始文献，次选二手文献，避免使用三手文献**
* 引用其他网站内容时，请核实其内容是否真实可信，尽量查阅一手来源而非直接引用网站内容
* 请提交至 main 分支
* 请避免学术不端行为，参见：高等学校预防与处理学术不端行为办法\[EB/OL]. \[2026-03-26]. <https://www.gov.cn/zhengce/2016-07/19/content_5713390.htm> （AIGC 相关规定除外）
* 请遵守 [FreeBSD 中文社区行为规范](https://docs.bsdcn.org/CODE_OF_CONDUCT)
* 所有 AIGC（AI-Generated Content，人工智能生成内容）必须经过人工二次确认，核实其原始出处与来源的可靠性，不得直接提交。但纯粹翻译可作为例外绕过本规定。任何人对所提交内容自行负责，无论其是否由 AIGC 生成

#### 使之成为“一本书”，而不仅是字典或手册

* 若某一技术在最新版本中已移除，应及时移除其在本书中的对应内容
* 使全书语气温和而坚定
* 尽量减少原文引用，重写各章节内容并删除冗余部分
* 实现 BSD 中文文档协作方式的现代化与简化：
  * 自动化（CI 检查、预览、生成 HTML/PDF）
  * 仅使用最基础的 Markdown 语法，避免复杂扩展和繁琐流程
  * 技术与选材应与时俱进，确保内容的现代化
* 严格验证每一部分内容：
  * 参考文献：不仅要求来源可查，更要求来源可信
  * 原理性内容：
    * 追溯至具体的 FreeBSD 源代码文件、提交记录或函数
    * 明确引用相关标准、规范或法律文件
    * 分析其设计哲学与开发思路
  * 操作性内容：应在 FreeBSD 环境中亲自测试，确保可复现
* 审视原作者的开发哲学与理念，评价其合理性，并尝试简单参与相关项目
* 指出并修正上游官方手册中的错误或过时内容
* 生成英文版本

#### 细则

* 非拉丁字符与拉丁字符之间应添加空格（中英文/数字之间应有一个半角空格），许多 Markdown 格式化工具可自动处理
* 不应使用 `sudo` 而应使用 `#` 代替，除非是特殊情况（如讲解如何使用 `sudo` 本身）；普通用户权限请使用 `$` 表示
* 安装软件时，请提供 pkg（FreeBSD 的二进制包管理器，用于安装、更新和管理预编译软件包，提供依赖关系解析和版本管理功能）或 Ports 两种方法，除非极不建议使用 pkg（如特定内核模块等）
* 请注意版权问题。引用内容或受到启发时，请备注文章链接出处，必要时可使用互联网档案馆快照保存
* 编辑时请尽量以最新的 FreeBSD RELEASE（FreeBSD 的正式发布版本，经过充分测试和稳定化，适合生产环境使用，每个 RELEASE 版本均有长期支持周期）为基准，绝对避免出现 `pkg_add` 等过时内容。如有必要，必须注明相关版本
* 编写工作会跟随每个 FreeBSD 大版本持续迭代更新
* 若因各种原因无法立即验证所写内容的正确性，请编辑者添加“警告：以下内容为理论，未经实际测试，仅供参考，如可使用请提交 issue 以移除本标签。”的提示标签来区分
* 不应在文学故事章节删减除错别字和排版以外的内容
* 请勿使用 Gitee 等境内无法确保信息安全与数据稳定的平台（此类平台无法保证文件的长期可访问性，不适合存放需长期归档的内容，未来存在无法获取文件的重大风险）
* 修改错别字时，请务必确认其确为错别字，可参考《现代汉语词典》第 7 版等资料佐证

## 实用附录

### 如何使用 Git 拉取本项目

> **技巧**
>
> 您完全可以通过 GitHub 在线完成所有提交。

![项目体积](https://img.shields.io/github/repo-size/FreeBSD-Ask/FreeBSD-Ask?style=for-the-badge\&label=%E6%9C%AC%E9%A1%B9%E7%9B%AE%E5%AD%98%E5%82%A8%E5%BA%93%E4%BD%93%E7%A7%AF\&color=EB0028)

本项目体积较大，使用 Git 拉取时可能导致缓冲区溢出，可通过修改 Git 配置文件来扩大缓冲区。

以下是一个可用的 `~/.gitconfig`（在 Windows 系统中的位置为 `C:\Users\你的用户名\.gitconfig`）的文件示例：

```ini
[filter "lfs"]
	required = true
	clean = git-lfs clean -- %f
	smudge = git-lfs smudge -- %f
	process = git-lfs filter-process
[user]
	name = # 你的用户名
	email = # 你的邮箱
	signingkey = # 你的密钥 ID，使用密钥签名时需要
[commit]
	gpgsign = true # 使用密钥签名时需要
[core]
	autocrlf = true # 自动调整末尾回车与换行
[http]
	proxy = http://localhost:7890 # 设置使用 http 代理
	postBuffer = 1048576000 # 扩大缓冲区，约 1 GB
	maxRequestBuffer = 1048576000 # 扩大缓冲区，约 1 GB
```

名词解释：

* `autocrlf`：配置 Git 自动处理（转换）行结束符的默认行为。参见：配置 Git 处理行结束符 - GitHub Docs\[EB/OL]. \[2026-03-26]. <https://docs.github.com/zh/get-started/git-basics/configuring-git-to-handle-line-endings>.
* `signingkey`：指设置带签名提交时默认使用的签名密钥。signingkey 既可指 GPG Key，也可以指 SSH Key。自 Git 2.34 起，Git 支持了 SSH 签名验证功能。参见：关于提交签名验证 - GitHub Docs\[EB/OL]. \[2026-03-26]. <https://docs.github.com/zh/authentication/managing-commit-signature-verification/about-commit-signature-verification>.

拉取命令：

```sh
$ git clone https://github.com/FreeBSD-Ask/FreeBSD-Ask
```

#### 附录：Windows Git 配置示例

```ini
[filter "lfs"]
	required = true
	clean = git-lfs clean -- %f
	smudge = git-lfs smudge -- %f
	process = git-lfs filter-process
[user]
	name = ykla
	email = yklaxds@gmail.com
	signingkey = 11B44C23A0A0B986
[commit]
  gpgsign = true
[core]
	autocrlf = true
	longpaths = true
	editor = 'C:/Program Files/Notepad++/notepad++.exe' -multiInst -nosession
[difftool "sourcetree"]
	cmd = "'' "
[mergetool "sourcetree"]
	cmd = "'' "
	trustExitCode = true
[http]
	proxy = http://localhost:7890
	postBuffer = 1048576000
	maxRequestBuffer = 1048576000

[gpg]
	program = C:/Program Files/GnuPG/bin/gpg.exe
[safe]
	directory = C:/Users/ykla/Documents/hub/unix-haters
```

#### 故障排除

* `致命错误：无法访问 'https://github.com/FreeBSD-Ask/FreeBSD-Ask/': Recv failure: 连接被对方重置`

请尝试拉取项目 `https://github.com/FreeBSD-Ask/LDWG`。

若报错类似，说明您的网络存在问题，请使用代理。

### 项目简介

本项目主要托管在 GitBook（即 `https://book.bsdcn.org`）；

`https://docs.bsdcn.org` 由社区自行构建，docs 网站本身的贡献指南参见：FreeBSD 从入门到跑路 VitePress 镜像项目\[EB/OL]. \[2026-03-26]. <https://github.com/FreeBSD-Ask/FreeBSD-Ask.github.io/blob/main/README.md>。

> **技巧**
>
> 若您仅想贡献内容本身，尚无改进 docs 网站浏览体验与构建优化等意向，则仅需阅读本文即可。

### 项目结构概览

```sh
> FreeBSD-Ask-main
│  .gitattributes  # 用于让 GitHub 正确识别 markdown，用于在 GitHub 正确高亮，正确显示编程语言（Languages）的统计信息
│  .gitignore # 一些规则，用于阻止 git 上传特定类型的文件或目录，如 node_modules
│  CHANGELOG-ARCHIVE.md # 普通文件，记录既往所有重要变动
│  CHANGELOG.md # 普通文件，记录当前季度的重要变动。当你有新的子章节提交或彻底重写时，请将其记录到此处
│  CODE_OF_CONDUCT.md # 用于合规，行为准则
│  CONTRIBUTING.md # 贡献指南（本文本身）
│  LICENSE # 许可证
│  mu-lu.md # 由 GitHub Action mulu.yml 自动同步
│  README.md # 主页
│  SECURITY.md # 用于合规，安全报告策略
│  SUMMARY.md # 目录文件，同时用于生成 vitepress 左侧边栏
│
├─.gitbook # 图片目录
│  └─assets # 图片
│          1-install.png
│          1.png
│          1011.png
│          其他图片从略
│
├─.github  # Github Action 相关
│  │  .autocorrectrc # 由 AutoCorrect.yml 调用
│  │  .markdownlint.json # 由 markdown-lint2.yml 调用
│  │  auto_assign.yml # 由 Auto-Assign.yml 调用
│  │  dependabot.yml # 检查 GitHub Action 调用的 Action 有无更新，并提交 PR
│  │  lychee.toml # 由 links.yml 调用
│  │
│  ├─ISSUE_TEMPLATE  # GitHub issue、PR 模板
│  │      bug_report.md  # GitHub issue 模板
│  │      feature_request.md  # GitHub PR 模板
│  │
│  ├─scripts # GitHub Action 相关，由 yml 脚本调用
│  │      check_images.py # 由 check-images.yml 调用
│  │      update_ga4_readme.py # 由 update-ga4.yml 调用
│  │      update_progress.sh # 由 Update-commit-progress.yml 调用
│  │
│  └─workflows # GitHub Action，用于自动化处理一些简单任务
│          Auto-Assign.yml # 自动为 issue PR 分配人员处理
│          AutoCorrect.yml # markdown 格式修正，会自动提交 PR
│          check-images.yml # 检查图片的调用情况，有无正确引用图片，不正确会生成 issue
│          create-pdf.yml # 用于在 GitHub release 生成电子书 PDF、EPUB
│          file-name-check.yml # 检查 SUMMARY.md 目录中的文件引用是否正确，不正确会生成 issue
│          links.yml # 链接检查，检查文中调用的 URL 是否能正常访问
│          markdown-lint2.yml # markdown 格式检查
│          md-padding.yml # markdown 空格检查与修复
│          mulu.yml # 从 SUMMARY.md 生成的镜像文件
│          sync-headers.yml # 从 SUMMARY.md 更新所有 markdown 文件的一级标题。如果你要修改 # 标题，必须在此处修改，否则会被它覆盖
│          Update-commit-progress.yml # 进度检查工具，每 3533 次提交为一个版本，用于插入到 README.md
│          update-ga4.yml # 谷歌统计数据，用于插入到 README.md
│
├─.vitepress # vitepress 相关，详见 FreeBSD-Ask/FreeBSD-Ask.github.io
│  │  config.mts
│  │
│  └─theme # vitepress 相关，详见 FreeBSD-Ask/FreeBSD-Ask.github.io
│          custom.css
│          index.js
│          Layout.vue
│
├─di-1-zhang-freebsd-chu-jian # 第 1 章的章节目录
│      di-1.1-jie-shen-me-shi-unix.md # 第 1 章的文件
│      di-1.2-jie-gnu-cao-zuo-xi-tong-he-zi-you-ruan-jian-yun-dong.md
│      di-1.3-jie-linux-yu-lei-unix.md
│      di-1.4-jie-shen-me-shi-freebsd.md
│
├─di-10-zhang-xian-ka-qu-dong # 第 10 章的章节目录
│      di-10.1-jie-xian-ka-qu-dong-gai-lun.md # 第 10 章的文件
│      di-10.2-jie-intel-xian-ka-qu-dong.md
│      di-10.3-jie-amd-xian-ka-qu-dong.md
│      di-10.4-jie-nvidia-xian-ka-qu-dong.md
│
└─其他目录和文件从略
│
├─public # vitepress 相关，参见 FreeBSD-Ask/FreeBSD-Ask.github.io
│      favicon.ico
│      logo.svg
│
└─其他目录和文件从略
```

### 如何新建章节

自行操作时参见操作实例 Commit 6023cc8\[EB/OL]. \[2026-03-26]. <https://github.com/FreeBSD-Ask/FreeBSD-Ask/commit/6023cc8d58f3a1b9849ff11fa63bf3980177c370> 和下方 `SUMMARY.md` 结构说明。

如果有困难可发邮件联系 ykla 协助操作。

#### `SUMMARY.md` 目录结构

```md
# Table of contents

* [FreeBSD 从入门到跑路](README.md)
* [编辑日志](CHANGELOG.md)
* [贡献指南与开放任务](CONTRIBUTING.md)
* [目录](mu-lu.md)

## 前言

* [前言](qian-yan/qian-yan.md)
* [绪论](qian-yan/xu-lun.md)
* [致读者：解放思想，回归本真，高扬人道主义，不走苦难哲学的邪路](qian-yan/zhi-du-zhe-jie-fang-si-xiang-hui-gui-ben-zhen-gao-yang-ren-dao-zhu-yi-bu-zou-ku-nan-zhe-xue-de-xie-lu.md)
* [致谢](qian-yan/zhi-xie.md)

## 第 1 章 FreeBSD 初见

* [1.1 什么是 UNIX？](di-1-zhang-freebsd-chu-jian/di-1.1-jie-shen-me-shi-unix.md)
* [1.2 GNU 操作系统和自由软件运动](di-1-zhang-freebsd-chu-jian/di-1.2-jie-gnu-cao-zuo-xi-tong-he-zi-you-ruan-jian-yun-dong.md)
* [1.3 Linux 与类 UNIX](di-1-zhang-freebsd-chu-jian/di-1.3-jie-linux-yu-lei-unix.md)
* [1.4 什么是 FreeBSD](di-1-zhang-freebsd-chu-jian/di-1.4-jie-shen-me-shi-freebsd.md)

## 第 2 章 FreeBSD 导论

* [2.1 FreeBSD：理想、现实与中道](di-2-zhang-freebsd-dao-lun/di-2.1-jie-freebsd-li-xiang-xian-shi-yu-zhong-dao.md)
* [2.2 关于 FreeBSD 项目](di-2-zhang-freebsd-dao-lun/di-2.2-jie-guan-yu-freebsd-xiang-mu.md)
* [2.3 FreeBSD 开发模型](di-2-zhang-freebsd-dao-lun/di-2.3-jie-freebsd-kai-fa-mo-xing.md)
* [2.4 FreeBSD 简史](di-2-zhang-freebsd-dao-lun/di-2.4-jie-freebsd-jian-shi.md)

其他从略
```

可以看到，`SUMMARY.md` 在形式上就是普通的 Markdown 文档，并无特殊支持。

但有一些注意事项：

* 第一行 `# Table of contents` 绝对不允许变更，否则 GitBook 将无法识别，导致失去同步。
* 要求格式应为 `* [2.2 使用 bsdinstall 开始安装](di-2-zhang-an-zhuang-freebsd/di-2.2-jie-start-install.md)`，不允许出现 `* [2.2 使用 bsdinstall 开始安装](di-3-zhang-ni-hao/di-2.2-jie-start-install.md)` 这种情况，即目录结构与文件放置位置必须一致（不一致虽不会报错，但本项目要求保持一致）。
* 通过 `sync-headers.yml`，将自动同步 `SUMMARY.md` 中的章节标题到具体的 Markdown 文件中。因此如果需要修改 `di-2.2-jie-start-install.md` 的一级标题 `# 2.2 使用 bsdinstall 开始安装`，必须仅修改 `SUMMARY.md` 中的 `2.2 使用 bsdinstall 开始安装`，否则会被 `sync-headers.yml` 覆盖。二者不一致时，若提交时未触发脚本构建，则 GitBook 将以 `SUMMARY.md` 中的目录为准。

### 预览页面

您提交 PR 时，系统会自动生成预览网站。

实际上，所有提交都有对应的网站版本：

![GitHub PR 页面](/files/ScglUbLz9N1uERYUxOhz)

您可通过该链接获取当前 PR 的实际显示样式：

![GitHub PR 页面](/files/sOUhv0afmXdhUVsk0arY)

![GitBook 预览页面](/files/9QKlFIQo0lmamn1TCOp3)

且每次 push 都会自动更新：

![GitBook 预览页面](/files/La9EZzLglRu3G85PO1uu)

## 开放任务

所有任务的排序均为随机，无优先级之分，您可选择感兴趣的任务参与。

### 开源社区

#### 维护百度百科、维基百科相关条目

如增补修订各 BSD 中文条目。

#### 帮助修订 USTC 镜像脚本

* <https://github.com/ustclug/ustcmirror-images/blob/master/freebsd-pkg/sync.sh>
* <https://github.com/ustclug/ustcmirror-images/blob/master/freebsd-ports/sync-ports.sh>

### FreeBSD ToDo

**不再需要** 的内容（请 **不要** 撰写下列条目）：

* [ ] 9.6.图像扫描仪（谁有？而且谁支持 FreeBSD？）
* [ ] 18.7.在 MAC Jail 中运行 Nagios（过时，不写。请用其他案例代替）
* [ ] 第 11 章 打印（本节对中英文均无意义，不引入）
* [ ] 24.8.基于 FreeBSD 的 Xen™ 虚拟机（过时、支持差。真的支持 Windows 11 吗？10 也行。Xen 真难用，而且删除了 PV 支持）
* [ ] 31.4.Sendmail（过时，用 Postfix 等代替）
* [ ] 32.2.inetd 超级服务器（过时。谁在用？）
* [ ] 32.4.网络信息系统（NIS）（过时，用 SSSD-LDAP 代替）
* [ ] 30.5.使用 ATM 上的 PPP (PPPoA)（过时）
* [ ] 29.4.拨入服务（过时）
* [ ] gbde 相关加密（已从 [源代码](https://github.com/freebsd/freebsd-src/commit/8d2d1d651678178aa7f24f0530347f860423fd9e)移除）
* [ ] 29.5.拨出服务（过时）
* [ ] 30.2.配置 PPP（过时）
* [ ] 31.3.DragonFly 邮件代理（DMA）（DMA 为 FreeBSD 14.0 起默认 MTA，可用 Postfix 等代替）
* [ ] 20.10.文件系统快照（UFS）（与 ZFS 快照相比功能有限）
* [ ] 21.8.通过 GEOM 实现 UFS 日志（无意义）

**Just for fun**（可有可无）

* [ ] 20.7.创建和使用软盘（谁还有这种东西？2024，日本政府决定全面淘汰软盘）（无意义，但勉强可以写，如果有光驱和软盘 *Just for fun*）
* [ ] 20.6.创建和使用 DVD（无意义，但勉强可以写，如果有光驱和光盘 *Just for fun*）
* [ ] 20.5.创建和使用 CD（无意义，但勉强可以写，如果有光驱和光盘 *Just for fun*）
* [ ] 16.9.Kerberos（谁在用？）

**需要重写** 的内容（请撰写这些内容）：

参见：Projects\[EB/OL]. \[2026-03-26]. <https://github.com/FreeBSD-Ask/FreeBSD-Ask/projects>。


# 目录

* [FreeBSD 从入门到跑路](/)
* [编辑日志](/changelog)
* [贡献指南与开放任务](/contributing)
* [目录](/mu-lu)

## 前言

* [前言](/qian-yan/qian-yan)
* [绪论](/qian-yan/xu-lun)
* [致读者：解放思想，回归本真，高扬人道主义，不走苦难哲学的邪路](/qian-yan/zhi-du-zhe-jie-fang-si-xiang-hui-gui-ben-zhen-gao-yang-ren-dao-zhu-yi-bu-zou-ku-nan-zhe-xue-de-xie-l)
* [致谢](/qian-yan/zhi-xie)

## 第 1 章 FreeBSD 初见

* [1.1 什么是 UNIX？](/di-1-zhang-freebsd-chu-jian/di-1.1-jie-shen-me-shi-unix)
* [1.2 GNU 操作系统和自由软件运动](/di-1-zhang-freebsd-chu-jian/di-1.2-jie-gnu-cao-zuo-xi-tong-he-zi-you-ruan-jian-yun-dong)
* [1.3 Linux 与类 UNIX](/di-1-zhang-freebsd-chu-jian/di-1.3-jie-linux-yu-lei-unix)
* [1.4 什么是 FreeBSD](/di-1-zhang-freebsd-chu-jian/di-1.4-jie-shen-me-shi-freebsd)

## 第 2 章 FreeBSD 导论

* [2.1 FreeBSD：理想、现实与中道](/di-2-zhang-freebsd-dao-lun/di-2.1-jie-freebsd-li-xiang-xian-shi-yu-zhong-dao)
* [2.2 关于 FreeBSD 项目](/di-2-zhang-freebsd-dao-lun/di-2.2-jie-guan-yu-freebsd-xiang-mu)
* [2.3 FreeBSD 开发模型](/di-2-zhang-freebsd-dao-lun/di-2.3-jie-freebsd-kai-fa-mo-xing)
* [2.4 FreeBSD 简史](/di-2-zhang-freebsd-dao-lun/di-2.4-jie-freebsd-jian-shi)

## 第 3 章 BSD 文化与 BSD 发行版概论

* [3.1 乔治·贝克莱与 BSD 文化传统](/di-3-zhang-bsd-wen-hua-yu-bsd-fa-xing-ban-gai-lun/di-3.1-jie-qiao-zhi-bei-ke-lai-george-berkeley-yu-bsd-wen-hua-chuan-tong)
* [3.2 BSD 许可证概览](/di-3-zhang-bsd-wen-hua-yu-bsd-fa-xing-ban-gai-lun/di-3.2-jie-bsd-xu-ke-zheng-gai-lan)
* [3.3 NetBSD 概论](/di-3-zhang-bsd-wen-hua-yu-bsd-fa-xing-ban-gai-lun/di-3.3-jie-netbsd-gai-lun)
* [3.4 OpenBSD 概论](/di-3-zhang-bsd-wen-hua-yu-bsd-fa-xing-ban-gai-lun/di-3.4-jie-openbsd-gai-lun)
* [3.5 DragonFly BSD 概论](/di-3-zhang-bsd-wen-hua-yu-bsd-fa-xing-ban-gai-lun/di-3.5-jie-dragonfly-bsd-gai-lun)

## 第 4 章 迁移指南

* [4.1 Windows 用户迁移指南](/di-4-zhang-qian-yi-zhi-nan/di-4.1-jie-windows-yong-hu-qian-yi-zhi-nan)
* [4.2 Linux 用户迁移指南](/di-4-zhang-qian-yi-zhi-nan/di-4.2-jie-linux-yong-hu-qian-yi-zhi-nan)
* [4.3 macOS 用户迁移指南](/di-4-zhang-qian-yi-zhi-nan/di-4.3-jie-macos-yong-hu-qian-yi-zhi-nan)

## 第 5 章 FreeBSD 安装基础

* [5.1 安装前的准备工作](/di-5-zhang-freebsd-an-zhuang-ji-chu/di-5.1-jie-an-zhuang-qian-de-zhun-bei-gong-zuo)
* [5.2 FreeBSD 15 安装指南（AMD64）](/di-5-zhang-freebsd-an-zhuang-ji-chu/di-5.2-jie-freebsd-15-an-zhuang-zhi-nan-amd64)
* [5.3 安装故障排除](/di-5-zhang-freebsd-an-zhuang-ji-chu/di-5.3-jie-an-zhuang-gu-zhang-pai-chu)
* [5.4 在 Windows 中将 USB 启动盘恢复为普通存储设备](/di-5-zhang-freebsd-an-zhuang-ji-chu/di-5.4-jie-zai-windows-zhong-jiang-usb-qi-dong-pan-hui-fu-wei-pu-tong-cun-chu-she-bei)

## 第 6 章 虚拟化平台安装 FreeBSD

* [6.1 使用 VMware Workstation Pro 安装 FreeBSD](/di-6-zhang-xu-ni-hua-ping-tai-an-zhuang-freebsd/di-6.1-jie-shi-yong-vmware-workstation-pro-an-zhuang-freebsd)
* [6.2 使用 VirtualBox 安装 FreeBSD](/di-6-zhang-xu-ni-hua-ping-tai-an-zhuang-freebsd/di-6.2-jie-shi-yong-virtualbox-an-zhuang-freebsd)
* [6.3 使用 Hyper-V 安装 FreeBSD](/di-6-zhang-xu-ni-hua-ping-tai-an-zhuang-freebsd/di-6.3-jie-shi-yong-hyper-v-an-zhuang-freebsd)
* [6.4 基于 Apple M1 和 Parallels Desktop 安装 FreeBSD](/di-6-zhang-xu-ni-hua-ping-tai-an-zhuang-freebsd/di-6.4-jie-ji-yu-apple-m1-he-parallels-desktop-an-zhuang-freebsd)
* [6.5 基于 Apple M1 和 VMware Fusion Pro 安装 FreeBSD](/di-6-zhang-xu-ni-hua-ping-tai-an-zhuang-freebsd/di-6.5-jie-ji-yu-apple-m1-he-vmware-fusion-pro-an-zhuang-freebsd)

## 第 7 章 命令行环境

* [7.1 虚拟控制台和终端](/di-7-zhang-ming-ling-xing-huan-jing/di-7.1-jie-xu-ni-kong-zhi-tai-he-zhong-duan)
* [7.2 shell 基础](/di-7-zhang-ming-ling-xing-huan-jing/di-7.2-jie-shell)
* [7.3 切换 shell](/di-7-zhang-ming-ling-xing-huan-jing/di-7.3-jie-qie-huan-shell)
* [7.4 命令行基础](/di-7-zhang-ming-ling-xing-huan-jing/di-7.4-jie-ming-ling-xing-ji-chu)
* [7.5 文本编辑器](/di-7-zhang-ming-ling-xing-huan-jing/di-7.5-jie-wen-ben-bian-ji-qi)
* [7.6 压缩和解压缩](/di-7-zhang-ming-ling-xing-huan-jing/di-7.6-jie-ya-suo-he-jie-ya-suo)

## 第 8 章 软件管理

* [8.1 FreeBSD 包管理器概述](/di-8-zhang-ruan-jian-guan-li/di-8.1-jie-freebsd-bao-guan-li-qi-gai-shu)
* [8.2 FreeBSD 软件源](/di-8-zhang-ruan-jian-guan-li/di-8.2-jie-freebsd-ruan-jian-yuan)
* [8.3 使用 pkg 管理二进制包](/di-8-zhang-ruan-jian-guan-li/di-8.3-jie-shi-yong-pkg-guan-li-er-jin-zhi-bao)
* [8.4 使用 Ports 以源代码方式安装软件](/di-8-zhang-ruan-jian-guan-li/di-8.4-jie-shi-yong-ports-yi-yuan-dai-ma-fang-shi-an-zhuang-ruan-jian)
* [8.5 Ports 构建调优](/di-8-zhang-ruan-jian-guan-li/di-8.5-jie-ports-gou-jian-diao-you)
* [8.6 使用 DVD 安装软件](/di-8-zhang-ruan-jian-guan-li/di-8.6-jie-shi-yong-dvd-an-zhuang-ruan-jian)
* [8.7 FreeBSD 镜像站现状](/di-8-zhang-ruan-jian-guan-li/di-8.7-jie-freebsd-jing-xiang-zhan-xian-zhuang)

## 第 9 章 网络管理

* [9.1 计算机网络基础](/di-9-zhang-wang-luo-guan-li/di-9.1-jie-ji-suan-ji-wang-luo-ji-chu)
* [9.2 基础网络管理](/di-9-zhang-wang-luo-guan-li/di-9.2-jie-ji-chu-wang-luo-guan-li)
* [9.3 无线网络管理](/di-9-zhang-wang-luo-guan-li/di-9.3-jie-wu-xian-wang-luo-guan-li)
* [9.4 蓝牙](/di-9-zhang-wang-luo-guan-li/di-9.4-jie-lan-ya)
* [9.5 USB 网络共享](/di-9-zhang-wang-luo-guan-li/di-9.5-jie-usb-wang-luo-gong-xiang)
* [9.6 系统代理](/di-9-zhang-wang-luo-guan-li/di-9.6-jie-xi-tong-dai-li)

## 第 10 章 显卡驱动

* [10.1 显卡驱动概论](/di-10-zhang-xian-ka-qu-dong/di-10.1-jie-xian-ka-qu-dong-gai-lun)
* [10.2 Intel 显卡驱动](/di-10-zhang-xian-ka-qu-dong/di-10.2-jie-intel-xian-ka-qu-dong)
* [10.3 AMD 显卡驱动](/di-10-zhang-xian-ka-qu-dong/di-10.3-jie-amd-xian-ka-qu-dong)
* [10.4 NVIDIA 显卡驱动](/di-10-zhang-xian-ka-qu-dong/di-10.4-jie-nvidia-xian-ka-qu-dong)

## 第 11 章 X Window 系统

* [11.1 X Window 系统概论](/di-11-zhang-xwindow-xi-tong/di-11.1-jie-x-window-xi-tong-gai-lun)
* [11.2 显示管理器](/di-11-zhang-xwindow-xi-tong/di-11.2-jie-xian-shi-guan-li-qi)
* [11.3 系统字体](/di-11-zhang-xwindow-xi-tong/di-11.3-jie-xi-tong-zi-ti)
* [11.4 远程桌面](/di-11-zhang-xwindow-xi-tong/di-11.4-jie-yuan-cheng-zhuo-mian)

## 第 12 章 Wayland 系统

* [12.1 Wayland 概论](/di-12-zhang-wayland-xi-tong/di-12.1-jie-wayland-gai-lun)
* [12.2 Wayland 显示管理器](/di-12-zhang-wayland-xi-tong/di-12.2-jie-wayland-xian-shi-guan-li-qi)

## 第 13 章 桌面环境

* [13.1 KDE 6 桌面环境（X11 会话）](/di-13-zhang-zhuo-mian-huan-jing/di-13.1-jie-kde-6-zhuo-mian-huan-jing-x11-hui-hua)
* [13.2 KDE 6 桌面环境（Wayland 会话）](/di-13-zhang-zhuo-mian-huan-jing/di-13.2-jie-kde-6-zhuo-mian-huan-jing-wayland-hui-hua)
* [13.3 MATE](/di-13-zhang-zhuo-mian-huan-jing/di-13.3-jie-mate)
* [13.4 Xfce](/di-13-zhang-zhuo-mian-huan-jing/di-13.4-jie-xfce)
* [13.5 Cinnamon](/di-13-zhang-zhuo-mian-huan-jing/di-13.5-jie-cinnamon)
* [13.6 LXQt](/di-13-zhang-zhuo-mian-huan-jing/di-13.6-jie-lxqt)
* [13.7 GNOME](/di-13-zhang-zhuo-mian-huan-jing/di-13.7-jie-gnome)
* [13.8 IceWM](/di-13-zhang-zhuo-mian-huan-jing/di-13.8-jie-icewm)
* [13.9 CDE（拟删除）](/di-13-zhang-zhuo-mian-huan-jing/di-13.9-jie-cde-ni-shan-chu)

## 第 14 章 多媒体和外部设备

* [14.1 声卡](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.1-jie-sheng-ka)
* [14.2 打印机](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.2-jie-da-yin-ji)
* [14.3 摄像头](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.3-jie-she-xiang-tou)
* [14.4 人机输入设备](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.4-jie-ren-ji-shu-ru-she-bei)
* [14.5 音频播放器](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.5-jie-yin-pin-bo-fang-qi)
* [14.6 视频播放器](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.6-jie-shi-pin-bo-fang-qi)
* [14.7 多媒体处理](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.7-jie-duo-mei-ti-chu-li)
* [14.8 文档查看器](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.8-jie-wen-dang-cha-kan-qi)
* [14.9 Web 浏览器](/di-14-zhang-duo-mei-ti-he-wai-bu-she-bei/di-14.9-jie-web-liu-lan-qi)

## 第 15 章 本地化与输入法

* [15.1 本地化环境变量](/di-15-zhang-ben-di-hua-yu-shu-ru-fa/di-15.1-jie-ben-di-hua-huan-jing-bian-liang)
* [15.2 特定语言的区域配置](/di-15-zhang-ben-di-hua-yu-shu-ru-fa/di-15.2-jie-te-ding-yu-yan-de-qu-yu-pei-zhi)
* [15.3 Fcitx 输入法框架](/di-15-zhang-ben-di-hua-yu-shu-ru-fa/di-15.3-jie-fcitx-shu-ru-fa-kuang-jia)
* [15.4 IBus 输入法框架](/di-15-zhang-ben-di-hua-yu-shu-ru-fa/di-15.4-jie-ibus-shu-ru-fa-kuang-jia)
* [15.5 五笔输入法](/di-15-zhang-ben-di-hua-yu-shu-ru-fa/di-15.5-jie-wu-bi-shu-ru-fa)

## 第 16 章 系统引导

* [16.1 启动引导器](/di-16-zhang-xi-tong-yin-dao/di-16.1-jie-qi-dong-yin-dao-qi)
* [16.2 启动消息（dmesg）](/di-16-zhang-xi-tong-yin-dao/di-16.2-jie-qi-dong-xiao-xi-dmesg)
* [16.3 引导管理器与 UEFI 固件](/di-16-zhang-xi-tong-yin-dao/di-16.3-jie-yin-dao-guan-li-qi-yu-uefi-gu-jian)
* [16.4 进程与守护进程](/di-16-zhang-xi-tong-yin-dao/di-16.4-jie-jin-cheng-yu-shou-hu-jin-cheng)
* [16.5 管理 FreeBSD 中的服务](/di-16-zhang-xi-tong-yin-dao/di-16.5-jie-guan-li-freebsd-zhong-de-fu-wu)

## 第 17 章 用户账户与权限

* [17.1 用户和基本账户管理](/di-17-zhang-yong-hu-zhang-hu-yu-quan-xian/di-17.1-jie-yong-hu-he-ji-ben-zhang-hu-guan-li)
* [17.2 权限](/di-17-zhang-yong-hu-zhang-hu-yu-quan-xian/di-17.2-jie-quan-xian)
* [17.3 用户分级](/di-17-zhang-yong-hu-zhang-hu-yu-quan-xian/di-17.3-jie-yong-hu-fen-ji)
* [17.4 权限提升工具](/di-17-zhang-yong-hu-zhang-hu-yu-quan-xian/di-17.4-jie-quan-xian-ti-sheng-gong-ju)

## 第 18 章 系统管理

* [18.1 系统目录结构](/di-18-zhang-xi-tong-guan-li/di-18.1-jie-xi-tong-mu-lu-jie-gou)
* [18.2 bsdconfig](/di-18-zhang-xi-tong-guan-li/di-18.2-jie-bsdconfig)
* [18.3 OpenSSH](/di-18-zhang-xi-tong-guan-li/di-18.3-jie-openssh)
* [18.4 设备资源提示](/di-18-zhang-xi-tong-guan-li/di-18.4-jie-she-bei-zi-yuan-ti-shi)
* [18.5 Cron 和 Periodic](/di-18-zhang-xi-tong-guan-li/di-18.5-jie-cron-he-periodic)
* [18.6 系统日志管理](/di-18-zhang-xi-tong-guan-li/di-18.6-jie-xi-tong-ri-zhi-guan-li)
* [18.7 sysctl 工具](/di-18-zhang-xi-tong-guan-li/di-18.7-jie-sysctl-gong-ju)
* [18.8 NTP 时间同步与时区](/di-18-zhang-xi-tong-guan-li/di-18.8-jie-ntp-shi-jian-tong-bu-yu-shi-qu)
* [18.9 Live 镜像与系统恢复](/di-18-zhang-xi-tong-guan-li/di-18.9-jie-live-jing-xiang-yu-xi-tong-hui-fu)

## 第 19 章 FreeBSD 系统更新

* [19.1 使用 freebsd-update 更新 FreeBSD](/di-19-zhang-freebsd-xi-tong-geng-xin/di-19.1-jie-shi-yong-freebsd-update-geng-xin-freebsd)
* [19.2 使用源代码更新 FreeBSD](/di-19-zhang-freebsd-xi-tong-geng-xin/di-19.2-jie-shi-yong-yuan-dai-ma-geng-xin-freebsd)
* [19.3 使用 PkgBase 更新基本系统](/di-19-zhang-freebsd-xi-tong-geng-xin/di-19.3-jie-shi-yong-pkgbase-geng-xin-ji-ben-xi-tong)
* [19.4 通过 ZFS 启动环境实现多版本共存](/di-19-zhang-freebsd-xi-tong-geng-xin/di-19.4-jie-tong-guo-zfs-qi-dong-huan-jing-shi-xian-duo-ban-ben-gong-cun)

## 第 20 章 Linux 兼容层

* [20.1 Linux 兼容层架构](/di-20-zhang-linux-jian-rong-ceng/di-20.1-jie-linux-jian-rong-ceng-jia-gou)
* [20.2 Rocky Linux 兼容层](/di-20-zhang-linux-jian-rong-ceng/di-20.2-jie-rocky-linux-jian-rong-ceng)
* [20.3 Ubuntu/Debian/Kali Linux 兼容层](/di-20-zhang-linux-jian-rong-ceng/di-20.3-jie-ubuntu-debian-kali-linux-jian-rong-ceng)
* [20.4 Arch Linux 兼容层](/di-20-zhang-linux-jian-rong-ceng/di-20.4-jie-arch-linux-jian-rong-ceng)
* [20.5 Slackware Linux 兼容层](/di-20-zhang-linux-jian-rong-ceng/di-20.5-jie-slackware-linux-jian-rong-ceng)
* [20.6 Gentoo Linux 兼容层](/di-20-zhang-linux-jian-rong-ceng/di-20.6-jie-gentoo-linux-jian-rong-ceng)
* [20.7 微信（Linux 版）](/di-20-zhang-linux-jian-rong-ceng/di-20.7-jie-wei-xin-linux-ban)
* [20.8 QQ（Linux 版）](/di-20-zhang-linux-jian-rong-ceng/di-20.8-jie-qq-linux-ban)
* [20.9 WPS Office（Linux 版）](/di-20-zhang-linux-jian-rong-ceng/di-20.9-jie-wps-office-linux-ban)
* [20.10 故障排除与未竟事宜](/di-20-zhang-linux-jian-rong-ceng/di-20.10-jie-gu-zhang-pai-chu-yu-wei-jing-shi-yi)

## 第 21 章 FreeBSD 高级安装

* [21.1 安装双系统（先安装 FreeBSD）](/di-21-zhang-freebsd-gao-ji-an-zhuang/di-21.1-jie-an-zhuang-shuang-xi-tong-xian-an-zhuang-freebsd)
* [21.2 安装双系统（后安装 FreeBSD）](/di-21-zhang-freebsd-gao-ji-an-zhuang/di-21.2-jie-an-zhuang-shuang-xi-tong-hou-an-zhuang-freebsd)
* [21.3 腾讯云轻量云安装 FreeBSD（传统引导和 MBR 分区表）](/di-21-zhang-freebsd-gao-ji-an-zhuang/di-21.3-jie-teng-xun-yun-qing-liang-yun-an-zhuang-freebsd-chuan-tong-yin-dao-he-mbr-fen-qu-biao)
* [21.4 KVM、QEMU 等平台安装 FreeBSD（传统引导和 MBR 分区表）](/di-21-zhang-freebsd-gao-ji-an-zhuang/di-21.4-jie-kvm-qemu-deng-ping-tai-an-zhuang-freebsd-chuan-tong-yin-dao-he-mbr-fen-qu-biao)
* [21.5 阿里云轻量应用服务器安装 FreeBSD（UEFI 和 GPT 分区表）](/di-21-zhang-freebsd-gao-ji-an-zhuang/di-21.5-jie-a-li-yun-qing-liang-ying-yong-fu-wu-qi-an-zhuang-freebsd-uefi-he-gpt-fen-qu-biao)
* [21.6 QEMU 安装 RISC-V FreeBSD（基于 x86 Windows 主机）](/di-21-zhang-freebsd-gao-ji-an-zhuang/di-21.6-jie-qemu-an-zhuang-risc-v-freebsd-ji-yu-x86-windows-zhu-ji)

## 第 22 章 高级网络

* [22.1 TCP/IP 协议栈](/di-22-zhang-gao-ji-wang-luo/di-22.1-jie-tcp-ip-xie-yi-zhan)
* [22.2 网桥](/di-22-zhang-gao-ji-wang-luo/di-22.2-jie-wang-qiao)
* [22.3 链路聚合与故障转移](/di-22-zhang-gao-ji-wang-luo/di-22.3-jie-lian-lu-ju-he-yu-gu-zhang-zhuan-yi)
* [22.4 VLAN](/di-22-zhang-gao-ji-wang-luo/di-22.4-jie-vlan)

## 第 23 章 存储管理

* [23.1 USB 存储设备](/di-23-zhang-cun-chu-guan-li/di-23.1-jie-usb-cun-chu-she-bei)
* [23.2 虚拟内存盘](/di-23-zhang-cun-chu-guan-li/di-23.2-jie-xu-ni-nei-cun-pan)
* [23.3 文件系统自动挂载](/di-23-zhang-cun-chu-guan-li/di-23.3-jie-wen-jian-xi-tong-zi-dong-gua-zai)
* [23.4 新增交换分区](/di-23-zhang-cun-chu-guan-li/di-23.4-jie-xin-zeng-jiao-huan-fen-qu)
* [23.5 加密交换分区](/di-23-zhang-cun-chu-guan-li/di-23.5-jie-jia-mi-jiao-huan-fen-qu)

## 第 24 章 ZFS 文件系统

* [24.1 ZFS 历史与现实](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.1-jie-zfs-li-shi-yu-xian-shi)
* [24.2 ZFS 特性和术语](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.2-jie-zfs-te-xing-he-shu-yu)
* [24.3 ZFS 存储池管理](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.3-jie-zfs-cun-chu-chi-guan-li)
* [24.4 更新 ZFS 存储池](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.4-jie-geng-xin-zfs-cun-chu-chi)
* [24.5 ZFS 管理](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.5-jie-zfs-guan-li)
* [24.6 ZFS 调优](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.6-jie-zfs-diao-you)
* [24.7 ZFS 委托管理](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.7-jie-zfs-wei-tuo-guan-li)
* [24.8 更新 OpenZFS](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.8-jie-geng-xin-openzfs)
* [24.9 ZFS 启动环境](/di-24-zhang-zfs-wen-jian-xi-tong/di-24.9-jie-zfs-qi-dong-huan-jing)

## 第 25 章 UFS 文件系统

* [25.1 UFS 文件系统概述](/di-25-zhang-ufs-wen-jian-xi-tong/di-25.1-jie-ufs-wen-jian-xi-tong-gai-shu)
* [25.2 添加 UFS 磁盘](/di-25-zhang-ufs-wen-jian-xi-tong/di-25.2-jie-tian-jia-ufs-ci-pan)
* [25.3 UFS 磁盘扩展](/di-25-zhang-ufs-wen-jian-xi-tong/di-25.3-jie-ufs-ci-pan-kuo-zhan)
* [25.4 UFS 磁盘快照](/di-25-zhang-ufs-wen-jian-xi-tong/di-25.4-jie-ufs-ci-pan-kuai-zhao)
* [25.5 UFS 磁盘配额](/di-25-zhang-ufs-wen-jian-xi-tong/di-25.5-jie-ufs-ci-pan-pei-e)
* [25.6 UFS 磁盘加密](/di-25-zhang-ufs-wen-jian-xi-tong/di-25.6-jie-ufs-ci-pan-jia-mi)

## 第 26 章 其他文件系统

* [26.1 Windows 文件系统](/di-26-zhang-qi-ta-wen-jian-xi-tong/di-26.1-jie-windows-wen-jian-xi-tong)
* [26.2 Linux 文件系统](/di-26-zhang-qi-ta-wen-jian-xi-tong/di-26.2-jie-linux-wen-jian-xi-tong)
* [26.3 macOS 文件系统](/di-26-zhang-qi-ta-wen-jian-xi-tong/di-26.3-jie-macos-wen-jian-xi-tong)

## 第 27 章 安全

* [27.1 信息安全概论](/di-27-zhang-an-quan/di-27.1-jie-xin-xi-an-quan-gai-lun)
* [27.2 账户认证安全](/di-27-zhang-an-quan/di-27.2-jie-zhang-hu-ren-zheng-an-quan)
* [27.3 资源限制](/di-27-zhang-an-quan/di-27.3-jie-zi-yuan-xian-zhi)
* [27.4 安全等级](/di-27-zhang-an-quan/di-27.4-jie-an-quan-deng-ji)
* [27.5 OpenSSL](/di-27-zhang-an-quan/di-27.5-jie-openssl)

## 第 28 章 安全审计

* [28.1 安全事件审计](/di-28-zhang-an-quan-shen-ji/di-28.1-jie-an-quan-shi-jian-shen-ji)
* [28.2 入侵检测系统（IDS）](/di-28-zhang-an-quan-shen-ji/di-28.2-jie-ru-qin-jian-ce-xi-tong-ids)
* [28.3 第三方漏洞与安全公告](/di-28-zhang-an-quan-shen-ji/di-28.3-jie-di-san-fang-lou-dong-yu-an-quan-gong-gao)
* [28.4 强制访问控制框架（MAC 框架）](/di-28-zhang-an-quan-shen-ji/di-28.4-jie-qiang-zhi-fang-wen-kong-zhi-kuang-jia-mac-kuang-jia)

## 第 29 章 防火墙

* [29.1 防火墙概论](/di-29-zhang-fang-huo-qiang/di-29.1-jie-fang-huo-qiang-gai-lun)
* [29.2 ipfirewall（IPFW）](/di-29-zhang-fang-huo-qiang/di-29.2-jie-ipfirewall-ipfw)
* [29.3 IPFilter（IPF）](/di-29-zhang-fang-huo-qiang/di-29.3-jie-ipfilter-ipf)
* [29.4 Packet Filter（PF）](/di-29-zhang-fang-huo-qiang/di-29.4-jie-packet-filter-pf)
* [29.5 Fail2Ban（基于 IPFW、PF 与 IPF）](/di-29-zhang-fang-huo-qiang/di-29.5-jie-fail2ban-ji-yu-ipfw-pf-yu-ipf)
* [29.6 blocklistd](/di-29-zhang-fang-huo-qiang/di-29.6-jie-blocklistd)

## 第 30 章 Jail 容器管理

* [30.1 Jail 基础](/di-30-zhang-jail-rong-qi-guan-li/di-30.1-jie-jail-ji-chu)
* [30.2 厚 Jail（Thick Jail）](/di-30-zhang-jail-rong-qi-guan-li/di-30.2-jie-hou-jail-thick-jail)
* [30.3 Qjail](/di-30-zhang-jail-rong-qi-guan-li/di-30.3-jie-qjail)

## 第 31 章 Linux Jail

* [31.1 Linux Jail 基础](/di-31-zhang-linux-jail/di-31.1-jie-linux-jail-ji-chu)
* [31.2 Debian Jail](/di-31-zhang-linux-jail/di-31.2-jie-debian-jail)
* [31.3 Ubuntu Jail](/di-31-zhang-linux-jail/di-31.3-jie-ubuntu-jail)
* [31.4 antiX Linux Jail](/di-31-zhang-linux-jail/di-31.4-jie-antix-linux-jail)
* [31.5 Alpine Jail](/di-31-zhang-linux-jail/di-31.5-jie-alpine-jail)
* [31.6 Linux Jail 中的 GUI](/di-31-zhang-linux-jail/di-31.6-jie-linux-jail-zhong-de-gui)

## 第 32 章 虚拟化与容器管理

* [32.1 使用 bhyve 及 vm-bhyve 工具安装 Windows 11](/di-32-zhang-xu-ni-hua-yu-rong-qi-guan-li/di-32.1-jie-shi-yong-bhyve-ji-vm-bhyve-gong-ju-an-zhuang-windows-11)
* [32.2 使用 BVCP 通过 Web 界面管理 bhyve 虚拟机](/di-32-zhang-xu-ni-hua-yu-rong-qi-guan-li/di-32.2-jie-shi-yong-bvcp-tong-guo-web-jie-mian-guan-li-bhyve-xu-ni-ji)
* [32.3 Podman 容器管理](/di-32-zhang-xu-ni-hua-yu-rong-qi-guan-li/di-32.3-jie-podman-rong-qi-guan-li)
* [32.4 在 FreeBSD 上安装 VirtualBox](/di-32-zhang-xu-ni-hua-yu-rong-qi-guan-li/di-32.4-jie-zai-freebsd-shang-an-zhuang-virtualbox)

## 第 33 章 数据库管理

* [33.1 数据库概论](/di-33-zhang-shu-ju-ku-guan-li/di-33.1-jie-shu-ju-ku-gai-lun)
* [33.2 PostgreSQL](/di-33-zhang-shu-ju-ku-guan-li/di-33.2-jie-postgresql)
* [33.3 pgAdmin 4](/di-33-zhang-shu-ju-ku-guan-li/di-33.3-jie-pgadmin4)
* [33.4 MySQL](/di-33-zhang-shu-ju-ku-guan-li/di-33.4-jie-mysql)
* [33.5 MongoDB](/di-33-zhang-shu-ju-ku-guan-li/di-33.5-jie-mongodb)

## 第 34 章 文件传输协议（FTP）

* [34.1 文件传输协议（FTP）概述](/di-34-zhang-wen-jian-chuan-shu-xie-yi-ftp/di-34.1-jie-wen-jian-chuan-shu-xie-yi-ftp-gai-shu)
* [34.2 Pure-FTPd（基于 MySQL）](/di-34-zhang-wen-jian-chuan-shu-xie-yi-ftp/di-34.2-jie-pure-ftpd-ji-yu-mysql)
* [34.3 ProFTPD（基于 MySQL）](/di-34-zhang-wen-jian-chuan-shu-xie-yi-ftp/di-34.3-jie-proftpd-ji-yu-mysql)
* [34.4 vsftpd](/di-34-zhang-wen-jian-chuan-shu-xie-yi-ftp/di-34.4-jie-vsftpd)

## 第 35 章 服务器

* [35.1 Rsync 数据同步](/di-35-zhang-fu-wu-qi/di-35.1-jie-rsync-shu-ju-tong-bu)
* [35.2 Samba 文件共享](/di-35-zhang-fu-wu-qi/di-35.2-jie-samba-wen-jian-gong-xiang)
* [35.3 网络文件系统（NFS）](/di-35-zhang-fu-wu-qi/di-35.3-jie-wang-luo-wen-jian-xi-tong-nfs)
* [35.4 零配置网络（mDNS/DNS-SD）](/di-35-zhang-fu-wu-qi/di-35.4-jie-ling-pei-zhi-wang-luo-mdns-dns-sd)
* [35.5 Webmin 管理平台](/di-35-zhang-fu-wu-qi/di-35.5-jie-webmin-guan-li-ping-tai)

## 第 36 章 Web 服务器

* [36.1 Apache Web 服务器](/di-36-zhang-web-fu-wu-qi/di-36.1-jie-apache-web-fu-wu-qi)
* [36.2 Nginx Web 服务器](/di-36-zhang-web-fu-wu-qi/di-36.2-jie-nginx-web-fu-wu-qi)
* [36.3 Caddy Web 服务器](/di-36-zhang-web-fu-wu-qi/di-36.3-jie-caddy-web-fu-wu-qi)
* [36.4 PHP](/di-36-zhang-web-fu-wu-qi/di-36.4-jie-php)
* [36.5 Tomcat 应用服务器](/di-36-zhang-web-fu-wu-qi/di-36.5-jie-tomcat-ying-yong-fu-wu-qi)
* [36.6 WildFly 应用服务器](/di-36-zhang-web-fu-wu-qi/di-36.6-jie-wildfly-ying-yong-fu-wu-qi)
* [36.7 Nextcloud 云服务（基于 PostgreSQL）](/di-36-zhang-web-fu-wu-qi/di-36.7-jie-nextcloud-yun-fu-wu-ji-yu-postgresql)
* [36.8 OnlyOffice 部署（基于 PostgreSQL）](/di-36-zhang-web-fu-wu-qi/di-36.8-jie-onlyoffice-bu-shu-ji-yu-postgresql)
* [36.9 GitLab Enterprise Edition 部署](/di-36-zhang-web-fu-wu-qi/di-36.9-jie-gitlab-enterprise-edition-bu-shu)
* [36.10 OpenList 部署](/di-36-zhang-web-fu-wu-qi/di-36.10-jie-openlist-bu-shu)

## 第 37 章 监控系统

* [37.1 Zabbix 监控系统（基于 PostgreSQL）](/di-37-zhang-jian-kong-xi-tong/di-37.1-jie-zabbix-jian-kong-xi-tong-ji-yu-postgresql)
* [37.2 Prometheus 监控部署](/di-37-zhang-jian-kong-xi-tong/di-37.2-jie-prometheus-jian-kong-bu-shu)
* [37.3 Telegraf、InfluxDB 与 Grafana 监控平台架构](/di-37-zhang-jian-kong-xi-tong/di-37.3-jie-telegraf-influxdb-yu-grafana-jian-kong-ping-tai-jia-gou)

## 第 38 章 游戏、科学计算和专业工具

* [38.1 Godot 开源游戏引擎](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.1-jie-godot-kai-yuan-you-xi-yin-qing)
* [38.2 我的世界（Minecraft）服务器](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.2-jie-wo-de-shi-jie-minecraft-fu-wu-qi)
* [38.3 我的世界（Minecraft）](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.3-jie-wo-de-shi-jie-minecraft)
* [38.4 Steam 客户端](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.4-jie-steam-ke-hu-duan)
* [38.5 R 语言](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.5-jie-r-yu-yan)
* [38.6 Wine](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.6-jie-wine)
* [38.7 科研和专业计算](/di-38-zhang-you-xi-ke-xue-ji-suan-he-zhuan-ye-gong-ju/di-38.7-jie-ke-yan-he-zhuan-ye-ji-suan)

## 第 39 章 人工智能

* [39.1 人工智能术语与概念](/di-39-zhang-ren-gong-zhi-neng/di-39.1-jie-ren-gong-zhi-neng-shu-yu-yu-gai-nian)
* [39.2 Transformer 数学基础与程序演示](/di-39-zhang-ren-gong-zhi-neng/di-39.2-jie-transformer-shu-xue-ji-chu-yu-cheng-xu-yan-shi)
* [39.3 人工智能哲学原著选读](/di-39-zhang-ren-gong-zhi-neng/di-39.3-jie-ren-gong-zhi-neng-zhe-xue-yuan-zhu-xuan-du)
* [39.4 大模型本地部署](/di-39-zhang-ren-gong-zhi-neng/di-39.4-jie-da-mo-xing-ben-di-bu-shu)

## 第 40 章 开发环境

* [40.1 C/C++ 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.1-jie-c-c-kai-fa-huan-jing)
* [40.2 Java 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.2-jie-java-kai-fa-huan-jing)
* [40.3 Qt 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.3-jie-qt-kai-fa-huan-jing)
* [40.4 Python 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.4-jie-python-kai-fa-huan-jing)
* [40.5 Rust 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.5-jie-rust-kai-fa-huan-jing)
* [40.6 Go 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.6-jie-go-kai-fa-huan-jing)
* [40.7 Node.js 开发环境](/di-40-zhang-kai-fa-huan-jing/di-40.7-jie-node-js-kai-fa-huan-jing)

## 第 41 章 开发工具

* [41.1 code-server 和 clangd 开发环境](/di-41-zhang-kai-fa-gong-ju/di-41.1-jie-code-server-he-clangd-kai-fa-huan-jing)
* [41.2 Vim 开发环境](/di-41-zhang-kai-fa-gong-ju/di-41.2-jie-vim-kai-fa-huan-jing)
* [41.3 使用 IDA Pro 调试 FreeBSD](/di-41-zhang-kai-fa-gong-ju/di-41.3-jie-shi-yong-ida-pro-tiao-shi-freebsd)
* [41.4 DTrace](/di-41-zhang-kai-fa-gong-ju/di-41.4-jie-dtrace)

## 第 42 章 嵌入式平台及开发环境

* [42.1 树莓派 FreeBSD 安装](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.1-jie-shu-mei-pai-freebsd-an-zhuang)
* [42.2 树莓派 FreeBSD 使用](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.2-jie-shu-mei-pai-freebsd-shi-yong)
* [42.3 树莓派 Linux 兼容层](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.3-jie-shu-mei-pai-linux-jian-rong-ceng)
* [42.4 Radxa X4 x86 开发板](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.4-jie-radxa-x4-x86-kai-fa-ban)
* [42.5 STM32 开发环境](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.5-jie-stm32-kai-fa-huan-jing)
* [42.6 ESP-IDF 开发环境](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.6-jie-esp-idf-kai-fa-huan-jing)
* [42.7 Arduino 开发环境](/di-42-zhang-qian-ru-shi-ping-tai-ji-kai-fa-huan-jing/di-42.7-jie-arduino-kai-fa-huan-jing)

## 第 43 章 FreeBSD 内核架构

* [43.1 FreeBSD 源代码目录结构](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.1-jie-freebsd-yuan-dai-ma-mu-lu-jie-gou)
* [43.2 FreeBSD 内核文件结构](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.2-jie-freebsd-nei-he-wen-jian-jie-gou)
* [43.3 机器相关的内核选项注解](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.3-jie-ji-qi-xiang-guan-de-nei-he-xuan-xiang-zhu-jie)
* [43.4 机器无关的内核选项注解](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.4-jie-ji-qi-wu-guan-de-nei-he-xuan-xiang-zhu-jie)
* [43.5 GENERIC 内核选项注解（AMD64）](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.5-jie-generic-nei-he-xuan-xiang-zhu-jie-amd64)
* [43.6 构建定制内核](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.6-jie-gou-jian-ding-zhi-nei-he)
* [43.7 在 Linux 系统上交叉构建 FreeBSD](/di-43-zhang-freebsd-nei-he-jia-gou/di-43.7-jie-zai-linux-xi-tong-shang-jiao-cha-gou-jian-freebsd)

## 附录 I 工具与资源

* [Bug 报告流程](/fu-lu-i-gong-ju-yu-zi-yuan/bug-bao-gao-liu-cheng)
* [FreeBSD 邮件列表订阅](/fu-lu-i-gong-ju-yu-zi-yuan/freebsd-you-jian-lie-biao-ding-yue)
* [FreeBSD 开发参与指南](/fu-lu-i-gong-ju-yu-zi-yuan/freebsd-kai-fa-can-yu-zhi-nan)
* [microSD 卡参数简介](/fu-lu-i-gong-ju-yu-zi-yuan/cun-chu-ka)
* [V2Ray](/fu-lu-i-gong-ju-yu-zi-yuan/v2ray)
* [Mihomo](/fu-lu-i-gong-ju-yu-zi-yuan/mihomo)

## 附录 II 参考文献与术语表

* [参考书目](/fu-lu-ii-can-kao-wen-xian-yu-shu-yu-biao/can-kao-shu-mu)
* [术语表](/fu-lu-ii-can-kao-wen-xian-yu-shu-yu-biao/shu-yu-biao)

## 后记

* [我与 FreeBSD 的故事](/hou-ji/wo-yu-freebsd-de-gu-shi)


# 前言

## 四版前言：和解与等待（草稿）

或许政治是一种分配利益的学问，而妥协是一种实现前者的手段。那么，和解究竟是一种与异化的妥协还是一种回到事物，回到主体本身的做法？等待似乎是在时间中的延宕，或许需要先定义时间，才能讨论等待。和解是事物真正完整的一刻，也是旧矛盾被新矛盾替代的一瞬。

其实只要仔细思考就会发现，似乎除了活着（抑或长生）主体本身内在目的外，其他任何事物都是平凡的。作为开源项目的操作系统终有一天会走到尽头，甚至在大多数人身前就能目睹到这一事实。问题不在于是否存在其他可选项，有观点认为，替代品是无穷无尽的，事实上否定了偶然性的存在。因为替代品是无穷尽，则其同质化的观点看上去暗含老庄之道，实则偏离颇远。花要开了。然而，只有在花落下，发霉的时候才能发现花是美的。和解往往取决于等待，或者说，取决于时间。这世间种种的等待，就好像沥青在滴落。抑或，“朝花夕拾”便是此意。并非晨曦看不到花，而是当想看花的时候刚好逢上傍晚。当意识到这种替代品只是一种幻觉后，便会自觉发现会者定离绝非痴言妄语。

这本身的意义是什么？这篇前言的意义，或者说，需要先考虑何为意义，意义是否存在。或者追根溯源要回到这种文字能否表达……等待一定是时间之中的吗？或者说等待只是对时间的一种外延？对于超越于时间的存在者，是否仍然存在一种等待？永恒的现在是否意味着等待实际上是一种国际计量大会定义的形式主义？

诚然，即使是形式主义本身，被形式化后的世界，本身也是一种存在，本身也是一种世界的真实样貌。有观点认为这是对真实存在之物的扭曲和遮蔽，但是毋庸讳言，为何不承认这种被扭曲和遮蔽的世界也是一种真实？仅仅因为其背后有或者可能有其合理性存在之依据就否定形式主义本身的合理性，是一种不诚实的表现，或者说，本身即是一种形式主义。为何不能承认，在某种意义上，所有的事物都是毫无意义的，都是一种形式主义。为何妄图要求人类走出山洞，山洞之外，人类肉体、知觉本身，难道不是一座座需要愚公移走的大山吗？发人深省地是，愚公年轻时（“北山愚公者，年且九十，面山而居”《列子·汤问》，下同）为何不移山？是无山看不见山，还是山并未阻碍他（“惩山北之塞，出入之迂也”）？山外有什么是山内没有的？既然安土重迁，为何不与自己和解。这种和解也是一种形式。看上去是人类在书写神话故事，神话故事中的人物的一举一动都受作者的支配，但是随着时间的发展，作者反而受到了神话人物的奴役。这并非强调文化的属性，看似存在先后的时间因果，是先下笔，而后存在故事。但是如果将不存在的时间抽离就会意识到，神话人物的诞生、其故事并非彻底由作者本人决定。反而是神话人物在藉着作者本身书写他们自己的故事。难道神话人物意识不到自己是被作者支配的吗？这与其本质属性相悖。

传统观念的物质和意识在根本上应该为一物。还是之前的例子，即使是游戏中的点灯也是使用现实的电力点亮的，这不意味着任何意识的东西都是物质的，反而证明任何物质的都是意识的，也说明形式主义是唯一的真实的不意味着其他的都是不真实的，最多只能说明其他的也是一种形式主义。唯一认识到的物质必然是意识形式化构成的，反之亦如此。这种形式是指肯定并接受当下知觉的到的一切并将其作为一切理解的前理解。这并不意味着不存在任何无法认识或者超越感知之物的存在或存在者，而是指在这种形式下的任何存在或存在者都是形式化的。换言之，这种超越性的存在本身也是一种基于形式的前理解的成果。因此，无论是物质还是意识的理解都是基于一种知觉构成的前理解的。

凡是现存的都是破烂的，都是毫无理性依据的；凡是既存的都是应当死亡的，都是有着充足理由的。凡是认为现存与既存都是一种存在或存在者的，都是一种形式主义。

人的第一行为是继续生活而不是思考世界的存在性，这不合理，这很奇怪，我发现这些会被遮蔽，被形式化的异化自我遮蔽。问题从来不在于认识世界，也不在于解释世界，更不在于改造世界，而是必须先证明世界。以往的哲学家们总是试图从各种角度与世界交互，可是真实的问题却被忽略，而这是最大的问题。有一种数学哲学认为证明数学不是最重要的。这是一种极其错误的看法。最重要的永远是证明形式化的存在是一种形式。而不是把被代替的形式当下直截地一切视为一种非形式的存在者。改变世界从来不是最重要的任务，真切地唯一的任务只有证明世界。证明本身是否可能，何为证明也同样需要证明。和解是否可能？从时间完全地类似快照还原，是否为一种和解达成了条件？为什么还是有一种执念或者说认为形式化的东西仍然最重要的？据我所知，任何事情都丝毫不重要：偶然性的世界中的必然性是自由的。重来能改变什么？主体性的变化并不存在断裂，根本什么也不会变。结局诚然是作者编造的，但是如何证明不是人物再编造结局？如果能重来，也是一模一样的。可以逆推，以后再说，或者说下次一定的这种说法的可能性是必然的，但是，是一种带有否定性的必然。主体的异化过程会随着形式化世界而加深，这不意味着有所谓的鼎盛年，即圆满的善，只能说明主体已经死亡。

## 三版前言：且有大觉而后知此其大梦也

### 第一段梦

我打开之前那个 Excel 问题收集表（CFC 问题收集表），发现还是没有人填写，表格中只有 4～5 行我自己预填充的示例。倏然，我发现多了一行，但很快又被删掉了。我发现表格的表头竟然多出了两列：要求填写真实姓名和类似政治面貌的内容。我以为是我写错了，可能套用了错误的模板，于是就在群里告诉群主，以后还是手动发给他，他再帮我收集问题。

然后我就往村北走，那边还是拆迁前的旧村。我发现有户人家，门口有个类似门铃的黄色方块，我刚想进去看看，发现狗在叫，便作罢了。

我接下来又梦见 FreeBSD 机构就在我住的村东边，但现实中前几天我刚去过，那里已经全部拆迁，一片空地，除了废土堆和垃圾什么也没有。

然后我去了村西边，按理来说应该也是空无一人，但是竟有许多穿着红色或褐色百褶裙的女学生倚靠着自行车在那里说话，场面非常热闹。

在梦里，我在 2015 年收到了一封来自山东的信和一万六千多块钱。信封上同时写着隐私号码和我的真实电话号码。那封信上，我的地址的末尾是 302，信来自 FreeBSD 中国的最后一位维护者。他说收到的单笔捐款最高只有 10 元。信里有本发货日志，最后一页记载着是给我发的这封信，他花了 302 元。他说他维护不了，希望我继续下去。还有一本介绍 UNIX 的书。

信还没拆完，接连来了两个无关紧要的电话把我叫醒了。

醒来，我打开 Excel 收集表看了看，发现还是只有我自己写的那一个示例。通话记录也只有一个电话。

2015 年是我初次接触 FreeBSD。当时 FreeBSD 存在缺陷，启动盘在 UEFI 模式下，HD 4000 显卡会花屏，我始终无法进入安装过程。由此搁置了三四年。光阴荏苒，至今已然十年了。

### 第二段梦

我梦见自己在一所大学毕业了。之前似乎参加了某种安全比赛，我还以偷袭击败敌人，最终获得了第二名，还有一张奖状。

毕业后，我从教室里收拾好东西准备出去“野”一趟。我骑车从学校的南门出去，一路顺风。途中看见一个玩得特别好的小学男同学在奔跑，我就跟着他，来到了一个像是水上乐园的地方。水流速不快，但我很快就看不见他了，于是我决定骑车往回走。

返回途中，遇见一位大娘，她正烤着猫。那猫似乎头和前爪都受了伤，后半身用锡纸包裹着，不知道她是在给猫治疗还是想吃猫。她堵在出口，我心里很着急，只能从别的出口绕出去。结果不只是我，后面还有一群人也跟着我一起出来了。

中间似乎有什么集市，我不断从一群又一群卖衣服的帷幕中穿梭来回。

我出来后，来到了学校的南门，却听说现在不让进了。有人说可以从西边的华西医院研究所那边进去。可我刚走到半路，又听说从研究所那边进更难，但学校搬迁到这个地方后一直可以从西边绕过来，只是兄弟院校管理问题，无能为力，我以为可以混进来。但到了研究所果然被挡住了，所有人都在过街天桥上进入研究院，还要查证件，我只好返回学校正门。

我找了一个地方靠边把自行车停好，这才发现自己没穿鞋。我从衣服口袋里掏出鞋穿上。校门口围了很多人，大家都因晚归被阻拦了，有个是领导的人，在批斗前面想溜进去的同学。我等了好久，看见校门快关了，便跑过去小声对领导说我今天毕业，还有点事。领导说：“这点事都办不明白，快进去。”我又跟门卫说：“那你们待会儿把我放出来。”门卫怕担责任，我说：“有事找刚才那位领导。”我好像是要回宿舍找东西或者等人。到此就结束了梦境。

### 第三段梦

我和同学正在路上走，他捡到了金属探测仪，就是考试时使用的那种，但外形特别诡异，像奥特曼中的变身器。他说要去厕所，我们便走进了一座类似大型商场的建筑。我们一起进了厕所，厕所很大，人很多。他把探测仪给了我，等拿到手才发现它确实特别沉。我一回头他人就消失在人海中。我返回到街道上，在建筑的大门口拿着金属探测仪等他。

突然，响起了一阵喧嚣的音乐。我从西门到了北边的大道上，发现有几个染着浅黄色头发的人骑着摩托车从远处过来，他们嘴里各自咬着喷火的东西，形状像玻璃管，却不断喷出火焰，并且火苗一个比一个喷得高，可他们似乎一点也不怕烫，咬住不松口。一共过去了四五个。

最后出现了一台类似坦克的机甲。原本人们在围观，但它突然开始四处攻击。我赶紧躲进商场里远远看着。机甲见外面无人，竟然径直冲进了商场。我想去厕所找我的同学，一路喊着他的名字，却没有回应。有人答应了我，但我发现根本不是他。

于是我往建筑的北门跑，北边是座过街天桥。刚跑上去就发现前面是断层，不能通行，我只好赶紧折返和后面的人说别往前走了，是断头路。回到北门口，此时，有许多人押着一个戴着纸面具的人从我旁边走过，而那正是机甲的驾驶者。

我想回家了，却发现自己原本穿的黄色上衣不见了，上身没有衣服，金属探测仪也弄丢了。我四处寻找却找不到，只能返回公交站点。站牌前面有家小超市，我看到有黄色的东西在那儿，我的衣服掉在地上，我赶紧捡起来穿上了。

我问店里的人有没有看到外观蓝色、形状奇怪的东西。她问是不是金属探测仪。我说是，那正是我弄丢的。她便把它还给了我。

### 第四段梦

全球两极反转，极点气温变得如同赤道，我和一群人被迫花两天时间整理东西逃难。

我一直在给充电宝充电，但是天气太冷了，始终充不进去电，一晚上只充了 58%。而且我的充电宝是老旧的，只有那种一拖三的非快充头才充得进去，因此并不好充。

有个邻居只拉了床和沙发。他用的货车，货车的护栏也未关闭（蓝色的车厢护栏），我帮他关上了。他也要向北极出发，我问他有没有电池，他说我为什么不早说，现在已经没有能用的了，他带我去看，果然那些大块头的电池（类似自制的铅酸蓄电池，都漏液了）都已冻住了，拔不出来，像长在地里的白萝卜。

有人说挖出了作业本，也许可以烤火，作业本是从红砖头与煤块混合的地下挖出来的，但是外观都是红色的，我说那是订书钉生锈了，作业本本身印刷的是绿色的。我换了几个充电器试图给两个旧的充电宝充电。是那种冻土，看不见冰雪。

***

由于无人协助合并提交，即便移植（Port）一款软件也难以发挥实际作用，只能无限期搁置（已经这样很多次了）。中文社区没有自己的提交者。FreeBSD 可能已经“死了”，目前只是在逐渐腐烂。上游的基金会、社区、期刊都严重缺乏时间感——或者说根本没有，看起来做一些外围工作意义不大。整个社区也处于停滞状态，无论是上游社区还是下游社区。所有的邮件列表似乎都失去了意义，要么塞满了错误报告，要么没有任何有效信息。另外，提交者本身也不关注邮件列表。错误报告往往只是简单转发到邮件列表。这同样无意义，永远不会被分配到具体的某个人。下游社区（包括我们中文社区自身）即使发现问题也不会报告。他还在那里苦苦移植一款无法启动的 GDM 47，恐怕如果我不报告的话，他自己也不知道它无法启动。FreeBSD 已经没有任何改进的可能了。FreeBSD 最终会像沙漠里的胡杨那样，生而千年不死，死而千年不倒，倒而千年不朽。

我意识到，人只有在活着的时候才能意识到自己活着。这说明，如果要实现永生，只需将“始终活着”的概念永恒地赋予活着的人，则他必然是永生的。这与这个人本身是否活着并无必然关系，也与生理状态无关，例如可以通过意识上传到互联网实现。人格同一性等问题暂且搁置不论。我们无法必然证明：究竟是活着才有意识，是活着产生了意识，还是意识让我们感知到“活着”，因为这在实验上目前是无法证实的。所以，我的这种说法，有可能成立。我们总是不言自明地认为世界的物质性源于实践，却不考虑实践本身的物质性是否成立。看起来是我们通过实践改造了所谓的环境。但是有没有一种可能，这一切都是预先决定的？并且这也无法证明实践与人类本身的物质属性。所以啊，有没有这样一种可能，FreeBSD 根本不存在？

看起来时间很多，其实不然。如果不立刻去做，机会在大多数情况下确实还是会有，但已经失去了再次行动的动机和环境。但即便立刻去做了，一切也可能只是一个冗长的省略号。一切真正重要的东西往往没有经过周全考虑便下决断，而一切细枝末节的东西总是看了又看。事实上，机会总有很多次，但真正愿意去做的次数却寥寥无几。记忆是一条无法重渡的河流。河流还在，两岸也还在，但船和摆渡的人都已不同。或许永远无法证明记忆本身是否属于当下的人格。我们总是盲目地信任这份记忆属于自己，并认定自己必定失去了某些可能的存在，这在多大程度上是自洽的？或者说，这些记忆可能是真正属于自己的，而非旁人臆造的？

所有人都在引用南宋刘过《唐多令·芦叶满汀洲》中的“欲买桂花同载酒，终不似，少年游”来强调些什么。但是，他们忽略了一点：很多时候绝非没有机会或条件——只要人还活着——而是你自己是否有心愿去实现。如果你真的愿意和你的几个朋友在一起再做些什么，我想在大多数情况下，你只需要支付他们一些报酬和路费即可，这并非多么苛刻的条件，难道不是吗？正如你现在不会去寻找小学一年级时在路边卖鸡蛋灌饼的大妈，即便你认为再也没尝过那种味道，你也不会花费一丝气力去寻找她，尽管找到她并不需要多少尝试和经济付出。

有人会强调“会者定离”，试图诠释人与人的关系是动态的，取决于经济、物质、年龄、价值观、住所距离的变化。这很正确，也很现实，但并非人们所期望的那样。现在的互联网技术如此先进，但人与人之间的距离却达到了史无前例的遥远。现在甚至可以与太空中的宇航员通话，却联系不上自己的朋友。若还以距离太远为借口，这不显得荒谬吗？

事实上，一切机会都有无数次，但是真正愿意做的次数是不多的。那么，什么是重要的东西，什么是不重要的东西？如果一切都不重要，剩下的也不会重要。一切回归到原点，无论重复多少次，结果大抵也是如此。看起来我们仍能改变一些所谓重要的事情，但最终的决定无可避免地又会重复过往的一切。换言之，即使选择了新世界，旧世界的一切都值得被否定吗？否定之后，注定会再次重现当下的选择与过往的否定。

“终不似，少年游”究竟是不似还是不愿？还是我们根本囿于世界，成为其一部分而不愿改变？少年被现代工业文明规训为绝对精神的一部分，放弃了所有主体性，异化为历史合力的一分子，仅此而已。

如果人类文明还存在的话，受益于 GitHub 的 Archive Program 和互联网档案馆等项目，一千年后的人们或许也会看到这些文字。其实在互联网上最孤独的是，你发现自己的疑惑别人早在几年前、几十年前就提出过，但是，没有人解决，甚至无人回复。FreeBSD 项目、基金会和社区的问题都很多、很大，这是现实。它使所有人都成了局外人，不过大部分人其实并不关心这些。制作抽象视频、建个群让大家一起玩也没什么意思，没人会陪你玩。社区在根本上也是不存在的东西。它只是少数人的贡献努力，以及相对广泛但罕有的真实用户的零星反馈。就算你每天给每人发 10 块、100 块钱，也没人会陪你。

不知道读者是否观看过《我们仍未知道那天所看见的花的名字。》，里面男主角仁太的伙伴们为什么难以再和他相处，仅仅是因为仁太放弃升学了吗？我们大部分人的非工作群里，现在就只剩寥寥几人还在发言，仅仅是因为我们有时间而他们没有吗？他们比特朗普忙吗？特朗普还能每天发几十上百条推文。他只是不在这里说话而已。而且退一步讲，假定他比特朗普还忙，他忙碌的意义是什么？对大部分人而言，仅仅是活着就已经很困难了。你会发现，是的，确有一种无形的存在挡在我们之间。这种东西，也许就是黑格尔所描述的绝对精神。有人说，你完全可以不上学、逃学，没有人绑着你。这种萨特式的绝对自由是不存在的，萨特本人在晚年也意识到了这一点。或者说，是我们自己放弃了可能性，而这决定也并非完全出自我们自身，而是由绝对精神的理性所决定的。但归根结底，二者又是一致的，这的确又成了我们自己的决定。但事情果真如此吗？在《圣经》中，上帝用大东风分开红海（出 14:21）。而我们与旧日朋友也被这看不见的风隔开，中间只留下我们的道路。人间的道路通往何方，无人知晓。人行大道，号曰道士，大道难行矣。

试图带动所有人提高水平，进而促进整个 FreeBSD 项目发展的计划与目标，在当今时代，缺乏足够的支撑。很多人上班一天后精力有限，难以再投入额外的学习活动，让他们起身锻炼也往往力不从心。并非锻炼了才有精力，而是有精力了才能锻炼。而那些相对有时间的学生和年轻群体，已经和这个地方渐行渐远了。自由软件与开源运动被狭隘地等同于 GNU/Linux 的历史。

这并非中国独有的问题。我在韩国的一个社区也探讨了许多，并浏览了列在 FreeBSD.org 上的日本、印度、俄罗斯、南非等地区的 FreeBSD 社区。衰退之势不可遏。

我注意到一些基督教敬拜团也存在同样的问题。但他们以巨大的毅力维持着。即使每个视频没有任何回复，总观看量也不及 B 站的搬运视频，即便他们的歌曲改编得相当完美，其他方面也不差。或许他们有一些赞助，但我并不清楚。我本人并不持有这种宗教信仰，但大家所做的事情并没有多大区别。但我对此的热忱显然不如他们。他们当中，甚至有人下了大力气去出版拼音版本的《圣经》。这是我远远做不到的，无关信仰。

在《BanG Dream! It's MyGO!!!!!》中，我感觉爽世（素世）的行动力仍不够强。按理说，祥子父亲投资失败的事虽未见于新闻报道，但爽世的母亲应该知晓，或者查一下投资者报告。而且祥子的目的是出道盈利，要求将业余活动转为专业。但我并未在二者间看到张力。重组 CRYCHIC 就和《未闻花名》中重组“超和平 Busters”一样。秩序一旦变化，人与人之间的联系就会改变。说到底，不是要重组谁，也不是一定就需要原来的那些人，而是想回到事物本身，回到最初的物质条件、经济水平、社会关系等构成的秩序。要重组的从来不是一个团体、一个家庭、一个组织或一个项目。而是它们所承载的文化、秩序与规则。随着人的社会化程度加深，其核心关系就会转移到别处，转移到他被异化最深的那个团体。其自由时间被完全占用。即使脱离了，也会被其他团队的文化产品或其他事物所异化。每代人的村庄都是不同的。你说村庄变了，但或许应该说，这里从未有过任何村庄，无论过去、现在还是将来。我从未想过要回到哪个地方，或哪一年。很多人都说想回到某一年。但是，即使回去了，也无力阻止这种浸染。简单的道理是我们不拥有任何生产资料，除了劳动力一无所有。但这只是表面现象，无法解释其必然性。唯一合理的解释只可能是，这个世界存在一种推动力，一种具有主体性的存在，推动着偶然成为必然。因为对任何人都是偶然的事件，是如何成为必然的？对于大部分人而言，生存本身并非难事。差异在于深层需求。但若将其视为必然，就必然有一种动力在推动，而这种动力绝非单纯的经济或物质因素。

我认为问题不在于解释世界和改造世界，而在于证明世界。我们在行动之前必须先使世界“生成”，去发现何为世界，世界是否真实存在。而这往往被视为一种形式主义。然而，若不假思索就认定世界的真实性，并开始所谓的解释和改造，这不仅是一种形式主义，更是掩耳盗铃，并且会天然陷入某种结构的合理性中不可自拔。以往的观点是从认识自己出发，进而推论到认识他人及世界。问题在于，包括自我存在可能性在内的这些前提，从未被纳入考量。若仅仅将“能看见”等同于可被理解、可认识，用实践代替生成，这才是一种真正的形式主义——用形式代替了真正的存在，并用实践产生的理论覆盖真实的合理性。这只能是一种虚假的观点，是经验主义或实证主义的态度。这种假象不应简单地视作思想懒惰，而是源于一些预设。我们确实能感受到自己的身体和身体之外的东西存在，问题在于，我们感受不到我们自身以及身体之外那些看不到的东西的存在。而且，证明行为本身又何尝不是一种基于存在预设和前理解的活动？语言、文字、逻辑都以世界存在为基础而生成，妄图通过它们来否定世界的生成，在根本上就已经预设了必然性。问题不在于我们回到哪里，也不在于如何解释和改造什么，而在于：我们是谁？从哪里来？又要到哪里去？

感觉找不到好玩的东西，没有什么乐趣。以前装个系统能玩好几天，现在像一个锤子，看什么都是钉子。一旦想改变一种结构，你本身已是这种结构的一部分，改变已不可能。与这种结构对话是不可能的，它已经内部自洽。说到底，权力是集中的，但互联网是去中心化的。开放 rsync 同步只是几分钟的事情。但让他理解其必要性是困难的。知难行易，故而“行”也变得困难。破山中贼易，破心中贼难（王守仁. 与杨仕德薛尚谦书\[C]//王守仁. 王阳明集. 王晓昕，赵平略，点校. 北京：中华书局，2016：卷四文录一.）你可以用数据和安全手段向他说明好处和项目优先级。但问题不在这里。Linux 的发展依靠不断的革命与彻底否定（或在其基础上再发展），而 BSD 这里只是不断的改革。改革的困难远高于革命，但确实带来了稳定和好处。很难评价，但现实要求改变。

现有记忆是以往所有记忆重构后的结果，“一切真记忆都是现在的记忆”。每份记忆都应该是完全不同的，因为实际上任何事物都在流变，这也是记忆所提示的。但是记忆完全将不同的地方遮蔽掉。或者说，记忆的东西从来都是不存在的，比如那天下雨、下雪、下冰雹。那天捡到了一百块钱，那天的一切偶然性都已转为必然性，都是不存在的。即使能够彻底再现记忆，也无法将那一天的任何事情都与其他日子区别开。这里的意思是指，不存在一条河流在流动。比如那天的太阳高度角，和地球的距离这种偶然性都是难以再现的。今天回忆的东西，究竟是什么？问题在于它在根本上，从来就没有存在过。我们不可能在过去的时间上拥有过去，因为过去的记忆在过去本不存在。我现在想到过去的一个建筑，它早已不存在。那么这个记忆中的建筑究竟是哪天的？有没有那么一刻？记忆中的人已经被定格在一个具体的时间点，或者说，在这种记忆中，该人已经在此处死亡。或者说活在另一种记忆的世界中按照自己的意愿重构。因此，不是说没必要回到过去的村庄或者找到某人，也不是村庄本不存在。而是村庄不在这个世界中。所以，不是回到 CRYCHIC，而是回到平行世界中的 CRYCHIC。但问题在于，这种偶然性不是必然的，或者说在现在，已经不再拥有转为必然的合理性。因为会被现在的其他必然性所覆盖，人们通常将其理解为一种物质性的力量，如经济因素、社会关系。因此，佛教的具念/正念是指出上述问题。不应将其复杂化和神秘化。但是在记忆中，这些仍是必然的。回不去的从来都不是 CRYCHIC/“超和平 Busters”，而是当下的主体。立刻马上，就能拥有 10 个 CRYCHIC，甚至更多。大多数人并非生理死亡，随时随刻，只要他不在太空站，看到很难吗？表面看似束缚的结构性因素，家庭、经济、责任，对于大部分人来说，抛开 3 天并非难事。3 天的 CRYCHIC 和 3 年、30 年的 CRYCHIC，并无差异。在这个意义上，一切真记忆又都是过去的记忆。同时，将这种念念不忘视为一种痛苦的根源，视为对过去的背叛，对将来的定性，对现在的无意义感，实则是自我的消解，将其用一种理论所覆写了，实际上是放弃了自己的主体性。主体本身的记忆和时间本身就是私有的，这种私有无法公有。因此，这种改变世界可能只是在制造另一种异化。

回到山洞才是唯一的解。或者说，我们始终在山洞当中。不是回到山洞，更不是发明山洞，而是发现山洞。我既非反对走出山洞，也不认为应该回到山洞，更不认为无法脱离山洞，而是我们本身就是山洞。这与他人即地狱有异曲同工之妙。虚无主义的问题在于忽略了即使是一种假象，也是构造出来的现实性的假象。这种形式主义的构建本身，这种虚无主义同样也是如此构建的。我并不否认也不认为形式主义是没用的东西。相反，这是人类文明的全部，没有这些，一箪食的一箪就根本不会存在。不是外物、不是资本异化了主体，而是主体本身就是在不断地异化。这和什么社会并无任何关系，甚至在不存在社会的时候，这种异化仍在持续。记忆本身就在不断地异化当下的自我，真正的否定不在于否定，而在于接纳与和解。这同所谓否定之否定有根本区别。任何理论本身的发展，最后都会变成八股文。变成最反动的，因为它没有勇气否定自己，不愿意承认人的主体性，不承认人类能进步能发展。真正的历史循环论其实是其本身。未能意识到，人类文明的发展靠的不是对抗与斗争，而是和解与接纳。一方面指出这种汇聚的力量，另一方面却不愿意承认这种力量的真实来源并非他的理论本身，而是每个个体的主体性。同时，异化是资本对劳动力自由时间的剥削，但是，任何理论为何不是一种异化？无论他如何论证自己理论的正确性，他也必须承认，他不能，也不敢否定自己。若仅仅将其称为一种否定之上的否定，进而变成忒修斯之船式的否定。这不是真正的发展。他否认实质上的自我消解，实则是和庄子一样，万物齐一了。一切真历史都是古代史，作为一种哲学，无法否认自己的前提，本身就是失败。一切发展都不过是一种形式主义，实际上是把人们的主体性禁锢了，一个理论越宣称自己越怎样，他就在实质上越不怎样，这是一种辩证的自反，是指它本身的反主体性，这是合理的。对于无法回到 CRYCHIC/“超和平 Busters”的原因，以往的解读大都从心境，从社会结构和资本对人的异化，从缘分因果，从团队本身，从个人命运出发。他们无法回答这样一个问题，他们的解释和实际存在一种断裂。而我则认为，问题不在于回到哪里，问题在于，苏格拉底古老的命题：“认识你自己”与孔子的“知之为知之，不知为不知，是知也”。认识到自己的主体性，从而理解，要回去的东西，实际上根本就是不存在的，是主体当下对既往记忆的重组与再现。从来不是要回到哪里，因为我们个人一直就在那里也不在那里。唯一的事情只有和解与接纳，同自己和解，接纳自己。记忆中的团队只是将许多偶然性认识为一种必然性。同时进一步否定了这种偶然性的发生。人们永远只能拥有对当下的真实感受，除此之外的感受都是非真实的。毋庸讳言，是主体的自我异化。要回去的，是过去的自己同将来自己的认同。但是这种认同，是肯定时间的治愈吗？还是仅仅对过去自我的否定。

我认为形式主义是世界的真实的存在，其他一切存在都是不真实的。何为真实？通过人的感性接触到并经过所谓理性分析出来的东西并不是真正真实的存在物。以往的观点认为这导致了不可知论例如康德的物自体。虽然康德本就是从不可知论出发的，但是不得不说康德哲学是一种形式主义哲学。换言之，以往的任何存在都是一种形式主义，而不仅仅是不可知论。形式主义是世界真正的本来面貌。一切人们所能认识的存在都是经过了人化的存在，本质上是一种所谓现实世界中本不存在的一种非存在。也即人们对存在的认识是一种非存在，人们的思维所反映的不是现实性的存在，而是一种非存在。这种非存在背后隐含的不是存在本身，而是一种形式主义存在。一种经过了人们加工过的存在，属于一种可知的非存在。过去康德的观点只反映了其中一点，即他认识到了人是不可能认识到所谓真实世界存在的样子的，一切存在只能经过人化方能为人们所认识和把握。但是人们认识和把握到的，究竟是不是真实的存在呢？只能说有可能是，但是大概率是不知道。或者说，人们所能认识到的不是真实的存在，物体本身的存在是什么样子受限制于人们本身。但是这不是问题的关键所在，即使人们对存在的认识是存在愿意呈现出来的那种存在，人们也无法认识到存在本身的被剥离了形式以后的真实面貌。存在的被认识是主观的，存在之为存在，一定是具有了某种形式主义因素的，倘若存在没有任何的夹杂形式主义因素。那么这种存在本身就是非存在。形式主义并非是没有内容的存在，而是一种真正的本源性质的存在，也是唯一真实的存在。这是由于一切被认识到了的存在是非存在，而这些非存在的存在，本身恰是这种形式主义的体现，并不是说非存在之中包含了存在的因素，而是指这种非存在的存在是一种人们对存在的形式主义化的即人化的认识。从这一点上看，人化是形式主义化。人们对物质存在的认识始终无法脱离人类自身的观点和视野范畴，这是人类自身局限性使然。那么，人类的认识到底来自何处？我认为人类的认识的本质是一种对存在的人化过程，即形式主义化过程。一存在只有经过上述过程才能变成非存在，人只能认识非存在，而无法认识存在。人对文本的阅读过程本身就是一种作者再创作的过程，而人对存在的理解过程认识过程不外乎如是。人的一切认识都是形式主义化的非存在。而存在真实的样貌，经过了形式主义化以后，就不再是存在了。这里的真实样貌，并非是指存在的本质，而是指没有经过形式主义化的存在。因为存在的真实本质，也有可能并非是一种存在，也可能是一种经过其他形式主义化的存在，即非存在。人们对非存在的形式主义化的产物，同样也是非存在吗？并且认为科学的发展是靠近真理的过程也是错误的。

> “只有在睡醒的时候才知道刚才是在做梦，并且还在梦里为梦占卜吉凶。”——庄子或许说过这句话。

而我则认为，现在或许就是在做梦。只有愿意相信在做梦，才能醒来。以往的观点认为现在是活着，是醒着。但是这一切都是预设的，根本毫无理由，并且也难以证明。我认为，人已经死了，并且是在睡觉。即使又醒来，如何证明不是还在递归做梦？以往的论证方法不诚实，总是试图靠超验或经验存在或存在者代替证明或预设，这属于递归论证。或者尝试绕过这个问题，认为现世更值得追求，这是典型的异化表现。质疑问题本身成立的合理性，本身也是一种异化的表现。在《黑客帝国》中，从母体醒来的人为什么从不怀疑，这种醒来本身也是一种梦或另一重矩阵世界？游戏是虚拟的，但是游戏中的灯也是用现实中的电点亮的。不是为了证明任何虚拟中的存在都有物质性因素，而是为了反证，假如所谓现实世界中仅有灯是真实存在，能够扩大范围演绎为所有都是物质性的吗？因此，即使所谓整个大自然都是真实的，也无法得出人类是真实的这一结论。大多数的人所认识的非存在之所以有共识存在并非是因为非存在的真实性，而是因为非存在的形式主义化本身这个过程具有普遍性。也就是说，人们对非存在的认识本身是被约束在一定范围内的。即所谓的人化的条件。普遍性之所以存在，就是因为形式主义的非存在是非存在，不是真实的存在，是受限于主体本身的，这是主体存在的特殊性，但是整个人类又是一种特殊的主体，内部存在的矛盾也是作为整体性而统一存在的。所以说人们认识到的非存在往往是一致的，以至于对存在达成共识。世界的真实性并不决定其中一切情感的存在与否。相反，我往往觉得，有很多事情值得去做的应该被承认其价值的抑或都已经被遗忘的那些是虚假的，但是真实的世界与虚假的世界并没有什么根本上的区别，即使一切都是真实的或相反，又能说明些什么？无非就是那些东西罢了。

所谓现代和现代文明及现代性只是假象。我们仍然并永远处于不文明的时代。一切现代史都是古代史都是远古史，都是不发达文明史学。现代社会或文明只是一种表面的外观，而实际上人类的本质或状态并没有真正发生根本性的改变。现代社会所标榜的文明与进步真实存在吗，人类历史中不断存在着原始或未开化特征。“文明”或“现代”只是相对的概念，而不是绝对存在的状态。而所谓的“文明”可能只是一种表面的遮掩或假象。理想社会或大同社会只可能是一种形式主义。

## 再版前言：回到复制粘贴，面向教程本身

> 引用一：
>
> > 本书注重例子，少理论，只要你对着例子一步一步操作（原文“对着”误作“对这”，此处据意调整），就会成功，会让你有成就感并能坚持学下去，因为很多人遇到障碍就会放弃，其实我就是这种人，只要让他看到希望，就能坚持下去。（陈景峯. 序：FreeBSD 使用手册\[EB/OL]//Netkiller FreeBSD 手札. (2024)\[2026-04-08]. <https://www.netkiller.cn/freebsd/preface.html>.）

> 引用二：
>
> > 群里有人发过《道德经》中的这段话：“有道无术，术尚可求；有术无道，止于术。”<注 ①> 诗无达诂，对此类经典，每人都可能有不同的解释。但我想借此告诉你：要尽力去探求每个操作背后的含义，这样才能举一反三，而不是学会了装某个桌面之后又去找人问怎么装另一个桌面。这也是本教程不提供可以直接复制粘贴的命令的原因。有所探求，得之其道，从而长进。（Alex11. 写给 FreeBSD 新人\[EB/OL]//Alex11 的 FreeBSD 手册. (2024-02-23)\[2026-04-08]. <https://alex6357.github.io/freebsd-book/preface/to-beginners.html>.）
>
> 注 ①：此处引用的原文有讹误。查道德经（王弼，注. 老子道德经注校释\[M]. 楼宇烈，校释. 北京：中华书局，2016. ISBN: 978-7-101-11674-8）并无此语或类似含义。实出：豆豆. 遥远的救世主\[M]. 北京：作家出版社，2005：446. ISBN: 978-7-5063-3174-6，对应：张前，导演. 天道\[Z/OL]. 中国大陆：浙江天润影视发行有限公司，2008. 第 18 集第 42 分钟后的 [删减片段](https://www.bilibili.com/video/BV1bT4y1F7qK)。但在郭德纲相声中也反复出现类似“艺、术”的内容：“有艺无术是诈骗，有术无艺的是商贩。”（画质比较清楚的视频是德云社. 德云社师徒父子相声大典（上海站）\[Z/OL]. 中国上海：梅赛德斯奔驰文化中心，2018-08-11. <https://www.youtube.com/watch?v=qpW_SRVEzEg>. 从第 1:07:00 开始）从作品创作年代及出版地看，“有道无术，术尚可求；有术无道，止于术。”这几句话可能受了郭德纲的影响。

***

以上两段话体现了解释学循环的难点：要想理解局部，必须理解整体；要想理解整体，必须理解局部。而前见又是必然存在的。我们总是基于一定的理论假设与个人意见（前见）参与其中。但这不必然是负面的，相反，前见是不可或缺的。试问，你将如何向人解释，为什么手机屏幕坏了，但截取的屏幕图像仍然是完整的？这与破碎的镜子和镜像的关系是一致的吗？

绝大多数古希腊哲学家认为流变的事物是不真实的。如果一切都变动不居，会不会下一刻整个世界就消失了？他们甚至认为现实世界只是真实世界的投影，故而始终追求着那不变的本原与理念世界，追寻着那不变的太一。康德认为理应存在一个“物自体”。我们所能认识的只是事物的表象，事物的真实样貌（物自体）我们永远无法经验。事物果真如同我们看到的那样真实吗？笛卡尔的“恶魔假设”真的只是假设吗？

胡塞尔的现象学强调“回到事物本身”（Zurück zu den Sachen selbst），而非“回到康德”。现象学研究一切的原则之原则即是直观。悬置一切传统哲学思考、意见与前见。在事物自身被给予性中对其进行追问，即主张无前提性。呈现出来的事物本身是何面貌，就是何面貌。现象学认为，你看到了什么，那就是什么，那就是事物的本质。为何要假设一个永远无法经验、不存在的逻辑本体？胡塞尔无疑将笛卡尔的“清楚明白”（Clarté et distinction）原则更彻底地推进了一步。其学生海德格尔主张“面向事情本身”（Zu den Sachen selbst），他是个反叛的学生，承认前提是我们揭示现象的必要之物。

“故人不独亲其亲，不独子其子，使老有所终，壮有所用，幼有所长，鳏寡孤独废疾者皆有所养，男有分，女有归。”《礼运大同篇》对孔子的“正名”思想进行了发挥。“文艺工作者要有文化，医生要会医术，游泳运动员要会游泳”，我经常看到有人用这种看似语义重复的“废话”来讽刺。事实上，让事物回到事物本身并非易事。“天下多忌讳，而民弥贫；人多利器，国家滋昏；人多伎巧，奇物滋起；法令滋彰，盗贼多有”（高明. 帛书老子校注\[M]. 北京：中华书局，2022. 下同）我们看到了太多诸如“垃圾桶里不能有垃圾”、“街道招牌必须统一格式不能引人注目”、“床上不能躺人”的规定。同时我们也注意到，大量理工科教科书，无论中外，总是充斥着各种炫技（如“由 xxx 可得”“易证”）和防御性措辞（如“注意到”“显然”），甚至作者本人都不会做印在书中的练习题。

然而事实是，计算机科学作为一种科学，是基于经验主义的。如果仅从超越计算机本身的理论层面进行研究，计算机科学存在的合法性会被消解——这个世界果真存在吗？研究这些真的有意义吗？如果就连快乐本身也是不存在的呢？我们中的绝大部分人不会涉足计算机相关的科学研究，也不会在 Intel、AMD 这类公司工作，更难取得相关领域的博士学位。满足于复制粘贴的快乐真的是一种过错吗？有多少人愿意接受洞穴外太阳的照射？苏格拉底强调德性的重要性，并一再强调“认识你自己”，可苏格拉底最终是被雅典公民投票处死的。其实大部分所谓的理论也不过是另一种可以复制粘贴的内容。你可以将 C 语言追溯到汇编语言，再到处理器指令、信号与系统、计算机体系结构、中央处理器设计、物理学、数学。然后呢？到数学就真的结束了吗？科学与数学从不且也无法研究本质，科学仅仅研究现象。换言之，科学中本不存在所谓的“道”，只有“术”。若你仅仅满足于此，那也不过是另一种“苦难哲学”罢了。庄子在《南华经》中就阐明了这一点——“吾生也有涯，而知也无涯。以有涯随无涯，殆已！”人们真的能拥有知识，而非仅仅是意见吗？苏格拉底对此持否定态度。

事实上，若强行从《老子》中抽象出“道”与“术”，你会发现二者并不矛盾，亦难分高下。你从后世道人的作品中也能看出端倪。看过《仙剑奇侠传》的人应该对《太上洞玄灵宝元始无量度人上品妙经》中的这几句话并不陌生：“人道眇眇，仙道莽莽。鬼道乐兮，当人生门。仙道贵生，鬼道贵终。仙道常自吉，鬼道常自凶。高上清灵爽，悲歌朗太空。惟愿仙道成，不欲人道穷。”人道渺茫却有归处，而仙道却不知所终。难道仙道就比人道高明到哪里去吗？电视剧《士兵突击》（第三集开头）中，李梦说“光荣在于平淡，艰巨在于漫长”。“道”并非是对“术”的简单否定，其实它本身也是另一个层面的“术”。“究竟谁能说得清，道路向何方延伸？又要谁能说清，日子向何方流逝？”恩雅（Enya）的回答是“唯有时光”（Only Time）。冯·诺伊曼曾说“If people do not believe that mathematics is simple, it is only because they do not realize how complicated life is.（如果有人不相信数学是简单的，那是因为他们没有意识到人生有多复杂）”可见平凡的人生是难以理解、也最难度过的存在。的确，复制粘贴人人都可以做，问题在于，究竟是谁去做了？我们需要有人做复制粘贴的工作：如果人人都想当医生，那大街上的垃圾谁来清理，谁来扫大街？而垃圾总是存在的，总是需要清理的——不能因为把街道上的垃圾桶藏起来就欺骗自己没有垃圾，那样只会把所有地方都变成垃圾桶。“玻璃晴朗，桔子辉煌。”现在的学院派学者，把康德研究得比康德本人还要“清楚明白”，其著作量更是康德本人著作的万倍不止。但这当中究竟有几个人能留名于哲学史？有哪几个人的哪几本著作，超越了康德本人的批判理论？他们大多也只是在复制粘贴罢了。难道你能指望人人如龙，每个人都是柏拉图、亚里士多德、康德、黑格尔、马克思吗？这可能吗？如果没有超越他们，你的工作与复制粘贴亦无本质区别。然而，这些工作真的毫无意义吗？我见过太多粗制滥造的哲学史教程，连经典文献的人名翻译都是错的。没有人能够站出来写一本大家都能看懂的书。有多少人在二十年前就说要完成某某书籍的翻译或创作，我至今也不知道他们申请的 CIP 和 ISBN 编号是多少。难道每个人都是佛陀，可以无师自通、顿悟大道吗？还是说每个人都是维特根斯坦，不需要研读哲学史也能成为哲学家？

韩愈认为自己是儒家道统的正统继承人，一生旨在复兴儒学，排抑佛老。《师说》也不例外：韩愈以“师道”为手段，希望培养能够弘扬儒道的士大夫，以期重振儒学。所谓“道之所存，师之所存也”。然而真正的问题在于，“师道”是可能的吗？教育是可能的吗？启蒙与现代化是可能的吗？事实证明，这是不可能的。很多人看似在追求所谓的“道”，但对科学的认识根本上错得离谱，也不愿挣脱洞穴的枷锁。真理的确如同太阳，问题在于，我们始终身处洞穴之中。自以为身在洞穴之外的人，实则仍处于另一处洞穴之中。坦白讲，我不知道。“知之为知之，不知为不知，是知也。”我的确不知道，我也不想知道，我只需要快乐。很显然，《师说》中“是故弟子不必不如师，师不必贤于弟子，闻道有先后，术业有专攻，如是而已。”看似是对《论语》中“三人行，必有我师焉”的具体发挥。但实际上，尽管韩愈一生抨击佛法，这几句话却明显受了禅宗思想的影响。在佛法中常有此类讨论：这也是宗教与思想政治教育的明显差异，弟子与师父在面对佛法（或神）时地位是平等的，是共同求道的身份。

“你的眼目要向前正看，你的眼睛当向前直观。要修平你脚下的路，坚定你一切的道。不可偏向左右，要使你的脚离开邪恶。”（箴言 4:25-27）“所以，凡他们所吩咐你们的，你们都要谨守遵行，但不要效法他们的行为；因为他们能说，不能行。”（马太福音 23:3）“凭着他们的果子，就可以认出他们来。荆棘上岂能摘葡萄呢？蒺藜里岂能摘无花果呢？”（马太福音 7:16）“是以圣人居无为之事，行不言之教。”试问，如果自诩为 FreeBSD 社区，所有成员每日都在空谈，这不也是一件快乐的事吗？

与绝大多数操作系统不同，BSD 既提供二进制包供用户快速安装，也提供源代码供用户自定义配置。古今两种思潮在此汇聚。如果有人既悬置“道”，也悬置“术”——正如此篇文章一样。很难想象他该有多么快乐呐！在当今时代，快乐是极难获得的。睁眼看看这个世界，有哪一点是能够让人满足的？郭德纲都说这年头花钱能买个高兴已经是不易了。“一切希望都带着注释，一切信仰都带着呻吟”。这个世界真的会变好吗？“梁漱溟之问”深深困扰着几代学者。FreeBSD 真的会变好吗？我真的会变好吗？这深深困扰着我。

其实无论你怎样解读道家或《老子》，都难免被那一抹消极的哀彩抚摸。这个世界存在的真实性与否也不能掩盖她的恶。城市化与工业化使得一代又一代人失去他们的家园。其实没有什么复杂的，过于复杂的理论除了让自己失去传人外没有任何好处，这点在中国佛教史上体现得很明确。“想不明白的不要想，弄不清楚的不要弄，做不出来的不要做”：回归自然，回到简朴的社会，是《道德经》反复陈述的箴言。我们看到了什么，那就是什么，即使它背后可能有更大的存在，你也无法否认，我们看到的事物，她就是如此。在现代社会里，几乎所有人都在无休止地重现昨日。回到复制粘贴，就是回到这种简单的三点一线乃至两点一线的琐碎生活。

一个显而易见的事实是，绝大部分人搜索教程、查找方案并非为了追求真理或满足好奇心，而是为了谋生。你所追求的“真理”，早在面试时就被你背诵的 Java“八股文”和在平台上刷的无穷算法题所覆盖了。这些真的有意思，有意义，有乐趣吗？说这些我都觉得好笑和荒唐。如今抬头看看天，除了塔式起重机的灯、雾霾以及脚下的坑，绝没有星星。郭德纲说：“先搞笑吧，相声要是不搞笑，那就太搞笑了！”先复制粘贴吧，要是连复制粘贴都没人做，那就更是一片空白了！

## 初版前言：好望角与塔式起重机

FreeBSD 是一款开源的类 UNIX 操作系统，直接继承自 BSD UNIX。

自 2004 年 9 月后，中文世界就再也没有一本 FreeBSD 的入门和基础教程了（此前最后一本为冯宝坤，陈子鸿. FreeBSD 完全攻略\[M]. 北京：中国物资出版社；北京：北京希望电子出版社，2004. ISBN: 978-7-5047-2160-0；此前尚有 McKusick M. K, Bostic K, Karels M. J, Quarterman J. S. 4.4BSD 操作系统设计与实现（中文版）\[M]. 李善平，等，译. 北京：中国电力出版社，2003.）。知网上的硕博论文（需要说明的是，部分高校如清华大学、复旦大学等部分硕博论文未上传知网，但仍能说明一种趋势），有关 FreeBSD 的论文仅有 10 篇，均为硕士论文；而 Linux 则有 2 万余篇，其中百余篇为博士论文。在国内招聘网站上几乎找不到任何与 FreeBSD 相关的工作岗位，学校也不会开设相关课程。看起来市场完全不需要了，是这样吗？

当初那些推广宣传 FreeBSD 的人，如今在哪里？是否还会偶尔访问一下 <https://freebsd.org> 呢？水木年华的《一生有你》中唱道，“多少人曾爱慕你年轻时的容颜/可知谁愿承受岁月无情的变迁/多少人曾在你生命中来了又还/可知一生有你我都陪在你身边”。只有与你同行的才是你的朋友，无论在先还是在后，都会被人遗忘。

这个世界的确很大，但对大部分人而言，穷极一生也不会到达非洲的好望角。受墨卡托投影的限制，人们意识不到非洲有多么广阔。人们只觉得俄罗斯很大，格陵兰岛更大。事实上，二者面积之和，尚不及非洲面积的三分之二。这个世界果真很大，就像开源世界一样。面对头顶无垠的星空，人们是会选择继续抬头前行（哪怕掉进泥沼），还是低头用忙碌来充实自己？有的人可能一辈子都住在乡村，从未出过几次远门，但这并不妨碍世人了解他那深邃的思想世界。即使人们完全没有能力读懂他的思想，也会每年去纪念他。世界的确很大，大到穷极一生也无法到达彼岸；世界又真的很小，小到每天来来回回却连镇子都没有踏出一步。我们的好望角究竟在哪里？世界越大，世界也就越小。

自我接触 FreeBSD 至今已 7 年有余。我从未直接对 FreeBSD 项目贡献过，也没有向 src 提交过任何代码。我已经尽最大程度去延续这份敝帚自珍。

之所以将这一系列教程和文章作为一本开源书籍来呈现，根本上是因为我希望此书能像 BSD 一样得到最大程度上的使用，产生最广泛的效益。

法国哲学家让-保罗·萨特认为，存在先于本质（参见《存在主义是一种人道主义》）；君子不器，人的存在没有固定本质，人的本质是在实践中动态建构的。很明显，现在大多数人也持此观点：人要去创造意义，才能同时获得意义。这看起来似乎是对意义问题的终极解答了。那么，事实果真如此吗？萨特早年认为人的自由是绝对无限的，不承认任何所谓的客观限制。我可以做，但我还没有做，因为我还没有找到做此事之意义。

现在想起来，刘震云《一句顶一万句》中有个角色叫“老詹”，从意大利到中国来传教，结果传教没成效，成了卖葱的；当中还有一个角色叫“老汪”，时常不知道在走些什么，就一直四处乱走。在这个世界中，我们除了安慰自己这已经是可能世界中最善的那个、已经是上帝的全能意志的体现，还有什么借口说这个世界的美好？我时常乱走，我不认识任何人。就像在看 VR 电影一样。这个世界会不会是一场电影？我们除了是自我感知意识的集合体以外，和电影中的人有什么区别？我在一场影像的放映之中，我并不存在。幼儿园的墙壁摸起来很粗糙，看起来是黄色的，敲击起来很硬。但这并非毫无根据。是由工人如此搭建而成。但这和这一切是场电影并不冲突。仔细想来，是谁让我看到了围栏？是谁让我摸了一下这根柱子？真的没有人吗？有一个原因可以解释这一切吗？我有不去触摸它的自由吗？我真的有自由不去触摸这根坚硬的、粗糙的黄色柱子吗？为什么我到处彳亍，仍旧回到了原点？

除疾病外，我一无所有。生命真的存在吗？正如加缪所言，我一直是个局外人。我却用《庄子·山木》中的“君子之交淡若水”慰藉自己。我十几年前常去的图书批发市场，它还在，但也不在了，我再也找不到教辅书以外的任何书籍了；当初和我一起看书的人，他还在，但也不在了，我再也和他说不上话了。也许二者根本就从未存在过，只是我看过的一部电影罢了。电影结束后，剧组也就该解散了。我当时还在和众人打《三国杀》，不知道是谁丢的铁盒，里面是塑封的卡牌。最后我赢了。我以为以后还会有很多如此快乐的日子，但那却是结束。我再也凑不齐人来打三国杀了。无论线上还是线下。甚至 2V2 都找不到人。胜地不常，盛筵难再；兰亭已矣，梓泽丘墟。我已经很久很久没有玩过三国杀了。

我可能这辈子也无法去 BSD 的诞生地求学，甚至看一眼都是不可能的。我也永远无法获取他们要求的哲学博士学位。我的好望角在哪，它真的存在吗？如今，我抬头除了一片雾霾，什么也望不到。我以为是月亮，结果发现那是塔式起重机的照射灯。

存在即破烂。再美好的东西，也不过是一堆破烂。很多美好的东西即使再用心去推广宣传，也终究会消逝。所有的开源项目迟早都会变成数字墓地，后遂无问津者。

事实是，每天都会和无数人错过。北岛诗言“一切交往都是初逢”。即使是认识的人，也会永远离开。我的意思不是指生理上的死亡。而是指，比如群里的群友，他不说话了，就等于“死”了，没有区别。你找回他说话，也没有意义。第一，你不想这么做；第二，他也不想这么做。所有人在一起不都是短暂的几年吗？就实际意义而言，不说话就是“死”了。只有能说得上话的，对自己来说才算“活人”。这与他的生理健康无关。这样的“死人”遍地都是，我们不是一直活在墓地之上吗？聊天群也会消失不见。人还在，群没了，再拉回来也是“死人”。他把你用的聊天软件都卸载了，你即使追随过去用同样的软件，也没什么用。所有的聊天群迟早都会变成数字坟茔。没意思啊，无论群里还是现实，无非就是吹牛。什么也留不下，现实也一样。截图不就是赛博合照吗，没区别。这世界很大吗？为什么感觉这么小。和你待的时间最长的人你几乎都不认识，也不想认识，那就是工具人。谁会想和同事、同学真正交朋友？忙起来好啊，都不记得了，多好。大家都忙起来，那这个世界该有多“美好”。事实是，他们只是换了一个地方吹牛罢了。反而安慰自己很充实。那些未与我们同行的人，真实存在吗？我对他们的印象，那代表下线的黑白头像就是遗照。那些是他们的遗照吗？他们最后的消息，是遗言吗？那电子签名，是墓志铭吗？

我一直是个局外人。从未参与过任何 FreeBSD 的开发与维护。对于 FreeBSD 项目来说，我就像是南阳刘子骥，再也找不到桃花源了。我为什么没有参加？我可以做，但我还没有做，因为我还没找到做此事之意义。我也的确“做过”，我也从未“做过”。

这是一个大流变的时代。工业化和现代科学要求以标准、效率和货币来衡量一切。凡是花里胡哨的都是形式主义，凡是长篇累牍的都是废话唠叨，凡是瞻前顾后的都是懦弱胆怯，凡是没有数学化的全是无稽之谈。现代性从未存在过，你能在虫豸身上找到任何所谓的文明吗？人类始终愚昧又落后，却往往用形式主义和现代科学遮蔽这一切。人类文明真能永不落幕吗？我告诉你，我不相信！

《玫瑰三愿》（龙七词，黄自曲，1932 年）中玫瑰花“我愿那妒我的无情风雨莫吹打，我愿那爱我的多情游客莫攀摘，我愿那红颜常好不凋谢，好教我留住芳华”。然而玫瑰终究化归泥土。我真的能找到一朵烂开在碧栏杆下的玫瑰花吗？如果存在，她在哪里？

我始终在思考。会者定离，已经没有人与我同行了。我的确是找不到任何朋友了。朋友，我怎么待他，他就怎么对我，这样就可以了。

虽然以前也是如此，但中文社区现在和其他群已经没有区别了。看看其他群，那个近 100 人的翻译群没有一个人翻译，你不觉得荒谬吗？讨论 BSD 却连 BSD 的基本常识都没有。没有什么意义。

我是 2018 年开始使用 FreeBSD 的。同年，我因严重的躯体化症状就医，被诊断为重度抑郁症。因为根本动不了，手指也是，所以最开始几年只能在群里聊天。群里有个人说为什么不把教程总结起来。我说，那服务器和域名的费用你出吗？他就买了个域名——freebsdcn.org，服务器用的 Vercel。我一晚上就整理出了二三十篇——因为晚上根本睡不着。还是浑身疼痛，后来过了两年，换了一家医院，开了别的药，不疼了。但是，时常会感觉这个世界破破烂烂的。什么事情都觉得没有意义。我花费数年时间学习了西方哲学与基督教神学。我已经好几年没有去医院了。这本书的编写工作中间也中断了总计约一年半。我愈发怀疑世界的真实性。讨论具体的计算机知识没有任何意义，科学也没有意义，科学是经验性的。尽管我以前曾深入研究过，但数学也是不完备的，再深入研究，没有意义。我已经尽我所能去建设了。其他的，不是我不想做，是我做不了。我只是花了几个小时、几分钟去写一些没有意义的东西。但是那是我一天中唯一的活动了。我从未在网上和别人说过这些。我只是说我身体不好。我每天都感觉自己要不存在了。但是后来觉得没有意义，也许我从未存在过。我看到动漫里那些人物，组乐队啊，参加各种社团。包括所谓的追梦电影，探索外星人的，如《宇宙探索编辑部》，我始终觉得他们不够努力。我知道说这些会对别人造成困扰，故我从未说过。我现在感觉自己一无所有，除了不健康的身体。我想做些什么事情，对我来说真的是非常困难的。我 7 号打开的书，现在就读了 15%，在过去，一本书几天就看完了。如果你查看 GitHub 的提交记录，你会发现绝大部分提交都在深夜，不吃药根本睡不着。说这些也没用。我只是想说，我这样都能有所贡献。那些正常的人，为什么连现成的东西都不去看一眼，就有资格说没意义？他们有什么资格说没意义。我每天都感觉自己到不了白天，我仍然在自我感动。我只是用鼠标点击了几下，但那天我基本上没有任何想做其他事情（包括吃饭）的念头。我在认为自己的存在都没有意义的情况下，还在复制粘贴。

我说了我不知道，我没有能力去知道，可能永远也不可能了。所有人都在说自己在上班，很忙，没空陪你玩，自己上班很累，做这个不赚钱。无论 FreeBSD 社区，还是其他社区，我都是个局外人。我知道这是我自己的问题，不怪他们。我也从来没有埋怨过任何人。我只是自己一个人复制粘贴，仅此而已。

我已经尽力了，但我从未努力过。

我自认他是我最好的朋友。我往他背后贴纸条，无论我怎么捉弄他也不生气，只是把纸团扔进垃圾桶。他给我 5 毛钱，祈求我和他一起走他那条路回家，让我等等他——他被体育老师抓去练长跑跨栏了。在路上，他把捡到的汽车零件，一个很精致的钢制圆环给了我。他看我很想要，就说他经常捡到，不差这一两个。他说他租住的房子要拆了盖啤酒厂。他要回到山西老家了。那时，流行玩悠悠球，他玩得最好，会很多招式。我什么也不会，像现在一样。我说，我花了 5 块钱“巨款”买了一个悠悠球，一定带过来给你看看。第一天，我忘记了。第二天，我忘记了。第三天，放假了。直到现在，快二十年了。他家，仍旧一片荒芜。我昨天去看了，和以前相比，真的没有变化。我们再也没有见过面。他仍然没有见过那天我所提到的悠悠球的样子。我为什么没有问一下他的户口所在地，哪怕是可能再也打不通的电话号码，我为什么没有去看看他家到底在哪里？我相信我们还会再见，但我仍未知道那天所提及的家的样子。钢制圆环也早不知道去了哪里。离开了 BSD，我也不知道我还能去哪儿。但是是时候离开这一切了，我已经什么都不知道了。我不知道他家在哪，我不知道他是不是还记得我，我不知道他是不是把我视作局外人。我这个人，满脑子都只想着自己呢。我从未努力去做任何事情。但我已尽力。

佛教允许比丘还俗的次数可以有七次（参见《增一阿含经》，比丘尼仅能还俗一次）。我也三度放弃 FreeBSD。如今，已经没有机会再继续下去了。

我很久以前写道，“我们必须团结起来做些什么事情，无论大小，哪怕只是谈谈自己的学习体会（但并非出于炫耀）。否则如果只是夸夸其谈，我们和那些只会吹嘘的、只会键政的、互称大佬的群或社区有任何区别吗？如果没有区别，那就没有任何意义，那么我宁愿这个社区不再存在。如果大家有时间有精力，可以考虑翻译文档，如果会编程，可以考虑移植软件到 BSD，如果能力更高甚至可以参与系统开发。”

如果凡是存在的必然有其合乎理性的地方，一切新事物都在不断地获取其存在的理性，而一切的旧事物都在不断地失去其必然的理性。那么只有一个不存在的点是事物绝对完美的那一刻。所以无论是新事物还是旧事物都是破烂而已，都是非充分理性所决定的。即存在即破烂。新事物获得的所谓继承旧事物的理性也不过是一种幻觉而已，因为根本不存在一个状态存在完美的事物，进而构成世界。很明显，现今无论是公众号还是别的什么，都已经没有存在的意义了，都已经让时代解构了。《BanG Dream! It's MyGO!!!!!》中长崎爽世说“只要是我能做的，我什么都愿意做”，我亦如此。我不想再看到，连初一考试倒数的学生都能参照我的简陋教程在 VMware Workstation Pro 上安装好 FreeBSD 和 KDE Plasma 5，竟有成年人在九个月内连在虚拟机里安装系统都做不到，反而理直气壮地空谈这一切。如今早已没有了巴别塔，但人们还是装作不识字，装作看不懂视频，装作看不懂文字。那么只有上帝能救他们了。

那些说了不做、每天都在讨论时髦话题的人，就喜欢这种自己根本不懂、看了以为自己懂了实则荒谬不通的东西。说了一堆全是假大空，看的人还自以为懂了。原来现在的市场喜欢这种东西，真是个“美好的新世界”呢。我也没什么两样，没资格批评他们。毕竟，那样是多么的快乐啊！如果像现在这样，我还自以为懂了，说些看上去自己都不懂的话，那不就是双倍的快乐吗！二十一世纪了，没有什么比快乐更重要的事情了！

是时候结束这一幕荒唐的闹剧了。没有什么意义，无论在用户还是开发者群体抑或我自己。我没有办法强求任何人和我一道同行，在世界这场巨大的过家家中再扮演什么旁的角色。那些能够一直陪伴你的，才是你所应该珍视的；那些和你高谈阔论的，未必是能和你说得上话的人；那些未曾到过的远山，不代表你从未登顶。虽然时间是不同人眼中流动的影像，可我们仍然在同一幕舞台之上。

## 参考文献

* Knuth D E. Ancient Babylonian algorithms\[J]. Communications of the ACM, 1972, 15(7): 671-677. <https://doi.org/10.1145/361454.361514>. 冯·诺伊曼名言“If people do not believe that mathematics is simple, it is only because they do not realize how complicated life is”出自 1947 年 9 月 15 日在哥伦比亚大学举行的 ACM 首届全国会议上的主题演讲，由 Franz L. Alt 在下文中引述: Alt F L. Archaeology of computers—Reminiscences, 1945–1947\[J]. Communications of the ACM, 1972, 15(7): 693-694. <https://doi.org/10.1145/361454.361528>.
* 洞真太上太霄琅书\[M]//道藏: 第 33 册. 北京: 文物出版社; 上海: 上海书店; 天津: 天津古籍出版社, 1988: 690b. 人行大道，号曰道士。
* CIA. The World Factbook: Area Rankings\[EB/OL]. (2023-07-06)\[2026-04-17]. <https://web.archive.org/web/20210204222711/https://www.cia.gov/the-world-factbook/field/area/country-comparison>. 原 CIA World Factbook 面积排名页面已下线，此为 Internet Archive 存档版本。俄罗斯面积约 17,098,242 km²。格陵兰面积约 2,166,086 km²，非洲面积约 30,370,000 km²。二者面积之和约 19,264,328 km²，不及非洲面积（约 30,370,000 km²）的三分之二（约 20,246,667 km²）。
* 龙七(龙榆生), 词; 黄自, 曲. 玫瑰三愿\[Z]. 1932. 歌词全文为“玫瑰花/玫瑰花/烂开在碧栏杆下/玫瑰花/玫瑰花/烂开在碧栏杆下/我愿那妒我的无情风雨莫吹打/我愿那爱我的多情游客莫攀摘/我愿那红颜常好不凋谢/好教我留住芳华”。详见龙榆生先生新体歌曲作品选 <https://longyusheng.org/xintigequ/lys-meiguisanyuan.html>。
* Husserl E. Logische Untersuchungen: Zweiter Band\[M]. Halle: Niemeyer, 1901. 原文为“zu den Sachen selbst”（面向事情本身），“Zurück zu den Sachen selbst”（回到事物本身）为后世现象学运动口号化表述。
* 刘万瑚. “回到事物本身”与“面向事物本身”——胡塞尔与海德格尔的现象学方法之争\[J]. 哲学动态, 2019(11): 84-91.
* Pascal B. Pensées\[M]. Paris: Brunschvicg éd., 1897: frag. 347. “L'homme n'est qu'un roseau, le plus faible de la nature; mais c'est un roseau pensant.”\[人不过是一根会思想的芦苇。]
* Apple Inc. BSD Overview\[EB/OL]. (2013-08-08)\[2026-04-17]. <https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/BSD/BSD.html>. 苹果官方开发者文档指出: “The BSD portion of the OS X kernel is derived primarily from FreeBSD”，但 XNU 内核本身是 Mach 与 BSD 的混合体，源自 NeXTSTEP，并非直接派生自 FreeBSD 内核。
* 梁济. 梁济遗稿\[M]//梁漱溟. 这个世界会好吗: 梁漱溟晚年口述. 艾恺(Guy S. Alitto), 采访. 北京: 东方出版中心, 2006. 1918 年 11 月 7 日梁济问其子梁漱溟“这个世界会好吗”，三天后投净业湖自尽，后世多称“梁漱溟之问”，实则发问者为梁济。
* FreeBSD Project. FreeBSD 1.0 RELEASE Announcement\[EB/OL]. (1993-11-01)\[2026-04-17]. <https://www.freebsd.org/releases/1.0/announce/>. FreeBSD 项目起源于 1993 年初，首个正式版本 FreeBSD 1.0 于 1993 年 11 月 1 日发布。
* Phoronix. Intel Ivy Bridge Borked On FreeBSD\[EB/OL]. (2012-06-22)\[2026-04-17]. <https://www.phoronix.com/news/MTEyNDg>. 该文测试了 Intel Ivy Bridge HD 4000 显卡在 FreeBSD/PC-BSD 上的图形驱动兼容性问题。
* procps-ng Project. procps Package Documentation\[EB/OL]. \[2026-04-17]. <https://gitlab.com/procps-ng/procps>. procps 包中 free 命令通过读取 Linux procfs (**/proc/meminfo**) 获取内存信息，而 FreeBSD 已弃用 procfs，故该命令无法使用。
* 1Ferrox. Lamps in Videogames use real electricity.\[EB/OL]. (2019-11-28)\[2026-06-04]. <https://www.reddit.com/r/Showerthoughts/comments/e2x6mo/lamps_in_videogames_use_real_electricity>. 在该贴中，提出“电子游戏中的灯具会消耗真实的电力。因为它们会照亮周围区域，所以屏幕需要变得更亮。而更亮的屏幕会消耗更多电力。”


# 绪论

绪论提供本书的整体概览，包括本书定位、对读者的要求、组织结构、书中命令及符号含义。

## 本书定位

本书涵盖 FreeBSD 15.x-RELEASE 与 14.x-RELEASE 的安装与日常使用，并尽可能向下兼容较早版本，同时包含部分 16.0-CURRENT 的内容。

本书主要面向 amd64（x86-64）与 arm64（AArch64）架构，并尽可能支持其他硬件架构。

本书测试环境为 Windows 11，并保持系统更新。

> **注意**
>
> 本书中涉及的软件版本号、功能状态、兼容性情况等信息以撰写时为准，后续版本可能已有变化。读者在实际操作时应以当前官方文档为准。

## 对读者的要求

本书以高等院校计算机科学与技术专业一般本科毕业生的合格及以上水平为难度基准。

但读者 **不需要** 具备以下基础知识：

* 操作系统基本概念（进程、内存管理、文件系统等）
* 命令行操作经验
* 计算机网络基础知识
* 英文阅读能力

我们希望读者：

* 活着，并且幸福地活着

## 本书的组织结构

**第 1 章 FreeBSD 初见**：介绍什么是 UNIX、GNU 操作系统和自由软件运动、Linux 与类 UNIX、什么是 FreeBSD。

**第 2 章 FreeBSD 导论**：深入探讨 FreeBSD 的理想、现实与中道，关于 FreeBSD 项目、FreeBSD 开发模型，并追溯 FreeBSD 简史。

**第 3 章 BSD 文化与 BSD 发行版概论**：介绍乔治·贝克莱与 BSD 文化传统、BSD 许可证概览，以及 NetBSD、OpenBSD、DragonFly BSD 等其他 BSD 发行版概论。

**第 4 章 迁移指南**：面向 Windows、Linux 和 macOS 用户提供迁移指南，帮助不同操作系统的用户顺利过渡到 FreeBSD。

**第 5 章 FreeBSD 安装基础**：介绍安装前的准备工作、FreeBSD 15 安装指南（AMD64）、安装故障排除，以及在 Windows 中将 USB 启动盘恢复为普通存储设备的方法。

**第 6 章 虚拟化平台安装 FreeBSD**：介绍使用 VMware Workstation Pro、VirtualBox、Hyper-V 安装 FreeBSD 的方法，以及基于 Apple M1 和 Parallels Desktop、VMware Fusion Pro 的安装方案。

**第 7 章 命令行环境**：涵盖虚拟控制台和终端、shell 基础、切换 shell、命令行基础、文本编辑器及压缩和解压缩等基础操作。

**第 8 章 软件管理**：介绍 FreeBSD 包管理器概述、FreeBSD 软件源、使用 pkg 管理二进制包、使用 Ports 以源代码方式安装软件、Ports 构建调优、使用 DVD 安装软件及 FreeBSD 镜像站现状。

**第 9 章 网络管理**：介绍计算机网络基础、基础网络管理、无线网络管理、蓝牙、USB 网络共享及系统代理的配置方法。

**第 10 章 显卡驱动**：介绍显卡驱动概论，Intel、AMD 和 NVIDIA 显卡驱动的安装与配置。

**第 11 章 X Window 系统**：介绍 X Window 系统概论、显示管理器、系统字体及远程桌面。

**第 12 章 Wayland 系统**：介绍 Wayland 概论及 Wayland 显示管理器。

**第 13 章 桌面环境**：介绍在 FreeBSD 上运行的各类桌面环境与窗口管理器，包括 KDE 6（X11 与 Wayland 会话）、MATE、Xfce、Cinnamon、LXQt、GNOME、IceWM 及 CDE（拟删除）。

**第 14 章 多媒体和外部设备**：介绍声卡、打印机、摄像头、人机输入设备、音频播放器、视频播放器、多媒体处理、文档查看器及 Web 浏览器的使用方法。

**第 15 章 本地化与输入法**：介绍本地化环境变量配置、特定语言的区域配置，以及 Fcitx、IBus 输入法框架和五笔输入法的安装与设置。

**第 16 章 系统引导**：介绍启动引导器、启动消息（dmesg）、引导管理器与 UEFI 固件、进程与守护进程及管理 FreeBSD 中的服务。

**第 17 章 用户账户与权限**：介绍用户和基本账户管理、权限、用户分级及权限提升工具。

**第 18 章 系统管理**：讲解系统目录结构、bsdconfig 配置工具、OpenSSH、设备资源提示、Cron 和 Periodic、系统日志管理、sysctl 工具、NTP 时间同步与时区及 Live 镜像与系统恢复等系统管理功能。

**第 19 章 FreeBSD 系统更新**：介绍使用 freebsd-update、源代码方式更新 FreeBSD 的方法，以及使用 PkgBase 更新基本系统和通过 ZFS 启动环境实现多版本共存。

**第 20 章 Linux 兼容层**：介绍 FreeBSD 的 Linux 兼容层架构，涵盖 Rocky Linux、Ubuntu/Debian/Kali Linux、Arch Linux、Slackware、Gentoo 等多种 Linux 发行版的兼容环境搭建，以及微信、QQ、WPS Office 等 Linux 应用的运行方法和故障排除。

**第 21 章 FreeBSD 高级安装**：介绍安装双系统（先安装 FreeBSD 与后安装 FreeBSD），腾讯云轻量云、KVM/QEMU 等平台安装 FreeBSD（传统引导和 MBR 分区表），阿里云轻量应用服务器安装 FreeBSD（UEFI 和 GPT 分区表），以及 QEMU 安装 RISC-V FreeBSD（基于 x86 Windows 主机）。

**第 22 章 高级网络**：介绍 TCP/IP 协议栈、网桥、链路聚合与故障转移及 VLAN 的配置方法。

**第 23 章 存储管理**：介绍 USB 存储设备、虚拟内存盘、文件系统自动挂载、新增交换分区及加密交换分区。

**第 24 章 ZFS 文件系统**：涵盖 ZFS 的历史与现实、特性和术语、存储池管理、更新 ZFS 存储池、ZFS 管理、ZFS 调优、ZFS 委托管理、更新 OpenZFS 及启动环境。

**第 25 章 UFS 文件系统**：介绍 UFS 文件系统概述、添加 UFS 磁盘、UFS 磁盘扩展、UFS 磁盘快照、UFS 磁盘配额及 UFS 磁盘加密。

**第 26 章 其他文件系统**：介绍 Windows、Linux 与 macOS 文件系统的使用。

**第 27 章 安全**：介绍信息安全概论、账户认证安全、资源限制、安全等级及 OpenSSL。

**第 28 章 安全审计**：介绍安全事件审计、入侵检测系统（IDS）、第三方漏洞与安全公告，以及强制访问控制框架（MAC 框架）。

**第 29 章 防火墙**：介绍防火墙概论与 FreeBSD 内置防火墙系统，包括 ipfirewall（IPFW）、IPFilter（IPF）、Packet Filter（PF）的配置，以及 Fail2Ban（基于 IPFW、PF 与 IPF）和 blocklistd 工具的使用。

**第 30 章 Jail 容器管理**：介绍 FreeBSD 原生轻量级虚拟化技术 Jail 的基础配置、厚 Jail（Thick Jail）及 Qjail 管理工具的使用。

**第 31 章 Linux Jail**：介绍在 FreeBSD Jail 中运行 Linux 发行版的方法，涵盖 Linux Jail 基础，以及 Debian、Ubuntu、antiX Linux、Alpine Linux 等 Jail 创建及 Linux Jail 中的 GUI 配置。

**第 32 章 虚拟化与容器管理**：介绍使用 bhyve 及 vm-bhyve 工具安装 Windows 11、通过 BVCP 的 Web 界面管理 bhyve 虚拟机、Podman 容器管理及在 FreeBSD 上安装 VirtualBox。

**第 33 章 数据库管理**：介绍数据库概论，以及 PostgreSQL、pgAdmin 4、MySQL 及 MongoDB 在 FreeBSD 上的安装与配置。

**第 34 章 文件传输协议（FTP）**：介绍文件传输协议（FTP）概述，以及 Pure-FTPd（基于 MySQL）、ProFTPD（基于 MySQL）、vsftpd 等 FTP 服务器的配置。

**第 35 章 服务器**：介绍 Rsync 数据同步、Samba 文件共享、网络文件系统（NFS）、零配置网络（mDNS/DNS-SD）及 Webmin 管理平台等服务的搭建。

**第 36 章 Web 服务器**：介绍 Apache、Nginx、Caddy Web 服务器的部署，以及 PHP、Tomcat、WildFly 应用服务器的配置，同时涵盖 Nextcloud 云服务（基于 PostgreSQL）、OnlyOffice 部署（基于 PostgreSQL）、GitLab Enterprise Edition 部署和 OpenList 部署。

**第 37 章 监控系统**：介绍 Zabbix 监控系统（基于 PostgreSQL）、Prometheus 监控部署，以及 Telegraf、InfluxDB 与 Grafana 监控平台架构。

**第 38 章 游戏、科学计算和专业工具**：介绍 Godot 开源游戏引擎、我的世界（Minecraft）服务器与客户端、Steam 客户端、R 语言、Wine 配置，以及科研和专业计算工具的使用。

**第 39 章 人工智能**：介绍人工智能术语与概念、Transformer 数学基础与程序演示、人工智能哲学原著选读，以及大模型本地部署与 AI 编程工具（llama.cpp、Ollama、Claude Code、GitHub Copilot CLI）。

**第 40 章 开发环境**：介绍 C/C++、Java、Qt、Python、Rust、Go、Node.js 等语言开发环境的搭建。

**第 41 章 开发工具**：介绍 code-server 和 clangd 开发环境、Vim 开发环境、使用 IDA Pro 调试 FreeBSD 及 DTrace 动态追踪工具的使用。

**第 42 章 嵌入式平台及开发环境**：介绍树莓派上 FreeBSD 的安装与使用、Linux 兼容层配置，Radxa X4 x86 开发板，以及 STM32、ESP-IDF、Arduino 等嵌入式开发环境的搭建方法。

**第 43 章 FreeBSD 内核架构**：介绍 FreeBSD 源代码目录结构、内核文件结构、机器相关与机器无关的内核选项注解、GENERIC 内核选项注解（AMD64）、构建定制内核的方法，以及在 Linux 系统上交叉构建 FreeBSD。

**附录 I 工具与资源**：包括 Bug 报告流程、FreeBSD 邮件列表订阅、FreeBSD 开发参与指南、microSD 卡参数简介，以及 V2Ray、Mihomo 的配置方法。

**附录 II 参考文献与术语表**：列出全书核心参考文献和术语表。

**后记**：收录与 FreeBSD 相关的文学性内容，包括个人故事与感悟。

## 本书中的命令及符号含义

### 权限标识

`#` 表示在 `root` 权限下的操作，通常通过 `su`、`sudo` 或 `doas` 获得。

`$`、`%` 表示普通用户权限。本书中通常使用 `$` 作为普通用户提示符；在 FreeBSD 官方文档（例如 Handbook）中，也常使用 `%` 作为普通用户提示符。

### 提示块

#### 注意提示块

> **注意**
>
> 提示读者不应忽略的内容。

#### 技巧提示块

> **技巧**
>
> 提示一些有助于提高效率、转变思路的方法。

#### 警告提示块

> **警告**
>
> 如果不了解或不按要求执行，将无法完成操作或可能造成重大危害。

### 思考题

> **思考题**
>
> > 美国国家标准与技术研究院（NIST）发布的数字身份指南（NIST. NIST SP 800-63B-4: Digital Identity Guidelines: Authentication and Authenticator Management\[EB/OL]. (2025-07)\[2026-04-04]. <https://pages.nist.gov/800-63-4/sp800-63b.html>）指出：
> >
> > 必须要求，当密码被用作单因素认证机制时，其长度至少为 15 个字符。可以允许仅作为多因素认证过程一部分使用的密码较短，但必须要求其长度至少为 8 个字符。
> >
> > 应当允许最大密码长度至少为 64 个字符。
> >
> > 应当接受所有可打印的 ASCII（RFC 20）字符以及空格字符作为密码的一部分。
> >
> > 应当接受 Unicode【ISO/IEC 10646】字符作为密码的一部分。在评估密码长度时，每个 Unicode 码点必须被计为一个字符。
> >
> > 不得强制要求其他组成规则（例如，要求混合不同类型的字符）用于密码。
>
> > 不得要求订阅者定期更改密码。然而，如果有证据表明认证器已被泄露，必须强制更改密码。
> >
> > 不得允许订阅者存储提示信息（例如，关于密码如何创建的提醒），该提示信息不应能被未经认证的声明者访问。
> >
> > 不得在用户选择密码时提示其使用基于知识的认证（KBA）（例如“你的第一只宠物叫什么名字？”）或安全问题。
> >
> > 必须要求完整提供密码（而非部分提供），并且必须验证整个提交的密码（例如，不得截断密码）。
>
> > “尽管近年来不少专家一再批评现行密码规则的弊端，但银行、互联网平台和政府机构大多依然固守这些过时、无效甚至有害的规则。”（GoUpSec. “定期更换密码”是最愚蠢的密码规则？\[EB/OL]. (2024-09-27)\[2026-04-04]. <https://www.goupsec.com/news/17579.html>.）
>
> 问题：我们习以为常的“知识”究竟有没有坚实可靠的根基？我们固守的一些东西，究竟是一种传承，还是一种陈规陋习？如何划分二者的界限？

思考题旨在帮助有意愿探索和有动力追问的读者。这种形式类似于常见的课后习题，不同之处在于思考题的位置是随机的。需要说明的是，尽管可能预设了某些立场和理解，答案通常是开放的，具体取决于读者自身。此外，若读者感到疲惫，可以选择跳过。

### 特殊章节

```
故障排除与未竟事宜
```

旨在将现存的问题、改进方向或未解的谜团留置其中，以期借助后人的智慧。

```
课后习题
```

纯粹理论章节最后通常附有“课后习题”，用以帮助读者深入研讨章节内容。

### 删除线

~~为何人要活着？越是想探究生命的意义，越会陷入混乱。——《Caligula 卡里古拉》（和田纯一，导演. 卡里古拉\[V]. 日本：Caligula 制作委员会，2018.~~ [~~https://www.bilibili.com/bangumi/media/md77552~~](https://www.bilibili.com/bangumi/media/md77552)~~.）第三集标题。~~

~~KDE 6 在 Wayland 上右键单击会导致黑屏~~（注：2025 年 7 月此问题已通过 qt6-wayland 补丁修复）

删除线表示过时内容或带有诙谐意味的文字，它不属于正文部分；如无法理解相关典故，可直接跳过，不影响阅读。

## pkg 与 Ports

FreeBSD 提供两种软件安装方式：pkg（二进制包管理）和 Ports（源代码编译）。这两种方式各有优势，可以根据实际需求选择使用，也可以混合使用。

pkg 是 FreeBSD 的二进制包管理器，通过预编译的软件包提供快速、便捷的安装方式，适合大多数用户的日常使用。Ports 则提供了从源代码编译安装的方式，允许用户根据需要自定义配置选项，适合需要定制化或优化的场景。

> **请注意**
>
> Ports 通常对应 HEAD 分支，建议 pkg 与 Ports 保持在同一主线上，即均选择 `latest`。也可以自行使用 pkg 对应的 Ports 季度分支，如 `2025Q1`。

如果要安装软件 `yyy`，`yyy` 在 Ports 里是 `xxx/yyy`，那么路径即为 **/usr/ports/xxx/yyy**。

首先可通过 pkg 安装二进制软件包，与绝大多数 Linux 发行版的用法一致：

```sh
# pkg install yyy
```

也可以采用以下方式：

```sh
# pkg install xxx/yyy
```

或采用简写形式：

```sh
# pkg ins yyy
```

还可通过 Ports 编译安装：

```sh
# cd /usr/ports/xxx/yyy
# make install clean
```

系统将陆续弹出配置窗口供用户选择。若采用默认选项，可执行以下命令：

```sh
# cd /usr/ports/xxx/yyy
# make BATCH=yes install clean
```

如果需要一次性完成所有依赖配置：

```sh
# cd /usr/ports/xxx/yyy
# make config-recursive # 将递归询问直至所有依赖配置完毕
# make install clean
```


# 致读者：解放思想，回归本真，高扬人道主义，不走苦难哲学的邪路

对大部分读者而言，理解全文可能是困难的，甚至是不可能的。“与恶龙缠斗过久，自身亦成为恶龙；凝视深渊过久，深渊将回以凝视。”因此，阅读此文本身或许是一种“苦难哲学”的体验。若读者在阅读过程中感到障碍，尽可跳过相关段落乃至全文，直接寻找所需内容即可。

## 你并不孤单

两个经典问题是：

1. “Vi 究竟如何退出？”

![Nvi 主界面](/files/KbiD5rP8bDMYvbo21pO6)

一眼望去，Vi 界面没有任何操作提示或帮助信息。

作为与记事本同属文本编辑软件的 Vi，在保存与退出方面对初学者而言并不直观，其编辑操作也更为复杂。

> **思考题**
>
> 我们讨论的究竟是 Vi、Nvi、Vim，还是 Neovim？在发行版中，它们可能都被链接到 vi 命令。对于上述发行版，Vi 是真实存在的吗？当我们讨论“Vi”难用时，我们究竟在谈论什么？

> **思考题**
>
> 回溯历史，分析为何 Vi/Vim 必须先按 ESC 键，再输入英文冒号 : 和字母 q（强制退出需加英文叹号 !），最后按回车键才能实现不保存退出。应如何理解这种技术债务，其历史设计所带来的代价又应由谁来承担？

> **思考题**
>
> > 有人将 Vi/Vim 与其他编辑器比作 F1 赛车和家用小轿车的区别。也有人将 Vi/Vim 与其他编辑器比作“五笔输入法”与“拼音输入法”的区别。
>
> 请思考上述比喻是否存在根本差别？
>
> > 如果一件事物期望更多人来使用，为大众所接纳，而不是固步自封自诩“F1 赛车”或“高端学术论坛”等类似存在，那么它势必要在功能性与用户友好之间有所取舍，而这种“退化”又几乎是必然的，因为这会将其拉到大众平均水平，无论是认知还是其他。即使是一向只有业内人会使用的专业软件，也始终有更大众化用户体验更佳的版本对其进行挑战。
>
> > 哪怕是 F1 赛车也在速度与安全性（如 HALO 系统）之间存在张力，这何尝不是一种用户友好设计呢？有人称 F1 赛车是“手动挡”，其实这也是一大误区，F1 赛车自 1989 年起采用半自动序列式变速箱（拨片换挡），既非传统手动挡也非自动挡，而是由车手通过方向盘拨片控制的电液半自动变速系统。F1 历史上曾使用手动挡，自 1989 年法拉利首先引入半自动变速箱后逐步过渡，最后一辆手动挡 F1 赛车于 1995 年退出赛场。一个显而易见的事实是，无论是纯粹手动挡还是纯粹自动挡都会影响 F1 的公平性与观赏性。如果单纯考虑速度，那么自动驾驶技术无疑才是最佳路径。但这在事实上取消了比赛，或者将其转为了遥控车大赛。因此问题绝不在于 F1 为什么不是自动挡，这是一个伪问题和虚构想象。也可以看出，FIA 始终以观赏性优先，而不是一味地追求最佳的速度和成绩。因此 F1 和其他传统体育竞技存在一种张力，必须考虑用户友好性且视之为决定性因素，不仅体现在观众接受度，也在于竞技本身的风险远高于其他体育运动。如果不考虑用户友好为首要优先级，那么观众必然会拒绝这种形式的比赛，整个比赛就会自然地被市场取消掉。在这种意义上，奥地利红牛对极限运动的赞助同样也是为了获得这种在市场上的支配地位而牺牲了一定的安全性，或者根本就是不安全。在这种比赛中，参赛者的用户友好性被异化为观赏者的用户友好性。旁观者总是期待更极限的比赛。用户友好性不会被取消，只会被资本转移。由此可以得出一个有争议的判断：某些高度商业化的赛事并非以人的主体性发展为核心，而更侧重于资本化运作。如果仅从运动本身进行分析，就会落入包装好的陷阱。这种比赛是不人道的。一个简单的道理就是，观众爱看什么，就应该怎么发展，否则自身存在的合理性将彻底失去。一切以资本化和效率化为优先。
>
> > 要发展体育必须取消体育。体育的真实性和竞技性是存在张力的，如果你认为某些靠激素药物等人体“增强体育”是违背真实性的，那么它的确提高了竞技性，且这无关伦理取向，是职业体育盲目的、必然的追求。传统体育会强调竞技的教育功能，认为可以带动群众运动健身。现在实践证明，这种观点存在局限性，造就了这种过于强调排名和荣誉，而忽视体育本质的扭曲局面。你必然可以筛选出成绩异常优秀的运动员，但它对于人类的体育事业来说未必具有真正的意义，体育事业可能沦为政治的牺牲品。它只会使全国的体育资源高度集中到几个人身上。你必须承认这实际上就是一种表演赛，职业体育的公平公正只是虚伪的，只是相对于业余原则下的体育更加隐蔽罢了。每个人的自由时间、身体素质、拥有的场地环境、接受的体育教育都是不同的，并且差异巨大。体育运动职业化将永远只有少部分头部运动员享受高度集中的资源和资本。这对所有人包括他们自己以及观众都是不公平的。所谓“全国运动会”，它分明是职业运动员的运动会，职业运动员职业水平评定大会。这种情况下，将其称为“全国运动会”是否恰当，值得商榷。
> >
> > 体育精神不是一种形而上的东西，它本质上是使人发展的物质力量。而现在的专业化、职业化、国家化的运动员才是真实违背了体育精神的存在。使体育转向以场外为核心才是真正的全民体育，才是发扬奥运精神。现在的问题是场外人成为了观众而非参与者，也没有自由时间成为参与者，观看比赛不过是不拿工资的被异化的非参赛运动员罢了，甚至观众被讥讽“旁观者的姓名永远爬不到比赛的计分板上”。他们意识不到，如果没有观众，他们的比赛本身就是不成立的。他们没有意识到，如果没有观众，连计分板也不会存在，比赛本身也会被取消。他们更没有意识到，无论观众在形式上在不在场，观众本身即是比赛不可或缺的一部分，比赛可以没有运动员，可以没有裁判，但是观众是必然的。持有这种认为观众是旁观者而非参与者的观点，是不可理解的。
> >
> > 如果你真的认为用户友好是次要的，你所谓的专业性 = 复杂性 = 困难性 = 学习曲线陡峭，那么理应支持“增强运动会”。因为无论怎么看，“更快、更高、更强——更团结”带来的无疑是这种“增强运动会”。在 1988 年之前奥运会在反对职业运动员（纯业余原则）的时候，顾拜旦究竟在反对什么呢？应该取消职业运动员。这违背了真正的奥林匹克精神，本来就是为了让普通人拥有健康的身心，通过体育促进世界团结“更团结”，现在变成了一小撮人的狂欢，反过来异化大众，侮辱大众。说探索人类极限也是伪命题，那是生物学的事情。而且本身大部分比赛都禁止人类增强技术。它和体育的精神完全相悖。体育本身是鼓励所有人运动、参与，而不是围观别人。而且现实是通过围观别人促使自己也有想法的例子微乎其微。让一些人花很长时间投入到体育项目本身，取得更好的成绩，而不是去发展这个项目本身，就是一种异化。甚至连规则都不研究，等自己吃亏又奋起，而且发展了这么久话语权寥寥。除了沦为表演赛和政治工具，究竟还有什么用处？
> >
> > 这和电子竞技一样值得商榷。一排五个人的网吧还收费，去现场看投影仪？一群人看他们怎么露天打游戏？真赛假赛尚不可知。它每次找公证处公证都是真打吗？所有人都想当第一，这是可能的吗？而只要不是第一，就绝对等于失去一切。不明白体育竞技的意义是什么。而且看人打和看一个同等水平 AI 打的本质区别是什么？从最早的足球、乒乓外交、女子排球，甚至也推行过全民棒球。在一些体育商业属性有待发掘的国家，历史上体育运动的发展几乎完全不取决于体育事业本身的发展，其发展方向和资源分配过去完全取决于政治目标，商业和群众体育的价值遭到边缘化，最终导致了体育异化和资源浪费。而我们注意到，体育商业化不仅无法扭转这种异化，反而会加重。因此，取消体育是必然的、合理的，是符合历史与现实的。
>
> 你怎么看待这种现象？以及为什么说“退化”是必然的？当我们使用比喻时，是否真正了解进行比喻的对象（有人误以为 F1 赛车是手动挡，只考虑速度不考虑用户友好）？业余原则究竟是虚伪的，还是现实的？有这种本质区别吗？
>
> > 用户友好还体现在“防呆”或者“失效安全”上，无论是机械工厂、核电站、加工厂、建筑工地、军事设施、盾构机施工现场、高铁机车、地下金库/冷库，你都会发现这种用户友好并不是一种抽象的概念，也并非是一味地取悦用户：
> >
> > * 机械工厂大部分需要切割的机器都需要两只手分别按在两个按钮上才能启动，并且会检测是否是真手，而非其他重物。
> > * 核电站的大部分操作都需要不同的人员进行确认核验。
> > * 加工厂有的地方必须戴手套，而有的地方则严格禁止戴手套。
> > * 军事设施也有类似机械工程的设计。
> > * 盾构机在施工现场施工完成后一般就会就地掩埋，并且其存在本身就是一种用户友好。
> > * 高铁机车要求驾驶员在特定时间内必须踩下踏板，必须口呼手指。
> > * 地下金库/冷库都会检测入侵，防止人员被意外关在门内，内部还有电话、棉毯、消防斧等物品。
>
> 你能否自行举出更多例证？归纳推理不具有普遍必然性。我们有必要通过演绎论证进一步探讨用户友好在各领域的合理性，此任务留给读者自行完成。

> **思考题**
>
> 请读者现在就找出本书中至少一处论证逻辑无法自洽的地方，并在 GitHub 上发起 PR 来完成修改。

2. “我的密码为什么一直输入不了？”

![sudo 和 su](/files/uKdykYFMP3YG6UGXe2BR)

因为屏幕上的密码输入区域始终是空白的，连 \*\*\*\* 这样的掩码都不会显示，即无任何视觉反馈，其设计便是如此。

提示语“密码不可见”在语义表达上不够明确。

实际上，早在 2009 年，常用的权限提升工具 sudo 就已提供 pwfeedback 选项（随 sudo 1.7.1 引入），但默认启用该选项的发行版寥寥无几，且其相关代码曾被报告存在多个 CVE 漏洞。

> **思考题**
>
> 大多数发行版倾向于不使用 pwfeedback 的一种原因是其相关代码可能会引入更多的安全漏洞。这是 sudo 让我们陷入了平衡安全与便捷的讨论泥潭，还是 sudo 本身设计有问题？了解那些替代实现（[sudo-rs](https://github.com/trifectatechfoundation/sudo-rs)、[doas](https://man.openbsd.org/doas)），你能否在保证安全的前提下，为这些工具实现 pwfeedback？如果在现有的安全模型下永远也无法实现，你认为我们还能做些什么？

许多人经常打错或混淆命令、参数及选项，但这并非读者的错。

在当今时代，一些中国科学院院士仍需要学习如何使用计算机和手机，并可能感到操作不够便利。你或许认为这是设计问题，但如何解释同一年龄群体（老年人）却能熟练操作短视频应用呢？这是否在一定程度上说明，短视频类软件在用户体验设计上更为友好？

许多命令或受历史条件限制，或受开发者和维护者能力所限，其设计并不统一，也不便于记忆或使用。从历史角度看，上述命令的设计或许是当时的“最优解”。我们常见的家用门锁，在输入的密码中，只需要包含正确的密码片段，即可开门。而今日操作系统的某些提示依然违背最小惊讶原则（不应让用户承担糟糕设计带来的后果）。

> **思考题**
>
> 这种评价是公允的，还是“事后诸葛亮”？你怎么看？

查询手册页即可发现专门有一个条目是“BUGS”，用来表述当前软件的缺陷。

就笔者个人体验而言，若一款开源软件几乎没有严重影响使用的 Bug，往往并不符合人们对典型大型开源项目的常见印象。因为 Bug 数量过多，或现实情况令人迷茫，且他们缺乏修缮的经济动力，大多数维护者对此无能为力。绝大多数拥有百万乃至千万用户量的开源软件，其维护者大多从未从中获得任何经济报酬或显著声誉。

> **思考题**
>
> 我们常面临的现实是，维护者一意孤行，拒绝或反对你的拉取请求（PR）。说服他们几乎不可能，而独立分支又不可行。在这种情况下，问题似乎是无解的。

> **思考题**
>
> 那些大公司是否应出于道德义务为开源软件提供经济支持，而非仅通过代码贡献来逐渐掌控其发展方向？

请相信笔者，并非仅有你觉得这些东西难用，甚至想砸键盘。这也是人们不断“造轮子”（从头实现一款工具）的原因之一。如果你觉得 GCC 难用，那么可以改用 Clang/LLVM。你绝非第一个感到 GCC 难用的人，也不会是最后一个。

很多人强调命令行的重要性，并以傲慢的态度鄙视使用 IDE 等图形用户界面软件的用户，这实无必要。许多人会故意唱反调，强调这些工具的所谓优势。这种观点有时表现出对高使用成本的过度合理化倾向，可视为一种“苦难哲学”的体现。Unix 的哲学精髓不在于恪守亘古不变的既有规范，而是强调以人为本。正因如此，在 21 世纪业已走过四分之一的今天，我们仍需强调 Unix 哲学的意义。许多人受苦难哲学的影响，一味强调追根溯源，而忽视了技术应服务于人这一根本宗旨。“人是会思想的蒹葭”，我们不是只能被动接受而不去改变的主体，我们有责任有义务去改造这个世界，改善不尽合理的设计，而不是让人强忍不适接受一套不够完善的设计原则。面对存在不足的设计，我们有必要客观地指出：“这个软件在设计上确实存在问题，这不是你的错。”我们可以不断尝试改变这一切，通过提交补丁和反馈来表达我们的态度。

一种十分经典的观点认为：“必须完全掌握某些命令行工具或传统的编译环境，才能彻底理解 UNIX 操作系统。”其中的工具之一就是 Vim。在今天讨论图形界面与命令行的优劣，实际上会让我们错失重点，最终得出的平凡且看似理性的结论，无非是二者在不同环境下各有其用。笔者真正质疑的是一种优绩主义（其核心观点是类似能者上、庸者下的社会达尔文主义），凡是命令行就一定是难用的，凡是选项就必须背诵，凡是要精通就必须走这条路，凡是偏好图形化界面和桌面的用户就要贬低他们。无论是基督教主张的超越性的爱世人、爱神，儒家的有差等之爱，还是墨家的无差别兼爱，都启示我们：长久以来，这样做并无益处。计算机应服务于人类，而非规训人类。归根结底，不应让大部分人被极小群体的黑客文化所异化。过去大多数人难以接触计算机，无法获得良好教育，这本质上形成了一种话语权集中，亦是文化不自信、“缺钙”的表现。凡是圈子越小的地方，这种话语权垄断现象就往往越是严重，越是脱离大众文化，背离大众单纯朴素的认知。而我们要做的就是正视一切神话，没有任何天然的、神圣的不可侵犯之存在。这看似是观点冲突，实则是不同文明间的碰撞。这本质上或许是工业文明对效率优先、压制一切人性的渴求。理解这种观点的要义在于，它将所有人的人生目标都一律统一定义为“我要成为第一名”，一律否定“我只是普通用户，为了好玩，我不想学什么编译原理”这种大部分人的实际预设，它决不会允许你不会任何命令行就能在操作系统上实现你的一切合理需求。凡不会使用者，皆被视为末位淘汰，遭到筛选和过滤。我们使用技术、发展科学，是为了解放人类，而非让科技代替宗教或儒学，重新奴役人类。更非为了让走出大山的人，去嘲笑仍留在山里的人。

> **思考题**
>
> > “撰写简洁的程序—不要耍小聪明”。
> >
> > ——Kernighan B W, Plauger P J. 编程格调\[M]. 北京：人民邮电出版社，2015：2. ISBN: 978-7-115-37952-8.
>
> 这称得上一种用户友好设计吗？人工智能编程有无必要遵守此种风格？请读者思考。

只要人们用得快乐、开心，又有何不可？人们总强调，这些是知识，应当背下来。真正的问题在于：何为知识？知识与学位是挂钩的吗？那如何解释大多数本科毕业生分不清显示器和主机？

美国哲学家 B.F. Skinner 曾言：“教育就是当一个人把在学校所学全部忘光之后剩下的东西。”不同于强调记忆的传统西方观念（如柏拉图的回忆说、奥古斯丁的光照与上帝记忆、洛克的白板说）、儒家学说（如“学而时习之”）乃至民俗（如孟婆汤致失忆），庄子更强调“忘”——这也是对老子“行不言之教”（《道德经》第二章）的发挥。庄子在《逍遥游》中强调“小知不及大知”，我们日常所学大抵皆是“小知”。庄子认为，无论古今，学习在根本上都是外物对人的异化；人所接受的是现代社会的规训，是工业革命的文化，而非真知。

> **思考题**
>
> 本书已尽量列出日常所需的命令和选项。
>
> 一条命令的选项或参数可能有数十上百个，而字典或文档（无论是 man 还是 info）是供查阅而非背诵的。
>
> 你如何看待“吾生也有涯，而知也无涯。以有涯随无涯，殆已”（《庄子·内篇·养生主第三》）？

人们曾认为工业化和互联网会加速世界形成“地球村”。从 2G 通话到 3G、4G 视频通话，“在一起”的渠道已然畅通。但你会真切发现，找到一个能说上话的“人”，依然不容易。我们会明白，真正决定距离的不是时间，不是空间，也不是科技水平，更不是我们有没有时间，而是我们自己。读到这些文字时，或许 FreeBSD、乃至操作系统这个概念，包括计算机本身，都已消亡。但你会发现，这里有一种声音在告诉你：你是对的。你并不孤单！

一切苦难都不值得提倡，那只是一种类似宗教救赎的神话叙事结构。苦难并不会使人变得优秀，只会让人隐藏真实的主体性。在这种结构中，苦难被别有用心者包装成为通达幸福的必由之路。即便在宗教内部，如佛教面对苦难也分裂为两派对立的观点。苦难即是莱布尼茨所论世界中的“恶”，也是一个恒久的神学命题。我们可以看到，苦难无处不在。这些“恶”与我们的幸福之间存在强大的张力。历经苦难者，其主体性已被苦难所异化。提倡这种恶，表面上的唯一可取之处在于一种超越的可能性。然而，这种超越性反而否定了苦难本身的合法性。这种超越性不以苦难为目的，仅将其当作通往彼岸或来世的方法。综上，凡是强调苦难意义、推崇苦难本身者，皆有其潜在的龌龊目的。它强调人们去适应甚至病态地享受一切苦难，而非高扬人的主体性去改造世界，亦不相信这种主体性的真正力量，这实际上背叛了人民。恶无处不在，问题不在于与恶和解，而在于认清其存在的根源。不要因为自己曾与恶龙缠斗太久，便将这种战斗视为必然。不愿正视苦难之无意义，其本身就是一种形式主义。恶仅充当了叙事合法性的形式，却无视了神话最终指向的至善与幸福。这最多只能充当精神鸦片，维持人片刻的稳定。这反而更说明恶存在的现实基础，但这绝不意味着恶值得推崇和提倡。这种“苦难哲学”的目的不在于发展人，而在于筛选人，并赋予被筛选者一种神圣感与道德优越感。使之看似拥有了批判那些拒绝被苦难化之人的合法叙事武器。需要反思的是，苦难哲学的本真性意义究竟是什么？是理解一种虚构世界的秩序与规则不可更改，还是认识到存在一个满目疮痍的真实世界，将人消解为其中破败的一分子？一个简单的事实是，人是“会思想的蒹葭”，是能够制作、使用并发展工具以改造世界的。对于任何质疑这一事实的苦难观点，我们都有必要考量其背后不可告人的真实目的。真正能发展人、解放人的从来不是苦难，而是人自身的主体性——它让人认识到自己是谁、想做什么、如何获得幸福与快乐。真正值得推崇的社会是具有包容性的社会，能让人老有所养、老有所为、老有所依，而非让人适应孤独与死亡。在这种苦难哲学下，人失去了一切反抗的行动力与实践的可能性。必须警惕这种“苦难哲学”的道德宣言与方法论。这是一条反对革命与改革、用于消解潜在革命火种与改革动力的邪路，是既得利益者对权力再分配的实质拒绝，亦是背离人民群众、背离解放的邪路。一个简单的表述可能是“苦难能不能发展人我不知道，但是苦难绝对能让人不再是个人”。值得宣扬的从来不是苦难本身，而是在面对一个充满“恶”的世界时，仍保有试图让其更美好、包容更多人的主体性，并思考如何避免他人陷入同样的苦难，推动社会与政策的革新。人类总是乐观的，反对虚无和宿命，这不在于人类认识不到恶的存在，而在于认识到之后，在面对恶时，人类文明不会屈服，不相信自己无能为力。无论中国神话中的精卫填海、愚公移山、大禹治水，还是《圣经》中的诺亚方舟、巴别塔建造，都说明先民面对恶劣世界时，并非一味祈求神祇、图腾、圣物或祖先帮助，也非宣扬“苦难哲学”的必要性。先民认识到，真正的尘世并无净土，“上帝之城”仅存于书卷，一切都要靠自己的双手创造。人类绝不应将自身成就归因于苦难，而应正视自身的伟力。认识到苦难的普遍性与不可避免性，与反对苦难本身并无矛盾。这绝不意味着苦难是不可或缺的。最荒谬的现实是，让所有人承受本不必要的、人为施加的苦难，最后却发现自己仅是普通人。因为“人人如龙”是不切实际的幻想，苦难无法使之改变，这是“苦难哲学”的真正破产；而“苦难哲学”却又宣称，你受的苦不及他人，故无资格发言。那么谁有资格？靠优绩主义吗？因为他在逻辑上根本不存在，你找不出这样一个人。这一点在察举制时期便已被古人察觉，如“二十四孝”中的卧冰求鲤（一说剖冰）。可见，这是一种彻头彻尾的谎言与骗局，其核心主旨在于遮蔽人的思想，规训人的身体，消解人的主体性。

如果你读完本书后全部忘光，只知用人工智能查询命令用法，或干脆“从入门到跑路”，祝贺你！你已掌握了本书最精髓的部分。

对于一本自诩应归类于“TP316.81”的书籍，书中大量可复制粘贴的内容，可能在撰写时便已过时。但笔者相信，无论读者反对抑或支持，其实都不重要。我们必须承认，我们对世界唯一确知的事情，便是我们一无所知。

对于那些希冀从本书中获得具体计算机原理、实现或类似词典的工具书的读者，可能会感到失望或认为本书毫无价值。因为笔者亦不擅长，更毫无兴致，这都在预料之中。在漫漫时间长河与人类文明中，即便你是科举状元，也难留下痕迹。哪怕你是统一大陆的征服者，也将深埋地下，甚至被后人怀疑你与你的帝国是否真实存在。古埃及人认为死亡并非终结，而是通往来世（Duat）的门户，亡者将与冥界之主奥西里斯（Osiris）合而为一，追随太阳神拉（Ra）夜行冥界的轨迹，期冀如朝阳般重获新生。你看地球是多么巨大的球体，再看银河系全景，看目前科技所能拍摄的可见宇宙，你会发现，一切都如北岛《一切》诗言：

> 一切都是命运
>
> 一切都是烟云
>
> 一切都是没有结局的开始
>
> 一切都是稍纵即逝的追寻
>
> 一切欢乐都没有微笑
>
> 一切苦难都没有泪痕
>
> 一切语言都是重复
>
> 一切交往都是初逢
>
> 一切爱情都在心里
>
> 一切往事都在梦中
>
> 一切希望都带着注释
>
> 一切信仰都带着呻吟
>
> 一切爆发都有片刻的宁静
>
> 一切死亡都有冗长的回声

## 简要评价《提问的智慧》《如何提问》《XX 提问》之类的文档

在一款开源红白机游戏模拟器的项目中，存在以下场景：

> I am using ubuntu 14.04 and even though I install the `liballegro5.0`, It seems no header files are downloaded with it (I search it and look up in usr/include). So do I have to download source and make it as tutorial said? Thanks.（我正在使用 Ubuntu 14.04，即使我安装了 `liballegro5.0`，似乎也没有随之下载任何头文件（我搜索过，而且也在 usr/include 里找过）。那么我是否必须下载源代码并像教程中说的那样自行编译？谢谢。）
>
> Try install liballegro5-dev as pointed in the tutorial, and the problem should be fixed.（尝试按照教程中的说明安装 liballegro5-dev，应该就能解决问题。）
>
> Oh, thank you very much. May I ask what's the differences between those two packages(xxx and xxx-dev)? I am new to it. Thanks again.（哦，非常感谢。可以请问一下这两个包（xxx 和 xxx-dev）之间有什么区别吗？我是新手。再次感谢。）
>
> Find the answers on Google or StackOverflow. If you are participating in open source software development, this kind of configuration problems should not be proposed as an “issue” unless you have strong evidence of faults existed in the code base or documentation.（在谷歌或 StackOverflow 上可以找到答案。如果你在参与开源软件开发，除非你有充分证据表明代码库或文档中确实存在缺陷，否则这类配置问题不应被作为“issue”提出。）

注意到 xxx and xxx-dev 的意义本就不明确：

* 开发版的二进制包
* 用于共存的新版本二进制包
* 包含头文件的二进制包
* 启用了开发功能的二进制包
* 纯源代码包，带或不带头文件

可以看到，关于 xxx and xxx-dev 的命名是缺乏规范的，还有许多项目，其正式版也是 dev。认为世界是有秩序的，是预定好的，是有规律的，本身无可厚非，但是忽略了一点：在由人类构建的世界中，一切都需要人类自行维护、构建秩序，而不是指望有神预定好了一切法则，一劳永逸。

重要的是分享，众人共同参与，而非以教育者自居。实际上就是草台班子论，祛魅之后，并不承认存在所谓不可替代的权威。

一方面指出有这样一个大佬，是不可替代的；另一方面，工业化要求的是标准化和统一化。这二者是冲突的，那么肯定有一个是假象。那么唯一的答案是替代成本，而后者又要求不断地通过标准化降低这种成本。

综上，这是一种幻觉。真正的问题不在于解决问题，而在于回答他究竟想干什么。如果他的目的根本不是编译，你为什么不能直接发个 deb 包呢？能用 Windows 完成的，为什么非要在 Linux、BSD 下坚持苦难哲学的思路？

大音希声，真正的解决问题的方式在于消解问题本身。简言之，若不付费，别人没什么义务，所以对面怎么回答也属合理。只是粗暴的回答者，他要知道自己也并非上帝，也会有这一天。确实看到很多人，明确告诉他在哪，他还装作看不见的，这种属于故意刁难。

《提问的智慧》不仅不能从根本解决问题，也不能从表面解决问题。花钱解决问题并不显得愚蠢，他应该开个付费区。他说的确实很有道理，不是吗？然而问题不在于有没有道理，问题在于：对于一个团队的成员，这种责任是预设好的，即使许可证已经在形式上 100% 免除担保，这种结构仍然是这样的。市场化难道是什么可耻的事情吗？无论计划还是市场，都无法完美地分配，不是吗？

有现成的，谁愿意挨个看文档？连问 AI 都觉得麻烦，为什么不承认这是人类的天性？所以像 FreeBSD Jail 这类技术的普及度有限，类似的还有 bhyve，其易用性仍有待提升。

再看以下场景：

> “但中文翻译有的词汇使用并不标准，例如将 library 翻译为图书馆。因此后续讲义中介绍 Logisim 时主要还是给出英文词汇，并在括号中给出中文版的翻译。”

所以为什么不去反馈、不去修正？是没有权限，还是提交了对方亦不会接受？无论如何，在此处建议读者弃用中文而改用英语，这种思路本身便值得商榷。简单注明反馈渠道，岂非更为妥当？当前之人难道尚不及原始先民？原始先民尚知从打制石器演进至磨制石器，主动适应蹩脚的工具，实则可能限制了改进的动力。Apple 开发工具 Xcode 长期未提供完整的中文界面支持（核心界面锁定为英文），部分用户因此使用了非官方渠道的版本，导致安全事件的发生。其逻辑是：缺乏中文支持时用户只能使用英文正版。然而，无论在多么恶劣的环境下，生命都会自行找到出路。在没有开放 Discussion 的 GitHub 项目中，任何问题都只能作为 Issue 提出；在 Issue 也关闭的项目中，并且未提供其他更方便的渠道的情况下，该项目将永远不存在任何问题。

窃以为第一课应该是教人如何改造工具，从具体的小事开始做，比如复制粘贴。其忽略了一个问题：如果新手反复提及一个问题，那么这肯定不是新人自己的问题。路不平，要修路，而不是怪人不行。

如今的思路还是先把原型构建出来再迭代，不考虑、也不认为一开始的考虑和设计是有必要的。这种思路认为本质是在时间中构建的，从而否定了一种不变的主体性；随着不断迭代，系统本身就会自然而然地涌现出意识。这实则也是 BSD 和 Linux 的根本分歧，传统 Unix 哲学，暂且这么说。“原型先行”实际上形成了一种否定之否定的局面，而这实际上是忒修斯之船式的否定，我们常听人说：先把代码拿出来，先把轮子造出来。简而言之，这是技术话语权的分配问题，也不只是计算机行业这样。认为只要存在一个项目，社区就会自发地组织起来，并且是严密地组织起来；系统外围那些看起来和代码无关的内容也会自组织，并且认为它们始终毫无意义。实际上，这种思想在 Sun 被 Oracle 收购的时候就该没有市场了。

以往的体育哲学中，认为观众是无关紧要的，计分板上永远也不会出现观众的名字。事实上，他们忽视了一个真理：没有观众，比赛本身根本不可能成立。他们获得的荣誉完全无法和观众剥离开，甚至荣耀应该完全属于观众。因为在根本上，这些代码没有几年就完全没用了，甚至过几天就不行了。真正使项目得以成立的，不是代码，而是这些外围的形式主义的东西。

真正的开源和社区很简单，共同参与，以快乐为导向，只不过是把玩的对象从其他东西转移到了计算机。

## Talk 和 Code

> Date Fri, 25 Aug 2000 11:09:12 -0700 (PDT)
>
> From Linus Torvalds < >
>
> Subject Re: SCO: “thread creation is about a thousand times faster than on native”
>
> On Fri, 25 Aug 2000, Jamie Lokier wrote:
>
> > Well well. I think it's possible to over the best of user-space “fake” threads plus the advantages of “true” kernel threads in one blindingly fast combination, in less than 8kB per thread.
>
> Talk is cheap. Show me the code.
>
> Linus
>
> ——Torvalds L. Re: SCO: “thread creation is about a thousand times faster than on native”\[EB/OL]. (2000-08-25)\[2026-04-04]. <https://lkml.org/lkml/2000/8/25/132>.

> **思考题**
>
> 请读者自行查阅 Jamie Lokier 对 Linux 内核线程性能的影响。 A：换行符是不是骗局，回车在 Windows 是 \r\n，换行在 Unix 是 \n，Word 的换行符是不是 Word 自己定义的？其他文本编辑器不识别。
>
> B：Word 我用 GPT 生成的都是换行符，不是回车符，整得我每个都要删除再按回车。
>
> A：你往哪复制的？或者纯文本粘贴，Word 粘贴的时候可以选不带格式啊。
>
> B：生成的文件，我往哪里复制？
>
> A：就算是软回车也不用挨个删除啊，你可以查找替换成普通回车啊。输入查找内容：在“查找内容”框中输入 `^l`，这代表软回车符号（手动换行符）。输入替换内容：在“替换为”框中输入 `^p`，这代表硬回车符号（段落标记）。查找替换就行了啊。
>
> B：我怎么知道这个符号的标识？
>
> A：ChatGPT 会告诉您，您首先要提出一个想法，至于怎么实现那一点也不重要。Code is cheap. Show me the talk. 人工智能可以快速地将任何想法付诸实践，即使现在难以实现，日后也可以轻易完成。

> “提出一个问题往往比解决一个问题更重要。”
>
> ——爱因斯坦 A，英费尔德 L. 物理学的进化\[M]. 北京：中信出版集团，2019：92. ISBN 978-7-5217-0141-8. 该书从相对论视角阐述科学哲学，强调问题意识的重要性。英文原版（Simon and Schuster, 1966）此句位于第 92 页。

> “哲学家们只是用不同的方式解释世界，问题在于改变世界。”
>
> ——《关于费尔巴哈的提纲》第十一条，马克思 1845 年稿本（马克思，恩格斯. 马克思恩格斯选集：第 1 卷\[M]. 北京：人民出版社，1995：57.）

> 夫国者人之积也，人者心之器也，而国事者一人群心理之现象也。是故政治之隆污，系乎人心之振靡。吾心信其可行，则移山填海之难，终有成功之日；吾心信其不可行，则反掌折枝之易，亦无收效之期也。心之为用大矣哉！夫心也者，万事之本源也。满清之颠覆者，此心成之也；民国之建设者，此心败之也。夫革命党之心理，于成功之始，则被“知之非艰，行之惟艰”之说所奴，而视吾策为空言，遂放弃建设之责任。如是则以后之建设责任，非革命党所得而专也。迨夫民国成立之后，则建设之责任当为国民所共负矣，然七年以来，犹未睹建设事业之进行，而国事则日形纠纷，人民则日增痛苦。午夜思维，不胜痛心疾首！夫民国之建设事业，实不容一刻视为缓图者也。
>
> 国民！国民！究成何心？不能乎？不行乎？不知乎？吾知其非不能也，不行也；亦非不行也，不知也。倘能知之，则建设事业亦不过如反掌折枝耳。
>
> ……予之所以不惮其烦，连篇累牍以求发明“行易知难”之理者，盖以此为救中国必由之道也。夫中国近代之积弱不振、奄奄待毙者，实为“知之非艰，行之惟艰”一说误之也。此说深中于学者之心理，由学者而传于群众，则以难为易，以易为难。遂使暮气畏难之中国，畏其所不当畏，而不畏其所当畏。由是易者则避而远之，而难者又趋而近之。始则欲求知而后行，及其知之不可得也，则惟有望洋兴叹，而放去一切而已。间有不屈不挠之士，费尽生平之力以求得一知者，而又以行之为尤难，则虽知之而仍不敢行之。如是不知固不欲行，而知之又不敢行，则天下事无可为者矣。此中国积弱衰败之原因也。夫畏难本无害也，正以有畏难之心，乃适足导人于节劳省事，以取效呈功。此为经济之原理，亦人生之利便也。惟有难易倒置，使欲趋避者无所适从，斯为害矣。
>
> ——孙中山. 建国方略\[M]. 北京：生活·读书·新知三联书店，2014：建国方略之一孙文学说——行易知难（心理建设）自序、第五章知行总论. ISBN 978-7-108-04074-9. 该书系统阐述“知难行易”学说，为中国现代化提供了理论依据。

> 人们争论马克思理论的可信性，但对其影响毫无争议。历史上没有任何哲学家能宣称有如此大比例的、国际性的、有组织的积极追随者。然而，这个哲学家的光环和他的生活之间的差别是一个惊人的讽刺。卡尔·马克思的名字实际上成了革命的符号。然而，马克思很少把时间花在直接的街头政治运动上。相反，构成他生活的是在大英博物馆图书室里无休无止的研究和写作，他每天在那里的同一张书桌前从早上 9 点工作到晚上 7 点闭馆。他在家里继续这一天的工作达几个小时之久，直到精疲力竭，需要睡觉来结束这一天为止。讽刺的是，虽然他的思想塑造了 20 世纪的很大一部分，马克思却过着一种相对隐秘和孤独的生活。如果不是因为他的家庭和一小群密友与政治朋友陪伴，隐居在书籍和手稿世界中的他很难与中世纪僧侣区分开来。更讽刺的是，尽管他经常轻视文字和观念的力量（他称之为“哲学家头脑中的幻影”），他却表明了它们可以是多么可怕的武器。作为他理论的成果，政府被推翻，地图被改写，他的名字成了 20 世纪家喻户晓的词。
>
> ——劳黑德 W F. 哲学的历程\[M]. 第 4 版. 北京：中国轻工业出版社，2017：448. ISBN 978-7-5184-1260-0. 该书是西方哲学史入门教材，全面梳理了哲学思想发展脉络。

> **思考题**
>
> 结合上述内容，以“知之非艰，行之惟艰”为核心探讨下面这段话。
>
> > “但中文翻译有的词汇使用并不标准，例如将 library 翻译为图书馆。因此后续讲义中介绍 Logisim 时主要还是给出英文词汇，并在括号中给出中文版的翻译。”

> **思考题**
>
> 请读者现在就找出本书中存在的至少三处失效的 URL 链接、错别字或事实错误，并在 GitHub 上发起 PR 来完成修改。

## 二十一世纪四分之一处的 Unix 哲学观

事实证明，技术很快就会过时。正因如此，很多人在今天认为谈论 Unix、谈论 Unix 哲学毫无意义。然而，将 Unix 哲学简单地归结为纯粹而具体的技术性操作，这是对 Unix 哲学最大的误读，也是促使不少人走上苦难哲学这条改旗易帜的歪路的诱因。

真正的 Unix 哲学绝不是上面那些因循守旧的既有规范，Unix 哲学的精髓在于以人为本，真正的 Unix 哲学是一种人道主义。在不同的年代，Unix 哲学应有不同的诠释，但是归根结底是一种人道主义——我们要高扬人的主体性。正是为了好玩，为了玩太空旅行才诞生了 Unix，为了“Just For Fun”才有了 Linux：这无不说明，是改造计算机以适应人，而非被动适应所谓计算机的规则，去迎合吹捧那些本就不够完善的设计思路。

大道至简在西方哲学中表现为奥卡姆的剃刀，即“如无必要，勿增实体”。这在某种程度上也启发了现象学的观念，我们应该将一些自行设定的观念从我们的头脑中排除出去，只留下我们能够直接感受到的东西——回到事物本身。

我们现在回到操作系统本身，回到计算机本身，计算机不应成为一种额外的负担，而应为人服务——正如 FreeBSD 的口号“The Power To Serve（服务的力量）”那样。

所以，现代的 Unix 哲学具体而言，不应该是“避免仅用户界面”，而应该是“避免仅命令行”。每款程序都应该报告自己的操作进度，最好还有进度条（无论是否真的体现了进度），可以使用参数静默上述行为，但默认行为不应该是所谓的沉默是金——你有多少次在使用 dd 等命令的时候渴望看到一个进度条而不是什么都没有，即使无响应也无从得知？ChatGPT 这种程序无疑是对“小即美”“一个程序只做一件事”最大的反叛。人们需要什么，就应该有什么。

## 从入门到跑路

现有如下场景描述：

* “按任意键继续。”

我们会得到：

> “‘任意键’到底是哪个键？键盘上似乎没有‘任意键’这个按键，搜索也搜不到。”

* “请将文件夹名改为英文。”

我们又会得到：

```sh
$ ls
英语
English
```

* “请打开我的电脑。”

我们会得到：

“这是我的电脑，不是你的电脑。”

* “请关闭计算机。”

我们会得到：

“显示器已断电，但主机仍在运行，散热风扇依旧在转。”

有观点认为语言是文字的家，折射人的主体性；也有观点认为自然语言存在边界，我们只能理解所能理解之事，对语言不及之处应保持沉默；还有人试图创建全新的人工语言，以数学、逻辑学替代问题重重的自然语言。有观点认为不同语言体现不同的世界观与文化差异；还有观点认为语言是一种结构，将人类文明局限其中。另有观点认为圣人“行不言之教”，真正美妙的语言便是沉默（全部沉默，即一无所知）。

以上对语言的种种探索启示我们，不能简单将上述情境中的当事人视为负面存在而放弃教育的可能性。而应反思自身的教学方式。孔子面对不同学生，强调因材施教。我们确实可用更完善、无歧义的方式说明，问题在于我们往往预设了读者与作者享有相同的“前理解”与“前意识”。因此，随着讨论深入，分歧只会越来越多。

诚然，将一切公理化在形式上似乎能消解此问题：

请按你键盘上的字母 A，可能表现为 a 或者 A（附不同类型的键盘图片）。如果你不知道什么是键盘，请参见下图（附图片）。“按”的意思是用手指压后即抬起，时间约 1 秒。如果你没有键盘，请购买一个（附购买链接，付款），如果你没有钱……如果你不知道 1 秒有多长请眨 3 次眼睛……如果你不知道眨眼睛是……

但问题在于会陷入解释学循环。可见，这种因果倒退的唯一解决方式是回到起点。我们本意是让其按任意键，却演变为如何挑选购买键盘……实际上，因为他们认为这实际上超越了（理解的）边界，以往做法是：若读者不识键盘或 26 个字母，便中断对话，而非无穷倒退。认为存在一种边界，这是实证主义科学中的一种典型思路。

对此类问题的研究与理解是困难的。很少有人正视此问题，正如他们自称存在语言的边界那样。那不是语言的边界，而是自身理论的边界。

因此，指望靠一本书让所有人理解，是困难的。我们有必要思考：真正困难的是撰写经同行评审、编辑推荐的核心期刊文章，还是编写简单的基础入门文章？

我们需要解决的从来不是“任意键在哪”、“文件夹叫什么”、“电脑如何关机”。而是解决“为何要按键”、“为何不支持中文”、“为何关机需多次操作”等问题。这才是真正的边界，或曰结构性限制。我们为何如此？计算机起初便是如此吗？不，那时更为麻烦。为何到了现在，不知晓、不理解这些反而成了部分人的“错误”？这种“权力”究竟由谁定义？

若我们一开始便选择“从入门到跑路”，避免被此结构框住后又反遭指责，岂不快哉！中国社会科学院语言研究所词典编辑室，编. 现代汉语词典\[M]. 第 7 版. 北京：商务印书馆，2016：982. 对“跑路”的定义是“1. 走路；2. 逃跑，出逃。”从字面看，“跑路”未尝不是从预设的知识牢笼中挣脱？

如今翻开当年的甲种本、乙种本，甚至在你正学习的那一刻，知识便已过时。例如，国际纯粹与应用化学联合会（IUPAC）对元素周期表的修订已持续数十年（自 1988 年起），但课本仍沿用主族、副族划分。实际上，对许多学科或专业而言，学生直至博士毕业，也不过刚刚叩开 20 世纪的大门。但他们似乎对一切都能指点一二，并直接中止与自认为无共识者的对话。笔者认为并无必要。有人来自大山，毕业后又回到大山；正如我们在城市化，而他国在逆城市化。这均属合理。问题在于，我们终将把这些注定过时的、被称为知识的东西完全抛弃。那时，是否会有人指责我们：“你为何连‘按任意键’都不懂？”而不愿简单地将空间留给乐于助人者，或只说一句“按回车键就行”。

> **思考题**
>
> 请读者现在就找出本书中存在的至少一处描述不清晰或不准确的地方，并在 GitHub 上发起 PR 来完成修改。

你现在或许知晓一些，或许不知；学过或未学过什么，笔者认为也不重要。真正重要的是什么，完全由读者定义。因为笔者才是那个什么都不会、从来学不明白、永远有疑惑、永远不正确的人，笔者完全理解。读者大可轻松地“从入门到跑路”。无论读者作何选择，皆无不可。

“入门”是一种快乐，“跑路”亦是一种豁达。“本乘兴而行，兴尽而反，何必 FreeBSD 邪！”

## 参考文献

* 李征. 何积丰: 以“积”累迎来“丰”收\[EB/OL]. (2014-04-02)\[2026-03-25]. <https://www.whb.cn/zhuzhan/kandian/20140402/5053.html>. 和年轻人一样，71 岁的何院士现在也在使用智能手机。该文介绍中国科学院院士何积丰的科研历程与育人理念。
* RYANHANWU. 提问的智慧(How To Ask Questions The Smart Way)\[EB/OL]. \[2026-04-19]. <https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md>. 原作者之一是大家熟悉的 Eric S. Raymond（《UNIX 编程艺术》作者，[OSI](https://opensource.org/) 开源促进会创始人）~~师出同门~~。该文档是开源社区经典的提问指南，倡导高效沟通方式。
* Skinner B F. New Methods and New Aims in Teaching\[J]. New Scientist, 1964, 22(392): 483-484. <https://www.bfskinner.org/wp-content/uploads/2014/02/New-Methods-aims-in-Teach.pdf>. “教育就是当一个人把在学校所学全部忘光之后剩下的东西”这句话并非爱因斯坦所述。现在以讹传讹，人们获取的知识，真的是那么正确无误吗？Skinner 论述行为主义教育理论，澄清教育名言归属。
* 谢延龙. 庄子“忘”的教育图景阐释\[J]. 大学教育科学, 2022(1): 105-112. 该文从庄子哲学视角探讨“忘”在教育中的积极意义。
* Carse J P. 有限与无限的游戏: 一个哲学家眼中的竞技世界\[M]. 马小悟, 余倩, 译. 北京: 电子工业出版社, 2019. ISBN: 978-7-121-36425-9. 该书以游戏视角重新审视人类社会活动与文化现象。
* 尼采. 善恶的彼岸\[M]. 赵千帆, 译. 北京: 商务印书馆, 2015: 146. ISBN: 978-7-100-11749-4. “与恶龙缠斗过久，自身亦成为恶龙；凝视深渊过久，深渊将回以凝视”出自第 §146。
* Sudo Project. Legacy Releases of sudo\[EB/OL]. \[2026-04-17]. <https://www.sudo.ws/releases/legacy/>. 记载 sudo 1.7.1 于 2009 年 4 月 19 日发布，首次引入 pwfeedback 选项。
* Ferrari S.p.A. Great Ferrari Innovations: The F1 semi-automatic gearbox\[EB/OL]. (2022-02-04)\[2026-04-17]. <https://www.ferrari.com/en-EN/magazine/articles/great-ferrari-innovations-the-f1-semi-automatic-gearbox>. 1989 年 Ferrari 640 赛车首次搭载半自动序列式变速箱（由 John Barnard 设计），终结了 F1 手动换挡时代。
* Fédération Internationale de l'Automobile. Formula One technical regulations 1995\[EB/OL]. (1995)\[2026-04-17]. <https://historicdb.fia.com/sites/default/files/regulations/1728484024/formula_one_techical_regulations_1995.pdf>. 技术规范。
* Fédération Internationale de l'Automobile. Formula 1 technical regulations 2020\[EB/OL]. (2020)\[2026-04-17]. <https://api.fia.com/sites/default/files/2021_formula_1_technical_regulations_-_iss_6_-_2020-10-30.pdf>. 技术规范。
* Fédération Internationale de l'Automobile. FIA Formula Regional technical regulations 2024\[EB/OL]. (2024)\[2026-04-17]. <https://api.fia.com/sites/default/files/2025_fia_formula_regional_technical_regulations_-_issue_2_-_2024.12.11.pdf>. 技术规范。
* 金寿福, 译注. 古埃及《亡灵书》\[M]. 北京: 商务印书馆, 2020. 古埃及人来世信仰中，亡者在 Duat 与奥西里斯合而为一，并追随太阳神拉夜行冥界以期重生。
* 北岛. 履历\[M]. 北京: 生活·读书·新知三联书店, 2015: 16. 北岛的《一切》。
* 中国奥林匹克委员会. 职业选手何时进入奥运会？\[EB/OL]. (2004-08-05)\[2026-04-18]. <https://www.olympic.cn/olympic/know/2004/0805/25385.html>. 回顾奥运会从业余原则向允许职业运动员参赛转变的历史过程。
* International Olympic Committee. “Faster, Higher, Stronger – Together”: IOC Session approves historic change in Olympic motto \[EB/OL]. (2021-07-20)\[2026-04-19]. <https://www.olympics.com/ioc/news/-faster-higher-stronger-together-ioc-session-approves-historic-change-in-olympic-motto>. 2021 年 7 月 20 日国际奥委会第 138 次全会表决通过，在奥林匹克格言“更快、更高、更强”之后加入“更团结”（Together），系格言自 1894 年提出以来首次修改。
* IUPAC. New Notations in the Periodic Table\[J]. Pure and Applied Chemistry, 1988, 60(3): 431-436. <https://www.iupac.org/publications/pac/1988/pdf/6003x0431.pdf>. IUPAC 于 1988 年发布元素周期表新族编号体系，此后持续修订周期表（包括 1997 年超锕元素命名、2016 年确认第 113、115、117、118 号元素等）。


# 致谢

## 文献来源与基础架构

本书初版架构基于 Smile\_Zheng. 操作系统笔记\[EB/OL]. 百度贴吧. \[2026-04-04]. <https://tieba.baidu.com/p/7424071955>. 主要引用了防火墙章节、用户与权限章节。原笔记主要转引了《FreeBSD 技术内幕》（Urban M, Tiemann B. FreeBSD 技术内幕（FreeBSD Unleashed）\[M]. 智慧东方工作室，译. 北京：机械工业出版社，2002.），以及参考了 [🎀🌸 星不萌 🌸🎀](https://tieba.baidu.com/home/main?un=%E6%98%9F%E5%85%89Re) 的博客文章（[互联网档案馆存档](https://web.archive.org/web/20201128071425/https://www.moebsd.cn/)）。

在第二版中，除防火墙章节外，已经移除了所有对“操作系统笔记”（实际上是《FreeBSD 技术内幕》）的引用。

在第三版中，移除了对“🎀🌸 星不萌 🌸🎀”博客的所有引用、彻底移除了所有对“操作系统笔记”的引用；还援引 FreeBSD 文档项目的内容，大篇幅地增补了理论、命令选项和历史部分，FreeBSD 文档项目的许可证参见 **COPYRIGHT** 文件。

**作为项目目标的一部分，我们会重写所有直接引用的相关章节，并规范化标注引用来源及作者。**

由于历史原因以及对开源许可证规范认识不足，可能仍然存在未按原作者要求注明来源及作者的现象。在此表示歉意。如果读者有任何疑问，请联系 `yklaxds@gmail.com`。

## 社区管理与技术维护人员

[超平和 Busters](https://github.com/banbo96)（QQ 昵称/微信名）对本社区及文档的管理，以及 QQ 群、微信公众号、微信群的运营，发挥了重要作用，并创建和维护过本社区的多个关联账号。

本项目早期发起人为 [clean-master 清理大师](https://github.com/clean-master)。他自费创建了域名 `freebsdcn.org`（现已不再使用），并创建了目前仍在维护的主页 <https://bsdcn.org>。他鼓励 ykla 创建项目来维护相关的 FreeBSD 教程。

[Roberta Wheeler](https://github.com/rowheel) 曾自费部署并维护本项目的服务器（现已切换至 GitBook 及 GitHub Pages 免费服务），并撰写了部分文章。

[safreya](https://github.com/safreya) 开发了两款用于导出本项目 PDF 文档的开源工具（目前仍在使用），并撰写了大量文章。

Ubuntu 吧前吧主 Simple 曾建议修改项目的章节文件名与许可协议，这提升了本项目的可维护性。

本项目的域名 `bsdcn.org` 由 FreeBSD 中文社区（CFC）及 ykla 赞助。

目前，本项目的主要管理者是 [Voosk](https://github.com/MilkGolium)，他也参与了部分文章的撰写。

目前，本项目的主要技术维护者为 [ykla](https://github.com/ykla)。

## 按字母顺序排列的贡献者名录

* [5gura](https://github.com/5gura)
* [algotao](https://github.com/algotao)
* [Alex6357](https://github.com/Alex6357)
* April Simone🍥
* [VZstless](https://github.com/atlarator)
* [bduath](https://github.com/bduath)
* [blu10ph](https://github.com/blu10ph)
* bsdwiki
* [dacheng119](https://github.com/dacheng119)
* [Dedicatus5457](https://github.com/Dedicatus5457)
* 地铁卡
* DogeW
* [dongdigua](https://github.com/dongdigua)
* 兜率
* [fanyang1997](https://github.com/fanyang1997)
* [fjh1997](https://github.com/fjh1997)
* freyr
* [gua-leopard](https://github.com/gua-leopard)
* heguru5
* isNijikawa
* Jack
* Jiacong Fang（[zldrobit](https://github.com/zldrobit)）
* 极品盗号
* kuntop
* LFour86
* [LuoTianyi-arm64](https://github.com/LuoTianyi-arm64)
* [李大鹏](https://dapeng.li/)
* [liguangsheng](https://github.com/liguangsheng)
* livrth
* [凌莞](https://clansty.com)
* [柳离枝](https://github.com/liulitchi)
* 刘昕宇
* matatabi-wang
* 墨子
* [魔王酱](https://github.com/maou-sama-desu)
* [mxdyeah / mxdabc](https://mxdyeah.top/)
* [nerdroychan](https://github.com/nerdroychan)
* [number201724](https://github.com/number201724)
* [orzyyyy](https://github.com/orzyyyy)
* [peiyafei](https://github.com/peiyafei)
* [pengxingwei](https://github.com/pengxingwei)
* [puffinjiang](https://github.com/puffinjiang)
* 清和 [qinghecyn](https://github.com/qinghecyn)
* 清热解毒口服液
* [Rintim](https://github.com/Rintim)
* [ruur](https://github.com/ruur)
* [Sayunosyjou](https://github.com/Sayunosyjou)
* 施主
* [Suyun114](https://github.com/Suyun114)
* [tergel93](https://github.com/tergel93)
* [tomblackwhite](https://github.com/tomblackwhite)
* 艳阳天
* [Wang Yan Hao](https://github.com/Wang-Yan-Hao)
* [玟茵开源社区](https://www.wenyinos.com/)
* [wyathou](https://github.com/wyathou)
* X-Ray
* 心即理物即心
* 🎀🌸 星不萌 🌸🎀（贴吧账户）
* 仰望天空
* 雨天
* [Zomby7e](https://github.com/Zomby7e)

## 技术基础设施与平台支持

本项目部署过程中使用了若干开源项目，我们对其作者表示感谢。

本项目主要托管在 [GitHub](https://github.com) 上。

本项目获得了 [GitBook 开源计划](https://www.gitbook.com/solutions/open-source) 的赞助，网站 `book.bsdcn.org` 即由其驱动。

本项目的镜像网站 `docs.bsdcn.org` 基于 [VitePress](https://vitepress.dev/) 构建。

本项目的镜像网站 `doc.bsdcn.org` 已针对境内访问进行了优化。


# 1.1 什么是 UNIX？

FreeBSD 源自 BSD，即加州大学伯克利分校开发的 UNIX® 版本。

## 何谓 UNIX？

UNIX 的内涵已从具体技术实现演变为一种文化象征。UNIX 系统起源于美国电话电报公司（American Telephone & Telegraph，AT\&T）贝尔实验室。

20 世纪 60 年代末至 70 年代初，UNIX 作为一种操作系统，最初采用汇编语言编写，后来主要以 C 语言重写。

20 世纪 80 年代以后，UNIX 逐渐成为一种 [**标准规范**](https://www.opengroup.org/openbrand/register/xym0.htm)。

在当代语境中，UNIX 不仅意味着法律上的 [**商标**](https://www.opengroup.org/openbrand/register/index2.html)，更是一种 **哲学思想** 和一系列 **软件工程原则**。

![三位一体的 UNIX](/files/a3RV8SwDUwUOovZMdaol)

根据当前 UNIX 商标持有者开放组织（The Open Group）官网 [UNIX® Certification](https://www.opengroup.org/openbrand/register/) 所述：“Only systems that are fully compliant and certified according to the Single UNIX Specification are qualified to use the UNIX® trademark.”（只有完全符合《单一 UNIX 规范》并通过认证的系统，才有资格使用 UNIX® 商标）

***

查询美国专利商标局 UNIX 商标注册信息如下：

![法律上的商标](/files/veBMvxDV6bcESdqi4Nmv)

***

UNIX 操作系统认证查询网址：[The Open Group official register of UNIX Certified Products](https://www.opengroup.org/openbrand/register)。

![UNIX 认证查询](/files/cr5GKdBmcisJxf7uANLV)

根据开放组织要求，认证 UNIX 需要满足以下两项核心条件：

1. 技术标准要求：符合 [单一 UNIX 规范](https://www.opengroup.org/openbrand/register/xym0.htm)（Single UNIX Specification，SUS），该规范定义了 UNIX 系统必须实现的接口、命令、实用程序和库函数，确保不同 UNIX 操作系统互相兼容。
2. 法律与费用要求：缴纳相应的 [认证费用](https://www.opengroup.org/openbrand/Brandfees.htm)。

当前经认证的 UNIX 操作系统包括 Apple 公司的 macOS。从商标角度看，macOS 是符合标准的 UNIX 操作系统。~~因此，要安装 UNIX 的人可考虑 macOS。~~

表面上看是移动端的 Android 与 iOS 之争，实质上是 Linux 与 BSD 之争。~~这也许还是大教堂与市集之争。~~

## 传统的 UNIX 哲学观（以《UNIX 编程艺术》为核心）

UNIX 哲学是 UNIX 操作系统于长期开发实践中逐渐形成的设计理念，由肯·汤普森（Ken Thompson）与丹尼斯·里奇（Dennis Ritchie）等早期核心开发者共同塑造。其核心主张可归纳为以下原则：

| 原则                     | 说明                                            |
| ---------------------- | --------------------------------------------- |
| **小即美**                | 程序应设计得简洁小巧，功能单一明确，便于理解和维护。                    |
| **一个程序只做一件事**          | 每个工具专注于单一功能，通过组合多个工具协作完成复杂任务。                 |
| **原型先行**               | 先快速构建可工作的原型，再逐步优化，避免过度设计。                     |
| **可移植性先于高效性**          | 优先保证代码能在不同平台上运行，性能优化次之。                       |
| **避免使用不必要的二进制格式或复杂表示** | 使用简单的文本格式，便于人工阅读和处理。                          |
| **沉默是金**               | 程序在正常执行时不应产生冗余输出，仅在出错时给出提示；成功操作不输出信息，亦不显示进度等。 |
| **避免独占式用户界面**          | 应提供命令行接口，确保可通过脚本实现自动化操作。                      |

这些原则在当时的软件设计中相辅相成，帮助开发者构建出简洁、高效、可维护的系统。FreeBSD 的开发实践深受 UNIX 哲学影响。其先进的网络功能、性能、安全与兼容性等目标，与 UNIX 哲学中“可移植性先于高效性”及“小即美”等原则一脉相承。

FreeBSD 的手册页系统是 UNIX 哲学的典型体现：每个命令、系统调用和配置文件均配有独立的手册页，内容简明扼要，便于用户通过 man 命令随时查阅。

> **思考题**
>
> > 1. UNIX 哲学一言以蔽之，大道至简。“Keep it simple, stupid”。
>
> > 2. Brooks F P Jr. 人月神话\[M]. UMLChina，译. 纪念典藏版. 北京：清华大学出版社，2023. ISBN: 978-7-302-63538-3
>
> 阅读上述文本和参考文献，如何理解 UNIX 哲学的局限性及其背后的时代背景。

> **思考题**
>
> > Those who do not understand UNIX are condemned to reinvent it, poorly.（那些不懂 UNIX 的人注定要再造一个四不像式 UNIX。）
>
> 亨利·斯宾塞（Henry Spencer）并未明确批评某一操作系统，试问，当前该论断更适用于何种主流操作系统？原因何在？

## UNIX 的一段历史

UNIX 的诞生有特定的历史背景，需追溯至前身 Multics。

### Multics 项目

Multics 是深刻影响 UNIX 的重要项目。1961 年，麻省理工学院（Massachusetts Institute of Technology，MIT）演示了 **兼容分时系统**（Compatible Time-Sharing System，CTSS）——当时最具创新性的操作系统之一。在此基础上，研究人员于 1964 年决定设计更为先进的版本，即 **多路复用** 信息和计算服务（Multiplexed Information and Computing Service，Multics）系统。

Multics 旨在创造功能强大的新软件，以及比肩 IBM 7094 且功能更丰富的新硬件。1964 年 8 月，通用电气公司（General Electric，GE）被选定为硬件供应商并签署合同；同年 11 月，贝尔实验室加入该项目，形成三方合作。其中，通用电气公司负责设计并生产具有全新硬件特性的计算机，以更好地支撑分时及多用户体系；贝尔实验室在计算机发展早期就开发了自己的操作系统，具备相关经验。

Multics 的开发最终陷入困境。该系统设计了大量程序及功能，且频繁引入相互矛盾的组件，导致系统过于复杂。1969 年，贝尔实验室认为，Multics 作为信息处理工具已无法为实验室提供计算服务，且设计成本过高。同年 4 月，贝尔实验室退出 Multics 项目，仅麻省理工学院和通用电气公司继续开发。

### UNICS 的诞生

UNIX 系统最初被命名为 UNICS，其诞生源于一项游戏项目。贝尔实验室退出 Multics 开发项目后，项目组成员肯尼斯·蓝·汤普森（Kenneth Lane Thompson）在实验室找到了一台闲置的数字设备公司（Digital Equipment Corporation，DEC）PDP-7 型计算机。该计算机性能有限，仅 8K 字（约 18 KB）内存，但具备较为完善的图形显示能力。Thompson 此前已在 Multics 系统上编写了游戏 Space Travel（《星际旅行》），随后改写为 Fortran 版本，在 GE 635 计算机的 GECOS 操作系统上运行。但因运行费用高昂且显示效果不佳，Thompson 与 Ritchie 将该游戏移植到了 PDP-7 上。PDP-7 配备了一台大容量单盘片磁盘驱动器，Thompson 编写了磁盘调度算法以最大化磁盘吞吐量。

> **技巧**
>
> 《星际旅行》已被移植，目前可通过网页端体验（[Space Travel](https://akr.am/st/)），移植后的项目源代码位于 [C port of Ken Thompson's Space Travel](https://github.com/mohd-akram/st)。
>
> ~~虽然操作简单，但还是看不懂怎么玩。~~

为验证该算法，需向磁盘写入数据，Thompson 于是编写了批量写入数据的程序。

他以每周一个程序的速度，先后完成了三项工作：用于编写代码的编辑器、将代码转换为 PDP-7 可执行机器语言的汇编器，以及“内核的外层，即操作系统”，最终初步构建了操作系统。

Thompson 在 PDP-7 上完成新操作系统的初步开发后，与数位同事讨论时，该系统尚无正式名称。直到 1970 年，布莱恩·柯尼汉（Brian Kernighan）建议将其命名为 **UNICS**（**Uniplexed** Information and Computing Service, **单路复用** 信息和计算服务），作为对 **Multics**（**Multiplexed** Information and Computing Service, **多路复用** 信息和计算服务）的戏仿。该名称后来演变为 **UNIX**。

上述从 Multics 到 UNIX 的关键演进节点可归纳如下：

```sh
1961 │  MIT 演示 CTSS（兼容分时系统）                           
     │ 
1964 │  08 月  通用电气公司签约，提供硬件                           
     │  11 月  贝尔实验室加入，形成三方合作                       
     │ 
1969 │  04 月  贝尔实验室退出 Multics 项目                                
     │ 
1970 │  柯尼汉建议命名 UNICS（后演变为 UNIX）                                
```

## 参考文献

* Raymond E S. UNIX 编程艺术\[M]. 姜宏,何源,蔡晓骏,译. 北京: 电子工业出版社, 2012. ISBN: 978-7-121-17665-4. 阐述 UNIX 哲学与软件工程实践原则。
* Gancarz M. Linux/Unix 设计思想\[M]. 漆犇,译. 北京: 人民邮电出版社, 2012. ISBN: 978-7-115-26692-7. （已绝版）提炼 UNIX 系统设计核心思想与实践方法。
* The Open Group. The Open Group Standards Process\[EB/OL]. \[2026-03-25]. <https://www.opengroup.org/standardsprocess/certification.html>. 规范 UNIX 认证流程与技术标准框架。
* National Academy of Engineering. Dr. Fernando J. Corbato\[EB/OL]. \[2026-04-16]. <https://www.nae.edu/29551/Dr-Fernando-J-Corbato>. Corbato 主持开发了 CTSS，据该文记载，CTSS 于 1961 年 11 月在 IBM 709 上首次演示。
* Ritchie D M. The Development of the C Language\[EB/OL]. \[2026-04-16]. <https://www.bell-labs.com/usr/dmr/www/chist.html>. Ritchie 回忆 C 语言与早期 UNIX 开发历程，提及 PDP-7 内存为 8K 18-bit words。
* Tom Van Vleck. The Multicians web site\[EB/OL]. (2026-04-08)\[2026-04-17]. <https://multicians.org/chrono.html>. Multics 编年史，记载 GE 于 1964 年 8 月签约，贝尔实验室于 1964 年 11 月加入。
* Computer History Museum. Atlas computer\[EB/OL]. \[2026-04-17]. <https://www.computerhistory.org/timeline/1962/>. 记载 Atlas 计算机于 1962 年首次投入运行，引入虚拟存储器概念。
* Ritchie D M. The Evolution of the Unix Time-sharing System\[EB/OL]. (1984)\[2026-04-18]. <https://www.read.seas.harvard.edu/~kohler/class/aosref/ritchie84evolution.pdf>. Ritchie 详述 Unix 从 PDP-7 到 PDP-11 的演进历程，记载 Space Travel 最初在 Multics 上编写，后改写为 Fortran 在 GECOS/GE 635 上运行，最终移植至 PDP-7。
* Van Vleck T. Multics: Bell Labs withdrawal\[EB/OL]. \[2026-04-18]. <https://www.multicians.org/general.html>. 记载贝尔实验室于 1969 年 4 月退出 Multics 项目。
* 克尼汉 B W. UNIX 传奇：历史与回忆\[M]. 韩磊,译. 北京: 人民邮电出版社, 2021: 31-42. ISBN: 978-7-115-55717-9. 2.3 节记载 Thompson 编写磁盘调度算法以最大化 PDP-7 磁盘吞吐量，并以每周一款程序的速度编写了编辑器、汇编器与内核。
* SPENCER H. space news from Sept 28 AW\&ST\[EB/OL]. sci.space.shuttle, Google Groups, (1987-11-15)\[2026-04-17]. <https://groups.google.com/g/sci.space.shuttle/c/L8-Upf8gZoY/m/NN6ngTI0K0QJ>. 亨利·斯宾塞言语出处。

## 课后习题

1. 在 FreeBSD 上安装 QEMU 并运行 FreeBSD 1.0 版本，记录启动过程中与当代 FreeBSD 的显著差异。
2. 在网页端体验 Thompson 最初的 Space Travel，总结其玩法。
3. 试列举 SUS 规范与 Windows 操作系统在设计理念与实现上的差异。


# 1.2 GNU 操作系统和自由软件运动

理查德·斯托曼于 1983 年发起 GNU 项目，旨在创建一种完全自由且与 UNIX 兼容的操作系统。

## GNU 操作系统与自由软件运动的缘起

GNU 通用公共许可证（GPL）在自由软件生态中的核心地位，可从 Linux 内核文档中窥见一斑。根据 Linux Kernel Documentation 的相关说明：

> Code is contributed to the Linux kernel under a number of licenses, but all code must be compatible with version 2 of the GNU General Public License (GPLv2), which is the license covering the kernel distribution as a whole. In practice, that means that all code contributions are covered either by GPLv2 (with, optionally, language allowing distribution under later versions of the GPL) or the three-clause BSD license. Any contributions which are not covered by a compatible license will not be accepted into the kernel.（Linux 内核中贡献的代码受多种许可证授权，但所有代码都必须与 GNU 通用公共许可证第 2 版（GPLv2）兼容，因为 GPLv2 覆盖了整个内核发行。实际上这意味着，一切贡献的代码要么受 GPLv2 约束（可选地包含允许在 GPL 后续版本下发布的条款），要么受三条款 BSD 许可证约束。那些由非兼容许可证授权的贡献都不会被内核接纳）

UNIX 在后期发展中渐趋封闭，最初作为开放的研究项目（受当时美国法律要求），后来转为商业产品。普通用户无法自由获取和修改其源代码，许可证价格高昂，使用权受商业公司严格限制。理查德·马修·斯托曼（Richard Matthew Stallman，RMS）希望创造一种自由且与 UNIX 兼容的操作系统，这一愿景直接推动了自由软件运动的兴起。

* 1983 年，理查德·马修·斯托曼发表了 GNU 项目初始公告；其中 GNU 即“GNU's Not Unix”（GNU 不是 UNIX）的递归缩写。GNU 是一种旨在完全替代 UNIX 的操作系统。
* 1984 年，理查德·马修·斯托曼正式创建了 [GNU 项目](https://www.gnu.org/)。
* 1985 年，理查德·马修·斯托曼撰写了 GNU 宣言；同年创建了非营利组织（**501(c)(3)**）自由软件基金会（Free Software Foundation，FSF）。
* 1989 年，自由软件基金会发布了 GNU General Public License V1.0（GPLv1，GNU 通用公共许可证第 1 版）。
* 1991 年，自由软件基金会发布了 GNU General Public License V2.0（GPLv2，GNU 通用公共许可证第 2 版）。
* 2007 年，自由软件基金会发布 GNU General Public License V3.0（GPLv3，GNU 通用公共许可证第 3 版）。

上述 GNU 项目与 GPL 许可证的关键节点可归纳如下：

```sh
1983 │  发表 GNU 项目初始公告
     │
1984 │  正式创建 GNU 项目
     │
1985 │  撰写 GNU 宣言，创建自由软件基金会（FSF）
     │
1989 │  发布 GPLv1
     │
1991 │  发布 GPLv2
     │
2007 │  发布 GPLv3
```

在 GNU 项目初期，理查德·马修·斯托曼为 UNIX 开发了大量实用程序（用户空间组件），**在 GNU 项目中，还以 GPL 许可证重新实现了许多常用的 BSD 工具**，然而 GNU 始终未能产出稳定的内核。[**GNU Hurd**](https://hurd.gnu.org/) 是 GNU 项目的内核，采用微内核架构设计，开发始于 1990 年。尽管 Debian GNU/Hurd 移植团队已于 **2025 年 8 月 10 日** 发布了 **Debian GNU/Hurd 2025**（该版本是 Debian sid 在 Debian 13 Trixie 发布时的快照，大部分源代码与 Trixie 相同；这是官方的 Debian GNU/Hurd 移植版发布，但非官方的 Debian 发行版），但其硬件支持和软件生态仍不成熟。Linux 内核的诞生打破了这一技术僵局。

> **思考题**
>
> > BSD 最大的历史影响，恰恰在于它太成功，以至于大量思想成为整个计算机世界的“默认常识”，反而没人记得来源，一切都是理所应当的，都是 GNU/Linux 的成就。
>
> > 对于了解米泽穗信作品《冰菓》的读者或动漫观众来说，想来对“KANYA 祭”这一为期三天的校园文化祭并不陌生。仅有名字和形式传了下来，真正的血泪故事却被隐匿了。
>
> 如何理解“这样取得了统治地位的传统首先与通常都使它所‘传下’的东西难于接近，竟至于倒把这些东西 **掩盖起来了**。流传下来的不少范畴和概念本来曾以真切的方式从源始的‘源头’汲取出来，传统却赋予承传下来的东西以 **不言而喻** 的性质，并 **堵塞了** 通达‘源头’的道路。传统甚至使我们 **忘掉了** 这样的渊源。”

Linux 是 Linux 内核与 GNU 软件的组合体，在发展过程中不断融入 GNU 理念，最终形成 GNU/Linux 操作系统。尽管 GNU 的贡献巨大，其作用却常被低估。这一现象的部分原因在于 Linux 内核的开发由林纳斯·托瓦兹（Linus Torvalds）主导，而托瓦兹对自由软件基金会及理查德·马修·斯托曼的理念并不完全认同。Linux 内核项目与自由软件运动乃至严格的开源理念之间存在一定的分歧（例如，Linux 内核包含了一些不符合自由软件或严格开源定义的二进制固件模块〔参见 **Linux-libre**〕）。此外，Linux 内核采用的是 GPLv2 许可证，而非 GNU 所推荐的 GPLv3。

在 Linux 诞生之前，软件自由领域的代表性运动是“自由软件运动”（代表人物为理查德·马修·斯托曼）。Linux 的流行促成了另一种理念的兴起，即“开源运动”，代表人物包括开放源代码促进会（Open Source Initiative，OSI）的共同创始人、《UNIX 编程艺术》与《大教堂与集市》的作者埃里克·斯蒂芬·雷蒙德（Eric S. Raymond），以及 OSI 的另一位共同创始人、Debian 项目前领导人布鲁斯·佩伦斯（Bruce Perens）。OSI 所定义的开源标准源于 Debian 自由软件指导方针（Debian Free Software Guidelines，DFSG）。

自由软件运动与开源运动之间存在理念差异，至今仍是软件许可领域的核心分歧之一。

### 参考文献

* Linux Kernel Documentation. 1. Introduction — The Linux Kernel documentation\[EB/OL]. \[2026-03-26]. <https://www.kernel.org/doc/html/latest/process/1.Intro.html>.
* Linux Kernel Documentation. Linux kernel licensing rules — The Linux Kernel documentation\[EB/OL]. \[2026-03-26]. <https://www.kernel.org/doc/html/latest/process/license-rules.html>.
* Stallman R. The GNU Manifesto\[EB/OL]. \[2026-03-26]. <https://www.gnu.org/gnu/manifesto.html>. GNU 宣言。
* Linux-libre Project. Linux-libre\[EB/OL]. \[2026-03-26]. <https://www.fsfla.org/ikiwiki/selibre/linux-libre/>. 一款由拉丁美洲自由软件基金会（FSFLA）维护的去除所有二进制固件的 Linux 内核变体
* 海德格尔. 存在与时间\[M]. 陈嘉映, 王庆节, 译. 修订第 2 版. 北京: 商务印书馆, 2015: 28. ISBN：978-7-100-11067-9.

## 自由软件运动与开源运动的张力

自由软件运动与开源运动之间存在一定的理念差异。理查德·马修·斯托曼在私人通信中强调，GNU 与自由软件运动并不强调“开源”（甚至是反对使用这一术语），而是强调“Free”所代表的自由。部分观点将“开源”等同于 OSI 的定义，这是一种片面的观点。

以下引用自理查德·马修·斯托曼的私人通信，内容不涉及隐私信息。

> 致所有阅读我邮件的美国国家安全局（National Security Agency，NSA）和联邦调查局（Federal Bureau of Investigation，FBI）特工：请考虑一下，捍卫美国宪法以抵御一切敌人，无论是外国的还是本国的，是否需要你效仿爱德华·斯诺登（Edward Snowden）的做法。
>
> > 但是我有点困惑：GNU 项目是否强制要求开发必须开源？因为 GNU 通用公共许可证（GPL）强制开源。
>
> GNU 项目并不倡导“开源”。我们从不用这个词，除非是为了表达与它的分歧。我们代表的是自由软件（Free Software）——自由如同自由的言论。我们致力于在计算中为用户争取自由。
>
> 请参见：free-software-even-more-important\[EB/OL]. \[2026-03-26]. <https://gnu.org/philosophy/free-software-even-more-important.html>.
>
> “开源”这个词是一些反对自由软件运动的人发明的——他们与我们意见相左。他们想谈论同样的软件，却又掩盖自由的理念。
>
> 关于自由软件与开源的区别，请参见：open-source-misses-the-point\[EB/OL]. \[2026-03-26]. <https://gnu.org/philosophy/open-source-misses-the-point.html>.
>
> 另请阅读叶夫根尼·莫罗佐夫（Evgeny Morozov）的文章：<https://thebaffler.com/salvos/the-meme-hustler>，他在文中也探讨了这一点。
>
> 所以请不要问我们关于“开源”或“开放”某些东西的问题。我们不是那样思考的。你真正应该问我们的是：我们如何以自由软件的方式做事情。
>
> > 它属于 GNU 项目，那么 GNU 项目是否也会强制他人……
>
> 我不太确定你所说的“强制”是什么意思，这里可能存在误解。通常我们会告诉人们我们认为什么是对的，什么是错的，但我们无法命令他们做什么。
>
> 唯一的例外是他们使用了 GPL 许可的软件代码。在这种情况下，GNU GPL 本身是一种法律上的约束，规定了他们如何使用这些代码。它要求他们在再发布代码时，尊重其他用户的自由。
>
> 这正是著佐权（Copyleft）的意义所在。
>
> 如果你还有更多问题，请写信至 <licensing@gnu.org>。

> **技巧**
>
> 与 GPL 许可证的“著佐权”（Copyleft）机制不同，FreeBSD 项目采用更为宽松的 BSD 许可证。FreeBSD 项目的源代码中包含部分受 GNU 通用公共许可证（GPL）和 GNU 宽通用公共许可证（LGPL）许可的软件，这些许可证的著佐权（Copyleft）条款对源代码再发布施加了更严格的限制。然而，由于 GPL 软件在商业使用中可能带来额外复杂性，在合理可行的情况下，FreeBSD 项目更倾向于接受 BSD 许可证的软件提交。这一许可证选择差异是 FreeBSD 与 Linux 在软件生态治理上的核心区别。

### 参考文献

* Debian Project. Debian GNU/Hurd\[EB/OL]. \[2026-04-17]. <https://www.debian.org/ports/hurd/>. Debian GNU/Hurd 官方页面，2025 年 8 月 10 日发布了 Debian GNU/Hurd 2025（基于 Debian sid 在 Trixie 发布时的快照，大部分源代码与 Trixie 相同；这是官方的 Debian GNU/Hurd 移植版发布，但非官方的 Debian 发行版）。
* GNU Project. What is the Hurd?\[EB/OL]. \[2026-04-17]. <https://www.gnu.org/software/hurd/hurd/what_is_the_gnu_hurd.html>. GNU Hurd 项目介绍，阐述其微内核架构设计理念。
* Open Source Initiative. The Open Source Definition\[EB/OL]. (2024-02-16)\[2026-03-26]. <https://opensource.org/osd>.

## 附录：自由软件与开源软件的常见误解辨析

自由软件与开源软件的概念常易混淆。本附录从“营利”与“盈利”的词语辨析入手，梳理自由软件的四项基本自由与 OSI 开源协议十条标准，辨析自由软件与开源软件的关系，并厘清 CC-BY-NC/ND 等非开源许可证的边界。

### 厘清“营利”和“盈利”

这两个词语含义和用法均不相同。

* “盈利”：名词，扣除成本后获得的利润，也作赢利。引自中国社会科学院语言研究所词典编辑室，编. 现代汉语词典\[M]. 第 7 版. 北京：商务印书馆，2016：1572. ISBN: 978-7-100-12450-8.
* “营利”：动词，谋求利润。引自中国社会科学院语言研究所词典编辑室，编. 现代汉语词典\[M]. 第 7 版. 北京：商务印书馆，2016：1572. ISBN: 978-7-100-12450-8.

### 自由软件定义：四项基本自由

> 一种软件若为自由软件，必须为用户提供以下四项基本自由：
>
> 自由度 0：无论用户出于何种目的，必须可以按照用户意愿，自由地运行该软件。
>
> 自由度 1：用户可以自由地学习并修改该软件，以此来帮助用户完成用户自己的计算。作为前提，用户必须可以访问到该软件的源代码。
>
> 自由度 2：用户可以自由地分发该软件的拷贝，以便帮助他人。
>
> 自由度 3：用户可以自由地分发该软件修改后的拷贝。借此，用户可以将改进后的软件分享给整个社区，令他人也从中受益。作为前提，用户必须可以访问到该软件的源代码。

即：“用户可以自由地运行、复制、分发、学习、修改并改进该软件。”

推论 1：如果商业用户为了营利（自由度 0）而修改（自由度 1）再分发（自由度 2），只要修改后仍然开源（自由度 3），商业用户的行为是完全合规的。这表明商业用户完全有权自由使用、修改、分发及通过该软件营利。任何自由度均未限制 **营利** 行为。引证 1：[自由软件可以是商业软件](https://www.gnu.org/philosophy/free-sw.zh-cn.html#four-freedoms)。

### 开源协议定义与开源软件定义

开放源代码促进会（OSI）旨在坚持开源定义（Open Source Definition，OSD）并防范开源运动原则的滥用，其对开源协议的定义如下——开源软件的分发条款必须符合以下核心标准：

| 序号 | 标准              | 说明                                      |
| -- | --------------- | --------------------------------------- |
| 1  | **自由再分发**       | 许可证不得限制任何一方出售或赠送该软件，不得要求对此类销售收取版税或其他费用。 |
| 2  | **源代码**         | 程序必须包含源代码，并允许以源代码以及编译形式分发。              |
| 3  | **衍生作品**        | 许可证必须允许修改和衍生作品，并允许按照与原始软件许可证相同的条款进行分发。  |
| 4  | **作者源代码的完整性**   | 许可证可以限制以修改形式分发源代码，仅当允许分发带有源代码的“补丁文件”。   |
| 5  | **不得歧视个人或群体**   | 许可证不得歧视任何个人或群体。                         |
| 6  | **不得歧视应用领域**    | 许可证不得限制任何人在特定应用领域中使用该程序。                |
| 7  | **许可证的分发**      | 附加到程序的权利必须适用于所有重新分发程序的人。                |
| 8  | **许可证不得特定于产品**  | 附加到程序的权利不得取决于程序是否为特定软件分发包的一部分。          |
| 9  | **许可证不得限制其他软件** | 许可证不得对与许可软件一起分发的其他软件施加限制。               |
| 10 | **许可证必须保持技术中立** | 许可证的任何条款都不得基于任何单一技术或界面风格。               |

OSI 基于开源定义（OSD）所认证的开源许可证，已成为全球公认的开放软件判定标准，并因国际组织、产业界与政府政策的采纳而确立了权威性。

经 OSI 认证的开源许可证参见 [OSI 官方许可证列表](https://opensource.org/licenses)。严格意义上，仅该列表中的许可证属于开源许可证。

### 关于各种软件的定义

根据自由软件基金会. 自由与非自由软件的分类\[EB/OL]. (2025-12-28)\[2026-03-26]. <https://www.gnu.org/philosophy/categories.zh-cn.html>. 定义如下：

* 自由软件：符合上述四项基本自由定义的软件即称为自由软件。推论：商业软件可以是自由软件，商业不等于非自由。引证 1：自由软件基金会. 什么是自由软件？\[EB/OL]. \[2026-03-26]. <https://www.gnu.org/philosophy/free-sw.zh-cn.html>. 引证 2：Free Software Foundation. Words to Avoid (or Use with Care) Because They Are Loaded or Confusing\[EB/OL]. \[2026-03-26]. <https://www.gnu.org/philosophy/words-to-avoid.html>.“Commercial”部分。
* 开源软件：使用上述开源协议授权的软件。所有自由软件都是开源软件，但并非所有开源软件都是自由软件。二者的定义与理念均存在差异。自由软件是开源软件的充分不必要条件。

![自由软件与开源软件的包含关系](/files/3ibJjY09Xi9Ve5fAVkv4)

* 专有软件/私有软件（Proprietary Software）：即真正意义上的“非自由软件”，GNU 宣言最初的目标即消除此类非自由软件，大部分商业软件属此类型。
* 免费软件：界定标准不一。前述各类软件均可能免费分发，但免费本身不构成其性质的判定依据。
* 商业软件：商业软件由企业作为其业务的一部分开发。

#### 推论

* 推论 1：商业软件可以是开源软件或自由软件。反之，开源软件或自由软件也可以是商业软件。
* 推论 2：商业软件形式的开源软件或自由软件可以营利（无论项目作者是否参与此商业软件），且合规。例如，典型情形为电商平台商户利用开源许可的软件营利。在遵守许可的前提下，此类营利是合乎伦理的。现实中对此类商家的指责，多源于公众对所采用的开源协议缺乏理解。
* 推论 3：商业软件不一定是私有软件或专有软件。反之，私有软件或专有软件也不一定是商业软件（如将个人项目以非营利目的闭源分发给朋友）。

### 自由/开源软件与免费

依据“自由度 2：用户可以自由地分发该软件的拷贝”及 GPLv2/v3 等相关开源协议的条款，上述协议并未限制开源软件的营利行为。红帽公司（Red Hat）便是典型例子。

开源软件/自由软件不等于免费。

### 开源不等于无版权

部分公众会混淆开源与无版权，而“开源即无版权”这一观点实际存在逻辑问题：如果不持有版权，便无法要求他人遵守开源协议。部分人会将版权转交给自由软件基金会，但版权在事实上依然存在。

在司法实践中，许多开源软件项目作者仍被依法追究法律责任。如果是无版权，则无法确定责任主体。

在各国版权法中，版权的所有权利通常不可完全转让，只能让渡部分权利。以《中华人民共和国著作权法》为例，发表权、署名权、修改权、保护作品完整权等权利是无法让渡的。

在实践中，作者通常不受开源协议本身的限制（除非引用了他人的项目），协议旨在约束第三方。

### CC-BY-NC 与 CC-BY-ND 既不自由也不开源

知识共享署名-非商业性使用协议（Creative Commons Attribution-NonCommercial，CC-BY-NC）与知识共享署名-禁止演绎协议（Creative Commons Attribution-NoDerivs，CC-BY-ND）等均不属于开源软件许可证或自由软件许可证。基于对各类许可证及其评论的分析，上述协议限制了商业用户的使用，剥夺了商业用户的“自由”；前述 CC 协议也不符合自由软件精神，其要求的冗长署名与声明增加了项目复用时的合规成本。

### 可以获取源代码不等于开源或自由

根据微软（Microsoft）的企业源代码许可计划（Enterprise Source Licensing Program，ESLP）或微软参考源代码许可证（Microsoft Reference Source License，Ms-RSL），商业用户在满足一定条件后即可获取对应的源代码。

虽然可以获取源代码，且在某些情况下允许修改（如神州网信政府版 Windows 10），但此类协议并不属于开源协议。本质上，CC-BY-NC 与 CC-BY-ND 与此类许可协议并无根本区别。

### 参考文献

* 自由软件基金会. 自由与非自由软件的分类\[EB/OL]. \[2026-03-26]. <https://www.gnu.org/philosophy/categories.zh-cn.html>.
* Open Source Initiative. Licenses - Open Source Initiative\[EB/OL]. \[2026-03-26]. <https://opensource.org/licenses>.
* Open Source Initiative. International Authority & Recognition - Open Source Initiative\[EB/OL]. (2025-06-03)\[2026-03-26]. <https://opensource.org/about/authority>.
* Debian Project. Debian Social Contract\[EB/OL]. (2022-10-01)\[2026-03-26]. <https://www.debian.org/social_contract#guidelines>. DFSG。
* 自由软件基金会. 什么是自由软件？\[EB/OL]. \[2026-03-26]. <https://www.gnu.org/philosophy/free-sw.zh-cn.html>. 引用自由软件基金会相关内容来定义自由软件的自由。

## 课后习题

1. 查阅理论文献，分析 Linux 发行版（Debian、Ubuntu、Fedora、Arch Linux 等）与 GNU 项目及 GNU GPL 许可证之间的技术、法律与社区关系，绘制三者互动关系图。
2. 选定一个 Linux 发行版，研究其系统核心组件与 GNU 项目之间的依赖关系。该发行版中哪些关键组件来自 GNU 项目？其内核（Linux 内核）与 GNU 工具链如何协同工作？查阅相关技术文档和架构资料，撰写技术分析报告。
3. 阅读 GNU GPLv2 许可证原文，归纳 copyleft 机制的核心条款，与 BSD 2 条款许可证在再分发限制方面逐条对比。


# 1.3 Linux 与类 UNIX

本节以 Linux 内核官方文档的定义为起点，阐述 Linux 作为 UNIX 克隆操作系统的技术架构与许可证体系，并说明其“类 UNIX”属性的法律与功能依据。

## 何谓 Linux？

Linux 是当今世界广泛使用的开源操作系统。Linux 在不同语境下含义不同：狭义上指 Linux 内核，广义上通常指完整的操作系统，即 GNU/Linux。Linux 内核官方文档对这一问题的回答如下：

> What is Linux?（什么是 Linux？）
>
> Linux is a clone of the operating system Unix, written from scratch by Linus Torvalds with assistance from a loosely-knit team of hackers across the Net. It aims towards POSIX and Single UNIX Specification compliance.（Linux 是 UNIX 操作系统的克隆版本，由 Linus Torvalds 从零开始编写，并在网络上一支组织松散的极客团队协助下完成。Linux 旨在实现对 POSIX 和单一 UNIX 规范的兼容）
>
> It has all the features you would expect in a modern fully-fledged Unix, including true multitasking, virtual memory, shared libraries, demand loading, shared copy-on-write executables, proper memory management, and multistack networking including IPv4 and IPv6.（Linux 拥有现代化、功能完备的 UNIX 系统所应具备的全部特性：真正的多任务处理、虚拟存储器、共享库、按需加载、共享写时复制可执行文件、完善的内存管理，并且支持多协议栈网络，包括 IPv4 和 IPv6）
>
> It is distributed under the GNU General Public License v2 - see the accompanying COPYING file for more details.（Linux 在 GNU 通用公共许可证 v2 下进行分发——更多有关细节，请参阅随附的版权文件）
>
> 参见 Linux Kernel Organization. What is Linux?\[EB/OL]. \[2026-04-04]. <https://www.kernel.org/doc/html/latest/admin-guide/README.html>.

以下框架图可更清晰地展示 Linux 系统的层次结构：

![Linux 的狭义与广义](/files/GrFzGMaO26wbWiBI4p6x)

**核心系统工具层** 包含 GNU 基础工具（如 bash、gcc、glibc 等）、包管理器和初始化系统等组件。**GNU 基础工具** 是 GNU 项目开发的命令行工具和系统库，为操作系统提供基本功能。

Linux 的开发受 Minix 启发，后者是一种专用于教学的微内核操作系统，诞生于 UNIX 版权受限的背景之下。Linus Torvalds 时年 21 岁，就读于芬兰赫尔辛基大学计算机科学系。彼时芬兰大学体系中，学生入学后通常直接攻读硕士学位，本科仅为中间学位而非独立招生阶段，因此学制较为灵活；1991 年 Torvalds 仍处于学业的早期阶段。

GNU 与 Linux 的成功离不开 Minix 引发的社区讨论。1992 年，Andrew Stuart “Andy” Tanenbaum（Minix 作者）就内核架构与 Linus 展开激烈辩论，认为 Linux 的宏内核设计已然过时；Linus 则承认微内核在理论上更优，但从实用性角度为宏内核设计辩护。Linux 自始即采用宏内核架构，这场论战并未改变其架构选择，但使宏内核与微内核的优劣之争成为操作系统领域的经典议题。同一时期，Linus 原有的许可证禁止任何收费分发（包括收取介质成本），在社区请求与 GNU copyleft 兼容的推动下，Linus 于 Linux 0.12 版本将许可证更改为 GPL，并吸收 GNU 组件，逐步完善 Linux 的生态体系。

Linus Torvalds 的硕士毕业论文是 [《Linux: A Portable Operating System》](https://www.cs.helsinki.fi/u/kutvonen/index_files/linus.pdf)（Linux：一种可移植的操作系统），他在 1997 年（27 岁）获得理学硕士学位。由于赫尔辛基大学当时并无最长学习期限限制，他得以长期保留学籍。根据该校官网的说明，课程成绩的有效期为十年，但课程到期不会影响在大学继续学习的权利。官网明确指出：“课程到期不会影响在大学继续学习的权利。”（注：芬兰《大学法》（UNIVERSITIES ACT）规定了自 2005 年 8 月 1 日起，学位完成的目标时间和最长时间。）

> 我们探讨了在将 Linux 操作系统移植到多种 CPU 和总线架构时所暴露出的硬件可移植性问题。我们还讨论了软件接口的可移植性问题，尤其是与能够共享同一硬件平台的其他操作系统之间的二进制兼容性问题。文中描述了 Linux 所采取的方法，并对其中几个架构进行了更为详细的介绍。
>
> 论文摘要中文译文。

> **技巧**
>
> 几乎每颗英特尔处理器上的管理引擎（Intel Management Engine）都运行着基于 Minix 的微内核。自 ME 11（随 Skylake 处理器引入）起，Intel Management Engine 基于 Intel Quark x86 微控制器并运行 MINIX 3 操作系统。
>
> ~~或许基于 Minix 的微内核才是世界上最广泛部署的操作系统内核。~~

UNIX 标准 SUS 包含 POSIX 标准，前者是后者的超集。Single UNIX Specification 的基础卷是现有 POSIX.1 和 POSIX.2 规范的超集。Linux 实现了 POSIX 标准，但未获得 POSIX 认证：IEEE, The Open Group.

### 参考文献

* 杨天平，金如意.博洛尼亚进程述论\[J].华东师范大学学报(教育科学版),2009,27(01):9-22.DOI:10.16382/j.cnki.1000-5560.2009.01.007. 关于芬兰学制的发展。
* 芬兰. Universities Act (No. 558/2009, amendments up to No. 644/2016 included) \[Z]. 2009-07-24.
* The Open Group. The Base Specifications Issue 6, Preface\[EB/OL]. \[2026-04-23]. <https://pubs.opengroup.org/onlinepubs/009604299/frontmatter/preface.html>. 指出“These were selected since they were a superset of the existing POSIX.1 and POSIX.2 specifications and had some organizational aspects that would benefit the audience for the new revision.”
* Portnoy E, Eckersley P. Intel's Management Engine is a security hazard\[EB/OL]. (2017-05-08)\[2026-04-23]. <https://www.eff.org/deeplinks/2017/05/intels-management-engine-security-hazard-and-users-need-way-disable-it>.
* HandWiki. Intel Management Engine\[EB/OL]. \[2026-04-23]. <https://handwiki.org/wiki/Intel_Management_Engine>.
* jmcph4. Intel Management Engine\[EB/OL]. \[2026-04-23]. <https://jmcph4.dev/wiki/ime.html>.
* University of Helsinki. Expiry of Studies\[EB/OL]. (2026-02-16)\[2026-04-04]. <https://studies.helsinki.fi/instructions/article/expiry-studies>. 芬兰赫尔辛基大学官网的说明。
* POSIX Certification Policy\[EB/OL]. (2012-12-05)\[2026-04-04]. <http://get.posixcertified.ieee.org/docs/POSIX_Certification_Policy_v1.1.pdf>.
* Torvalds L. Linux: a Portable Operating System\[D/OL]. Helsinki: University of Helsinki, 1997 \[2026-04-04]. <https://www.cs.helsinki.fi/u/kutvonen/index_files/linus.pdf>. Linus 的论文。

## 狭义 Linux：操作系统内核

Linux 在不同语境下含义不同。狭义上，Linux 指 Linux 内核。[Linux kernel](https://www.kernel.org/) 项目始于 1991 年。

## 广义 Linux：GNU/Linux 操作系统

广义上，Linux 通常指完整的操作系统。GNU/Linux = Linux 内核 + GNU 等软件 + 包管理器。

[**Chimera Linux**](https://chimera-linux.org/) **除外。**

Linux 的全称为 GNU/Linux。

从 GNU 这一递归缩写（GNU's Not Unix，意为“GNU 不是 UNIX”）可以看出，Linux 与 UNIX 并无直接的源流关系。

具体而言：

* GNU/Linux 发行版 = Ubuntu、RHEL、Deepin、openSUSE……
  * Ubuntu = Linux kernel + apt/dpkg + GNOME（默认桌面环境）
  * openSUSE = Linux kernel + libzypp/rpm（包管理器后端，支持 RPM 格式）+ KDE（默认桌面环境之一）

> **思考题**
>
> 1. 如果去掉文件系统、Linux 内核、Shell、systemd（init）、桌面环境、包管理器以及所有第三方软件，一种 Linux 发行版还剩下哪些内容？
> 2. 在上述组件全部移除，并将其重新组合后，若仍将该系统称为“发行版”，它与传统 Linux 发行版相比存在哪些本质区别？
> 3. 在这种情况下，该系统是否仍然可以视为原来的发行版？请说明理由。
> 4. 如果不能视为原来的发行版，是在移除哪一类关键组件之后，其不再具备“发行版”的属性？
> 5. 如果仍然可以视为原来的发行版，那么哪些部分可以认为真正继承自原有发行版，依据是什么？

> **技巧**
>
> 如有疑虑，建议亲自安装 [Gentoo](https://www.gentoo.org/downloads/)（stage3）或 [Slackware](https://www.slackware.com/)，若仍存疑虑可亲自体验 [Gentoo (stage1)](https://wiki.gentoo.org/wiki/Stage_file) 或 [LFS](https://www.linuxfromscratch.org/lfs/)。
>
> 上述操作较为复杂，需要一定的经验与基础知识。~~又陷入了前理解循环。~~

## Linus 与 Linux 基金会

“Linux”商标的所有权属于 Linux 的创造者 Linus Torvalds 本人，但由 Linux 基金会代为管理。Linux 基金会是美国旧金山的一家非营利组织（**501(c)(6)**），组织形式类似中国的行业联盟或商业协会。

Linux 基金会的官方网站是 <https://www.linuxfoundation.org>。

501(c)(6) 是指美国《国内税收法典》（*Internal Revenue Code*, IRC）第 501 条第 (c)(6) 款，现将其与第 (c)(3) 款做比较如下表：

| 维度           | IRC §501(c)(3)                                                                  | IRC §501(c)(6)                                                |
| ------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| 法律依据         | 《美国国内税收法典》§501(c)(3)                                                            | 《美国国内税收法典》§501(c)(6)                                          |
| 法定组织类型       | 公司、信托、基金会、基金等                                                                   | 商业联盟、商会、房地产委员会、交易所协会、职业体育联盟                                   |
| 法定目的         | 必须“专门（exclusively）”用于宗教、慈善、科学、公共安全测试、文学、教育；或促进业余体育；或防止虐待儿童/动物                   | 不得以营利为目的（not organized for profit），用于促进一个或多个行业的共同商业利益，并改善商业条件 |
| 目的标准         | 虽写“exclusively”，司法解释为“主要目的测试（primary purpose test）”，不得“实质性（substantial）存在”非公益目的 | “主要用于促进行业共同商业利益”，行业自利性本身是合法目的组成部分                             |
| 利润分配限制       | 严格禁止任何净收益向私人股东或个人分配（private inurement absolute prohibition）                     | 同样禁止净收益向私人分配（但成员共享行业收益属于允许结构）                                 |
| 私人利益规则       | 严格 private benefit doctrine，仅允许附带性（incidental）私人利益                              | 允许成员获得行业性共同利益（mutual benefit 本身即制度目的）                         |
| 游说限制         | 仅允许非实质性游说；可选择 §501(h) 额度制；超限可能导致失去免税资格                                          | 可进行游说；但会费中用于游说部分不得税前扣除（§162(e)）                               |
| 政治活动         | 绝对禁止参与或干预任何选举政治（Johnson Amendment）                                              | 允许进行行业相关政治游说与倡议，但需遵守税务披露与费用拆分规则                               |
| 捐赠税务处理       | 符合条件的捐赠可抵扣（§170 慈善扣除）                                                           | 不属于慈善捐赠；通常作为商业费用扣除（§162），但游说部分不可扣除                            |
| UBIT（非相关业务税） | 适用（§511）                                                                        | 适用（§511）                                                      |
| 失格后果         | 免税资格撤销 + 可能追溯征税                                                                 | 免税资格撤销 + 转为一般公司税制                                             |
| 法律本质         | 公共利益补贴型实体（public benefit entity）                                                | 行业共同利益型实体（mutual benefit association）                         |
| 制度功能         | 国家通过税收补贴公共服务供给（教育、慈善、宗教等）                                                       | 为行业提供协调平台、降低交易成本、集中游说与政策表达                                    |

## UNIX-like 系统的概念界定

除获得正式 UNIX 认证的系统外，还有许多采用类似 UNIX 设计理念的操作系统。

UNIX-like 即类 UNIX，指基本符合 UNIX 标准，或基本遵守 POSIX 规范但未获得相应认证、商标使用权的操作系统。

该术语用于描述设计理念和技术实现上与 UNIX 高度相似但缺乏正式认证的系统。

当前主流操作系统中，许多遵循 POSIX 规范或采用类 UNIX 设计理念的操作系统可称为 UNIX-like，其典型代表包括 Linux 和各种 BSD 系统。

## 课后习题

1. 在现代 FreeBSD 环境中配置交叉编译工具链，构建并在 QEMU 中运行 4.4BSD-Lite2，记录交叉编译过程中遇到的工具链兼容性问题。
2. 查阅 SUS 与 POSIX 标准的正式文档，从系统调用接口、C 标准库函数和编译程序约定三个维度列举两者的异同。
3. 梳理 OpenRC 与 FreeBSD 原生 rc.d 框架在服务依赖解析机制上的差异。


# 1.4 什么是 FreeBSD

> 一群 PC 黑客坐下来，试图为 PC（个人电脑）编写一套 Unix 系统，其产物便是 Linux。
>
> 一群 Unix 黑客坐下来，试图将 Unix 系统移植到 PC（个人电脑）上，其产物便是 BSD。
>
> ——佚名

此处的黑客（hacker）指热心并精通于计算机编程和设计等方面的人员，而非利用系统安全漏洞对网络进行攻击破坏或窃取资料的人。

## 如何拼读 FreeBSD

FreeBSD 的正确读法是新用户普遍关注的问题。目前社区共识和普遍的读法是：/ˌfriːˌbiːɛsˈdiː/，即读作“Free（/friː/）+ B（/biː/）+ S（/ɛs/）+ D（/diː/）”，类似“福瑞/必/哎司/地”。

即先读 Free，再逐字母拼读 B、S、D。

通常不会将 BSD 或 FreeBSD 视为一个词语连读。不会读作“百思得”或“福瑞百思德”。~~FreeBSD 基金会在中国大陆注册商标的机构中文译名为“福瑞百思德基金会”。~~

## 什么是 FreeBSD？

FreeBSD 不是 Linux，也不是 UNIX 的克隆。FreeBSD 是一种自由软件，源代码公开且可自由使用、修改和分发。

![什么是 FreeBSD？](/files/h0Iep2sFYhmrumr9OTz3)

FreeBSD 一词由两部分构成，即“Free”和“BSD”。

```sh
FreeBSD 名称构成

FreeBSD = Free + BSD
           │      │
           │      └── Berkeley Software Distribution
           │           （伯克利软件发行版）
           │           源自加州大学伯克利分校 CSRG
           │
           └── 双重含义：
                · 自由（Liberty）—— BSD 许可证，自由使用/修改/分发
                · 免费（Gratis） —— 无需付费即可获取
```

BSD 最初由加州大学伯克利分校（University of California, Berkeley）的计算机系统研究小组（CSRG）开发，这一工作被命名为 `Berkeley Software Distribution`（伯克利软件发行版）。FreeBSD 等 BSD 系统都是计算机系统研究小组（CSRG）工作的延续。

Free 包含自由（Liberty）和免费（Gratis）两种含义。

FreeBSD 日为 6 月 19 日。FreeBSD 基金会和社区在这天庆祝 FreeBSD 的生日。

## 吉祥物

FreeBSD 或者说 BSD 家族吉祥物是 BSD Daemon（守护进程），名为“beastie”，发音接近“BSD”，如下图所示：

![beastie](/files/C5dTkR0DxDSmF17PgP5g)

此图出自源代码 **share/examples/BSD\_daemon/beastie.svg** 文件。

Beastie 身着运动鞋、手持草叉，表情愉悦。其三叉戟意味着进程的分叉（`fork()`）。

Daemon 出自希腊语“δαίμων”（代蒙），原指一种非善非恶，介于神人之间的实体。

> **思考题**
>
> 苏格拉底被控的罪证之一就是引入新神代蒙：
>
> > ἔχει δέ πως ὧδε· Σωκράτη φησὶν ἀδικεῖν τούς τε νέους διαφθείροντα καὶ θεοὺς οὓς ἡ πόλις νομίζει οὐ νομίζοντα, ἕτερα δὲ **δαιμόνια καινά**.(Plato, Apology 24b–c.）. 此处 δαιμόνια 是 δαίμων 名词化而来的中性复数形式。“起诉书大概是这样写的：它声称苏格拉底犯有不义之罪——他败坏青年，并且不承认城邦所承认的神，而承认新的神灵。（申辩篇）”
>
> > 其实类似的天命观表述在中国哲学中也可以找到，例如孔子的“天命”：子曰：“莫我知也夫！”子贡曰：“何为其莫知子也？”子曰：“不怨天，不尤人。下学而上达。知我者，其天乎！”（《论语·宪问》）子曰：“天生德于予，桓魋其如予何？”（《论语·述而》）苏格拉底的 δαιμόνιον 与孔子的天命虽处于不同文化传统，但都体现了一种思想：他们都不是简单意义上的人格神，而是某种超越个人经验的神圣秩序或召唤。
>
> 请读者思考：究竟是“愚公移山”，还是“山移愚公”。

根据作者要求（[Statement on the Use of the BSD Daemon Figure:](https://www.mckusick.com/beastie/mainpage/copyright.html)）标注版权信息如下：

```
    BSD Daemon Copyright 1988 by Marshall Kirk McKusick.
    All Rights Reserved.

    Permission to use the daemon may be obtained from:
	Marshall Kirk McKusick
	1614 Oxford St
	Berkeley, CA 94709-1608
	USA
    or via email at mckusick@mckusick.com
```

## UNIX 之船：FreeBSD 是不是 UNIX？

该问题远非表面所见那般清晰明确。诸多讨论者，甚至是那段岁月的亲历者，也难以给出明确回答或澄清。有观点认为，BSD 并未进行过任何 UNIX 认证，没有持有法律上的商标便简单定论；更有甚者只是笼统地说 FreeBSD 是 UNIX 的延续者与正统继承者，仅是“有实无名”；另有观点认为，BSD 之于 UNIX，正如 Linux 之于 UNIX。

上述回答存在分歧，原因在于该问题并非可简单套用法律商标归属或代码继承性来分析的纯粹技术性难题。其牵涉到深刻的本体论哲学问题：究竟是不能两次踏进同一条河流，还是一次也不能踏进同一条河流？如何回答此问题，反映着回答者的哲学观与科学技术观。

> > **忒修斯之船**
> >
> > 忒修斯和雅典青年安全返航所乘的是有三十支桨的大帆船，雅典人把这只船一直保存到德米特里·法勒琉斯的时代。他们一次又一次地拆掉了朽烂的旧船板，换上坚实的新船板。从此以后，这只船就成为哲学家们就事物的发展问题展开争论时经常援引的实例，一派认为它还是原来那只船，另一派争辩说它已不再是原来的船了。
>
> * Plutarch. 希腊罗马名人传\[M]. 黄宏煦，陆永庭，吴彭鹏，译. 北京：商务印书馆，1990：23.
>
> **思考题**
>
> 1. 如果这艘船替换了若干组件，这艘船是不是忒修斯之船？
> 2. 如果有一天，这艘船原有的所有组件都被完全替换了一遍，这艘船还是不是忒修斯之船？
> 3. 如果将所有替换下来的组件拼凑起来，组成一艘新船，这艘船是不是忒修斯之船？

BSD 操作系统并非复刻品，而是 AT\&T Research Unix 操作系统的开源衍生版本，与现代 UNIX® System V 同为 UNIX 的两大主要分支。在 4.4BSD 以前，BSD 全称为 BSD UNIX。

![UNIX 之船：FreeBSD 是不是 UNIX？](/files/68HA0zcIALHlIazAl0Jk)

最初，UNIX 是 AT\&T 开发的操作系统。20 世纪 80 年代初，加州大学伯克利分校的计算机系统研究小组（CSRG）正式成立，开始深入研究 UNIX，并为其开发了大量用户空间的程序，形成了新系统 BSD（Berkeley Software Distribution, 伯克利软件发行版）。随着时间推移，BSD 系统逐渐发展，加入了许多创新，例如实现了 TCP/IP 协议栈。至 20 世纪 90 年代初，CSRG 开始重新实现 AT\&T 专有代码，于 1991 年发布了 Networking Release 2（Net/2）。然而，Net/2 中仍残留少量 AT\&T 代码，成为日后 USL 诉讼的导火索。1992 年，William Jolitz 与 Lynne Jolitz 夫妇将 Net/2 移植到 Intel i386 平台，形成 386BSD。1993 年，FreeBSD 和 NetBSD 相继从 386BSD 分支诞生。1994 年 USL 诉讼和解后发布的 4.4BSD-Lite 彻底移除了所有 AT\&T 代码，FreeBSD 2.0（1994 年 11 月）与 NetBSD 后续版本相继整合 4.4BSD-Lite 代码。此后，BSD 系统进一步分裂：1995 年 OpenBSD 从 NetBSD 中复刻出来，2003 年 DragonFly BSD 从 FreeBSD 中复刻出来。

如果查阅 FreeBSD 的源代码，还会看到早期开发者在 1982 年留下的注释和版权声明：

```c
/*-
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * Copyright (c) 1982, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.

 ……以下省略许可证原文……

 */
```

上面这段版权声明出自源代码文件 **sys/sys/\_timespec.h**。

> **思考题**
>
> 如何理解 FreeBSD 与 UNIX 的关系？

## 参考文献

* Marshall Kirk McKusick. History of the BSD Daemon\[EB/OL]. \[2026-06-01]. <https://www.mckusick.com/beastie/index.html>. 此页面说明了 BSD Daemon 的历史。
* M.D.Fuller, BSD For Linux Users\[EB/OL]. \[2026-06-01]. <https://www.over-yonder.net/~fullermd/rants/bsd4linux/01>. 文章转述了“Linux is what you get when a bunch of PC hackers sit down and try to write a Unix system for the PC. BSD is what you get when a bunch of Unix hackers sit down to try to port a Unix system to the PC.”这一名言。
* FreeBSD Foundation. Join us to celebrate FreeBSD Day!\[EB/OL]. \[2026-03-26]. <https://freebsdfoundation.org/freebsd-day/>.
* Identity Over Time\[EB/OL]. \[2026-03-26]. <https://plato.stanford.edu/entries/identity-time>. SEP 条目：跨时间的同一性。
* Sorites Paradox\[EB/OL]. \[2026-03-26]. <https://plato.stanford.edu/entries/sorites-paradox/>. SEP 条目：沙堆问题、秃头问题。

## 课后习题

1. 观看纪录片《操作系统革命》（Moore J T S, 导演. 操作系统革命\[V]. 美国: Seventh Art Releasing, 2002.），结合影片内容与本章所述 UNIX/BSD 历史，分析开源运动对传统软件商业模式的冲击。


# 2.1 FreeBSD：理想、现实与中道

## 谁在使用 FreeBSD

以下是一些典型的应用案例。

![谁在使用 FreeBSD](/files/WZsDLeT5K7jDXEVW7cbF)

图片来源 [FreeBSD 基金会宣传图](https://i.imgur.com/qW0IePB.png)。

* 华纳兄弟. 黑客帝国\[EB/OL]. \[2026-03-26]. <https://movie.douban.com/subject/1291843/>. 黑客帝国的特效正是在一组 FreeBSD 集群上制作的。另见 Urban M, Tiemann B. FreeBSD 技术内幕\[M]. 智慧东方工作室，译. 北京：机械工业出版社，2002：2. ISBN: 978-7-111-10201-4、FreeBSD Project. FreeBSD Press Release: April 22, 1999\[EB/OL]. (1999-04-22)\[2026-03-26]. <https://www.freebsd.org/press/press-rel-1/>.
* The New Stack. Apple’s Open Source Roots: The BSD Heritage Behind macOS and iOS\[EB/OL]. \[2026-03-26]. <https://thenewstack.io/apples-open-source-roots-the-bsd-heritage-behind-macos-and-ios/>. Apple 的操作系统如 macOS、iOS 等大量复用了 BSD（不限于 FreeBSD）的技术栈。BSD 堪称 macOS 的开源基石。
* Sony. FreeBSD Kernel\[EB/OL]. \[2026-03-26]. <https://www.playstation.com/en-us/oss/ps4/freebsd-kernel/>. 索尼（Sony）的游戏机 PlayStation 4（PS4）和 PlayStation 5（PS5）使用的操作系统基于 FreeBSD。PlayStation 3（PS3）的 CellOS 和 PlayStation Vita（PSV）的操作系统也以 FreeBSD 和 NetBSD 为基础构建。
* FreeBSD Foundation. Netflix Case Study\[EB/OL]. \[2026-03-26]. <https://freebsdfoundation.org/netflix-case-study/>. 奈飞（Netflix）几乎所有网络活动（内容缓存/CDN）均基于 FreeBSD 设备运行。
* QNX. Search Results\[EB/OL]. \[2026-03-26]. <https://www.qnx.com/developers/docs/8.0/search.html?searchQuery=freebsd>. QNX 操作系统。QNX 是一种微内核实时操作系统（RTOS），其内核为自主研发，并非基于 FreeBSD。QNX 以前是黑莓手机的操作系统。QNX 现在被广泛应用为汽车安全操作系统——在主流座舱架构中，QNX Hypervisor 负责安全关键域（如仪表盘、ADAS），同时将 Android Automotive 作为客户操作系统在虚拟机中运行，以实现信息娱乐功能（参见：BlackBerry QNX. QNX Hypervisor 8.0\[EB/OL]. \[2026-04-17]. <https://blackberry.qnx.com/en/products/foundation-software/qnx-hypervisor>）。国内新能源车辆广泛采用了 QNX 操作系统，QNX 在汽车安全关键系统中占据重要市场份额。QNX 在其新一代网络栈 io-sock（QNX 8.0 起）及部分用户空间组件中复用了 FreeBSD 的代码（旧版网络栈 io-pkt 复用的是 NetBSD 代码）。
* Dell. PowerScale OneFS：了解基于源的路由\[EB/OL]. (2024-05-28)\[2026-03-26]. <https://www.dell.com/support/kbdoc/zh-cn/000020056/isilon-onefs-understanding-source-based-routing-sbr-in-isilon?lang=zh>. Dell EMC Isilon，戴尔的 Isilon（面向企业的 NAS 存储设备）设备使用的操作系统 OneFS 基于 FreeBSD（OneFS 8.2 基于 FreeBSD 11；OneFS 9.x 的 FreeBSD 底层版本未公开）。
* Beckhoff. TwinCAT/BSD: operating system for Industrial PCs\[EB/OL]. \[2026-03-26]. <https://www.beckhoff.com/en-en/products/ipc/software-and-tools/twincat-bsd/>. Beckhoff 倍福自动化控制系统的操作系统 TwinCAT/BSD，将 TwinCAT 实时核与 FreeBSD 结合，应用于工业 PC 平台。
* OpenHarmony. kernel\_liteos\_a\[EB/OL]. \[2026-03-26]. <https://gitee.com/openharmony/kernel_liteos_a/tree/master>. OpenHarmony LiteOS 内核引入了 FreeBSD 代码用于驱动程序等。

### 参考文献

* FreeBSD Foundation. Read how organisations are using FreeBSD across the globe\[EB/OL]. \[2026-03-25]. <https://freebsdfoundation.org/end-user-stories/>. FreeBSD 基金会官方整理的 FreeBSD 各领域典型应用案例汇总。

## 为什么选择 FreeBSD

### 核心缘由：FreeBSD 能在这流变的世界中寻求理想的中道

相较于大多数主流操作系统或内核，FreeBSD 在 STABLE 分支内保持 ABI 稳定，内核 API 则不保证跨版本兼容。

FreeBSD 项目整体风格偏于保守，奉行最小惊讶原则（Principle of Least Astonishment，POLA），即设计必须符合用户的习惯、期望和心智能力。其配置文件和系统组件不会频繁变化，大版本间迁移尤为审慎。FreeBSD 也谨慎对待破坏性变更（Breaking change），要求在大版本内保持 ABI 稳定。

FreeBSD 不仅在生命周期内保持稳定，大版本更新也具有连贯性和稳定性，可便捷实现大版本间的迁移。FreeBSD 上的软件版本可以滚动更新，不会锁定特定版本（如 Python 等）。

### 选择 FreeBSD 的一般原因

* 追求软件的稳定性与新颖性，既需具备二进制包，又需支持编译安装。除 FreeBSD 外，鲜有开源系统兼具上述特征（~~Void Linux 还是算了吧~~）。
* BSD 赋予了更纯粹的自由：不以限制自由来保障自由，而以信任与开放成就真正的自由。
* FreeBSD 是学院派工程实践的成果，也是 UNIX 哲学的现代延续。
* 其他操作系统生态愈发碎片化，而 FreeBSD 的一体化设计避免了持续的选择困境，但这并非限制，亦可按需自由修改。
* BSD 是一款完整的操作系统，而非单纯的内核。内核和基本系统作为一个项目整体维护。缺乏基本系统的概念，将带来持续的混乱与有悖直觉的使用体验。
* FreeBSD 完全 BSD 化，基本系统除第三方项目外，不含任何 GPL 代码。
* 统一而一致的中央存储库，而非独立的内核项目。
* 便于读者学习操作系统相关课程：以往大多数操作系统课程实际上是“内核原理与实践”，**并非** 真正的“操作系统”课程。
* FreeBSD 项目由核心小组领导。
* FreeBSD 社区与开发者均秉持“慢就是快，快就是慢”的哲学理念。~~我们的确需要花些时间慢下来，审视自己的一切，无论知识还是自我。花些时间在路旁的花朵石子上面，也许并不是浪费时间，无所事事。~~
* 教育与研究：FreeBSD 项目将内核与用户空间整合在同一代码仓库中，极大便利了研究与学习，且代码注释清晰丰富，便于查阅特定功能的实现方式。

> **技巧**
>
> 还可以从更多视角审视选择 FreeBSD 的原因：
>
> * 从佛法来说，因为缘分。万物缘起性空，有缘相聚，会者定离。万般诸相皆如此。
> * 从基督教来讲，这是主的指引。上帝在永恒的现在中创世。就像《出埃及记》一样，看上去是自己的选择，实际上都是主的安排。
> * 从黑格尔来讲，由于辩证否定。FreeBSD 是 UNIX 的直接后裔，而很多协议又脱胎于 UNIX，所以注定了要来到这里。

### 选择 FreeBSD 的技术原因

* FreeBSD 基本系统的配置文件与第三方软件配置文件相分离，系统级配置文件与用户配置文件相分离。FreeBSD 的文件系统层次结构遵循明确的组织原则。~~再也不用到处用 `find` 命令查找某个 `.conf` 文件到底安装在哪了。~~

```sh
FreeBSD 文件系统层次结构

/ (根目录)
├── /etc/          ← 基本系统配置文件
│   ├── rc.conf        系统级配置
│   ├── sysctl.conf    内核参数
│   └── ...
├── /usr/
│   ├── /usr/local/ ← 第三方软件（Ports/Pkg）
│   │   ├── etc/        第三方软件配置
│   │   ├── bin/        第三方可执行文件
│   │   └── ...
│   └── /usr/src/   ← 系统源代码（可选）
├── /home/         ← 用户主目录（用户级配置）
└── /var/          ← 日志、缓存等可变数据

系统配置与第三方配置严格分离，互不干扰
```

* 由于基本系统的存在，第三方的软件几乎不影响系统的稳定性。FreeBSD 在软件更新和系统稳定之间保持了平衡。
* 基本系统完全 BSD 化，不含有任何 GPL 代码。注：仅 **sys/contrib** 第三方软件包含有少量 GPL 2.0 许可代码，但无任何 GPL 3.0 许可代码。
* 通过 BSD 的 Ports 可以编译安装软件，自由配置。
* 不会锁定软件版本。例如 Python、GCC 等常见的系统依赖软件。但所有的 FreeBSD 都共用相同的 Ports，无论新旧系统，其第三方软件的版本都是相同的；仅极个别软件和系统版本硬捆绑，其余所有软件都可滚动更新。
* 由于 Ports 系统的存在，旧版 FreeBSD 系统仍能正常获取并编译软件，并非在达到生命周期终点（EoL）后便无法获得软件更新。
* 在 FreeBSD 项目中，文档并非附属品。FreeBSD doc 项目与 src 项目地位同等，无主次之分。
* 可便捷地为根分区（**/**）配置使用 ZFS 文件系统。ZFS 被公认为功能最为完备的文件系统之一。
* 每 2 年一次的大版本发布周期和 4 年的维护周期（自 FreeBSD 15 起由原有的 5 年调整为 4 年）保障了 FreeBSD 的稳定性。
* Jail 不需要额外安装和维护底层虚拟化栈，也无需为每个实例启动完整的操作系统内核和用户空间，节省系统资源；bhyve 虚拟化同样内置于基本系统，但作为虚拟机管理程序，每个实例需运行完整的客户操作系统。
* 传统的 BSD init 引导，回归简洁，回归纯文本的可见性。
* DTrace 框架与 GEOM 存储框架。
* Linux 二进制兼容层可运行 Linux 软件，系统调用密集型工作负载下存在少量性能开销，计算密集型任务则接近原生性能。
* FreeBSD 的驱动以内核模块形式存在，可动态加载和卸载，便于按需管理硬件。
* FreeBSD 秉持人人自由开发的理念，可以直接在 GitHub 上[提交代码](https://github.com/freebsd/freebsd-src/pulls)，或者注册账号在 <https://reviews.freebsd.org/> 提交大规模变更。
* FreeBSD 的代码风格是 BSD KNF（Kernel Normal Form），基于 CSRG 的 KNF 规范，其大括号布局是 K\&R 风格的一种变体（函数左大括号独占一行，控制语句左大括号与语句同行），与 Kernighan & Ritchie 经典著作《The C Programming Language》（中译本：Kernighan B W, Ritchie D M. C 程序设计语言\[M]. 徐宝文，李志，译. 第 2 版. 北京：机械工业出版社，2019. ISBN: 978-7-111-61794-5.）中使用的 K\&R 风格一致。

#### 参考文献

* FreeBSD Foundation. Submitting GitHub Pull Requests to FreeBSD\[EB/OL]. \[2026-03-25]. <https://freebsdfoundation.org/our-work/journal/browser-based-edition/configuration-management-2/submitting-github-pull-requests-to-freebsd/>. 详解 FreeBSD 通过 GitHub 接受贡献的流程与规范。
* FreeBSD Project. Contribution Guidelines for GitHub\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/blob/main/CONTRIBUTING.md>. FreeBSD 源代码贡献的官方指导与要求。
* Linux Kernel Documentation. Linus Torvalds 是决定改动能否进入 Linux 内核的最终裁决者\[EB/OL]. \[2026-03-25]. <https://www.kernel.org/doc/html/latest/translations/zh_CN/process/submitting-patches.html>. 展示 Linux 内核开发的集中式决策模式。
* Linux Kernel Documentation. Linux 内核编码风格\[EB/OL]. \[2026-03-25]. <https://www.kernel.org/doc/html/latest/process/coding-style.html>. 规范 Linux 内核代码风格与格式要求。
* Linux Kernel Documentation. Linux 内核开发是个较为封闭的过程\[EB/OL]. \[2026-03-25]. <https://www.kernel.org/doc/html/latest/process/submitting-patches.html>. 说明 Linux 内核开发的参与门槛与流程。
* Cdaemon. Sandbox Your Program Using FreeBSD's Capsicum\[EB/OL]. \[2026-03-25]. <https://cdaemon.com/posts/capsicum>. FreeBSD 安全沙盒框架的基本原理与使用方法。

### 选择 FreeBSD 的社会意义

#### 红帽公司影响下的 Linux 生态偏向

GNOME、Xorg（X11）、D-Bus、systemd、PulseAudio、Wayland、PipeWire 等主流 Linux 项目实际上受到红帽公司（Red Hat）的显著影响，且大多难以完全适配其他类 UNIX 操作系统。

目前 FreeBSD 桌面部件缺失，在较大程度上源自对 Linux 特有函数库的强依赖，例如包含 `ip` 命令的 `iproute2` 软件包。更为重要的原因在于这些桌面或部件与 systemd 存在深度捆绑或强制依赖关系，例如 `NetworkManager`。而 Samba 等项目的开发以 Linux 为中心，对非 Linux 平台的兼容性关注不足。FreeBSD 社区将此类现象称为“Linuxism”（Linux 主义/Linux 歧视）。

这种行为将导致何种后果尚不得而知，但此类程序正变得越来越多，并有成为主流的趋势。许多开发者开发程序（如 `todesk`）时也不再考虑对传统 init 系统的兼容。Java 程序也逐渐丧失了可移植性；由于此类捆绑问题，FreeBSD 上的 Eclipse 更新曾长期滞后。如果此趋势持续，可运行在 Linux 上的程序的可移植性可能进一步降低。

目前 FreeBSD 所面临的困境，未来其他系统也可能会遇到。

* 选择 FreeBSD，即选择保留自由软件的根基。
* 选择 FreeBSD，即选择保留一份真正自由的操作系统。能够使开源事业持续发展，并践行真正的 UNIX 哲学。

**参考文献**

* D'Pong P. Bug 562443 - SWT spams temp folder with innumerable folders\[EB/OL]. (2020-05-26)\[2026-04-05]. <https://gitlab.simantics.org/simantics/eclipse/eclipse.platform.swt/-/commit/19153b908d6d4cedcbd59824686717502cfde4f7>.
* FreshPorts. java/eclipse\[EB/OL]. \[2026-06-06]. <https://www.freshports.org/java/eclipse/>. 截至 2026 年，Port **java/eclipse** 已恢复活跃维护
* FreeBSD Forums. Are Linuxisms impossible to overcome when porting?\[EB/OL]. \[2026-06-07]. <https://forums.freebsd.org/threads/are-linuxisms-impossible-to-overcome-when-porting.45805/>.

#### FreeBSD 基金会重大捐赠事件

> 上周，我向 FreeBSD 基金会捐赠了 100 万美元，FreeBSD 基金会支持着开源操作系统 FreeBSD。FreeBSD 帮助了数百万程序员追随他们的热情、实现创意。我自己就是受益者。在 90 年代末，我开始使用 FreeBSD，那时我经济拮据，住在政府提供的住房中。在某种程度上，FreeBSD 帮助我摆脱了贫困——我能进入 Yahoo!（雅虎）工作的重要原因是他们使用 FreeBSD，而这正是我首选的操作系统。多年后，当 Brian 和我开始创建 WhatsApp 时，我们依然使用 FreeBSD 来支撑我们的服务器运营，直到今天也是如此。
>
> 我发布这项捐赠的消息，是希望让更多人看到 FreeBSD 基金会所做的有益工作，并激励他人也能支持 FreeBSD。我们大家都会受益，如果 FreeBSD 能够继续为像我一样的人提供机会，帮助更多的移民子女脱贫，帮助更多的初创公司取得成功，甚至是具有变革性的成果。
>
> ——WhatsApp 原 CEO 及创始人 Jan Koum（FreeBSD Foundation. Updated! – FreeBSD Foundation Announces Generous Donation and Fundraising Milestone\[EB/OL]. (2014-11-17)\[2026-04-05]. <https://freebsdfoundation.org/blog/updated-freebsd-foundation-announces-generous-donation-and-fundraising-milestone/>.）

#### 诚实与可信

像 FreeBSD 这样在后台静默运行以至于鲜为用户所察觉的系统，堪称久经考验。如果每日不时出现蓝屏报错、内核恐慌（Kernel Panic）抑或“内部错误”、`You are in emergency mode`、`BusyBox (initramfs)`、`grub rescue>` 等，反而能提醒用户该系统的存在。

目前，部分将 Linux 用作专用设备操作系统，或基于其他 GPL 软件构建商业产品的公司，并未严格遵守 GPL 协议发布其修改后的代码。部分国内企业对 GPL 的含义认识不足，仅将“免费”视为唯一考量。那些为规避 GPL 强制开源规定而采取规避措施的企业产品，其合规性与技术可信度均存疑。抢注开源软件商标的现象亦不鲜见。相较而言，采用 FreeBSD 的公司在许可证合规方面更为规范、可靠，也切实推动了 BSD 代码的广泛复用。纵然有人认为 FreeBSD 已趋衰落，事实上，大量用户可能始终受益于 FreeBSD 技术的支撑。

**参考文献**

* 王波. FreeBSD 在中国的未来\[M]//王波. FreeBSD 使用大全. 第 2 版. 北京: 机械工业出版社, 2002: 前言. ISBN: 978-7-111-10286-1. 探讨了 FreeBSD 在中国的发展前景与应用前景。

## FreeBSD 当前的技术局限性

FreeBSD 具有诸多优势，但也面临着现实的挑战。

* 大型技术企业对 FreeBSD 支持不足，如 GitHub Actions 需通过第三方工具（如 `vmactions/freebsd-vm`）实现 CI/CD，NVIDIA CUDA 也未予支持，在 AI 与 LLM 时代存在滞后。
* FreeBSD 项目缺乏对欧洲和北美以外地区的关注与投入。
* 相比其他开源项目中“仁慈的终身独裁者”模式，集体领导在 FreeBSD 项目中并未显现出明显优势，有时甚至可能导致责任分散、效率低下的问题（即“集体行动困境”）。部分分管 FreeBSD 子项目的核心成员对项目本身的了解和关注尚有不足，面对若干问题亦难以有效决策和承担责任。
* FreeBSD 项目整体风格偏于保守，新技术的引入往往需要数年，跨越多个大版本方能完成。通常需等待已有技术轮替一到两代后才会引入；引入后亦往往缺乏后续关注与维护开发。
* FreeBSD 系统在部分方面尚欠现代化，缺少某些当代操作系统常见的特性。尤其是在嵌入式方面仍有较大提升空间。
* FreeBSD 未在基本系统中提供预配置的桌面环境。
* FreeBSD 的硬件驱动支持相对有限。
* 关于 FreeBSD 的学习资料相对较少。
* FreeBSD 的开发者数量较少，且对外部贡献者的反馈往往不及时。
* FreeBSD 基金会、期刊、Bug 报告系统等对外部贡献者的反馈也常有不及时的情况。
* FreeBSD 文档项目曾停滞多年，个人贡献者除季度报告外的提交事实上很难被接纳；src 和 Ports 项目也同样难以接纳新的个人贡献者。
* 尚未完全支持安全启动（Secure Boot），需通过手动签名 EFI 二进制文件实现。
* 对 TPM 的支持有限。
* 由于部分软件对 Linux 特有特性存在依赖（Linuxism），导致若干软件无法直接移植。
* FreeBSD 支持的两款主要文件系统 ZFS 与 UFS，其存储空间通常只能扩大，难以直接缩小（ZFS 自 FreeBSD 13.0 起可通过 `zpool remove` 移除镜像或非冗余顶级 vdev，但无法移除 raidz vdev，且需满足 `device_removal` 特性标志已启用的条件；UFS 则不支持缩小）
* FreeBSD 在面向最终用户的上层应用生态方面有所欠缺，虚拟化技术 bhyve 也有待改进。

### 参考文献

* FreeBSD Foundation. FreeBSD UEFI Secure Boot\[EB/OL]. \[2026-06-06]. <https://freebsdfoundation.org/freebsd-uefi-secure-boot/>.
* OpenZFS. zpool-remove(8)\[EB/OL]. \[2026-06-07]. <https://openzfs.github.io/openzfs-docs/man/v2.2/8/zpool-remove.8.html>. 可通过 zpool remove 移除镜像或非冗余顶级 vdev，但无法移除 raidz vdev

## 课后习题

1. 观察四周，分析你身边哪些产品是基于 FreeBSD 操作系统构建的。


# 2.2 关于 FreeBSD 项目

## FreeBSD 项目宗旨

FreeBSD 项目的宗旨是：使 FreeBSD 的代码得到最广泛的利用，让所有人，无论其目的为何，都能从中受益。这一宗旨可概括为“只求我为人人，不求人人为我”的开放共享理念。

FreeBSD 项目的源代码中包含部分受 GNU 通用公共许可证（GPL）和 GNU 宽通用公共许可证（LGPL）许可的软件，项目正在持续努力降低其所占比重。尽管这些许可证要求开源而非闭源，但它们仍带来一定的法律挑战和额外复杂性。为充分实现 FreeBSD 的宗旨，即尽可能提供无附加条件的软件以降低商业使用中的复杂性，FreeBSD 项目在可能的情况下更倾向于采用限制更少的 BSD 许可证。

> **思考题**
>
> > BSD 2 条款许可证摘录：“在满足以下条件的前提下，允许在源代码和二进制形式中 **重新分发** 和使用本软件，无论是否经过修改”
> >
> > “你可以继续从上游获取 BSD 授权的原始源代码，但如果你使用了基于原 BSD 衍生代码但以 GPL 再授权的版本，则仍需遵循 GPL。这形成了一条从 BSD 到 GPL 的单向通道：一旦 BSD 源代码被并入 GPL 项目，就如同进入了‘黑洞’，即 **BSD 代码的 GPL 化** 是不可逆的。BSD 世界逐渐被 GPL 蚕食。但事实上，BSD 代码在开源和闭源世界都得到了最大程度的复用。”
>
> 1. 除了可以将 BSD 许可的软件转为专有软件外，还能怎样理解这种“重新分发”？在满足条件（主要是一些免责和版权声明）后，能以何种许可证再分发和重许可？
> 2. 为什么自由软件基金会称 BSD 2 条款许可证和 GPLv2/GPLv3 兼容？如果 BSD 许可的软件 A 进入 GPLv2 项目 B 中成为其一部分。下游用户再分发时，在何种条件下，要求软件 A 也遵守 GPLv2 而非通过 BSD 协议转为专有软件？为什么？
> 3. 站在许可证的感染性角度，再理解 Linux kernel 的 GNU 化以及 FreeBSD 基本系统的去 GNU 化。
> 4. 怎样理解这种代码复用目的的成功达成？

## FreeBSD 治理结构

FreeBSD 的治理结构包含存储库、基金会、社区、提交者和核心小组等。

![FreeBSD 治理结构](/files/MDMy5wskVBCEtCZVAbOz)

### 源代码存储库

FreeBSD 项目历史悠久，其版本控制工具历经 CVS、SVN、Git。多年来，FreeBSD 的中央源代码树由 CVS（Concurrent Versions System）维护。CVS 是一款自由软件，提供源代码控制功能。随着源代码树的快速扩张和已存储历史记录的大量增加，CVS 的技术局限性日益明显，各存储库的迁移时间线如下：

| 时间          | 存储库   | 事件                            |
| ----------- | ----- | ----------------------------- |
| 2008 年 5 月  | src   | 从 CVS 迁移至 SVN                 |
| 2012 年 5 月  | doc   | 从 CVS 迁移至 SVN                 |
| 2012 年 7 月  | Ports | 从 CVS 迁移至 SVN（CVS 与 SVN 双轨运行） |
| 2013 年 2 月  | Ports | 正式关闭 CVS 访问                   |
| 2020 年 12 月 | src   | 迁移至 Git                       |
| 2020 年 12 月 | doc   | 迁移至 Git                       |
| 2021 年 4 月  | Ports | 迁移至 Git                       |

目前使用 Git 进行协作开发。

FreeBSD 项目的存储库分为三个：freebsd-src（源代码）、freebsd-ports（Ports 软件移植）、freebsd-doc（文档）。三个项目地位平等。

### FreeBSD 基金会

FreeBSD 基金会是美国科罗拉多州博尔德的一家非营利机构（**501(c)(3)**），致力于在全球范围内支持和推广 FreeBSD 项目及社区。基金会通过项目资助为软件开发提供资金，并配备专职人员及时应对紧急问题、实现新功能。基金会购买硬件以改善和维护 FreeBSD 基础设施，资助人员以提高测试覆盖率、持续集成和自动化水平。基金会通过在全球技术会议和活动中推广 FreeBSD 来进行宣传。基金会还提供研讨会、教育材料和演示，以招募更多用户和贡献者加入 FreeBSD。此外，基金会还代表 FreeBSD 项目执行合同、许可协议及其他需要认可法律实体的法律安排。基金会的所有权力集中在董事会，董事由现有董事会成员选举产生（新董事仅限现任董事提名），任期由章程规定。

FreeBSD 基金会还负责 FreeBSD 项目的合规认证及标准化，如实现软件物料清单（SBOM）、满足欧盟的网络弹性法案（Cyber Resilience Act）等。

在大部分国家，FreeBSD 商标由 FreeBSD 基金会持有。

### FreeBSD 社区

FreeBSD 项目通过网络进行远程开发。

FreeBSD 社区由来自世界各地的开发者和用户组成。FreeBSD 社区并非法律实体，也无固定办事处。FreeBSD 社区不仅是英文社区，还有中文、俄语、韩语、日语等社区。

### 提交者

提交者是指拥有直接写入 FreeBSD 存储库权限的人员。要成为提交者，需要通过导师机制，必须由已有提交者推荐。为了防范潜在的安全风险，提交者并非终身制，各存储库的非活跃期限如下：

| 存储库           | 非活跃期限        |
| ------------- | ------------ |
| freebsd-src   | 18 个月内至少一次提交 |
| freebsd-doc   | 18 个月内至少一次提交 |
| freebsd-ports | 12 个月内至少一次提交 |

非活跃提交者的权限将被暂停，但可以申请恢复。

### FreeBSD 核心小组

FreeBSD 核心小组是 FreeBSD 项目的最高领导机构，按章程由 9 名成员组成，采取集体领导制度，每位成员分管不同的子项目。FreeBSD 核心小组负责授予或撤销提交者权限及账户、执行行为准则（CoC）、管理项目子团队等。

FreeBSD 核心小组选举每两年举行一次，成员可以连选连任。只有在过去 12 个月内有过提交的提交者（视为活跃提交者）才拥有选举权和被选举权。

历史上，核心小组从未出现全体轮替的情况，一位核心小组成员在实践中通常会连任两届或更多届。核心小组成员和 FreeBSD 董事会成员往往存在交叉任职的情况。

FreeBSD 核心小组成员并不直接从中获取任何利益，均为志愿者。有些成员可能会接受 FreeBSD 基金会的雇佣或赞助来参与特定项目的开发。

## 课后习题

1. 分析 FreeBSD 的提交者（Committer）机制与核心小组选举制度，选取另一个开源项目（如 Linux 内核或 OpenBSD），从治理结构、代码审查流程和决策机制三个维度展开比较。


# 2.3 FreeBSD 开发模型

FreeBSD 的版本发布遵循：从 CURRENT（main 分支）分出 STABLE 分支后，在 STABLE 分支上依次经历 ALPHA → BETA → RC → RELEASE 的迭代周期，STABLE 分支的 ABI 则保持固定，各有明确的适用场景。

## FreeBSD 版本概述

FreeBSD 的版本管理体系包含两个开发分支（CURRENT 与 STABLE）和四个版本阶段（ALPHA → BETA → RC → RELEASE），其中 ALPHA 为 STABLE 分支创建后的预发布快照。

具体流程：CURRENT → 分出 STABLE 分支 → ALPHA → BETA → RC → RELEASE。

RELEASE 版本经过完整的 BETA→RC 测试周期，发布后仅接受安全与稳定性修复，适用于生产环境。

![FreeBSD 版本更迭](/files/MtjJxqYnOB2LSg3IdKnD)

> **注意**
>
> 该图展示的版本更迭关系较为简化，实际流程中 X.0-RELEASE 来自 X-STABLE 分支，而 X-STABLE 由 main 分支（即 X.CURRENT）分出。

> **注意**
>
> `freebsd-update` 命令仅适用于 ALPHA、BETA、RC 和 RELEASE 版本；其余版本（如 CURRENT、STABLE 的非发布快照）需通过源代码编译或使用二进制的 PkgBase 更新。

## CURRENT 分支

FreeBSD-CURRENT 是 FreeBSD 最前沿的源代码，包含正在进行的工作、实验性变更和可能出现在下一个正式版本中的过渡机制。虽然许多 FreeBSD 开发人员每天都会编译 FreeBSD-CURRENT 的源代码，但有时会出现源代码无法编译的情况。这些问题会尽快得到解决，但 FreeBSD-CURRENT 所带来的究竟是灾难还是新功能，取决于同步的源代码版本。

FreeBSD-CURRENT 主要面向三个兴趣群体：

* 积极参与某部分源代码树的 FreeBSD 社区成员。
* 积极的测试者，他们愿意花时间解决问题，提出关于变更和 FreeBSD 整体方向的建议，并提交补丁。
* 想要关注 FreeBSD 状态，使用当前源代码作为参考，或偶尔发表评论或贡献代码的用户。

预发布功能尚未经过充分测试，且很可能存在缺陷，FreeBSD-CURRENT 不应视为提前获取新功能的捷径。其他提交同样有可能引入新缺陷，而不是修复既有缺陷，因此它也不是获取缺陷修复的捷径。FreeBSD-CURRENT 并未得到“正式支持”。

使用 -CURRENT 的用户应跟踪 FreeBSD-CURRENT：

1. 加入 [FreeBSD-CURRENT 邮件列表](https://lists.freebsd.org/subscription/freebsd-current) 和 [源代码仓库主分支提交信息列表](https://lists.freebsd.org/subscription/dev-commits-src-main)。这是 **必需** 的，以便了解人们对系统当前状态的评论，并接收有关 FreeBSD-CURRENT 当前状态的重要公告。[源代码仓库主分支提交信息列表](https://lists.freebsd.org/subscription/dev-commits-src-main) 会记录每个变更的提交日志条目，以及关于可能副作用的相关信息。

   要加入这些列表，请访问 [FreeBSD 列表服务器](https://lists.freebsd.org/)，点击要订阅的列表，并按照说明进行操作。如果要跟踪整个源代码树的变更，而不仅是 FreeBSD-CURRENT 的变更，订阅 [所有分支的源代码仓库提交信息列表](https://lists.freebsd.org/subscription/dev-commits-src-all)。
2. 与 FreeBSD-CURRENT 源代码同步。通常使用 git 从 FreeBSD Git 仓库的 `main` 分支检出 -CURRENT 代码。
3. 由于仓库体积较大，有些用户选择仅同步他们感兴趣的部分源代码或他们正在贡献补丁的部分。但计划从源代码编译操作系统的用户必须下载 **所有** 的 FreeBSD-CURRENT，而不仅是选定的部分。请阅读 [FreeBSD-CURRENT 邮件列表](https://lists.freebsd.org/subscription/freebsd-current) 和 **/usr/src/UPDATING** 以保持更新，了解有时会成为必要的启动过程。
4. 积极参与！建议 FreeBSD-CURRENT 用户提交增强功能或缺陷修复。附带代码的方案始终受到欢迎。

## STABLE 分支

FreeBSD-STABLE 是用于发布主要版本的开发分支。

与一般 Linux 发行版中的“稳定版”概念不同，其名称中的“稳定”指的是该分支的 ABI（Application Binary Interface，应用程序二进制接口）保持稳定，而非指系统整体稳定性，也可以理解为“固定”。在没有充分测试的开发或测试环境中，不应将任何生产服务器更新到 FreeBSD-STABLE。应使用 FreeBSD 的最新正式版本，即 RELEASE。

CURRENT 分支中的代码在经过充分测试后（通常需满足 MFC 最短三天的要求，MFC 指 `Merge From CURRENT`，类似于 `backporting` 即向后移植）会推送到 STABLE 分支，但这并不保证两个分支都没有重大缺陷。尽管 FreeBSD-STABLE 分支应该始终能够编译并运行，但这并无保证。

STABLE 仍然是一个开发分支，任何时候，FreeBSD-STABLE 的源代码都可能不适合普遍使用。它只是另一条工程开发轨道，并非面向终端用户。

更多用户运行 FreeBSD-STABLE 而非 FreeBSD-CURRENT，某些在 FreeBSD-CURRENT 中未发现的缺陷和极端情况会在 FreeBSD-STABLE 中暴露，因此不能盲目地跟踪 FreeBSD-STABLE。

希望跟踪或参与 FreeBSD 开发过程，特别是与下一个 FreeBSD 发布相关的开发者，应该考虑跟踪 FreeBSD-STABLE。

要跟踪 FreeBSD-STABLE：

1. 加入 [FreeBSD-STABLE 邮件列表](https://lists.freebsd.org/subscription/freebsd-stable)，以便及时了解 FreeBSD-STABLE 中可能出现的构建依赖或其他需要特别注意的问题。开发人员在此邮件列表中也会宣布他们正在考虑的有争议的修复或更新，用户可以在此期间回应并提出意见。

   加入相关的 git 列表以跟踪所选分支。例如，跟踪 15-STABLE 分支的用户应该加入 [稳定分支提交信息列表](https://lists.freebsd.org/subscription/dev-commits-src-branches)。该列表记录每个变更的提交日志条目，以及任何可能副作用的相关信息。

   要加入这些列表，请访问 [FreeBSD 列表服务器](https://lists.freebsd.org/)，点击要订阅的列表并按照说明进行操作。如果要跟踪整个源代码树的变更，订阅 [所有分支的源代码仓库提交信息列表](https://lists.freebsd.org/subscription/dev-commits-src-all)。
2. 安装新的 FreeBSD-STABLE 系统，可以从 FreeBSD 镜像站获取基于 FreeBSD-STABLE 的每周快照进行安装。 如果要编译或升级现有的 FreeBSD 系统到 FreeBSD-STABLE，请使用 git 检出所需分支的源代码。分支名称（如 **stable/15**）在 <https://www.freebsd.org/releng> 上列出。
3. 在编译或升级到 FreeBSD-STABLE 之前，请仔细阅读 **/usr/src/Makefile** 和 [FreeBSD-STABLE 邮件列表](https://lists.freebsd.org/subscription/freebsd-stable) 和 **/usr/src/UPDATING** 以保持更新，了解有时在向下一个发布版本过渡过程中所需的其他启动过程。

## 课后习题

1. 分析 FreeBSD 的版本变更历史。


# 2.4 FreeBSD 简史

```sh
FreeBSD 发展关键里程碑

1961 │ CTSS 分时系统
1969 │ UNIX 诞生
1973 │ UNIX 内核用 C 语言重写
1978 │ 1BSD 发布
1983 │ 4.2BSD 发布
1991 │ Net/2
1992 │ 386BSD
1993 │ FreeBSD 项目成立（6 月 19 日）
1994 │ FreeBSD Ports；USL 诉讼和解
2000 │ Jail；FreeBSD 基金会成立；kqueue
2008 │ ZFS 进入 FreeBSD
2012 │ Clang/LLVM 成为默认编译器
2020 │ src 仓库迁移至 Git
2025 │ PkgBase 引入（15.0-RELEASE）
2026 │ 真正自由的操作系统：基本系统完全移除 GPL 代码
```

* 1961 年：分时操作系统（Timesharing OS）

在 20 世纪 60 年代初，分时操作系统诞生。1961 年 11 月，麻省理工学院的 Fernando Corbató 在 IBM 709 上首次演示了兼容分时系统（CTSS），即最早的分时系统之一。同期，曼彻斯特大学设计的 Atlas 计算机上也实现了 Atlas 监控程序，该系统于 1962 年 12 月 7 日正式投入运行，首次将虚拟存储器投入实际使用——虚拟存储器的概念则由德国物理学家 Fritz-Rudolf Güntsch 于 1957 年在其博士论文中率先提出（参见：Denning P J. Virtual Memory\[J]. ACM Computing Surveys, 1970, 2(3): 153-189）。在那个时代，分时共享系统意味着两个人共用同一台计算机，通常需要安排一张小时时间表来规划使用计算机的时间。

* 1964 年：MULTICS（**多路复用** 信息和计算服务）

Multics 最初的规划与开发始于 1964 年，地点位于马萨诸塞州的剑桥市。最初，Multics 是由麻省理工学院（Fernando Corbató 领导的 MAC 项目）主导的项目；1964 年 8 月，通用电气公司签约成为硬件供应商；同年 11 月，贝尔实验室加入，形成三方合作。Multics 在专为操作系统设计的通用电气 645 计算机上开发；GE 645 原型机于 1967 年 1 月交付给麻省理工学院，Multics 于同年 12 月在该硬件上首次启动。

* 1969 年：UNIX（UNIX 操作系统）

在贝尔实验室退出 Multics 项目前，Dennis Ritchie 和 Ken Thompson 已经意识到了 Multics 的潜力。1969 年，Ken Thompson 在一台闲置的 PDP-7 计算机上着手开发一款新程序 Unics（Uniplexed Information and Computing Service，**单路复用** 信息和计算服务）。随后在 1970 年初，他们以开发文本处理（text processing）的名义提出购买申请，在研究部门主管 Lee McMahon 和 Doug McIlroy 的支持下获得资金，于同年 5 月下达订单，夏末收到了 PDP-11/20 计算机，将 Unics 移植到了这台性能更强的机器上。

* 1973 年：UNIX 代码迁移到 C 语言

Dennis Ritchie 决定为 UNIX 开发一种高级语言，使其语句能编译成少数几条机器指令。这促使他开发了 C 编程语言。1973 年夏天，第四版研究 UNIX（Research Unix V4）使用 C 语言重写了内核（Thompson 曾在 1972 年做过尝试但放弃了）。这令 UNIX 具备了可移植性，从而改写了操作系统的历史。

* 1974 年：加州大学伯克利分校引入 UNIX

1974 年，加州大学伯克利分校的 Bob Fabry 教授从 AT\&T 获得了 UNIX 的源代码许可证。Bob Fabry 此前在 1973 年的国际计算机学会（Association for Computing Machinery，ACM）操作系统原理研讨会上见过 UNIX 第 4 版，并有意引入加州大学伯克利分校。1979 年，Bob Fabry 在伯克利成立了计算机系统研究小组（CSRG）。1980 年 4 月，美国国防高级研究计划局（DARPA）与伯克利签订合同后，CSRG 开始基于 AT\&T Research Unix 进行系统性修改和改进，并将修改后的版本称为“BSD Unix”或“BSD”。

* 1978 年 3 月 9 日：1BSD 发布

基于 UNIX 创建的伯克利软件发行版（1BSD）是 UNIX 第六版的一种附加组件，而非独立完整的操作系统。此版本发行了大约 30 份。

* 1979 年 5 月 10 日：2BSD 发布（最终版本）

第二款伯克利软件发行版（2BSD）初版发布于 1978 年，经过增补后完整发布于 1979 年 5 月。涉及 1BSD 的软件更新，以及由 Bill Joy 新开发的两个至今仍在 UNIX 系统上使用的程序：vi 文本编辑器（ex 的可视化版本）和 Csh。2BSD 是 Bill Joy 参与 PDP-11 相关工作的最后一个 BSD 版本，发行了约 75 份。

* 1980 年 4 月：DARPA 的赞助

在 1980 年初，美国国防高级研究计划局（DARPA, Defense Advanced Research Projects Agency）正在寻找一种有助于军事项目的操作系统。基于 3BSD 的成功，Bob Fabry 于 1979 年秋向 DARPA 提交了提案，建议伯克利为 DARPA 社区开发 3BSD 的增强版本。1980 年 4 月，DARPA 与伯克利签订了为期 18 个月的合同，开始赞助伯克利进行相关工作。

* 1983 年 8 月：4.2BSD 发布

在 Bill Joy 离开伯克利并与他人创建 Sun Microsystems（太阳计算机系统公司）（1982 年）之后，4.2BSD 于 1983 年 8 月正式发布，这是 Bill Joy 离开后的第一个版本。1984 年，USENIX 为 4.2BSD 出版的《Unix System Manager's Manual》封面首次使用了由 John Lasseter 绘制的 BSD 吉祥物形象，这一形象后来成为 BSD 最广为人知的标志。该版本发行了 1000 余份拷贝，意味着已有大量计算机在使用。

* 1988 年 6 月：4.3BSD-Tahoe

随着开发人员逐渐淘汰老旧的 VAX 平台，4.3BSD-Tahoe 发布了针对 Power 6/32 平台（TAHOE）的版本。该平台由 Computer Consoles Incorporated 开发，代号 Tahoe，虽商业上未获成功，但首次实现 BSD 向非 VAX 架构的移植，将机器相关代码与无关代码分离，为后续系统可移植性奠定基础。

* 1991 年：Net/2 与 1992 年 386BSD

Keith Bostic 发起了一个项目，旨在不使用 AT\&T 代码的前提下，重新实现大多数标准的 UNIX 软件。最终发布了 Networking Release 2（Net/2）——一种几乎完全可自由分发的操作系统。在 Net/2 的基础上，BSD 为英特尔 80386 架构分别移植了两个版本：由 William Jolitz 和 Lynne Jolitz 夫妇开发的免费的 386BSD、由 Berkeley Software Design（BSDi）开发的专有 BSD/386（后来更名为 BSD/OS）。386BSD 本身昙花一现，但成为不久后启动的 NetBSD 和 FreeBSD 项目的代码基础。

* 1992 年：USL 诉讼案

BSDi 很快就陷入了与 AT\&T 的 UNIX System Laboratories（USL，UNIX 系统实验室）子公司的法律纠纷中，当时 USL 是 System V 版权和 UNIX 商标的所有者。USL 对 BSDi 的诉讼于 1992 年提起，并导致对 Net/2 的分发禁令。该诉讼于 1994 年 1 月达成和解。和解条件之一是加州大学伯克利分校承认 Net/2 中有三个文件属于“受限制代码”（encumbered code），因为这些代码归 Novell 所有（Novell 此前从 AT\&T 处获得了这些权利），必须删除。作为交换，Novell“认可”了 4.4BSD-Lite 发布时将声明为不受限制的代码，并强烈建议所有现有的 Net/2 用户迁移至 4.4BSD-Lite。FreeBSD 也在此列，项目被要求在 1994 年 7 月底之前停止发布基于 Net/2 的产品。根据协议条款，项目被允许在截止日期前做最后一次发布，即 FreeBSD 1.1.5.1。在 BSD 的约 18,000 个文件中，仅需删除三个文件，并修改另外 70 个文件以添加 USL 的版权声明。本次和解为首个基于 4.4BSD-Lite 的 FreeBSD RELEASE 的发布铺平了道路。

* 1993 年 6 月：FreeBSD 项目成立

FreeBSD 项目起源于 1993 年初，部分源自非官方的 386BSD 补丁包的最后三位协调人的创意：Nate Williams，Rod Grimes 和 Jordan Hubbard。他们最初的目标是制作一个 386BSD 的中间快照，以解决一些补丁包机制无法解决的问题。该项目早期的工作名称是 386BSD 0.5 或 386BSD Interim，正体现了这一事实。386BSD 是 Bill Jolitz 开发的操作系统。当时该系统问世已将近一年，但一直被严重忽视。随着补丁包日益膨胀，臃肿不堪，他们决定通过提供 386BSD 过渡项目来帮助 Bill 走出困境。然而，在没有明确提供备选方案的情况下，Bill Jolitz 突然决定退出 386BSD 过渡项目，他们的计划被迫搁浅。三人认为，即使没有 Bill 的支持，这个项目也是值得的，因此他们采用了 David Greenman 创造的“FreeBSD”之名。为了改善 FreeBSD 的发行渠道，Jordan Hubbard 随后联系了 Walnut Creek CDROM。Walnut Creek CDROM 不仅支持在 CD 上发行 FreeBSD，还为此项目提供了一台工作用机和高速互联网连接。如果没有 Walnut Creek CDROM 对这一当时完全未知项目的近乎前所未有的信任，FreeBSD 很可能无法如此迅速地发展至今天的规模。1993 年 6 月 19 日，正式将该项目命名为“FreeBSD”。首个 FreeBSD RELEASE（FreeBSD 1.0）发布于 1993 年 11 月，基于 4.3BSD Net/2（Networking Release 2）磁带，并包含 386BSD 和自由软件基金会提供的许多组件。

* 1994 年 8 月：FreeBSD Ports

FreeBSD 的 Ports 和软件包为用户和管理员提供了一种简便的安装应用程序的方式。Ports 目前提供了多达 37,000 个 Port。它们首次现身于 1994 年，当时 Jordan Hubbard 将“port make macros”提交到 FreeBSD 的 CVS 存储库中，目的是给他的软件包安装套件 **Makefile** 打补丁。

* 1994 年 11 月 22 日：IPFW

ipfirewall（IPFW）随 FreeBSD 2.0-RELEASE 引入，这种采用“首次匹配（First Match）”规则的防火墙自此成为系统的重要组成部分。ipfw 曾作为 Mac OS X（10.0 至 10.6 版本）的内置数据包过滤防火墙（自 Mac OS X 10.7“Lion”起，Apple 将默认防火墙替换为 PF）。

* 1998 年 5 月：软更新（Soft Updates）

1998 年 5 月，FreeBSD 采用了软更新依赖跟踪系统。软更新旨在通过跟踪并强制执行元数据更新之间的依赖关系来维护文件系统元数据的完整性，防止因崩溃或断电导致损坏。

* 1999 年 10 月 17 日：首届 BSD 大会

首届 FreeBSD 大会（FreeBSDCon'99）在加利福尼亚州伯克利举行。来自世界各地的 350 多名开发者和用户参加了此次活动，标志着 FreeBSD 受欢迎度和影响力的重要里程碑。

* 2000 年 3 月 14 日：FreeBSD Jail

FreeBSD Jail 随 2000 年初发布的 FreeBSD 4.0 引入。Jail 是一种操作系统级虚拟化机制，允许管理员将 FreeBSD 系统划分为多个独立的子系统，各子系统之间相互隔离。

* 2000 年 3 月 28 日：FreeBSD 基金会成立

FreeBSD 基金会是一家总部位于美国的非营利组织，注册为 501(c)(3) 机构，致力于支持 FreeBSD 项目、其开发和社区。资金来自个人和企业的捐款，用于赞助开发人员进行特定活动、购买硬件和网络基础设施，并提供开发者峰会的差旅津贴。该基金会由 Justin Gibbs 等人于 2000 年 3 月 28 日创立。

* 2000 年 7 月 27 日：kqueue(2)

kqueue(2) 是旨在替代 select/poll 的创新解决方案，于 2000 年 7 月 27 日随着 FreeBSD 4.1-RELEASE 引入。这一可扩展的事件通知接口与后来 Linux 内核中引入的 epoll 机制在目标和设计思路上具有相似性。

* 2000 年 9 月：首次核心团队选举

尽管此前已存在自我推选产生的核心团队，但首次通过选举形式组建核心团队是在 2000 年 9 月。当时任命了由 9 名成员组成的团队，自此以后每两年举行一次选举。

* 2001 年 11 月：EuroBSDCon

EuroBSDCon 2001 于 2001 年 11 月 9 日至 11 日在英国布莱顿举行（EuroBSDCon. Short History of EuroBSDCon\[EB/OL]. \[2026-04-18]. <https://2024.eurobsdcon.org/history.html>.）。随着全球社区的不断扩大，EuroBSDCon 的目标是聚集在 BSD 操作系统家族及相关项目上工作的用户和开发者。

* 2004 年 1 月 12 日：5.2-RELEASE

在 5.1 版本实验性支持 amd64 架构后，5.2-RELEASE 正式提供了对 amd64 的支持。amd64 成为首个被列为一级（Tier 1）架构的 64 位平台。

* 2004 年 3 月：首届 AsiaBSDCon；5 月首届 BSDCan

在 EuroBSDCon 获得成功之后，首届 AsiaBSDCon 于 2004 年 3 月 13 日至 15 日在台湾“中央研究院”举办，紧随其后的是 BSDCan，于 5 月 13 日至 16 日在加拿大渥太华举行。随着 FreeBSD 社区的不断壮大，全球范围内对以 BSD 为主题的会议需求也随之增长。

* 2004 年 11 月 6 日：5.3-RELEASE 移植 PF

PF（Packet Filter）最初设计用于 OpenBSD，于 2003 年 3 月移植到 FreeBSD，2004 年 2 月 26 日由 Max Laier 集成到基本系统，随 5.3-RELEASE 一同发布。

* 2004 年 11 月 6 日：Libarchive

Libarchive 最初是为 FreeBSD 5.3 开发的，随该版本一同发布。它是一种用 C 语言编写的程序库，提供对多种不同存档格式的流式访问功能。

* 2005 年：谷歌编程之夏

FreeBSD 基金会在首年度的谷歌编程之夏就参与其中。谷歌编程之夏始于 2005 年，为新的开发者提供了一个机会，使其参与开源编程项目。在项目结束后，许多参与该项目的学生成为了 FreeBSD 的贡献者。

* 2005 年 8 月：首位执行董事

Deb Goodkin 于 2005 年 8 月加入基金会，成为基金会首位雇员，后担任执行董事。她之前在数据存储设备的市场营销、销售和开发领域有着 20 余年的工作经验。

* 2005 年 11 月 1 日：新的 FreeBSD Logo

项目举行了一项 Logo 设计大赛，由 Anton K. Gural 设计的 Logo 获胜（当前仍在使用）。

* 2005 年：jemalloc

Jason Evans 于 2004 年初开始构思 jemalloc，2005 年 9 月集成到 FreeBSD 的 libc 中，随 FreeBSD 7.0-RELEASE（2008 年 2 月 27 日）成为默认内存分配器，取代了原有的 phkmalloc。该工具改进了 FreeBSD 的可扩展性和碎片化行为。

* 2008 年 2 月：ZFS

ZFS 由 Sun Microsystems 自 2001 年起开始开发，作为一种集成了文件系统和逻辑卷管理器的系统。该系统具有良好的可扩展性，并提供强大的数据完整性保护与高效的数据压缩功能。OpenSolaris 版本的 ZFS 于 2007 年 4 月 6 日由 Pawel Jakub Dawidek 导入 FreeBSD 源代码树，随 2008 年 2 月 27 日发布的 FreeBSD 7.0-RELEASE 首次进入 FreeBSD 系统。

* 2009 年 1 月 4 日：DTrace

Sun Microsystems 开发了 DTrace，DTrace 可用于实时调试生产系统中的内核和应用程序问题。尽管该工具最初是为 Solaris 开发的，但它随 FreeBSD 7.1-RELEASE（2009 年 1 月 4 日发布）成为 FreeBSD 的标准组成部分，FreeBSD 为 DTrace 提供了全面支持。

* 2010 年 8 月：Capsicum

Capsicum 是一种轻量级的操作系统能力和沙盒框架，可用于应用程序沙盒化、将大型软件架构分解为隔离的组件，并限制软件漏洞的影响范围。Capsicum 最初由剑桥大学开发，于 2010 年 8 月在 USENIX Security 研讨会上首次发表论文，随后作为可选功能发布在 FreeBSD 9.0 中，后来成为 FreeBSD 10.0 中的默认功能。

* 2012 年：CHERI

CHERI（Capability Hardware Enhanced RISC Instructions）项目源于 DARPA 的 CRASH/CTSRD 计划，该计划于 2010 年 9 月启动，由剑桥大学与 SRI International 合作开展，主要研究者包括 Robert N. M. Watson 等（与 Capsicum 同一研究者）。2012 年 3 月，CHERI 首篇论文《CHERI: a research platform deconflating hardware virtualization and protection》在伦敦举行的 RESoLVE'12 研讨会上发表。CHERI 将混合能力模型引入 CPU 架构领域，实现在进程地址空间内的细粒度隔离，并支持当前软件设计。

* 2012 年 7 月：Ports 开始从 CVS 向 Subversion 迁移，2013 年 2 月完成

Ports 自 2012 年 7 月起进入 CVS 与 SVN 双轨运行期，项目于 2013 年 2 月 28 日正式关闭 CVS 访问，彻底完成了向 Subversion 的过渡。

* 2012 年 8 月：Poudriere

Poudriere 是一种通过 Jail 测试 Port，并构建 FreeBSD 镜像的工具，由 Baptiste Daroussin 开发，于 2012 年 8 月首次发布。

* 2012 年 11 月：Clang/LLVM

LLVM 项目是一组模块化和可重用的编译程序和工具链技术。Clang 项目为 LLVM 项目提供了 C 语言前端基础设施。FreeBSD 于 2012 年 11 月将 Clang 设为 i386 和 amd64 架构的默认编译器，随 FreeBSD 10.0-RELEASE 正式交付。

* 2012 年 9—11 月：黑客入侵 FreeBSD 集群（9 月 19 日起可能已被入侵，11 月 11 日被发现）

FreeBSD 项目集群检测到黑客入侵，攻击通过窃取开发者 SSH 密钥实现，影响第三方软件包构建系统，未涉及基础系统源代码。项目花费数月进行审计与还原。

* 2013 年 9 月 17 日：OpenZFS 项目启动

OpenZFS 项目衍生于 OpenSolaris。2013 年 9 月 17 日，ZFS 开源项目宣布 OpenZFS 成为 ZFS 的社区主导继任项目，并创建了一个正式的社区来维持开发和支持。但此时 FreeBSD 依旧使用的是最早的 OpenSolaris ZFS。

* 2014 年 1 月 20 日：pkg 成为默认的软件包管理器

pkg 首次出现在 9.1-RELEASE 中。在 10.0-RELEASE 中，pkg 成为默认的软件包管理器，取代了 `pkg_*` 等一系列命令。

* 2014 年 1-2 月：FreeBSD 期刊创刊号

作为 FreeBSD 社区的声音，也是了解 FreeBSD 最新发布版本和新进展的重要途径，FreeBSD 期刊的创刊号是 2014 年 1/2 月刊，重点关注 FreeBSD 10。最初以付费订阅模式发行，直至 2019 年 1 月才将 FreeBSD 期刊转为免费出版物，随后同时在基金会网站上进行刊载（同时提供了 HTML 和 PDF）。

* 2017 年 6 月 19 日：新设“FreeBSD 日”

国际 FreeBSD 日是每年一度的庆祝活动，以赞扬 FreeBSD 对技术的开创性和持续影响，并纪念其传承的价值。2017 年 6 月 15 日，National Day Calendar 注册官宣布每年 6 月 19 日为 National FreeBSD Day。

* 2018 年：FreeBSD 中文社区（CFC）成立

在千禧年代曾存在多个中文社区，但后来逐渐衰落。这些早期社区的部分核心成员虽仍活跃于 FreeBSD 项目，但已不再专注于中文社区事务，转而投身于个人事业与家庭。FreeBSD 中文社区（CFC）最早由百度贴吧 FreeBSD 吧发展而来。

* 2021 年 4 月 6 日：从 Subversion 迁移到 Git

FreeBSD 项目从 Subversion 到 Git 的迁移始于 2019 年 5 月的 DevSummit，当时成立了一个 Git 工作小组。src 仓库于 2020 年 12 月迁移，Ports 于 2021 年 4 月 6 日完成迁移。

* 2021 年 4 月 13 日：由 OpenSolaris ZFS 切换到 OpenZFS

在 13.0-RELEASE 中，FreeBSD 将 ZFS 实现从基于 illumos 的代码库切换到了统一的 OpenZFS 2.0 代码库，使 FreeBSD 能够更快地获取 ZFS 上游改进。该迁移计划最早于 2018 年提出。

* 2024 年 8 月：德国主权技术基金赞助 FreeBSD 项目实施基础设施现代化

该项目的主要目标是改进基本系统、Ports 和软件包的安全工具，更新项目基础设施以加快开发速度、增强构建安全性，并降低新开发者的参与门槛。项目于 2024 年 8 月启动，至 2025 年 12 月完成。

* 2024 年 11—12 月：笔记本和桌面工作组 LDWG 成立

笔记本和桌面工作组（LDWG）如其名称所示，致力于通过一系列功能改进和新增，使 FreeBSD 在个人设备上实现“开箱即用”的体验。该工作计划为期 1 至 2 年。

* 2024—2025：Alpha-Omega 审计

Alpha-Omega 项目先后审计了 FreeBSD 的 bhyve 虚拟机监视器和 Capsicum 沙盒框架，以提升 FreeBSD 项目的安全性。

* 2025 年 12 月 2 日：引入 PkgBase

历经十年岁月磨炼，FreeBSD 终于在 15.0-RELEASE 中新增了 PkgBase 安装方式，以通过软件包来管理基本系统。这种方式最初源于 TrueOS 项目。

* 2026 年 7 月 14 日：真正自由的操作系统：基本系统完全移除 GPL 代码

随着 <https://github.com/freebsd/freebsd-src/commit/134a4c78d070f8c4ea43a060a7ae28d22ac39558> 的提交，FreeBSD 基本系统中的 GPL 代码已经完全移除。现在 FreeBSD 是一款真正自由的操作系统！这一过程肇始于 2007 年 GPLv3（一种强著佐权许可协议）的发布，而同一时期的 GCC 亦转向了该协议。自此以后，FreeBSD 项目开始了长达近 20 年的征程。这同时也标志着 FreeBSD 工具链的集成化、现代化、宽松许可。

> **技巧**
>
> 这只是基本系统变更，不影响用户软件 Ports，用户仍可自由安装任意软件。

## 参考文献

* OpenZFS. OpenZFS\[EB/OL]. \[2026-06-07]. <https://en.wikipedia.org/wiki/OpenZFS>.
* FreeBSD Foundation. Infrastructure Modernization\[EB/OL]. (2025-12-19)\[2026-06-07]. <https://freebsdfoundation.org/blog/infrastructure-modernization-commissioned-by-the-sovereign-tech-agency/>.
* FreeBSD Foundation. Contributing to FreeBSD Ports with Git\[EB/OL]. \[2026-06-07]. <https://freebsdfoundation.org/wp-content/uploads/2022/03/mingrone.pdf>.
* Watson R N M, et al. CHERI: A Research Platform Deconflating Hardware Virtualization and Protection\[C]//RESoLVE'12 Workshop, London, UK, 2012-03.
* Gunkies. Power 6/32\[EB/OL]. \[2026-06-07]. <https://gunkies.org/wiki/Tahoe>.
* Laier M. Packet Filter (pf) An Extended Introduction\[EB/OL]. (2004-10-21)\[2026-06-07]. <https://people.freebsd.org/~mlaier/sucon.pdf>. PF 移植报告。
* Evans J. A Scalable Concurrent malloc(3) Implementation for FreeBSD\[C]//BSDCan, 2006. 新型内存分配器的实现。
* Dawidek P J. Porting the Solaris ZFS file system to the FreeBSD operating system\[C]//AsiaBSDCon, 2007. ZFS 移植报告。
* National Day Calendar. NEW DAY PROCLAMATION | NATIONAL FREEBSD DAY - June 19\[EB/OL]. (2017-06-15)\[2026-06-07]. <https://www.nationaldaycalendar.com/proclamations/new-day-proclamation-national-freebsd-day-june-19>. 美国国家日历。
* FreeBSD Project. FreeBSD.org intrusion announced November 17th 2012\[EB/OL]. (2012-11-17)\[2026-06-06]. <https://www.freebsd.org/news/2012-compromise/>. FreeBSD 2012 入侵事件。
* FreshPorts. ports-mgmt/poudriere-devel\[EB/OL]. \[2026-06-06]. <https://www.freshports.org/ports-mgmt/poudriere-devel/>. Port **poudriere** 添加日期为 2012-08-16。
* FreeBSD Foundation. Development Project Update: Toolchain Modernization\[EB/OL]. (202007)\[2026-06-06]. <https://freebsdfoundation.org/wp-content/uploads/2020/07/Development-Project-Update-Toolchain-Modernization.pdf>.
* Ritchie D M. The Evolution of the Unix Time-sharing System\[EB/OL]. (1984)\[2026-06-07]. <https://www.read.seas.harvard.edu/~kohler/class/aosref/ritchie84evolution.pdf>. 记载“In early 1970 we proposed acquisition of a PDP-11”。
* Multicians. GE-635s at Project MAC and BTL\[EB/OL]. \[2026-06-07]. <https://dps8m.gitlab.io/w3/multicians.org/ge635.html>.
* FreeBSD Foundation. Timeline\[EB/OL]. \[2026-03-25]. <https://freebsdfoundation.org/freebsd/timeline/>. FreeBSD 发展历史时间线。
* McKusick M K, Neville-Neil G V, Watson R N M. FreeBSD 操作系统设计与实现\[M]. 陈向群，郭立峰，叶顺平，译。原书第 2 版。北京：机械工业出版社，2021: VI. 记载“1995 年 OpenBSD 组从 NetBSD 组中分离出来”。
* FreeBSD Foundation. Staff\[EB/OL]. \[2026-04-16]. <https://freebsdfoundation.org/about-us/our-team/>. 记载 Deb Goodkin 于 2005 年 8 月加入基金会，为首位雇员。
* SeaGL. 25+ Years of FreeBSD and Why You Should Get Involved!\[EB/OL]. (2019-11-15)\[2026-04-16]. <https://osem.seagl.org/conferences/seagl2019/program/proposals/611>. 记载 Deb Goodkin“joining as the first employee back in August 2005”。
* FreeBSD Wiki. Jails\[EB/OL]. \[2026-04-16]. <https://wiki.freebsd.org/Jails>. 记载“Jails were introduced by Poul-Henning Kamp in March 2000 with FreeBSD 4.0-RELEASE”。
* Watson R N M, et al. CHERI: A Hybrid Capability-System Architecture for Scalable Software Compartmentalization\[C]//ISCA. 2015. CHERI 原始论文，阐述硬件能力架构扩展的设计与实现。
* ACM. Fernando J (“Corby”) Corbato\[EB/OL]. \[2026-04-17]. <https://amturing.acm.org/award_winners/corbato_1009471.cfm>. 记载 CTSS 于 1961 年 11 月在 IBM 709 上首次演示。
* Tom Van Vleck. The Multicians web site\[EB/OL]. (2026-04-08)\[2026-04-17]. <https://multicians.org/history.html>. 记载 Multics 项目历史，通用电气公司于 1964 年 8 月签约、贝尔实验室于 1964 年 11 月加入。
* FreeBSD Project. Core Bylaws\[EB/OL]. \[2026-04-17]. <https://www.freebsd.org/internal/bylaws/>. 记载首次核心团队选举于 2000 年 9 月举行。
* FreeBSD Foundation. Resolutions Document\[EB/OL]. \[2026-04-17]. <https://freebsdfoundation.org/wp-content/uploads/2015/12/ResolutionsDocument-1.pdf>. 记载 FreeBSD 基金会成立文件签署日期为 2000 年 3 月 28 日。
* FreeBSD Project. FreeBSD News Flash October 1999\[EB/OL]. \[2026-04-17]. <https://ftpmirror.your.org/pub/FreeBSD-CVS/www/data/news/1999/index.html>. 记载 FreeBSDCon'99 参会人数超过 350 人。
* USENIX. Announcing the USENIX AsiaBSDCon and Request for Papers\[EB/OL]. (2003-10)\[2026-04-17]. <https://web.archive.org/web/20041217153402/https://www.bsdnewsletter.com/2003/10/News107.html>. 记载首届 AsiaBSDCon 于 2004 年 3 月 13 日至 15 日在台湾“中央研究院”举办。
* IEEE Computer Society. Linus Torvalds\[EB/OL]. \[2026-04-17]. <https://www.computer.org/profiles/linus-torvalds/>. 记载 Linus Torvalds 于 1988 年入学赫尔辛基大学，后获得计算机科学硕士学位。
* Evans J. A Scalable Concurrent malloc(3) Implementation for FreeBSD\[C]//BSDCan, 2006. 记载 jemalloc 的设计与实现，2005 年集成到 FreeBSD libc。
* Evans J. jemalloc Background\[EB/OL]. \[2026-04-17]. <https://github.com/jemalloc/jemalloc/wiki/Background>. 记载 jemalloc 最初构思于 2004 年初，2005 年 9 月集成到 FreeBSD。
* OpenZFS. History\[EB/OL]. \[2026-04-17]. <https://www.openzfs.org/wiki/History>. 记载 ZFS 开发始于 2001 年，2008 年随 FreeBSD 7.0 移植发布。
* FreeBSD Project. FreeBSD 7.0-RELEASE Announcement\[EB/OL]. (2008-02-27)\[2026-04-17]. <https://www.freebsd.org/releases/7.0R/announce/>. FreeBSD 7.0-RELEASE 发布日期为 2008 年 2 月 27 日。
* FreeBSD Project. FreeBSD 7.1-RELEASE Announcement\[EB/OL]. (2009-01-04)\[2026-04-17]. <https://www.freebsd.org/releases/7.1R/announce/>. FreeBSD 7.1-RELEASE 发布日期为 2009 年 1 月 4 日，DTrace 随此版本引入。
* Watson R N M, Neumann P G, Woodruff J, et al. CHERI: A Research Platform Deconflating Hardware Virtualization and Protection\[C]//RESoLVE'12 Workshop, London, UK, 2012-03. CHERI 首篇论文。
* SRI International. CTSRD Final Technical Report\[EB/OL]. \[2026-04-17]. <https://web.archive.org/web/20251122133531/https://www.csl.sri.com/~neumann/20191213-ctsrd-ftr-final.pdf>. 记载 CTSRD/CHERI 项目始于 2010 年 9 月 24 日。
* MCKUSICK M K. Twenty Years of Berkeley Unix: From AT\&T-Owned to Freely Redistributable\[M]//SALUS P H, ed. Open Sources: Voices from the Open Source Revolution. Sebastopol: O'Reilly, 1999. 记载 DARPA 合同始于 1980 年 4 月，为期 18 个月。
* FreeBSD Core Team. Change to FreeBSD release scheduling and support period\[EB/OL]. (2024-07-10)\[2026-04-18]. <https://lists.freebsd.org/archives/freebsd-announce/2024-July/000143.html>. 自 FreeBSD 15 起，稳定分支支持周期由 5 年缩短为 4 年。
* USL v. BSDi Settlement Agreement\[EB/OL]. (1994-02-04)\[2026-04-17]. <https://web.archive.org/web/20240613194116/https://www.bell-labs.com/usr/dmr/www/bsdi/USLsettlement.pdf>. 记载 Net/2 中仍残留 AT\&T 代码，和解后 4.4BSD-Lite 方彻底移除。
* FreeBSD Foundation. Navigating FreeBSD's New Quarterly and Biennial Release Schedule\[EB/OL]. (2024-07-16)\[2026-04-17]. <https://freebsdfoundation.org/blog/navigating-freebsds-new-quarterly-and-biennial-release-schedule/>. 记载自 15.x 起维护周期从 5 年缩短至 4 年，大版本周期为每 2 年一次。
* FreeBSD Project. FreeBSD 5.2-RELEASE Announcement\[EB/OL]. (2004-01-12)\[2026-04-17]. <https://www.freebsd.org/releases/5.2R/announce/>. FreeBSD 5.2-RELEASE 发布日期为 2004 年 1 月 12 日，amd64 成为 Tier 1 架构。
* FreeBSD Project. FreeBSD 5.3-RELEASE Announcement\[EB/OL]. (2004-11-06)\[2026-04-17]. <https://www.freebsd.org/releases/5.3R/announce/>. FreeBSD 5.3-RELEASE 发布日期为 2004 年 11 月 6 日，PF 及 Libarchive 均随此版本发布。
* Libarchive Project. LibarchiveUsers\[EB/OL]. \[2026-04-17]. <https://github.com/libarchive/libarchive/wiki/LibarchiveUsers>. 记载“libarchive was originally developed for FreeBSD; it was first released with FreeBSD 5.3 in November 2004”。
* Max Laier. Packet Filter (pf) An Extended Introduction\[EB/OL]. (2004-10-21)\[2026-04-17]. <https://web.archive.org/web/20250503030531/https://people.freebsd.org/~mlaier/sucon.pdf>. PF 移植者 Max Laier 的演讲，PF 于 2003 年 3 月移植到 FreeBSD，2004 年 2 月 26 日集成到 FreeBSD 基本系统。
* FreeBSD Foundation. Development Project Update: Toolchain Modernization\[EB/OL]. (2020-03-19)\[2026-07-15]. <https://freebsdfoundation.org/blog/project-update-toolchain-modernization/>. 记录了 FreeBSD 工具链去 GPL 化的一些历史。
* FreeBSD Project. GPLinBase\[EB/OL]. \[2026-07-15]. <https://wiki.freebsd.org/GPLinBase>. FreeBSD 基本系统去 GPL 化的一些历史。

## 课后习题

1. 在 QEMU 中运行 FreeBSD 1.0 版本，记录启动过程中与当代 FreeBSD 的显著差异，分析这些差异反映出的系统设计演进。


# 3.1 乔治·贝克莱与 BSD 文化传统

20 世纪 80 年代初，加州大学伯克利分校计算机系统研究小组（Computer Systems Research Group，CSRG）正式成立，开始修改与扩展 AT\&T 贝尔实验室开发的 UNIX 操作系统。这些修改与扩展最初以软件发行包的形式发布，因此称为伯克利软件发行版（Berkeley Software Distribution，BSD），FreeBSD 即为 CSRG 工作的延续。

## 伯克利市、加州大学伯克利分校、BSD 的命名

BSD 之名源自其发源地：美国加州大学伯克利分校（University of California, Berkeley），该校所在的伯克利市，以及伯克利市名的由来——乔治·贝克莱。

伯克利市（Berkeley）的命名可以追溯至 1866 年。当时，加州学院（College of California）的受托人弗雷德里克·比林斯（Frederick Billings）援引爱尔兰近代经验论哲学家乔治·贝克莱（George Berkeley，1685—1753）的诗句“Westward the course of empire takes its way”（帝国之路向西延伸），建议将新校址所在城镇命名为 Berkeley。

1868 年，加利福尼亚州的立法机构决定在 Berkeley 上建立加州大学。

BSD 之名的命名渊源可归纳如下：

```sh
乔治·贝克莱（1685—1753，哲学家）
  │  诗句"Westward the course of empire takes its way"
  ↓
弗雷德里克·比林斯（1866 年）
  │  援引诗句，建议将城镇命名为 Berkeley
  ↓
加州大学伯克利分校（1868 年建校）
  │  CSRG（计算机系统研究小组）成立
  ↓
BSD（Berkeley Software Distribution，伯克利软件发行版）
  │
  ↓
FreeBSD（CSRG 工作的延续）
```

下面借贝克莱约 1726 年创作的这首诗《论在美洲传播艺术与学术之前景的诗篇》，了解伯克利之名的由来。该诗正式出版于 1752 年的 Miscellany 文集中，其确切创作年份尚存争议，但学界多据其与百慕大办学计划（1725 年提出）的关联，推定为 1725—1726 年间所作。

The Muse, disgusted at an age and clime Barren of every glorious theme, In distant lands now waits a better time, Producing subjects worthy fame.

In happy climes, where from the genial sun And virgin earth such scenes ensue, The force of art by nature seems outdone, And fancied beauties by the true;

In happy climes, the seat of innocence, Where nature guides and virtue rules, Where men shall not impose for truth and sense The pedantry of courts and schools:

There shall be sung another golden age, The rise of empire and of arts, The good and great inspiring epic rage, The wisest heads and noblest hearts.

Not such as Europe breeds in her decay; Such as she bred when fresh and young, When heavenly flame did animate her clay, By future poets shall be sung. Westward the course of empire takes its way;

The four first Acts already past, A fifth shall close the Drama with the day; Time’s noblest offspring is the last.

BERKELEY G. Verses on the Prospect of Planting Arts and Learning in America\[C]//A miscellany, containing several tracts on various subjects. London: Printed for J. and R. Tonson, and S. Draper, 1752.

译文：

缪斯已厌倦这时代与气候/全无辉宏之题可供撷取/遂在远方静候更好的时光/孕育值得传颂的主题。

在那幸福的土地上/和煦的阳光/与处女般的原野交相辉映/艺术之力似被自然超越/幻想之美亦不及真实。

在那幸福的土地上/纯真栖居之所/自然为引导/德行为主宰/人们不再以宫廷与学堂的迂腐之见/冒充真理与理性；

在那里/将歌唱另一个黄金时代/帝国与艺术的兴起/善与伟激发史诗般的激情/最睿智的头脑与最高贵的心灵。

并非欧洲衰败中所滋生的那般/而是如它初生而年轻时所孕育的模样/当神圣之火曾赋予泥土以生命/后世诗人将吟唱/帝国之进程/向西而行；

前四幕已然落幕/第五幕将在白昼中终结全剧/时间最崇高的产儿/总是最后登场。

## 乔治·贝克莱生平简介

在许多著作与文献中，乔治·贝克莱常被称为克洛因主教（Bishop of Cloyne）或贝克莱主教。

“Berkeley”在中文中有不同的音译写法，其英式与美式发音也有所差异（英 /ˈbɑːkli, ˈbəːkli/，美 /ˈbɚkli/），但英文拼写始终一致。

受历史因素（如贝克莱曾购买黑奴引发的争议）及翻译习惯（曾译作“巴克莱”等）的影响，伯克利市与贝克莱其人之间的关联，在汉语世界与英语世界均鲜为人知。

以下画像展示这位哲学家的形象：

![George Berkeley](/files/qVMTW8TeuDILWBCttsb3)

图片出处：[National Portrait Gallery](https://www.npg.org.uk/collections/search/portrait/mw00534/George-Berkeley)（John Smibert 绘，1730 年，藏于伦敦国家肖像馆）。

乔治·贝克莱（1685.3.12—1753.1.14），2023 年是他逝世 270 周年。2025 年也是他的 340 周年诞辰。

| 时间        | 年龄   | 事件                                                                                                                     |
| --------- | ---- | ---------------------------------------------------------------------------------------------------------------------- |
| 1685.3.12 | —    | 出生于爱尔兰的基尔肯尼，乡绅家庭，是家中长子。                                                                                                |
| 1696 年    | 11 岁 | 进入基尔肯尼学院。                                                                                                              |
| 1700 年    | 15 岁 | 进入都柏林圣三一学院。                                                                                                            |
| 1704 年    | 19 岁 | 获授文学学士学位。                                                                                                              |
| 1707 年    | 22 岁 | 被授予文学硕士学位，同年留校任特别研究员，讲授希腊语。                                                                                            |
| 1709 年    | 24 岁 | 为满足学院规定，担任爱尔兰教会执事。同年发表其首部重要著作《视觉新论》，其哲学思想基本形成。                                                                         |
| 1710 年    | 25 岁 | 担任爱尔兰教会牧师。同年发表《人类知识原理》，其中已包含许多关于运动的论述。                                                                                 |
| 1713 年    | 28 岁 | 发表《海拉斯与斐洛诺斯对话三篇》。                                                                                                      |
| 1716 年    | 31 岁 | 再次前往欧洲大陆，在意大利担任圣乔治·阿什（St George Ashe）之子导师，陪同其旅欧约 4 年，至 1721 年返回爱尔兰。                                                    |
| 1717 年    | 32 岁 | 被任命为圣三一学院高级研究员。                                                                                                        |
| 1721 年    | 36 岁 | 被授予神学博士学位，同年（或次年）任爱尔兰教会德罗莫尔教区座堂主任牧师（Dean），但他再次选择留在都柏林圣三一学院讲授神学和希伯来语，并发表 De Motu（论运动），其中指出牛顿的许多基本思想可能存在错误，并批评了牛顿的绝对时空观。 |
| 1723 年    | 38 岁 | 获得了一笔来自朋友的巨额遗产。                                                                                                        |
| 1724 年    | 39 岁 | 任爱尔兰教会德里教区座堂主任牧师（Dean），但从未赴任。                                                                                          |
| 1725 年    | 40 岁 | 准备在百慕大筹建一所神学院，但他一生从未去过百慕大。同年为筹款放弃了先前的座堂主任牧师职位。                                                                         |
| 1728 年    | 43 岁 | 与 Anne Forster 结婚，六周后启程前往美洲寻求办学赞助。他们在罗德岛居住数年，购置了一座种植园，并购买了数名非洲黑奴在园内劳作（此事存在争议）。                                         |
| 1729 年    | 44 岁 | 有了第一个孩子。                                                                                                               |
| 1731 年    | 46 岁 | 因办学无望而返回伦敦（斯坦福哲学百科全书与爱尔兰传记词典均记载为 1731 年返回）。随后将罗德岛的地产与图书馆捐赠给耶鲁大学。日后，他又将大部分财产及为办学筹备的物资捐赠给了相关大学。                          |
| 1734.1.18 | 48 岁 | 被爱尔兰教会任命为克洛因主教（Bishop of Cloyne），同年 5 月 19 日祝圣；并发表《分析家》一文。此后专注于基督教事业，逐渐淡出公众视野。                                         |
| 1739 年    | —    | 伦敦育婴堂医院成立，他曾积极参与其中。                                                                                                    |
| 1744 年    | 59 岁 | 出版《西利斯：关于焦油水的功效以及与之有关的、相互引发的其他课题的哲学反思和探讨之链》，他在书中主张将松焦油用作包治百病的“万灵药”。该书是其生前销量最高的著作。据记载，他对患者使用此疗法，亦可观察到相应疗效。              |
| 1752 年    | 67 岁 | 委托其弟罗伯特·贝克莱博士（Dr. Robert Berkeley）代理克洛因教区教务，移居牛津。                                                                      |
| 1753.1.14 | 67 岁 | 在妻子 Anne Forster 诵读布道文的陪伴下，他在牛津安息，归于主怀。                                                                                |
| 1786 年    | —    | 妻子 Anne Forster 去世。                                                                                                    |

注：此处爱尔兰教会指爱尔兰圣公会，隶属于英国圣公会体系。

## 贝克莱思想概述

### 悖论与数学基础

贝克莱在哲学领域影响深远，对微积分基础的批判也是数学史上的重要篇章。贝克莱的著作引发了关于无穷小量的数学哲学讨论（即贝克莱悖论，参见其 1734 年发表的《分析学家；或一篇致一位不信神数学家的论文，其中审查一下近代分析学的对象、原则及论断是不是比宗教的神秘、信仰的要点有更清晰的表达，或更明显的推理》）。

贝克莱悖论本身并未被“解决”，其哲学层面仍是开放性问题。ε-δ 定义只是使实分析在 ZFC 公理体系下变得形式自洽。许多人常以该定义来解决芝诺悖论，从而否定其哲学价值。

更多相关资源可参阅关于非标准分析、超实数及数学哲学等方面的书籍。

### 贝克莱与爱因斯坦

贝克莱的思想影响了哲学和数学，也对现代科学产生了间接影响。贝克莱主教以其形而上学思想，特别是对牛顿绝对时空观的批判，启发了包括爱因斯坦在内的众多 20 世纪科学家。爱因斯坦认为时间并非绝对，而是与观察者的运动状态密切相关。

> **技巧**
>
> 爱因斯坦信奉马赫主义，而马赫是贝克莱主义者。

> **逐渐地，哲学家和科学家们得出了一个令人震惊的结论**：既然每个物体仅仅是其性质的总和，而这些性质又只存在于心灵之中，那么整个由物质与能量、原子与星辰构成的客观宇宙，除了作为意识的建构外并不存在——它只是一个由人类感官塑造的常规符号体系。
>
> > “天上的浩瀚星辰与地下的山川草木，简而言之，所有构成这个宏伟世界框架的实体，离开心灵就毫无实体可言……只要它们没有被我实际感知，或不存在于我的心灵，或者其他被创造的灵魂之中，它们要么根本不存在，要么只能存在于某个永恒灵的心中。” 正如贝克莱——唯物主义的死敌——所表述的那样：
>
> 爱因斯坦将这一逻辑推向了极致，证明了即便是空间与时间，也只是直觉的形式，无法与意识分离，正如我们关于颜色、形状或大小的概念一样。空间除了作为我们感知中物体的排列和次序外，没有客观实在性；而时间也无法脱离我们用以衡量事件顺序的体系独立存在。
>
> **意识到** 我们对宇宙的全部认知不过是被我们不完美的感官所蒙蔽的印象残余，这让对现实的追求显得无望。如果一切的存在都必须以被感知为前提，那么世界似乎会分崩离析，沦为个体感知的无序状态。
>
> 然而，我们的感知中却存在一种奇特的秩序，仿佛确实存在某种客观现实的底层，而我们的感官将其翻译了出来。尽管没有人能够确定自己对红色或中央 C 的感受是否与他人相同，但我们仍然可以基于这样的假设行动：每个人对颜色和音调的感知大致相似。
>
> ——Barnett L. The Universe and Dr. Einstein\[M]. New York: William Sloane Associates, 1948.

### 贝克莱哲学

贝克莱最著名的哲学命题是关于存在与感知的关系。

> “esse est percipi, to be is to be perceived（存在就是被感知）”
>
> ——George Berkeley
>
> 注：贝克莱在《人类知识原理》第 3 节中的原文为拉丁语与英语混用的“esse is percipi”，后世哲学文献中更常以纯拉丁语形式“esse est percipi”归因于他。

> **注意**
>
> **上述命题绝不代表贝克莱主张主观唯心主义，也绝不代表他否认客观物质的存在。**

可以参阅《人类知识原理》等著作，其中贝克莱论证上帝的必然存在。在贝克莱哲学中，物质存在的客观性与上帝存在并不冲突。该著作也回应了诸多误解和诘难。

简言之：不存在任何独立且不依赖于人的思想与知觉的客观物质（我们所理解的“客观物质”必然是我们的思想与知觉所能把握的，否则这一概念就无意义）。如果存在这样的物质，由于它是不可知的，就等同于不存在，设定其存在也就没有意义（此外，如果承认物质的不可知性，那就不是纯粹的唯物主义，与贝克莱哲学也没有根本区别）。因此，我们所认为的、通常意义上的客观存在，必定依赖于我们的知觉才能被感知，即“存在就是被感知”。除此之外的所谓“客观存在”是不可知的，也没有意义。所以，贝克莱认为，物质存在依赖于心灵的感知，不被感知却仍然存在的物质，是不可设想的。但可以确定的是，我们的世界是存在的（如果你否认这一点，贝克莱哲学也没有太大分别）。因此，为了确保这一点，神是必然存在的。人们总是不言自明地、暗含地将经过实践验证的存在肯定为物质性的，这是不对的。如果实践活动的“物质性”本身是可质疑的，那么非物质性的存在如何能赋予这种活动以物质属性（靠松果腺吗）？而这种实践活动的“物质性”本身是无法被确证的，因为人类无法认识超越于自身感知以外的存在。除非诉诸上帝，但那样一来，你本身就预设了其非物质性。

当代现象学与贝克莱哲学存在相通之处：两者都强调直接经验与知觉的首要性。

> **思考题**
>
> 有关他的思想，最著名的一则哲学实验是：“假如一棵树在森林里倒下而没有人在附近听见，它有没有发出声音？”
>
> > * 如果你认为没有。恭喜你，你现在是贝克莱者了。
> > * 如果认为有，并给出了物理学（或其他科学、数学上）的证明。恭喜，你现在是贝克莱者了。
>
> 问题一：如何理解量子力学中的“观察者”与“树在森林中倒下”这一存在的关系？
>
> > * 如果认为有，因为世界是客观存在的，是不以人的意志为转移的。恭喜，你现在是贝克莱者了。
> > * 如果认为有没有不一定或者不可知或者别的什么情况。恭喜，你现在是贝克莱者了。
>
> 问题二：请结合上文或进一步阅读贝克莱著作，分别阐述上述结论的依据。

贝克莱还认为货币的价值并不取决于其金属含量，货币只是商品交换的手段。其价值来源于信用与社会共识。他认为应该使收入在国民间平均分配以实现经济公平。

他还主张借教育、培训，依靠民众发展经济。他认为应当借大型工程建设缓解贫困问题。

贝克莱主张各宗教团体放下纷争，为共同利益而团结。在他淡出公众视野后，专注于为当地民众（无论天主教徒还是新教徒）兴办公益事业。

贝克莱的思想在他有生之年未被广泛接受，但在其后数百年间影响深远。

几乎每一部主流的哲学史著作都对其思想有所论述\[旧版人教版思想政治必修四（生活与哲学）第 13 页即为一例（教育部普通高中思想政治课课程标准实验教材编写组. 思想政治必修 4 生活与哲学\[M]. 北京: 人民教育出版社, 2018. ISBN: 978-7-107-32710-0.）]，关于他的哲学实验亦是哲学考试中经久不衰的论述题。

在高中思想政治教材中，也能看到贝克莱思想的相关介绍 ~~尽管该教材表述被认为有误，教育部组织编写. 普通高中教科书思想政治必修 4 哲学与文化\[M]. 北京: 人民教育出版社, 2019. ISBN: 978-7-107-34195-3. 已删去相关内容~~。

![教材教科书高中思想政治必修 4 生活与哲学人教版第 13 页](/files/rGCq1bY97stLMMu1pguu)

### 参考文献

* Berkeley G. 人类知识原理和三篇对话\[M]. 张桂权,译. 北京: 人民出版社, 2022. ISBN: 978-7-01-023684-1. 系统阐述贝克莱唯心主义哲学体系与存在感知理论。
* 阎吉达. 贝克莱思想新探\[M]. 上海: 复旦大学出版社, 1987. ISBN: 7-309-00033-1. 深入剖析贝克莱哲学思想与科学方法论。
* Berkeley G. 西利斯\[M]. 曹曼,高新民,译. 北京: 商务印书馆, 2000. ISBN: 978-7-100-02886-8. 西利斯中译本。
* Downing L. George Berkeley\[EB/OL]. (2021)\[2026-03-25]. <https://plato.stanford.edu/archives/fall2021/entries/berkeley/>. SEP 贝克莱条目。提供了贝克莱哲学思想的权威学术综述与研究现状。
* Easwaran K, Hájek A, Mancosu P, et al. Infinity\[EB/OL]. (2024)\[2026-03-25]. <https://plato.stanford.edu/archives/sum2024/entries/infinity/>. SEP 无穷条目。探讨了数学哲学中无穷概念的历史发展与哲学争议。
* Urmson J O. 贝克莱\[M]. 孟令朋,译. 北京: 清华大学出版社, 2019. ISBN: 978-7-302-52555-4. 深入浅出介绍贝克莱哲学思想与历史影响。
* 汪芳庭. 数学基础\[M]. 修订版. 北京: 高等教育出版社, 2018. ISBN: 978-7-04-050242-8. 系统阐述数学基础理论与公理集合论框架。
* Robinson A. 非标准分析\[M]. 申又根,王世强,张锦文,译. 北京: 科学出版社, 1980. 统一书号:13031-1267. 建立超实数理论，为无穷小量提供数学基础。
* Tao T. 陶哲轩实分析\[M]. 李馨,译. 第 4 版. 北京: 人民邮电出版社, 2025. ISBN: 978-7-115-66554-6. 从数学基础（自然数和集合论）构建实分析体系，强调严谨性与直觉的结合。
* Berkeley G. The Querist, containing several queries proposed to the consideration of the public\[M]. Farmington Hills: Gale ECCO, Print Editions, 2018. ISBN: 978-1-38541-101-8. 探讨货币、经济与社会问题的哲学思考。
* Stanford Encyclopedia of Philosophy. Zeno's Paradoxes\[EB/OL]. \[2026-04-04]. <https://plato.stanford.edu/entries/paradox-zeno/>. 芝诺悖论条目。
* Schabas M. Economics in Early Modern Philosophy\[EB/OL]. (2022)\[2026-03-25]. <https://plato.stanford.edu/archives/sum2022/entries/economics-early-modern/>. 梳理近代经济思想的哲学根基与历史脉络。
* Cloyne District Community Council. George Berkeley, Bishop of Cloyne/Philosopher\[EB/OL]. \[2026-03-25]. <http://cloyne.ie/about/george-berkeley-bishop-of-cloyne/>. 介绍贝克莱主教在克洛因教区的生平与工作。
* Britannica. George Berkeley\[EB/OL]. \[2026-03-25]. <https://www.britannica.com/biography/George-Berkeley>. 提供贝克莱生平与思想的权威百科介绍。
* Stadtman V A, Centennial Publications Staff. The Centennial Record of the University of California, 1868–1968\[M/OL]. Berkeley: University of California, 1967\[2026-04-18]. <https://digicoll.lib.berkeley.edu/record/81096/files/centennial.pdf>. 记载 1866 年 Frederick Billings 援引贝克莱诗句建议将城镇命名为 Berkeley 的历史。
* 胡化凯. 20 世纪 50-70 年代中国科学批判资料选（上下）\[M]. 济南: 山东教育出版社, 2009. ISBN: 978-7-5328-5386-1. 其中整本下册都涉及对爱因斯坦的批判。记录特定历史时期科学与政治交织的学术史料。
* O'Grady P. Berkeley, George\[EB/OL]//Dictionary of Irish Biography. \[2026-04-18]. <https://www.dib.ie/biography/berkeley-george-a0611>. 爱尔兰传记词典贝克莱条目，提供贝克莱生平最详尽权威之学术传记，含精确日期（如 1696 年 7 月 17 日入基尔肯尼学院、1700 年 3 月 21 日入都柏林圣三一学院、1707 年 6 月当选研究员、1710 年春受按立为牧师等）。
* Stock J. An Account of the Life of George Berkeley, D.D., Late Bishop of Cloyne in Ireland\[M]. Dublin, 1776: 12. 贝克莱最早之传记，记载其临终时妻子在旁诵读布道文等细节。
* Popper K R. A Note on Berkeley as Precursor of Mach\[J]. The British Journal for the Philosophy of Science, 1953, 4(13): 26-36. 论证贝克莱对牛顿绝对时空观之批判先于马赫，为爱因斯坦广义相对论之思想先驱。
* Berkeley Historical Society. Why Is Berkeley Called Berkeley?\[EB/OL]. \[2026-04-18]. <https://berkhistory.org/why-is-berkeley-called-berkeley/>. 伯克利历史学会与博物馆，Frederick Billings 于 1866 年援引贝克莱诗句命名伯克利。
* Berkeley Plaque Project. How Berkeley Got Its Name\[EB/OL]. \[2026-04-18]. <https://berkeleyplaques.org/plaque/how-berkeley-got-its-name/>. 1866 年 5 月 24 日采纳 Berkeley 之名。

## 加州大学伯克利分校的校训“Fiat Lux”（Let There Be Light，要有光）

“Fiat Lux”也可以意译为“让世界充满光明”。加州大学伯克利分校的诸多奖项均以“Fiat Lux”命名。

加州大学伯克利分校成立于 1868 年，是一所公立大学。同年，后来担任中国近代第一所国立大学——北京大学（前身京师大学堂，成立于 1898 年）校长的蔡元培诞生。他“要有良好的社会，必先有良好的个人，要有良好的个人，就要先有良好的教育”的观点，与“Fiat Lux”所倡导的以个人进步推动社会发展的理念不谋而合。蔡元培被尊为北大“永远的校长”。同年，日本启动明治维新，迈入新时代并走上现代化道路，然而这一进程也为日本未来的侵略战争埋下了伏笔。

Fiat Lux 出自拉丁文圣经“1.3：Dixitque Deus: Fiat lux. Et facta est lux.”（圣经武加大译本）。“And God said, ‘Let there be light,’ and there was light.”（NIV 版圣经）“1.3：神说、要有光、就有了光。”（《和合本圣经》）

依据经文，先有光，后有世界。在基督教神学中，上帝先于人类创造了光，这真理之光照耀世人，也被视作人类理性的源泉。

作为校训，“Fiat Lux”意味着以知识启蒙世人。正如柏拉图的光照说，知识就像太阳照耀着世界，驱散无知的黑暗。这代表着学生要用知识改造世界，祛除灰暗。然而，光明所至，阴影亦必随行。

尼采指出，“与恶龙缠斗过久，自身亦成为恶龙；凝视深渊过久，深渊将回以凝视”。

此校训也时刻警醒学生，需注意自身及周遭环境，避免重蹈苏格拉底的覆辙：苏格拉底试图让人们承认自己实际上一无所知，拥有的只是意见而非真理。这与老子《道德经》所言“光而不耀”有相通之处。

它警示人们应避免将学术卷入意识形态纷争。然而，在当今美国强调身份政治的氛围下，加州大学伯克利分校图书馆以平等与包容为由，摘除了乔治·贝克莱的画像（因其曾购买奴隶）。而伯克利分校（UC Berkeley）之名正源自贝克莱（Berkeley）。此举与其一贯追求的自由理念相悖，也有违儒家孔子“名不正，则言不顺；言不顺，则事不成”的名正思想。这促使人们反思：初心是否已被遗忘？对黑暗的恐惧是否仍然存在？

现代科学对光的认识也异常曲折。研究表明，光同时具有波动性和粒子性。科学研究光的范式不断演变，“Fiat Lux”的精神内涵也随之变化。创校之初，伯克利定位为教育的灯塔；如今则强调每位学生作为独立光源的价值。2024 年的一项研究表明，光也存在影子。

“Fiat Lux”意味着，接受教育、获取知识不仅能改变个人命运，也能改变人类文明的进程。然而，这引出若干哲学追问：启蒙真的是可能的吗？教育是可能的吗？康德认为，“启蒙运动就是人类脱离自己所加之于自己的不成熟状态。”但问题在于，人们真的有勇气承认自己是不成熟的、无知的、愚昧的吗？人们真的愿意以知识的痛苦换取无知的快乐吗？柏拉图笔下洞穴中的人，真的愿意挣脱铁链，回到大地接受光明吗？有责任、有义务、有能力启蒙所有人吗？人人如龙可能吗？这对他们来说是快乐的吗？那些受过现代高等教育的人，是否仍处于“有学识的无知”状态？他们究竟是光，还是暗？是否将现代科学与光简单画等号，而无视现代科学自身理论根基的未固？

叔本华认为，许多人将圆滑世故视为成熟，而这实际上只是另一种不成熟。“Fiat Lux”号召学生永葆赤子之心，追求自由与理想。它鼓励学生不仅止于言说，更重于实践。

作为公立大学，Fiat Lux 意味着鼓励学生投身于加州地区乃至美国的建设，提高美国人民的受教育水平，伯克利分校的助学政策使约 38% 的本科生无需自付学费（加州大学系统整体则有 54% 的加州籍本科生免学费），旨在保障所有人接受高等教育的权利，使其不因经济拮据而放弃学业，从而实现大学的教育使命。加州大学伯克利分校在 2025 年的 QS 世界排名为第 12 名。加州大学伯克利分校已诞生 63 位 [诺贝尔奖](https://inspire.berkeley.edu/get-inspired/nobels/)得主，切实履行了大学的学术责任。

《说文解字》载：“光，明也”。Fiat Lux 意味着追求光明与正义。加州大学伯克利分校学子也始终通过反对越南战争、言论自由运动等一系列运动践行校训。作为中国教育史上的丰碑，国立西南联合大学，其纪念碑碑文载“河山既复，日月重光，联合大学之战时使命既成，奉命于三十五年五月四日结束。”在艰苦卓绝的环境中仍旧保留着学术的火种，散发着大学的光芒。国立西南联大存续时间虽短，却令人久久难忘。学生们或投笔从戎，或勤奋苦学以立志报国。“Fiat Lux”同时也是数十所其他高校的校训。国立西南联合大学的校训是“刚毅坚卓”，虽无“光”字，但师生皆化为光，推动中国现代化的进程。而今再也找不到西南联大了。

光也是流行文化中的核心元素之一。《迪迦奥特曼》剧中沙耶香说“每个人心里都有黑暗面，但是也有光明的一面！现在，我已经可以相信，只要努力到最后不轻言放弃，我相信人类，一定能够创造出光明的未来，也能创造出美好的生命。只要珍惜重要的东西，我相信一定能够办到！”正是对“追求光”“要有光”这一主题的深入诠释，使这部特摄作品在奥特曼系列中具有独特的思想深度。作品深刻探讨了诸多社会问题，如环境保护与能源开发的张力、城市化与乡村保护、战争与和平、宇宙探索等。剧中更指出，光明亦可能是极致的黑暗：面对类似《黑客帝国》中的“红蓝药丸”选择，人们是否愿意承认，美好世界或许只是一场空？（45 话《生命永存》）在邪恶迪迦篇章中，真角大古（マドカ ダイゴ）与正木敬吾（マサキ•ケイゴ）之间的张力，象征着光与影的矛盾，阐明光本身并无正邪之分，光影本是一体。《圣经》中，上帝创造了光，而在本作大结局中，只要心有光，人人都可以成为光，成为迪迦奥特曼。迪迦奥特曼乃至于整个奥特曼作品中，都涉及了正义问题。关于如何定义正义目前存在争议，引申问题则是道德的形成。若认为道德是约定俗成的，那么正义的定义便是因时因地而异的。例如基督教和本土国家的礼仪冲突。还有一种观点认为正义等词语是弱者用来欺骗奴役强者的谎言。实现自身能力的强者才是正义。如果认为道德是统治者意志的化身，那么正义的定义就来源于统治本身的合法性与基础。如果认为道德来自神，那么正义的定义是按上帝的旨意行事。如果认为道德是幻觉，根本不存在，那么正义本身即非正义。如果认为道德来自社会契约，那么正义即遵守法律。是什么使之成为正义？正义是否必然获得正向的道德评价与价值判断？是否承认有一些不因时因地而变化的永恒的道德准则？例如，“任何时候都不能杀人”。在某些观点看来，奥特曼打怪兽的行为可能是非正义的（例如，若地球人并非原住民，怪兽未造成实际损害，或怪兽本身是人类受害者转变而来等）。此外，正义与幸福或至高快乐之间是否存在必然联系？《迪迦奥特曼》深入探讨了这些哲学议题。其他奥特曼作品大多聚焦于单纯的战斗，即使是接续《迪迦奥特曼》的《戴拿奥特曼》《盖亚奥特曼》亦如此。迪迦奥特曼的不同之处在于他认识到了正义的多元化与不确定性，甚至在不同的设定中，迪迦奥特曼在远古曾是邪恶的化身。作品也深入探讨了天赋（大古具有巨人的 DNA 等），出身与个人努力之间的张力。该作并未简单地将怪兽定义为邪恶与非正义，也未主张必须消灭所有怪兽。这种简单的观点，只会让作品退化为类似 PVP 游戏的高级录像或单纯的玩具广告。抵抗大众化与娱乐化都难免失败，但不抵抗甚至纵容又令人遗憾。

在动漫作品《日常系的异能战斗》第 7 集 10-13 分中，角色栉川鸠子说道“血腥有什么帅的？疯狂有什么好的，我不明白！罪孽深重是什么意思？黑暗又是什么？黑暗就好吗？！正义和邪恶，为什么邪恶更好？为什么坏的反而是好的？！坏不就是因为它坏才叫坏的吗？！”一种观点认为栉川鸠子的话表达了朴素的道德直觉，而男主角安藤寿来的论述则流于表面修辞（中二病发作）。然而，这一判断本身值得重新审视。人们常先入为主地将某些事物视为神圣且毋庸置疑的，而实际上它们可能未经任何严肃的思考与论证。光明之所以是好的，仅仅因为它能照亮事物，而黑暗仅是光明的缺失吗？究竟什么是正义，是柏拉图《理想国》中讨论了数百页而未决的问题。难道仅凭“好”就能断定正义值得追求和向往吗？强迫别人接受光明，走出洞穴，真的是好的，是所谓正义吗？而洞穴中的生活，就一定是邪恶与黑暗的吗？难道能否认，他们身处洞穴之中，或许确实感到快乐这个事实吗？

康德限制了自由的地盘以保护人们的道德，但终究是不可知的。光，或许从未真正存在过。现实是，美国社会分化加剧，越来越多学生依靠贷款上学，甚至无家可归。加州大学系统屡次因生活成本问题爆发大规模学术罢工，校园治安环境不佳，校舍等基础设施也难以满足国际化校园的需求。伯克利校区的餐饮服务也曾因品质问题受到学生诟病。

“Fiat Lux”精神不仅关乎教育与知识，同样渗透于伯克利的科技创新之中，并辐射至现代计算机技术领域。

伯克利分校孕育了 BSD、RISC-V、RAID 等重要的计算机技术。以 FreeBSD 为代表的 BSD 操作系统所体现的开源精神（即 BSD 许可证不像 GPL 许可证那样具有“传染性”，不强制使用者开源），致力于知识共享，让技术得到尽可能广泛的应用以产生最大社会效益，忠实恪守了“Fiat Lux”的精神。

BSD 技术如同光一样，遍布诸多领域却不为人所熟知，从 iPhone 到新能源汽车车机，从索尼 PS5 到 Netflix，都有其身影。

唯有真正理解“Fiat Lux”，才能领悟为什么是 BSD，为什么是 FreeBSD。

Fiat Lux!

### 参考文献

* University of California, Berkeley. Fiat Lux Scholarship\[EB/OL]. \[2026-03-25]. <https://financialaid.berkeley.edu/types-of-aid-at-berkeley/scholarships/fiat-lux-scholarship/>. 为加州大学伯克利学生提供经济资助的奖学金项目。
* 北京大学校史馆. 蔡元培像\[EB/OL]. \[2026-03-25]. <https://www.xsg.pku.edu.cn/details/1893.html>. 展示蔡元培先生塑像。
* 山本四郎. 小川又次稿:清国征讨策案\[J]. 日本史研究, 1964(75). 随着明治维新，国力渐增，日本逐步迈上了对外侵略扩张的军国主义道路，1887 年，日本参谋本部制定了所谓“清国征讨策略”，逐渐演化为以侵略中国为中心的“大陆政策”。
* 蔡元培. 蔡元培：言有物，行有伦\[M]. 北京: 中国文史出版社, 2023. ISBN: 978-7-5205-3816-9. 阐述蔡元培教育思想与文化理念。
* Piazza L, Lummen T T A, Quiñonez E, et al. Simultaneous observation of the quantization and the interference pattern of a plasmonic near-field\[J]. Nature Communications, 2015, 6: 6407. 揭示等离子体近场的量子化与干涉现象。
* Kant I. 历史理性批判文集\[M]. 何兆武,译. 天津: 天津人民出版社, 2014: 22. 答复这个问题：“什么是启蒙运动？”. ISBN: 978-7-201-08641-5. 系统阐述启蒙运动的哲学内涵与历史意义。
* University of California, Berkeley Library. Portrait of UC Berkeley namesake no longer on display in Doe Library\[EB/OL]. \[2026-03-25]. <https://www.lib.berkeley.edu/about/news/george-berkeley-portrait>. 记录大学校园历史争议与文化反思。
* 尼采. 善恶的彼岸\[M]. 赵千帆,译. 北京: 商务印书馆, 2015. ISBN: 978-7-100-11749-4. 探讨道德哲学与价值重估的核心命题。
* 松原信吾,村石宏实,川崎乡太,等,导演. 迪迦奥特曼\[V]. 日本:圆谷株式会社,1996. 第 47 集《告别黑暗》，梅塔莫尔加登场，第 21 分钟，沙耶香。通过特摄作品探讨光明与黑暗的辩证关系。
* 清华大学. 国立西南联合大学纪念碑碑文\[EB/OL]. \[2026-03-25]. <https://www.tsinghua.org.cn/info/1952/17852.htm>. 记载西南联大历史使命与学术精神。
* 闻黎明. 西南联大与现代中国（1937\~1946）\[M]. 北京: 社会科学文献出版社, 2023. ISBN: 978-7-5201-9805-9. 全面研究西南联大历史地位与文化影响。
* 大冢雅彦,高桥正典,清水久敏,等,导演. 日常系的异能战斗(異能バトルは日常系のなかで)\[V]. 日本:泉光高中文艺部,2014. 以校园日常为背景的动画作品，其中角色对正义与邪恶的质问构成了本节讨论的引用来源。
* Abrahao R A, Morin H P N, Pagé J T R, et al. Shadow of a laser beam\[J]. Optica, 2024, 11(11): 1549-1555. 实验证明激光束存在阴影的光学现象（论文指出，光也有影子）。
* University of California, Berkeley. Nobelists\[EB/OL]. \[2026-04-16]. <https://inspire.berkeley.edu/get-inspired/nobels/>. 记载“By our count, there are 63 Berkeley Nobelists”。
* University of California, Berkeley. History & discoveries\[EB/OL]. \[2026-04-18]. <https://www.berkeley.edu/about/history/>. 加州大学伯克利分校官方校史，1868 年建校。
* University of California. Tuition & financial aid\[EB/OL]. \[2026-04-18]. <https://admission.universityofcalifornia.edu/tuition-financial-aid/>. 加州大学系统官方学费与资助信息，54% 加州籍本科生免学费。
* University of California, Berkeley. Cost\[EB/OL]. \[2026-04-18]. <https://admissions.berkeley.edu/cost/>. 伯克利分校官方招生页面，38% 本科生无需自付学费。
* Patterson D A, Gibson G, Katz R H. A Case for Redundant Arrays of Inexpensive Disks (RAID)\[R]. Berkeley: University of California, EECS Department, 1987. CSD-87-391. 加州大学伯克利分校技术报告，首次提出 RAID 概念。
* Asanović K, Waterman A, Lee Y. RISC-V ISA\[EB/OL]. RISC-V International, \[2026-04-18]. <https://riscv.org/about/>. RISC-V 指令集架构始于 2010 年加州大学伯克利分校 Par Lab 项目。
* 北京大学. 北京大学简介\[EB/OL]. \[2026-04-18]. <https://www.pku.edu.cn/about.html>. 北京大学官方页面，1898 年建校，初名京师大学堂。

## 课后习题

1. 将 *The analyst; or, a discourse addressed to an infidel mathematician. Wherein it is examined whether the object, principles, and inferences of the modern analysis are more distinctly conceived, or more evidently deduced, than religious mysteries and points of faith*（《分析学家；或一篇致一位不信神数学家的论文，其中审查一下近代分析学的对象、原则及论断是不是比宗教的神秘、信仰的要点有更清晰的表达，或更明显的推理》）翻译为中文，并尝试将之公理化。
2. 比较贝克莱《人类知识原理》的原始文本与中文译本，复现其中关于存在与感知关系的核心论证，并用一阶逻辑符号重构其推理结构。
3. 编写加州大学伯克利分校校史与国立西南联合大学校史。
4. 观看纪录片《在伯克利》（怀斯曼 F, 导演. 在伯克利\[V]. 美国: Zipporah Films, 2013.），归纳影片中加州大学伯克利分校在学术治理与教育理念方面的核心特征。


# 3.2 BSD 许可证概览

BSD 许可证是自由软件许可证中的重要类别，其使用条款较为宽松。本文列出主要的 BSD 许可证，包括 OSI（开放源代码促进会）认可的许可证，以及具有历史意义但未被 OSI 认可的 BSD-4-Clause。更多 BSD 许可证信息可参见 OSI。

下文列出的所有 BSD 许可证均属非 copyleft（著佐权）许可证，即不强制要求修改后的衍生版本仍需作为自由软件发布。

BSD 许可证条款编号用于表示附加义务和限制条件的复杂度。0BSD 限制最少，BSD-4-Clause 限制最多。

```sh
BSD 许可证限制程度递增

0BSD（零条款）
  │  无任何限制
  ↓
BSD-1-Clause（一条款）
  │  + 版权声明
  ↓
BSD-2-Clause（两条款，FreeBSD 优先选用）
  │  + 二进制再发布声明
  ↓
BSD-3-Clause（三条款）
  │  + 禁止背书
  ↓
BSD-4-Clause（四条款，原始版，未获 OSI 认可）
     + 广告条款
```

## BSD 零条款许可证（Zero-Clause BSD，0BSD）

BSD 零条款许可证是 BSD 许可证系列中限制最少的一种。该许可证虽然以“BSD”命名，实际上并非源自传统 BSD 家族。

此许可证为 ISC 许可证的变体。ISC 许可证源自 Internet Software Consortium（后更名为 Internet Systems Consortium），属简洁型宽松许可证；0BSD 则近似于公共领域许可证。

全文如下：

```
Zero-Clause BSD
=============

Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
```

非官方译文：

```
BSD 零条款许可证

特此授予任何人出于任何目的使用、复制、修改和/或分发本软件的权限，无论是否收取费用。

本软件按“原样”提供，作者不对本软件作出任何保证，包括所有对适销性和适用性的暗示保证。在任何情况下，作者均不对因使用、数据或利润的损失所造成的任何特殊、直接、间接或后果性损害，或任何形式的损害承担责任，无论该损害是在合同诉讼、过失或其他侵权行为中引起，或由使用或执行本软件所引起。
```

## BSD 一条款许可证（The 1-Clause BSD License，BSD-1-Clause）

BSD 一条款许可证在零条款的基础上增加了版权声明的要求。

全文如下：

```
Copyright (c) [年份]
[组织名称] [All rights reserved].

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY [Name of Organization] "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL [Name of Organization] BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

非官方译文：

```
版权所有 (c) [年份]

[组织名称] 保留所有权利。

在满足以下条件的前提下，允许在源代码和二进制形式中重新分发和使用本软件，无论是否经过修改：

源代码的再发布必须保留上述版权声明、本条件列表以及以下免责声明。
本软件由 [组织名称] 按“原样”提供，不作任何明示或暗示的保证，包括但不限于对适销性和特定用途适用性的暗示保证。在任何情况下，[组织名称] 均不对因使用本软件而引起的任何直接、间接、附带、特殊、惩罚性或后果性损害（包括但不限于采购替代商品或服务、使用、数据或利润的损失，或业务中断）承担责任，无论责任主张基于合同、严格责任或侵权行为（包括过失或其他），即使已被告知可能发生此类损害。
```

## BSD 两条款许可证（The 2-Clause BSD License，BSD-2-Clause）

BSD 两条款许可证应用较为广泛，即 FreeBSD 许可证，亦称简化版 BSD 许可证，为 FreeBSD 项目优先选用。该许可证删除了原始 BSD 许可证（BSD-4-Clause）中的广告条款与背书条款，仅要求在源代码和二进制再发布中保留版权声明、条件列表及免责声明。广告条款原本要求在所有提及本软件功能或用途的广告材料中注明使用了原作者开发的软件，因其实际使用不便，现已移除。

全文如下：

```
Copyright <年份> <版权持有者>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

非官方译文：

```
版权所有 <年份> <版权持有者>

在满足以下条件的前提下，允许在源代码和二进制形式中重新分发和使用本软件，无论是否经过修改：

1. 源代码的再发布必须保留上述版权声明、本条件列表以及以下免责声明。

2. 二进制形式的再发布必须在随附的文档和/或其他材料中复制上述版权声明、本条件列表以及以下免责声明。

本软件由版权持有者和贡献者按“原样”提供，不作任何明示或暗示的保证，包括但不限于对适销性和特定用途适用性的暗示保证。在任何情况下，版权持有者或贡献者均不对因使用本软件而引起的任何直接、间接、附带、特殊、惩罚性或后果性损害（包括但不限于采购替代商品或服务、使用、数据或利润的损失，或业务中断）承担责任，无论责任主张基于合同、严格责任或侵权行为（包括过失或其他），即使已被告知可能发生此类损害。
```

## BSD 三条款许可证（The 3-Clause BSD License，BSD-3-Clause）

BSD 三条款许可证在两条款的基础上增加了对使用作者名义推广的限制。BSD 三条款许可证亦称为新 BSD 许可证或修改版 BSD 许可证。此许可证删除了原始 BSD 许可证（即 BSD-4-Clause）中的广告条款，并额外限制以作者名义推广衍生产品。

全文如下：

```
Copyright <年份> <版权持有者>

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

非官方译文：

```
版权所有 <年份> <版权持有者>

在满足以下条件的前提下，允许在源代码和二进制形式中重新分发和使用本软件，无论是否经过修改：

1. 源代码的再发布必须保留上述版权声明、本条件列表以及以下免责声明。

2. 二进制形式的再发布必须在随附的文档和/或其他材料中复制上述版权声明、本条件列表以及以下免责声明。

3. 未经事先书面许可，不得使用版权持有者或其贡献者的姓名为源自本软件的产品背书或推广。

本软件由版权持有者和贡献者按“原样”提供，不作任何明示或暗示的保证，包括但不限于对适销性和特定用途适用性的暗示保证。在任何情况下，版权持有者或贡献者均不对因使用本软件而引起的任何直接、间接、附带、特殊、惩罚性或后果性损害（包括但不限于采购替代商品或服务、使用、数据或利润的损失，或业务中断）承担责任，无论责任主张基于合同、严格责任或侵权行为（包括过失或其他），即使已被告知可能发生此类损害。
```

## BSD 四条款许可证（BSD 4-Clause “Original” or “Old” License，BSD-4-Clause）

BSD 四条款许可证是 BSD 许可证的原始版本，具有较多限制条件。BSD 四条款许可证即原始的 BSD 许可证，目前未获 OSI 认可。此许可证带有广告条款，要求在所有提及本软件功能或用途的广告材料中声明使用了原作者的产品（参见下文第 3 条）。

全文如下：

```
Copyright (c) <年份> <持有者>. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software must display the following acknowledgement:
This product includes software developed by the organization.
4. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

非官方译文：

```
版权所有 <年份> <所有者>。保留所有权利。

在满足以下条件的前提下，允许在源代码和二进制形式中重新分发和使用本软件，无论是否经过修改：

1. 源代码的再发布必须保留上述版权声明、本条件列表以及以下免责声明。
2. 二进制形式的再发布必须在随附的文档和/或其他材料中复制上述版权声明、本条件列表以及以下免责声明。
3. 所有提及本软件功能或用途的广告材料中必须包含以下致谢声明：本产品包含由该组织开发的软件。
4. 未经事先书面许可，不得使用版权持有者或其贡献者的姓名为源自本软件的产品背书或推广。

本软件由版权持有者按“原样”提供，不作任何明示或暗示的保证，包括但不限于对适销性和特定用途适用性的暗示保证。在任何情况下，版权持有者均不对因使用本软件而引起的任何直接、间接、附带、特殊、惩罚性或后果性损害（包括但不限于采购替代商品或服务、使用、数据或利润的损失，或业务中断）承担责任，无论责任主张基于合同、严格责任或侵权行为（包括过失或其他），即使已被告知可能发生此类损害。
```

## 参考文献

* Open Source Initiative. OSI Approved Licenses\[EB/OL]. \[2026-04-17]. <https://opensource.org/licenses>. OSI 是开源软件许可证的官方认证机构，提供最权威的许可证审批与分类信息。更多 BSD 许可证信息参见 <https://opensource.org/licenses?ls=BSD>。
* SPDX. SPDX License List\[EB/OL]. \[2026-03-25]. <https://spdx.org/licenses/>. SPDX 提供标准化的许可证标识列表。
* FSF. BSD 许可证的问题\[EB/OL]. \[2026-03-25]. <https://www.gnu.org/licenses/bsd.zh-cn.html>. 更多关于 BSD 许可证与 copyleft 范式比较的讨论参见此处。


# 3.3 NetBSD 概论

本节介绍 BSD 家族的另一成员 NetBSD。NetBSD 是一个开源、可移植的类 UNIX 操作系统，作为 BSD 家族的重要成员，它起源于 4.3BSD Net/2 和 386BSD，其首个版本 0.8 发布于 1993 年 4 月 19 日（此后也引入了 4.4BSD-Lite 的变更）。

NetBSD 的学术渊源可追溯至加州大学伯克利分校（UC Berkeley）的 Berkeley Software Distribution（BSD）项目，在操作系统可移植性研究领域占有一席之地。

本节介绍 NetBSD 的技术特性、生态系统及实践应用。

## 技术特性与生态系统

NetBSD 的[口号](https://www.netbsd.org/about/portability.html) 是“Of course it runs NetBSD”（意为“当然可以运行 NetBSD”），这一口号体现了它在跨平台兼容性方面的技术追求。

NetBSD 支持[多种架构](https://wiki.netbsd.org/ports/)。其中，一级架构（Tier I）为官方战略重点支持的平台，二级架构（Tier II）为社区自主演进维护的平台。目前 NetBSD 支持 8 个一级架构和 49 个二级架构，其架构支持广度在同类操作系统中名列前茅。

NetBSD 主要面向技术爱好者和开发者，对普通用户而言具有一定的学习曲线，开发者是该系统的核心用户。

NetBSD 开发的 [pkgsrc](https://www.pkgsrc.org/) 包管理器框架也支持 macOS、Linux 等多个操作系统。pkgsrc 以可移植的构建脚本实现跨平台软件管理，体现了 NetBSD 的可移植性设计理念。

NetBSD 提供 Linux 兼容层，可运行部分 Linux 二进制程序，主要支持命令行工具和基础图形应用。

在硬件驱动方面，NetBSD 自带 i915 显卡驱动和 AMD 相关驱动，并支持 UEFI 启动和 NVMe 存储设备。

NetBSD 对 NVIDIA 显卡大致支持到 Pascal 架构（GeForce GTX 10 系列）。相关信息可参考 [nouveau / NetBSD](https://nouveau.freedesktop.org/NetBSD.html) 和 [nouveau(4) - NetBSD Manual Pages](https://man.netbsd.org/nouveau.4)（具体硬件支持列表）。

## 项目支持渠道

为 NetBSD 项目提供支持，最简单的方式是通过 [GitHub Sponsors](https://github.com/sponsors/netbsd) 捐赠。~~还可获得一个 GitHub 徽章~~ [~~Public Sponsor~~](https://github.com/orgs/community/discussions/19916)~~。~~

> **技巧**
>
> 支付后支付方式将绑定，如需解除绑定，可联系 GitHub 客服 [提交工单](https://support.github.com/)，通常在一个工作日内即可处理。

还可通过 [Donate using Stripe](https://www.netbsd.org/stripe.html) 捐赠，该方式支持中国银联、Google Pay 等多种支付方式。

## NetBSD 上的 ZFS

ZFS（Zettabyte File System，泽字节文件系统）作为一个功能完备的企业级文件系统，在 NetBSD 上也有相应的实现。以下为相关资源：

* 手册页 [zfs(8) - NetBSD Manual Pages](https://man.netbsd.org/zfs.8)，提供 ZFS 文件系统的官方命令参考
* [Finish ZFS](https://wiki.netbsd.org/projects/project/zfs/)，ZFS 移植项目进展报告
* [Google 编程之夏 2007](https://developers.google.com/open-source/gsoc/2007?hl=zh-cn)，记录了 ZFS 引入计划的早期阶段
* [Google Summer of Code zfs-port project](https://blog.netbsd.org/tnf/entry/google_summer_of_code_zfs)，ZFS 移植项目的官方技术报告
* [Root On ZFS](https://wiki.netbsd.org/root_on_zfs/)，提供 ZFS 根分区安装指南
* [NetBSD zfs Wiki](https://wiki.netbsd.org/zfs/)，NetBSD ZFS 维基，记录 NetBSD 引入 ZFS 代码的过程——最初从 OpenSolaris 移植，2009 年导入 NetBSD 基本系统，2018 年将 ZFS 代码库重新基于 FreeBSD 的 OpenZFS 实现进行更新，以获得更现代化的 ZFS 体验

在 NetBSD 源代码中，最早可见的 ZFS 提交为 [Import Opensolaris source code used with zfs port. Zfs code si from date](https://github.com/NetBSD/src/commit/c1cb2cd89c023350f357f813e12b526f6f71002f)（2009 年）。NetBSD ZFS 代码最初从 OpenSolaris 移植，2009 年导入基本系统，2018 年重新基于 FreeBSD 的 OpenZFS 实现进行更新。截至 2026 年，ZFS 代码仍持续维护（如 src/external/cddl/osnet 路径下可见定期提交），但存在若干已知问题（如部分架构内核栈空间不足、ARC 内存占用过高等）。

## 参考文献

* The NetBSD Foundation. Information about NetBSD 0.8\[EB/OL]. \[2026-04-14]. <https://www.netbsd.org/releases/formal-0.8/>. NetBSD 项目官方发行页面。该页面记载 NetBSD 0.8 发布于 1993 年 4 月 19 日。
* The NetBSD Foundation. The History of the NetBSD Project\[EB/OL]. \[2026-04-18]. <https://www.netbsd.org/about/history.html>. NetBSD 官方项目历史，记载 NetBSD 起源于 4.3BSD via Net/2 和 386BSD。
* The NetBSD Foundation. NetBSD Portability\[EB/OL]. \[2026-04-14]. <https://www.netbsd.org/about/portability.html>. NetBSD 官方可移植性说明，阐述跨平台支持策略。
* The NetBSD Foundation. Platforms Supported by NetBSD\[EB/OL]. \[2026-04-18]. <https://wiki.netbsd.org/ports/>. NetBSD 官方架构支持页面，当前有 8 个一级架构（Tier I）和 49 个二级架构（Tier II）。
* The NetBSD Foundation. pkgsrc -- The NetBSD Packages Collection\[EB/OL]. \[2026-04-14]. <https://www.pkgsrc.org/>. pkgsrc 包管理器框架官方站点，提供跨平台软件管理方案。
* The NetBSD Foundation. zfs(8) -- NetBSD Manual Pages\[EB/OL]. \[2026-04-14]. <https://man.netbsd.org/zfs.8>. NetBSD 上 ZFS 文件系统命令参考手册页。
* The NetBSD Foundation. NetBSD ZFS Wiki\[EB/OL]. \[2026-04-14]. <https://wiki.netbsd.org/zfs/>. NetBSD ZFS 维基，记录 ZFS 移植进展与使用指南。
* Nouveau Wiki. Feature Matrix\[EB/OL]. \[2026-04-16]. <https://nouveau.freedesktop.org/FeatureMatrix.html>. Nouveau 驱动功能支持列表，列出了各 GPU 架构的功能比较。
* Nouveau Project. CodeNames\[EB/OL]. \[2026-04-17]. <https://nouveau.freedesktop.org/CodeNames.html>. nouveau GPU 架构与代号映射表。

## 课后习题

1. 分析“发行版”（Distribution）这一术语的演进历史。


# 3.4 OpenBSD 概论

OpenBSD 是 BSD 家族中的重要成员，自 1995 年诞生以来，始终以“安全性优先”为设计理念，其发展与开源运动、网络安全和软件工程方法论紧密相连。

## 语录摘选

### Theo de Raadt（OpenBSD 创始人）

> Linux 那群人这样做是因为他们恨微软。我们这样做是因为我们热爱 Unix。

> 这玩意儿垃圾得不行（指 Linux），大家还都在用，完全没意识到问题有多大。那些搞 Linux 的也不想着停下来好好改一改，只知道接着用、继续往上堆砌功能，没人愿意说一句：“这玩意儿真是个垃圾，咱们得重新造轮子。”

> 我偶尔会浏览 DragonFly BSD 的代码，看看有没有什么东西 OpenBSD 可以用，但迄今为止我还没有发现任何东西。

> 我们面临的最大问题是人们会将 GPL 套在我们的代码上，以同样的方式（此处指以 GPL 许可重新分发 BSD 代码，该代码后续将无法合并回原有 BSD 项目）将我们排除在外。……我们有很多公司一直在回馈代码。但是一旦代码被 GPL 化，我们就无法再获取它。

### 林纳斯·托瓦兹 Linus Torvalds（Linux 创始人）

> 我觉得 OpenBSD 那帮人就像一群自慰的猴子，整天将“我们专注安全”这事儿当回事儿炒作个不停。

## OpenBSD 官方介绍

OpenBSD 是一种功能完备的多平台类 UNIX 操作系统，基于伯克利网络发布版本 2（Networking Release 2，Net/2）和 4.4BSD-Lite。尽管该家族中有多个操作系统，但 OpenBSD 以“安全性”和“严谨性”优先而独树一帜。OpenBSD 团队致力于实现“默认安全”状态，这意味着 OpenBSD 用户可以确信，新安装的系统不会轻易遭到入侵。通过积极的安全策略，OpenBSD 实现了这一目标。

安全漏洞本质上是设计或实现中的错误。OpenBSD 团队既注重新代码的编写，也重视发现和修复现有的设计缺陷及实现的漏洞，故 OpenBSD 系统不仅更加安全，也更加稳定。所有关键系统组件的源代码都经过检查，以防止远程访问、本地访问、拒绝服务、数据破坏以及信息收集等问题。

除了修复漏洞，OpenBSD 还将强大的加密功能集成到基本系统中。OpenBSD 系统提供了功能齐全的 IPsec 实现，并支持常用协议，如 SSL 和 SSH。同时，OpenBSD 也内置了网络过滤和监控工具，例如包过滤、NAT 和桥接，以及多种路由服务，如 BGP 和 OSPF。为了满足高性能需求，系统还加入了对硬件加密的支持。尽管安全性通常被认为与可用性存在权衡，OpenBSD 提供尽可能多的安全选项，让用户在享受安全计算的同时，不会感到负担。

由于 OpenBSD 源自加拿大，其加密组件（如 OpenSSH 和 IPsec）出口至全球不受限制。

（注意：如果 OpenBSD 进入美国，则不能从美国重新出口。因此，如果位于加拿大和美国以外地区，请勿从位于美国的镜像服务器获取发行版。）

## OpenBSD 简介

OpenBSD 也是一种类 UNIX 计算机操作系统，诞生于 1995 年，由南非出生的加拿大籍程序员 Theo de Raadt 从 NetBSD 复刻而来（他也是 NetBSD 的创始人之一）。根据现存的 [NetBSD 邮件列表](https://mail-index.netbsd.org/netbsd-users/1994/12/23/0000.html) 记载，他因言语不当和攻击他人被开除出核心小组。

> 在 12 月 20 日（指 1994 年），NetBSD 项目中仅存的核心成员要求 Theo de Raadt 下台。这是一个极其艰难的决定，其原因在于 Theo 长期以来对 NetBSD 的用户与开发者表现出的无礼和辱骂行为。我们认为，作为 NetBSD 项目的代表不应有此类行为，并且这种行为从整体上来说对 NetBSD 造成了损害。
>
> 这个决定之所以艰难，是因为 Theo 曾长期为 NetBSD 作出积极贡献。他曾是 NetBSD SPARC 支持的主要维护者，并编写了大量代码，数不胜数。我们当然愿意接受（并且非常希望看到）Theo 今后仍为 NetBSD 做出贡献，但我们认为他不再适合继续作为 NetBSD 的“官方”代表。

OpenBSD 每 6 个月发布一次新版本。

OpenBSD 被广泛认为是世界上最安全的操作系统。OpenBSD 的口号是“Only two remote holes in the default install, in a heck of a long time!”（在如此漫长的时间里，默认安装下仅存在两个远程漏洞！）

OpenBSD 采用 LLVM/Clang 项目构建系统，默认 shell 为 ksh（基于 pdksh，而非 David Korn 的原始 ksh88/ksh93）。OpenBSD 吉祥物是一只河豚：普菲（Puffy）。

相较于其他 BSD 系统，OpenBSD 的设计取向更偏向安全性（例如移除了 Linux 兼容层，用 doas 替代 sudo，并默认 [限制超线程](https://marc.info/?l=openbsd-tech\&m=153504937925732\&w=2)）。对此，用户体验则见仁见智（整个系统性能方面表现相对保守，例如包管理器运行速度较慢），毕竟这样的后果之一是软件相对较少，不仅远远落后于 FreeBSD，甚至比起 NetBSD 也略逊一筹。不过，OpenBSD 以极少量的人力和物力维护了 amd64/i386、arm64/armv7 及 riscv64 等诸多架构，是一款实实在在的通用操作系统。为了拓展桌面用户，也打包了 GNOME、MATE 和 Xfce 等桌面环境以及 Blender、Firefox、Krita 和 LibreOffice 等一大批软件。未来 OpenBSD 有望在保持安全特性的同时优化性能，拓展使用场景。

在中文互联网上，OpenBSD 被不少人熟知，概因一条让人感慨万千的新闻——在 2014 年，[OpenBSD 项目因欠缴电费，面临关停的风险](https://marc.info/?l=openbsd-misc\&m=138972987203440\&w=2)，但是 OpenBSD 开发的软件，几乎所有使用互联网的人每一刻都在使用——OpenSSH 是 OpenBSD 的子项目，这也很常见，整个开源生态均由少数项目支撑，并且可能仅有不到个位数的人在进行维护，但他们往往得不到应有的重视，却践行了自己的开源使命。危机最终由罗马尼亚比特币企业家 Mircea Popescu 捐赠的 2 万美元化解。此后，包括国内罗永浩的 [锤子科技](https://undeadly.org/cgi?action=article\&sid=20161123193708) 在内的多家企业与个人也陆续向 OpenBSD 基金会捐款。

很多人对 OpenBSD 有着深深的误解，认为资金或人力不足影响了其开发进度，或者认为其只关注安全而忽视其他方面。但事实并非如此，OpenBSD 在驱动方面实现了现代化（DRM 同步至 Linux 6.12.50，已支持 Intel AX200/AX210 等 Wi-Fi 6/6E 适配器的 [iwx 驱动](https://man.openbsd.org/iwx.4)——但需注意，该驱动目前仅以 802.11ac 模式运行，尚未实现 802.11ax 协议功能），还支持了 [UFS](https://man.openbsd.org/ufshci.4)（Universal Flash Storage）。这说明资金和人力固然重要，却不是决定性因素。这个世界是由广大的草台班子组成的，还是由学院派精英构成，这永远是一个值得深思的问题。

OpenBSD 软件包管理策略较为严格，过时的软件包会被移除。例如，用户几乎无法找到可用的图形显示管理器（GDM 除外）。

OpenBSD 对 NVIDIA 显卡的支持，`nv` 驱动大致停留在 2009 年左右的 GT200 系列，而 `nouveau` 驱动支持到 Pascal 架构（GeForce GTX 10 系列）。

### 文件系统

**FFS（Berkeley Fast File System，伯克利快速文件系统）** 是一种高性能的 UNIX 文件系统，最早于 1983 年在 4.2BSD 中引入，通过优化数据块布局和索引节点设计提升文件 I/O 性能。

OpenBSD 默认使用的文件系统 FFS 在实现上与 FreeBSD 的 UFS 属于同一体系。它们在挂载参数上保持一致。

### 参考文献

* nv - NVIDIA video driver\[EB/OL]. \[2026-03-26]. <https://man.openbsd.org/nv.4>.`nv` 驱动具体硬件支持列表。
* nouveau - NVIDIA video driver\[EB/OL]. \[2026-03-26]. <https://man.openbsd.org/nouveau.4>.`nouveau` 驱动具体硬件支持列表。
* FreeBSD Project. ffs -- Berkeley fast file system\[EB/OL]. \[2026-04-02]. <https://man.freebsd.org/cgi/man.cgi?query=ffs&sektion=7>. 详细介绍 FFS 文件系统的技术规范与实现原理，提供系统文件系统设计参考。
* Leffler S J. Changes to the Kernel in 4.2BSD\[R]. University of California, Berkeley, 1983-07-25. 记载 4.2BSD 的内核变更，FFS 随该版本首次引入。4.2BSD 的正式发布时间为 1983 年 8 月，参见 MCKUSICK M K. Twenty Years of Berkeley Unix\[M]//SALUS P H, ed. Open Sources: Voices from the Open Source Revolution. Sebastopol: O'Reilly, 1999.
* The Register. Romanian Bitcoin baron stumps up $20k to keep OpenBSD's lights on\[EB/OL]. (2014-01-20)\[2026-04-17]. <https://www.theregister.com/2014/01/20/openbsd_bailed_out/>. 记载 2014 年电费危机由 Mircea Popescu 捐赠 2 万美元化解。
* OpenBSD Project. iwx(4) Device Drivers Manual\[EB/OL]. \[2026-04-16]. <https://man.openbsd.org/iwx>. OpenBSD iwx 驱动手册页，指出该驱动不支持 802.11ax 功能。
* OpenBSD Project. OpenBSD 7.8 Release\[EB/OL]. (2025-10-22)\[2026-04-16]. <https://www.openbsd.org/78.html>. OpenBSD 7.8 发行说明，DRM 同步至 Linux 6.12.50。
* OpenBSD Project. OpenBSD FAQ - Introduction to OpenBSD\[EB/OL]. \[2026-04-17]. <https://www.openbsd.org/faq/faq1.html>. OpenBSD 官方常见问题，记载默认 shell 为 ksh（基于 pdksh）。

## 机遇与挑战

### 社区与协作

与几位 OpenBSD 维护者和社区交流后发现，部分维护者在技术讨论中态度较为坚持己见。例如，有用户反馈 KDE 5 无法正常启动并出现黑屏的情况，经过数月排查后，发现问题实际上出现在虚拟机环境中，尤其是在启用 UEFI 时才会触发该错误。

另一个问题涉及 EFI 分区的处理。OpenBSD 安装器默认创建的分区布局在某些场景下可能不够合理，尤其在仅有 100 GB 磁盘空间时需要仔细规划。默认分区将空间划分得较为细致，实际操作中，例如执行 `pkg_add gnome`，需要预留足够空间。在较早版本中，系统不允许用户在安装过程中自定义 EFI 分区：即使用户自行创建 EFI 分区，系统也无法识别。用户必须先让安装器创建默认 EFI 分区，随后手动删除其他分区，仅保留 EFI，才能继续进行自定义分区设置。直到 7.6 版本，这一方面才有所改进。

OpenBSD 安装器在网络处理和错误恢复方面也存在一些可改进之处。例如，在安装过程中需要在线下载驱动，但下载失败时的错误处理机制可以更加完善；若用户尝试使用 Ctrl+C 中断，系统可能直接崩溃，只能重新开始安装；在断网状态下，安装器也可能停滞在某一步，无法继续。

以上问题已向相关开发者报告。在 KDE 5 移植相关的讨论中，也进行了技术探讨。

### 开发方式与协作流程

OpenBSD 至今仍沿用传统开发方式，主要通过邮件列表进行协作。项目不接受 GitHub 上的 Pull Request（PR）。整个项目仍然使用 CVS（Concurrent Versions System）进行版本控制，CVS 对 HTTP 代理的支持有限。对许多现代开发者而言，SVN（Subversion）可能已不熟悉，更不用说更早期的 CVS 工作流。这种开发方式对新开发者造成了一定困扰。

OpenBSD 的源代码大多缺少详细的注释和说明文件，初学者较难直接理解和学习。

OpenBSD 的 Bug 报告缺乏统一的追踪和报告平台，反馈主要通过邮件列表提交，信息容易丢失。

OpenBSD 的发行公告结构与可读性有待改善，内容呈现较为简略，难以直接阅读。缺少 Wiki 或类似平台来跟踪具体子项目的开发进度。

### 不稳定的 ABI

**ABI（Application Binary Interface，应用程序二进制接口）** 定义了编译后二进制代码与操作系统内核之间的交互规范，包括系统调用约定、数据结构布局和函数调用机制等。ABI 稳定性是确保跨版本二进制兼容性的关键因素。

据 Rust 维护者反馈（[OpenBSD support](https://github.com/rust-lang/rustup/issues/2168)），OpenBSD 的 ABI 十分不稳定，与 Linux 内核严格保持用户空间 ABI 向后兼容的做法截然不同。因此，Rust 团队无法通过 `rustup` 向 OpenBSD 用户提供预编译的 Rust 工具链。

目前，OpenBSD 用户只能通过 Ports 获取 Rust 工具链，或拉取源代码自行编译。

> OpenBSD 并不尝试保持向下兼容。在任意时刻，OpenBSD 仅支持两个稳定版本，同时提供一个频繁更新的开发版本，称为 `-current`。通常，较旧稳定版的二进制文件无法在较新的稳定版上运行。也无法保证上周构建的 `-current` 二进制文件能在本周的 `-current` 上正常运行。

有人可能认为不同版本不兼容是正常现象，但需要注意 OpenBSD 的频繁发布周期。

### 安全考量

在 OpenBSD 中，一些现代操作系统常见的安全模型或安全框架尚未获支持：

* 不支持安全启动和 TPM
* 系统和软件包的构建流程尚不够清晰透明，且技术栈相对落后（例如 CVS 的维护明显不足）
* 几乎未进行过任何合规性认证，甚至未采用 CIS 基准
* 不支持访问控制列表（ACL），也不支持强制访问控制（MAC，Mandatory Access Control）框架
* 未提供运行时完整性保护
* 不支持多级安全（MLS，Multi-Level Security）和 Biba 完整性模型
* 缺乏基于角色的访问控制（RBAC，Role-Based Access Control）机制
* 缺乏前沿或权威学术论文对其安全性进行验证
* 未进行独立的外部安全审计
* 未获得任何形式的安全认证

一项多年前的研究表明，OpenBSD 中的代码漏洞数量逐年减少，并且已发现的漏洞通常难以被利用进行攻击。（J. Shi, Zou D, Xu S, Deng X, Jin H. Does OpenBSD and Firefox’s Security Improve With Time?\[J]. IEEE Transactions on Dependable and Secure Computing, 2023, 20(4): 2781-2793. doi: 10.1109/TDSC.2022.3153325. 该研究通过时间序列分析验证了开源操作系统安全防护能力的持续改进。）

OpenBSD 的安全策略基于以下判断：超线程机制可能带来潜在的安全风险。因此，其做法并非修补微码，而是直接将超线程功能禁用。其在安全模型和安全理念方面的洞察是否深入，需要更多研究加以验证。

> **思考题**
>
> > 有的观点认为：“如果任何操作系统采取像 OpenBSD 这样激进且严格的安全策略，它的安全性将会超过 OpenBSD。但事实真的如此吗？Android 的安全策略被认为在所有操作系统中最为全面，且兼顾软硬件结合。然而，现实情况如何？”
>
> 你怎么看？

### 捐赠 OpenBSD

[Donating to the Foundation](https://www.openbsdfoundation.org/donations.html) 对于中国大陆用户而言，因为该基金会仅接受国际 PayPal，提示信息为“此国家或地区不支持捐赠给此收款人”，捐赠存在一定困难。已通过邮件反馈此问题，并曾写挂号信寄给位于加拿大的 OpenBSD 基金会，但未收到任何回应。即便使用 GitHub Sponsors 方式也可以，但多次沟通仍未得到支持。对此，深感不便。

目前，中国大陆用户可通过国内版本的 PayPal 或普通银联储蓄卡，向 PayPal 账号 `obsd-paypal@openbsdfoundation.org`（该账号为收款账号，并非电子邮件）发起转账，以对 OpenBSD 基金会进行捐赠。具体操作方法请自行搜索“PayPal 个人转账”。

## 附录：OpenBSD IPsec 协议栈 FBI 后门事件

在 2010 年，Theo de Raadt 收到并向社区公开了 [一封邮件](https://marc.info/?l=openbsd-tech\&m=129236621626462\&w=2)：

> 我收到了一封关于 OpenBSD 最初开发 IPSEC 协议栈的邮件。有人指称，一些前开发者（以及他们曾供职的公司）接受了美国政府的资金，在我们的网络协议栈，特别是 IPSEC 协议栈中植入了后门——约在 2000～2001 年期间。
>
> 由于这是我们拥有的首款可自由使用的 IPSEC 协议栈，因此这部分代码现在出现了在许多其他项目或产品中。在过去的十多年里，IPSEC 代码经历了许多变更与修复，因此目前尚不清楚这些指控所造成的实际影响有多大。
>
> 这封邮件是由一位我十多年来未曾联系过的人私下寄来的。我拒绝参与这种阴谋，也不会与 Gregory Perry 谈论此事。因此，我决定公开这封信，以便：
>
> （a）使用这段代码的人可以审计其中是否存在此类问题；
>
> （b）对这种说法感到愤怒的人可以采取其他行动；
>
> （c）如果这些说法不属实，被指控的人可以为自己辩护。
>
> 我也不喜欢自己的私人邮件被转发。但相比之下，将私人邮件泄露这种“小节有亏”，还远远不及政府出资让公司收买开源开发者（我们社区的成员），在软件中植入侵犯隐私的后门这种“大德有亏”。
>
> > 发件人：Gregory Perry <Gregory.Perry@GoVirtual.tv>
> >
> > 收件人： “<deraadt@openbsd.org>” <deraadt@openbsd.org>
> >
> > 主题：OpenBSD 加密框架
> >
> > 日期：2010 年 12 月 11 日 星期六 23:55:25 +0000
> >
> > 你好 Theo，
> >
> > 好久不见。你可能还记得，早些时候我是 NETSEC 的首席技术官，并为 OpenBSD 加密框架争取了一些资助和捐赠。与此同时，我也曾为 FBI 提供咨询服务，具体是在他们的 GSA 技术支持中心（GSA Technical Support Center）参与一个密码逆向工程项目，旨在为智能卡和其他基于硬件的计算技术植入后门和密钥托管机制。
> >
> > 我与 FBI 的保密协议（NDA）最近已到期，我想让你知道，FBI 曾在 OpenBSD 加密框架中植入了一系列后门和侧信道密钥泄露机制，其明确目的是监控美国联邦检察官行政办公室（其隶属于美国司法部，即 FBI 的上级机构）所部署的站点对站点 VPN 加密系统。Jason Wright 和其他几位开发者负责了这些后门的实现，你最好全面检查所有 Wright 提交的代码，以及与他共事的 NETSEC 出身的开发者的代码提交。
> >
> > 这很可能也是你当年失去 DARPA（美国国防高级研究计划局）资助的原因——他们很可能察觉到了这些后门的存在，不想基于这些代码开发任何衍生产品。
> >
> > 这也是为什么 FBI 内部最近有些人极力鼓吹在虚拟化环境中使用 OpenBSD 进行 VPN 与防火墙部署。例如 Scott Lowe 就是一位在虚拟化领域颇具声望的作者，碰巧也是 FBI 的雇员。他最近还发表了几篇关于在企业 VMware vSphere 部署中使用 OpenBSD 虚拟机的教程。
> >
> > 圣诞快乐……
> >
> > Gregory Perry
> >
> > 首席执行官
> >
> > GoVirtual 教育
> >
> > “VMware 培训产品与服务”
> >
> > 电话：540-645-6955 分机 111（本地）
> >
> > 免费电话：866-354-7369 分机 111
> >
> > 手机：540-931-9099
> >
> > 传真：877-648-0555

号称世界上最安全的操作系统是否存在 FBI（美国联邦调查局，负责情报与安全事务）的后门？OpenBSD 项目迅速对现有代码进行审计，并未发现后门。

一星期后，Theo de Raadt 又发布了一封信：[关于 OpenBSD IPsec 后门指控的最新进展](https://lwn.net/Articles/420858/)。

> OpenBSD IPsec 后门指控的最新情况
>
> 来自：Theo de Raadt \<deraadt-AT-cvs.openbsd.org>
>
> 收件人：Kurt Knochner \<cdowlker-AT-googlemail.com>
>
> 主题：Re: 有关 OpenBSD IPsec 的指控
>
> 时间：2010 年 12 月 21 日 星期二 12:34:54 -0700
>
> 抄送：tech-AT-openbsd.org
>
> 没有“线索”（不论真假），
>
> 确实，这些指控没有提供任何指向具体代码的事实。
>
> 目前我的看法大致如下：
>
> (a) NETSEC 这家公司从事一种接近华盛顿特区的特殊业务，接受政府某些部门的合同，进行安全与反安全方面的工作。
>
> (b) 背景：1999–2001 年是个特殊时期，美国政府的许多部门在放宽加密技术的限制，因为加密技术从国防部（DOD）移交到了商务部（Commerce），以便可以“在某些限制下”出口；结果是私人领域对加密的使用将要爆炸性增长，于是政府为了继续窃听，不仅在发明技术手段，也在发明“正当理由”（他们向来窃听上瘾）。
>
> (c) Gregory Perry 曾在 NETSEC 工作，并负责面试与雇佣 Jason（当时刚刚毕业）；Jason 开始工作时，Perry 已因某些未知原因被“驱逐”出公司。
>
> (d) Jason 并未专门从事加密工作，他主要编写设备驱动，但由于 ipsec 层也涉及 IPCOMP，他也改动过 ipsec 层的代码。也就是说，他接触的是数据流部分，而非算法部分。
>
> (e) Jason 离职后，Angelos 接受了一份 NETSEC 的合同（他已经为 ipsec 栈工作了 4 年，是架构师与主要开发者），并在全球各地旅行的同时编写了加密层，使 ipsec 栈能够将请求传递给 Jason 之前写的驱动程序。这个加密层包含了当时美国政府推崇的一个欠妥且不安全的“半 IV”想法。合同结束后，这段代码就被移除了。不久之后，CBC oracle 问题也被发表出来，加密/ipsec 代码开始转向随机 IV（在那之前也许无法实现，因为我们缺乏高质量快速的伪随机数生成器，比如 arc4random）。我不认为这两个问题，或其他未被发现的问题，是出于恶意。到目前为止，我们挖出的这些问题都是特定历史时期的产物。
>
> (f) Jason 和 Angelos 在我们每天依赖的许多系统部分编写了大量代码，而不仅仅是 ipsec 栈。我将点名他们的指控转发了，但我仍难以亲自指责他们。请去看我原始邮件中关于 (a)-(c) 的内容。
>
> (g) 我相信 NETSEC 很可能被合同要求编写了后门，如指控所述。
>
> (h) 如果这些后门确实被编写了，我不相信它们进入了我们的源代码树。它们可能被部署为 NETSEC 自己的产品。
>
> (i) 如果 NETSEC 的这些项目存在，我不知道 Jason、Angelos 或其他人是否知情或参与。
>
> (j) 如果 Jason 与 Angelos 知道 NETSEC 在干这种事，我期望他们告诉过我。我和这个项目也许会根据这种情况进行某种调整；具体怎么调整，我也不确定。从这个角度看，我觉得 Jason 的邮件并不完全坦诚。
>
> (k) 我很高兴大家开始借此机会审核源代码树中的这个重要部分——太久以来，许多人以为它是“安全的”。
>
> 你从哪里开始审计代码？代码太多了。
>
> 实际上，这只是源代码树中的一小部分。如果我们每个人都尽自己的一份力，情况会变好。它仍然不会完美，还是太庞大。但我们已经证明了，只要我们从源代码树中开始一点点地寻找小 bug 或不清晰之处加以改进，最终一定会有成果。所以我没法指出具体从哪里开始。
>
> 既然我已经开始做了，我会继续，至少从加密代码和伪随机数生成器开始。
>
> 你发出邮件之后，至少有 10 个人去研究了这些代码。我自己就在随机数子系统的另一个部分发现了一个小 bug，并正在清理一段结构较为复杂的函数。
>
> 这已经是我们能希望的最好结果了。
>
> 从“半满的玻璃”角度看，能看到大家去尝试，其实令人欣慰！ :-)
>
> 顺便说一句：iTWire 提到，在加密代码中发现了两个 bug。能告诉我这两个 bug 的细节吗？
>
> <http://www.itwire.com/opinion-and-analysis/open-sauce/439>...
>
> 这是前两个发现的 bug。第一个与前文提到的 CBC oracle 问题相关（Angelos 在软件加密栈中修复了它，但 Jason 维护的所有驱动中都忽略了这个问题。当时 Jason 与 Angelos 都未在 NETSEC 工作，所以我认为这只是一个疏忽，虽然是个相当严重的疏忽）。
>
> ```
> CVSROOT:        /cvs
> Module name:    src
> Changes by:     [mikeb@cvs.openbsd.org](mailto:mikeb@cvs.openbsd.org)   2010/12/15 16:34:23
>
> 修改文件：
>    sys/arch/amd64/amd64: aesni.c via.c
>    sys/arch/i386/i386: via.c
>    sys/arch/i386/pci: glxsb.c
>    sys/dev/pci: hifn7751.c hifn7751var.h safe.c safevar.h
>             ubsec.c ubsecvar.h
>
> 日志信息：
> 将 cryptosoft.c 第 1.32 版中的 CBC oracle 攻击对策引入硬件加速加密驱动。这修复了 aes-ni、via xcrypt、glxsb(4)、hifn(4)、safe(4) 与 ubsec(4) 驱动。
> ```
>
> 原始提交信息（来自 angelos）：
>
> ```
> 在 CBC 模式中，不要保留最后一个 blocksize 字节的密文用于下一条消息的 IV。每条消息应使用 arc4random() 获取新的 IV。
>
> 通过并认可：deraadt, markus, djm
>
> CVSROOT:        /cvs
> Module name:    src
> Changes by:     [jsg@cvs.openbsd.org](mailto:jsg@cvs.openbsd.org)     2010/12/16 09:56:08
>
> 修改文件：
>    sys/crypto: cryptodev.h
>    lib/libssl/src/crypto/engine: hw_cryptodev.c
>
> 日志信息：
> 将 CRYPTO_VIAC3_MAX 从 cryptodev.h 移除，放入唯一使用它的文件中。
>
> 由 mikeb 请求并认可。
> ```
>
> 还有一些更新的提交也源于此次审计。请查看更新日志（Changelog）。

信中提及的 Jason L. Wright 也公开声明自己没有在软件中植入后门：

> 我在此明确声明，我没有在 OpenBSD 操作系统和 OpenBSD 加密框架（OCF）中添加后门。我在这项工作中涉及的代码主要与支持该框架的设备驱动有关。我相信我从未接触过 isakmpd 或 photurisd（用户态密钥管理程序），而且我很少触碰 ipsec 内部实现（但确实涉及过 cryptodev 和 cryptosoft）。不过，我欢迎对所有我提交到 OpenBSD 代码库中的内容进行审计。

Gregory Perry 后来 [回复道](https://cryptome.org/2012/01/0032.htm)：

> FBI、OpenBSD 后门与 RSA 加密漏洞
>
> 发件人：Gregory Perry \<Gregory.Perry \[at] govirtual.tv>
>
> 主题：关于 OpenBSD 加密框架后门讨论串的后续
>
> 日期：2012 年 1 月 12 日 星期四 01:57:39 +0000
>
> 如约奉上关于 FBI / OpenBSD / OpenBSD 加密框架加密后门讨论串的后续内容。我们家在圣诞假期期间发生了三级火灾，我也是刚刚恢复上线。
>
> 1）大约在 1997 年，FBI 找到了 Lew Jenkins，也就是 Premenos Technology Corp. 的董事长兼 CEO，他们当时在开发一种用于企业间 EDI（电子数据交换）交易的软件套件“Templar”。
>
> 2）在当时，加密技术（尤其是公钥加密算法）仍被美国政府视为军火，因此 FBI 可能对 Premenos 关于密钥托管和 RSA 加密会话恢复方面的研究很感兴趣。
>
> 3）Jenkins 先生的一部分研究与一位厄瓜多尔人合作进行，后者向 Premenos 提供了至少一个与 RSA 加密算法有关的数学漏洞，该漏洞与对加密后的 RSA 模数在不同进位制下的转换有关。Jenkins 与 Premenos 也和英王室保持着广泛联系，其中包括一些参与互联网通信技术的英国贵族。
>
> 4）Premenos 的一位投资者 Ross Pirasteh，据说他曾是伊朗国王（沙阿）的财政部长，甚至可能就是沙阿本人。传说中，1979 年霍梅尼领导的伊斯兰革命爆发前或期间，Ross 与其家人被卷在波斯地毯中秘密送出伊朗。到达美国后，FBI 为其一家提供了新身份，原因不言而喻。我是在 90 年代初一次基于 GPS 的汽车跟踪项目中结识 Ross（非军用 GPS），1995 年我向他介绍了 Templar 的相关信息，不久之后他便成了 Premenos 的投资者。
>
> 5）1999 年，我与 Ken Ammon 和 Jerry Harold 共同创办了一家计算机安全工程公司：Network Security Technologies Inc.（NETSEC）。Ken 是 CEO，Jerry 是 COO，我是 CTO。Ken 和 Jerry 是前 NSA（美国国家安全局）信息安全部门的高级员工，在国防部和联邦政府中有着广泛的人脉。我们向联邦政府和私营部门提供托管网络安全、渗透测试、漏洞分析和逆向工程服务。
>
> 6）NETSEC 的首位投资者是 Ross Pirasteh，他提供了一笔过桥贷款以启动公司。A 轮早期融资来自 Boca Raton 的一家天使投资团体，我认为是 Ross 介绍给 Ken 和他妻子的，但我不掌握详细内情。
>
> 7）我们原本打算推出的第一款产品，是一种基于 ATM 的高速嵌入式网络安全设备，部署在客户网络中进行远程协议分析、监控、入侵检测与防御。每台设备通过加密加速的 VPN 通道连接到 NETSEC 的 NOC（网络运营中心）进行监控。NOC 原型和网络管理系统由我设计。在开发该嵌入式硬件和寻找代工厂过程中，我聘请了 Doug Bostrom 和 Wayne Mitzen 两位工程师，他们此前在 Ross 位于波士顿的某个遥测相关企业工作（如美国专利 6,208,266）。
>
> 8）在该项目中，我联系了 OpenBSD 项目的 Theo de Raadt，希望资助并在 OpenBSD 中实现符合 POSIX 的抢占式实时线程能力，以替代成本高昂的 VxWorks RTOS（OpenBSD 及其许可方式是免费且无专利负担的）。NETSEC 为 OpenBSD 项目提供了硬件与资金，支持其加密框架（OCF）的初期开发，该框架基于 HiFN 系列的加密加速芯片，并最终被合并进了 OpenBSD 内核。我们本想采用博通，但由于 Ken 与 HiFN 有关系，所以初期用了 HiFN 的芯片。90 年代末的 x86 硬件无法承担 FIPS 140-1 与 140-2 认证要求下的高速 DES 与 3DES 加密任务，因此需要专用加密处理器以实现 ATM 级别的网络吞吐。
>
> 9）不久之后，NETSEC 启动了与美国联邦总务署（GSA）合作的项目，即 GSA 技术支持中心（GSA Technical Support Center）。该中心是 FBI 与国防部的联合项目，旨在为联邦和军方提供逆向工程与密码分析服务。项目负责人是 FBI 的 Ron Bitner（至少他是这么自称的），GSA 出资代表是 Dave Jarrell。我刚开始参与该项目时，曾对 FBI 与 DoD 之间职责划分模糊（或根本没有划分）表示担忧，这是明显违反《治安官动员法》（Posse Comitatus Act，PCA）的。Ken 的解释是，将使用 Trusted Solaris 这类多级安全系统（MLS），以允许不同机密级别的信息在 FBI 与 DoD 之间共享，从而在名义上维持军事与民政的传统分离。但我看出事态不妙，于是不再参与该项目。
>
> 10）同年晚些时候，我在公司会议中宣布辞去 NETSEC 职务，并创办了一家嵌入式无线带宽管理公司。由于与 NETSEC 有两年竞业协议，我在此期间不能再从事安全领域工作。
>
> 显然，这个故事远非一页纸能讲完。但我认为值得注意的是，美国与伊朗等“敌对国家”之间看似对立，实则有千丝万缕的联系。1995 年 FBI 坚决反对放宽加密技术出口规定，然而到 1999 年却态度骤变（例如此报导：<https://www.nytimes.com/1999/10/11/business/technology-easing-on-software-exports-has-limits.html>
>
> 我个人认为，FBI，或者说当时政府中的某些官员，是在发现 RSA 加密算法中存在关键性漏洞之后，才主动推动放松加密出口限制的。与当时主流的 Diffie-Hellman 公钥加密方法相比，RSA 的确存在未被公开的弱点。同样值得关注的是，RSA Security 公司在 RSA 专利期满后（美国专利 4,405,829）并未寻求延期，这一点令人意外。按常理他们可基于国家安全理由轻松获得延期许可，却主动放弃了专利权，使得 RSA 算法成为公开标准，而该公司靠授权 RSA 算法在美国获得了可观收入。
>
> 如果上述推测属实，那么可以合理断言：FBI 出于监听国内通信的目的，故意推动采用了一种在基础上存在弱点的加密算法，从而严重削弱了美国的关键基础设施和军事能力。这对大量基于 RSA 加密算法的技术产生了深远影响，如：用于武器定位的军用 GPS、Common Access Card 智能卡以及用于 RFID 与非接触支付的商用智能卡技术等。对嵌入式系统来说，这些标准几乎已定型，且大多数 OpenBSD / OpenBSD 加密框架安装实例都是嵌入式形式，因其小体积与宽松的 BSD 许可协议，几乎无升级路径。全球可能存在数百万甚至上亿台运行 OpenBSD 的嵌入式设备，如路由器、防火墙、VPN 设备等，此外还有许多操作系统直接集成了 OpenBSD 的加密框架与 PF 防火墙栈，却基于 OpenBSD 项目的安全声誉与可信度未对源代码进行审计。
>
> 如果你有其他问题，欢迎随时联系。祝你和 Cryptome 一起度过愉快的 2012。
>
> Gregory Perry

至此，事件的主要经过已介绍完毕。从结果来看，事件中包含一些可能引发争议的内容。

## 附录：其他专注于安全的 BSD 系统

### HardenedBSD

专注于安全的 BSD 操作系统不仅有 OpenBSD，还可以尝试 2014 年从 FreeBSD 复刻而来的[HardenedBSD](https://hardenedbsd.org/)。

其官网称“我们的主要目标是对 Grsecurity 补丁集（增强 Linux 内核安全的内核补丁集）中已公开文档的部分，进行净室开发。”

> Grsecurity 为 Linux 内核提供的补丁集是垃圾。
>
> ——Linus Torvalds（Linux 创始人）

### CheriBSD

[CheriBSD 官网](https://www.cheribsd.org/)

CheriBSD 基于 FreeBSD 实现了 Capability（能力式指针），提供内存保护和软件隔离功能。CheriBSD 主要面向 ARM 和 RISC-V 架构，由国际斯坦福研究所（SRI International）和英国剑桥大学（University of Cambridge）联合开发。

### FuguIta

[FuguIta 官网](https://fuguita.org/)

FuguIta 是一种基于 OpenBSD 开发的 Live 系统，同时支持部分型号的树莓派（树莓派 3/4/5, arm64 架构）。

## 课后习题

1. 不同 BSD 发行版与不同 Linux 发行版之间的根本不同是什么？


# 3.5 DragonFly BSD 概论

DragonFly BSD（蜻蜓 BSD）是一种基于 FreeBSD 4.8 衍生而来的类 UNIX 系统。该项目由 Matthew Dillon（20 世纪 80 年代末至 90 年代初的 Amiga 开发者，1994 至 2003 年间的 FreeBSD 开发者）于 2003 年 6 月启动，并于 2003 年 7 月正式发布于 [FreeBSD 邮件列表](https://lists.freebsd.org/pipermail/freebsd-current/2003-July/006889.html)。

Dillon 启动 DragonFly BSD 项目，是因为他对 FreeBSD 5 采用的 SMP（对称多处理）并行计算架构有不同判断。SMP 是指多个处理器共享同一内存空间的架构设计，他认为该设计可能引入不必要的性能开销。这一技术分歧导致与 FreeBSD 核心开发团队的讨论，最终促成了独立项目。尽管存在技术路径差异，DragonFly BSD 与 FreeBSD 项目在错误修复和驱动程序更新等领域仍保持协作关系。

DragonFly BSD 继承了 FreeBSD 4 的技术路线，同时在多个关键系统层面做了创新设计，包括轻量级内核线程实现机制和 HAMMER/HAMMER2 文件系统等核心组件。DragonFly BSD 的部分设计理念受到了 AmigaOS 架构的启发。

截至 2026 年 6 月，DragonFly BSD 的最新版本为 6.4.2（2025 年 5 月发布）。6.4 系列新增了对第二类管理程序（Type-2 Hypervisor）的 NVMM 支持、amdgpu 显卡驱动，以及远程挂载 HAMMER2 卷的实验性功能。

从硬件支持现状来看，DragonFly BSD 自带 i915 显卡驱动，架构仅支持 x86-64 平台，未提供 Linux 兼容层。其 DPorts 软件包系统与 FreeBSD Ports 基本保持兼容，当前版本基于 FreeBSD Ports 2024Q3 分支，正在向 2025Q2 推进。需注意 DragonFly BSD 的驱动支持相对滞后，特别是显卡驱动的更新节奏相对较慢。

捐赠 DragonFly BSD：[Sponsoring projects](https://www.dragonflybsd.org/donations/)，目前仅支持国际 PayPal。

DragonFly BSD 的文档相对陈旧，但这并不反映其实际开发进度。DragonFly BSD 的开发仍然活跃，不应因官方文档陈旧而放弃使用。


# 4.1 Windows 用户迁移指南

操作系统迁移涉及文件系统概念、字符编码、换行符规范、时区处理等多维度差异。从 Windows 迁移至 FreeBSD 的用户，需要先理解这些差异，才能顺利过渡。

## 文件系统基础

首先，观察以下两幅图像：

![屋后竹林](/files/O8dz7u0k3uSRQW8L5qag)

![傍晚的行道树](/files/8vDfAUscpdHznM5k1t2a)

前一幅图像展示的是竹子（Bambusoideae），后一幅图像展示的是若干棵行道树。

亚里士多德认为种子之所以能长成大树，是因为种子蕴含一种潜能，环境条件具备时便可能长成一棵树（《形而上学》IX.7, 1049b）。人与器物的差别，在于人没有固定不变的潜能——这契合了儒家“君子不器”和萨特“存在先于本质”之说。由此观之，理解 UNIX 目录与 Windows 目录的异同，便能洞悉操作系统设计与实现的逻辑。

![文件系统基础](/files/vac1HMtp9KAn1dQaBrlk)

竹子的生长发育常作为经典生物学案例：许多看似茂密繁盛的竹林，很可能只有一棵竹子真实存活——它们均从同一地下根系长出，看似多棵独立个体，实则同属一个整体。植物学称此现象为 **克隆生长**（clonal growth），这也是“雨后春笋”的由来。无论竹子之间相隔多远，仍旧一荣俱荣、一损俱损。正因如此，竹子（Bambusoideae）开花往往预示大片竹林将随之死亡。

这正是 UNIX 目录的写照：系统中的所有目录均依托根目录（root）。根（**/**）是一切目录的起点，构成 **单一层次的目录树结构**（single-rooted directory hierarchy）。例如 **/home/ykla/nihao**、**/bin/sh**、**/etc/fstab**，追根溯源，均从根目录出发。也就是说，删除 **/** 即意味着删除整个系统，所有设备上的目录均将一并删除。

![文件系统基础](/files/t3EpSCT5XfNmvMRG444k)

行道树则不同，每棵均独立生长。即便两树紧邻而立，也仍然是独立的个体。行道树正如 Windows 目录，盘符各自独立——**C:\Program Files (x86)\Google\Update**、**D:\BaiduNetdiskDownload\工具列表**、**E:\123\app**：`C`、`D`、`E` 盘彼此隔离、互不干扰。格式化 `D` 盘，不影响 `E` 盘中存储的文件。即便在 PE 中格式化 `C` 盘（可能不会显示为 `C` 盘），`E` 盘文件也不受影响。

Windows 的“盘符”并非固定存在。在 PE 环境中，`C` 盘可能显示为其他盘符（如 `X`）；运行中的 Windows 也可以任意分配盘符。

Windows 判断分区与盘符的对应关系，依据的是 GPT 分区类型 UUID（如 Windows 数据分区类型 UUID 为 `EBD0A0A2-B9E5-4433-87C0-68B6B72699C7`，即 Microsoft Basic Data 类型，适用于所有 Windows 数据分区，而非仅限 C 盘）以及分区的唯一 GUID（相关配置由 Windows 装入管理器 Mount Manager 写入注册表 **HKLM\SYSTEM\MountedDevices**），而非依靠盘符自身。

查看盘符和卷的映射关系：

```powershell
PS C:\WINDOWS\system32> Get-ItemProperty -Path "HKLM:\SYSTEM\MountedDevices"


\DosDevices\C:                          : {68, 77, 73, 79...}   # C: 盘符映射项，对应某个磁盘卷的二进制标识（Volume GUID/卷结构数据）
#{6dc6b5e1-fff0-11f0-bf73-b0416f0b5119} : {68, 77, 73, 79...}   # 卷 GUID（唯一卷标识符），表示某个物理分区；右侧为该卷的内部二进制数据
\DosDevices\D:                          : {68, 77, 73, 79...}   # D: 盘符映射项，对应另一个磁盘卷的标识数据
PSPath
                                 :
……省略其他输出……
```

盘符是一种抽象映射，本身并无固定不变的物理意义。文件系统中并不存在硬编码的 `C` 盘标识，这也解释了为何在其他操作系统中（包括 Windows 双系统环境）均看不到 `C` 盘。只有实际启动系统后，Windows 才能确定哪个分区对应 `C` 盘，并写入注册表。其他盘符的分配则存在不确定性，`D` 盘变为 `E` 盘的情形也屡见不鲜，例如某虚拟光驱可能在开机时被自动加载。

> **思考题**
>
> 阅读《深入解析 Windows 操作系统（第 7 版）（卷 2）》（978-7-115-61974-7，人民邮电出版社）及其他相关文献资料，回答问题：在传统的 BIOS + MBR 引导下，Windows 如何识别 `C` 盘？

### 挂载的概念与机制

![如何理解挂载](/files/lFU9aMPMDu5N9RqvZU9q)

从园艺角度看，通常需要从树 A 剪取一段枝条，斜插至树 B 上并包裹固定，待愈合后二者便成为一体：例如苹果树（UNIX）上可结出桃子（挂载 Windows 的 `C` 盘）。

这种方法称为“嫁接”。其实质是将树 A 的枝条（文件系统）挂载到树 B 上（嫁接点即挂载点，终究依托根目录 **/**）。

在操作系统技术层面，挂载（mount）是指将文件系统附加到系统目录树已有目录（挂载点）上的操作。文件系统可视作以 **/** 为根的树形结构，一个文件系统必须挂载到另一文件系统中的某目录上。文件系统 B 挂载至目录 A 后，B 的根目录取代 A，B 所含目录随之显现；A 中原有文件则暂时隐藏，直至 B 从 A 卸载后方重新出现。

工具 mount 调用 nmount(2) 系统调用，将一个特殊设备或远程节点（rhost:path）映射并嫁接到文件系统树中的节点（node）位置。系统维护当前已挂载文件系统的列表。如果不带任何参数调用 mount，将打印此列表。

> **注意**
>
> FreeBSD 的 `mount` 源于 4.4BSD，与 Linux 的 `mount` 在选项语法上基本兼容，但 FreeBSD 使用的是 nmount(2) 系统调用而非 Linux 的 mount(2)。FreeBSD 的 `mount` 会根据文件系统类型自动调用 **/sbin/mount\_type** 程序（如 `mount_nfs`、`mount_msdosfs`）。

### 卸载的概念与机制

![如何理解卸载](/files/BZdWsJEjXT5Wzy2SZvXH)

熟悉园艺的读者，对“扦插”这种植物培育方法应不陌生：

将一棵树新发的侧枝剪下，插入土中。悉心照料一段时间后，即可获得一株新的幼苗。

这与卸载的原理相通：将某个文件系统（如 **/mnt/test**）从完整的根（**/**）上卸下，即解除其与目录树的关联。

在技术层面，卸载（unmount）是挂载的逆操作，它将已挂载的文件系统从系统目录树中分离。文件系统 B 从 A 卸载后，A 中原有文件重新出现。

### fstab 文件

在启动过程中，系统将自动挂载 **/etc/fstab** 文件中列出的文件系统（标注 `noauto` 选项的条目除外）。

该文件中的条目格式如下：

```sh
设备       /挂载点 文件系统     选项      转储     fsck 检查顺序
```

说明：

| 字段          | 说明                                                                                                                          |
| ----------- | --------------------------------------------------------------------------------------------------------------------------- |
| `设备`        | 现有设备名                                                                                                                       |
| `挂载点`       | 现有的目录，用于挂载文件系统                                                                                                              |
| `文件系统`      | 传递给 mount(8) 的文件系统类型                                                                                                        |
| `选项`        | `rw` 表示读写文件系统，`ro` 表示只读文件系统，可跟其他选项。常用选项包括 `noauto`，表示启动时不挂载此文件系统                                                            |
| `转储`        | 供 dump(8) 判断哪些文件系统需要备份。默认值为 `0`                                                                                             |
| `fsck 检查顺序` | 决定在重启后，哪些文件系统应由 fsck(8) 检查，以及检查顺序。应跳过的文件系统设置为 `0`。根文件系统应优先检查，设为 `1`，其他文件系统应设为大于 1 的值。如果多个文件系统具有相同的 `passno`，fsck(8) 会尝试并行检查 |

示例：标准 ZFS 安装下的 **/etc/fstab** 文件。

```sh
# Device		Mountpoint	FStype	Options		Dump	Pass#
/dev/gpt/efiboot0		/boot/efi	msdosfs	rw		2	2	# EFI 分区
/dev/nda0p2		none	swap	sw		0	0	# 交换分区
```

> **注意**
>
> ZFS 并不使用 **/etc/fstab** 文件，因此，如果该文件中不存在任何 ZFS 文件系统（**/**），这属于正常现象。

示例：标准 UFS 安装下的 **/etc/fstab** 文件。

```sh
# Device	Mountpoint	FStype	Options	Dump	Pass#
/dev/nda0p2	/		ufs	rw	1	1	# 根分区
/dev/nda0p1	/boot/efi		msdosfs	rw	2	2	# EFI 分区
/dev/nda0p3	none		swap	sw	0	0	# 交换分区
```

### 参考文献

* Sartre J P. 萨特哲学论文集\[M]. 潘培庆，等，译. 合肥：安徽文艺出版社，1998. ISBN: 7-5396-1632-6.
* 何晏，注；邢昺，疏. 论语注疏\[M]. 北京：中国致公出版社，2016. ISBN: 978-7-5145-0846-8.
* 微软. PARTITION\_INFORMATION\_GPT\[EB/OL]. \[2026-04-18]. <https://learn.microsoft.com/en-us/windows/win32/api/winioctl/ns-winioctl-partition_information_gpt>. GPT 分区类型 GUID 定义，其中 Microsoft Basic Data 类型为 EBD0A0A2-B9E5-4433-87C0-68B6B72699C7。
* 微软. Supporting Mount Manager Requests in a Storage Class Driver\[EB/OL]. \[2026-04-18]. <https://learn.microsoft.com/en-us/windows-hardware/drivers/storage/supporting-mount-manager-requests-in-a-storage-class-driver>. Windows 装入管理器将盘符与分区的映射关系持久化存储于注册表 **HKLM\SYSTEM\MountedDevices**。
* GBIF. Bambusoideae Luerss.\[EB/OL]. \[2026-04-18]. <https://www.gbif.org/species/113642445>. 竹亚科许多物种具有群体开花（gregarious flowering）特性，开花后常因资源耗竭而死亡；竹子通过地下根茎系统进行克隆生长（clonal growth），同一克隆的个体共享资源。
* Aristotle. Metaphysics\[M]. Translated by W. D. Ross. Oxford: Clarendon Press, 1908. Book IX (Theta), Chapter 7, 1049b. 亚里士多德论潜能与现实：种子之所以能长成大树，是因为种子暗含着一种潜能。

## 文件名规范的差异

### 非法字符

许多在 FreeBSD 中合法的文件名或路径，在 Windows 中均属非法（即包含非法字符）。在 Windows 上使用 Git 拉取项目时，此类情形较为常见。

以下仅列举部分典型情况：

* 文件或文件夹名称中不能包含英文冒号 `:`。

![非法字符](/files/yBxVDAxloWltCIJQD6ud)

* 无法将文件或文件夹命名为 `con`。

![非法字符](/files/ng1jRSoCLz5fSC82fktj)

更多要求参见：微软. 命名文件、路径和命名空间\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/zh-cn/windows/win32/fileio/naming-a-file>.

> **技巧**
>
> 可在 Windows 下使用 Git 工具拉取 [freebsd-doc](https://github.com/freebsd/freebsd-doc) 项目验证兼容性问题。相关 Bug 报告：[The colon in the file name of the security report of the FreeBSD doc is not compatible with Microsoft Windows](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267636)

### 大小写敏感性

常见文件系统的大小写敏感性对比如下：

| 操作系统/文件系统     | 大小写行为       | 备注                                                                                                                                                          |
| ------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| FreeBSD ZFS   | 区分大小写       | 默认                                                                                                                                                          |
| FreeBSD UFS   | 区分大小写       | 默认                                                                                                                                                          |
| macOS HFS+    | 默认不区分       | 格式化时可选择区分大小写变体                                                                                                                                              |
| macOS APFS    | 默认不区分       | 格式化时可选择区分大小写变体                                                                                                                                              |
| Windows FAT32 | 不区分         | /                                                                                                                                                           |
| Windows NTFS  | 大小写保留，默认不敏感 | Windows 10 1803 以后可通过 `fsutil.exe file setCaseSensitiveInfo <路径> enable` 按目录启用大小写敏感，`fsutil.exe file queryCaseSensitiveInfo <路径>` 可查询目录的大小写敏感状态，主要用于 WSL 兼容 |

* Windows 下 **大小写不敏感**

![大小写敏感](/files/GutsbJmTWhJeNrDIAiec)

在 Windows 中，`abc` 和 `ABC` 视作同一文件，无法共存。

> **技巧**
>
> 判断网站服务器类型的简易方法：如果 `https://example.com/path` 和 `https://example.com/PATH` 均可访问且内容相同，则该网站可能运行在 Windows 操作系统上。

* FreeBSD 下 **大小写敏感**

```sh
$ touch ABC    # 创建文件 ABC
$ touch abc    # 创建文件 abc
$ ls           # 列出当前目录内容（区分文件名大小写）
abc    ABC
```

在 FreeBSD 中，`abc` 和 `ABC` 是两个独立文件，可以共存。

#### 参考文献

* 微软. 调整区分大小写\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/en-us/windows/wsl/case-sensitivity>. Windows 文件系统支持使用属性标志按目录设置区分大小写，提供跨平台文件兼容性支持。
* 微软. FAT32 File System\[EB/OL]. \[2026-04-18]. <https://learn.microsoft.com/en-us/previous-versions/aa364047(v=vs.85)>. FAT 文件系统卷不区分大小写。
* Apple. File system formats available in Disk Utility\[EB/OL]. \[2026-04-18]. <https://support.apple.com/guide/disk-utility/file-system-formats-dsku19ed921c/mac>. APFS 和 HFS+ 默认均不区分大小写，但可在格式化时选择区分大小写变体。

## 换行符差异

回车（Carriage Return，CR）和换行（Line Feed，LF）是不同的概念，均起源于电传打字机（真实 TTY）时代。

| 概念    | 全称              | 作用          |
| ----- | --------------- | ----------- |
| 回车 CR | Carriage Return | 将光标移动到当前行开头 |
| 换行 LF | Line Feed       | 将光标移动到下一行   |

可见，在早期二者各自独立，否则 CRLF 会使当前行“下沉”一行。

Windows 操作系统默认的文本换行符为 CRLF（即 `\r\n`，0x0D 0x0A，`^M$`），而 UNIX 默认使用 LF（即 `\n`，0x0A，`$`），Classic Mac OS 则使用 `\r`（0x0D）。

时至今日，这两种符号通常见于每行末尾。

二者互不兼容。将使用 Windows 换行符的文件置于 UNIX 系统，可能导致每行末尾多出 `^M` 字符；某些工具会因此产生识别错误，而对 FreeBSD Port 相关文件而言，则可能将多行识别为单行。

然而两种换行符可以互相转换。在 FreeBSD 中可使用 Port **converters/dos2unix** 实现，该软件包含两个命令：`dos2unix`（Windows 换行符到 UNIX）、`unix2dos`（UNIX 换行符到 Windows）。基本用法是 `dos2unix -n a.txt b.txt`，如果不需要保留源文件，可直接 `dos2unix a.txt b.txt c.txt`（一次转换多个文件）。可使用命令 `file a.txt` 来判断文件的换行符类型：

* 使用普通的 UNIX 换行符文本文件

```sh
$ file a.txt  # 查看文件类型
a.txt: Unicode text, UTF-8 text
```

* 使用 Windows 换行符的文本文件

```sh
$ file b.txt  # 查看文件类型
b.txt: Unicode text, UTF-8 text, with very long lines (314), with CRLF line terminators
```

### 参考文献

* IETF. RFC 2046: Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types\[EB/OL]. \[2026-04-18]. <https://datatracker.ietf.org/doc/html/rfc2046>. 规定文本类型的规范行结束符为 CRLF（0x0D 0x0A）。
* IETF. RFC 20: ASCII format for network interchange\[EB/OL]. \[2026-04-18]. <https://www.rfc-editor.org/rfc/rfc20.html>. ASCII 字符编码标准，定义 7 位 128 个字符的编码，其中 0x41 为大写字母 A；标准定义 CR 为 0x0D（第 13 号控制字符），LF 为 0x0A（第 10 号控制字符），二者均源自电传打字机时代的物理操作。
* Wasserburger E. dos2unix / unix2dos - Text file format converters\[EB/OL]. \[2026-04-18]. <https://dos2unix.sourceforge.io/>. dos2unix 与 unix2dos 命令行工具，用于在 CRLF（Windows）与 LF（UNIX）换行格式之间转换；FreeBSD Port 路径为 converters/dos2unix。基本系统版本与 Port 版本为不同程序。Port 为增强版本，支持更多选项。

## 字符编码差异

计算机只识别 `0` 和 `1`，因此字符编码是将字符转换为数字表示的规则体系。字符可为屏幕上可见的文字，也可为不可见的控制标记，如换行符（LF）、回车符（CR）等，涵盖数字、Emoji 表情符号、汉字、拉丁字母等文本常见元素。编码过程即为这些字符分配唯一数字标识（通常为整数），即代码点（code point）。

例如，ASCII（American Standard Code for Information Interchange，ANSI X3.4）编码中，`0x41`（二进制 `0100 0001`）代表大写字母 `A`。ASCII 仅支持英文字母、数字和常见标点，共 128 个字符。

而在 Unicode 编码体系中，“你”这个汉字的代码点是 U+4F60。在 UTF-8（8-bit Unicode Transformation Format，8 位 Unicode 转换格式）编码方式下，其编码后为字节序列 `0xE4 0xBD 0xA0`（二进制为 `11100100 10111101 10100000`）。UTF-8 编码所含字符范围远超 GBK（国标扩展），甚至包含埃及圣书体，如果当前屏幕上能看到 𓀀 𓃕 𓌊 这三个字符，则很可能正在使用 UTF-8 编码（如果使用 UTF-8 编码但仍无法显示这些字符，很可能是字体不支持这些字符集，而非编码问题）。

程序如何识别文本编码？某些文件会在开头使用特定字节序列（即 BOM，byte order mark，字节顺序标记）标明编码。例如 UTF-8 的 BOM 是 `0xEF 0xBB 0xBF`。但许多文本文件并无 BOM，读取程序需通过上下文猜测编码格式，这往往导致乱码。虽然通过程序分析文本内容（如统计字符分布或抽取字符计算）可猜测编码，但此法未必可靠。编码问题的根本原因，在于系统间默认编码不同或未明确指定编码。

Windows 默认使用 GBK（在简体中文环境下，为 GB2312 的超集），而 Linux 或 UNIX 通常使用 UTF-8。

* Windows 11 24H2 查看当前控制台代码页：

```powershell
PS C:\Users\ykla> chcp
活动代码页: 936 # CP936 编码（近似 GBK）
```

* Ubuntu 24.04/FreeBSD 输出当前区域设置（locale）的字符编码：

```sh
root@ykla:/home/ykla# locale charmap
UTF-8
```

此外，也可将 Windows 10 及后续版本的系统字符编码设置为 UTF-8。然而，如此设置往往只会引入更多编码问题，难以从根本上解决问题。

FreeBSD 的编码在 [main/usr.bin/login/login.conf](https://github.com/freebsd/freebsd-src/blob/main/usr.bin/login/login.conf) 文件中设置，编译后路径为 **/etc/login.conf**。

### 参考文献

* 微软. Code pages\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/en-us/globalization/encoding/code-pages>. 微软官方称，936 即是 GBK，用于中文简体字符编码；代码页 936 最初覆盖 GB 2312 字符集，后扩展为 GBK。严格来说，CP936 与 GBK 存在两处差异：CP936 增加了 Euro 符号（U+20AC → 0x80），但缺少 GBK 1.0 中定义的 95 个 PUA（Private Use Area）字符映射，二者并非完全等同。
* Unicode Consortium. UTF-8, UTF-16, UTF-32 BOM\[EB/OL]. \[2026-04-18]. <https://www.unicode.org/faq/utf_bom.html>. UTF-8 的 BOM 为字节序列 0xEF 0xBB 0xBF。
* 微软. Use UTF-8 code pages in Windows apps\[EB/OL]. \[2026-04-18]. <https://learn.microsoft.com/en-us/windows/apps/design/globalizing/use-utf8-code-page>. Windows 10 及后续版本可通过系统区域设置启用 UTF-8 支持（Beta 功能），但可能导致旧应用程序兼容性问题。
* FreeBSD Project. login.conf(5)\[EB/OL]. \[2026-04-18]. <https://man.freebsd.org/cgi/man.cgi?query=login.conf&sektion=5>. FreeBSD 登录类能力数据库，源文件位于 **usr.bin/login/login.conf**，编译后路径为 **/etc/login.conf**，用于设置字符编码等用户环境。

## 时间与时区差异

中国统一使用东八区，即 UTC+8。UTC（Coordinated Universal Time，协调世界时）在日常使用中与 GMT（Greenwich Mean Time，格林尼治时间）几乎等同。UTC 以国际原子时（temps atomique international，TAI）的秒长为基础（二者并不完全一致）：取铯（Cs）频率 ΔνCs——即铯 133 原子不受干扰的基态超精细跃迁频率——以 Hz（s⁻¹）表示时的固定数值 9,192,631,770 定义秒，此后又对国际原子时作了多项修正。

有过 Windows 和 UNIX 双系统安装经验的用户会发现，Windows 和 UNIX 的时间总相差 8 小时。现代计算机主板通常配备一颗由纽扣电池供电的 RTC（Real-time clock，实时时钟芯片），用于在系统断电后维持计时。

计算机操作系统开机时读取 RTC 时间以设定系统时间。RTC 时间未标注时区。

Windows 直接读取 RTC 的值，并视为本地时间（Local Time，地方时）；UNIX 则将 RTC 数据视为 UTC 时间，双系统时间由此相差 8 小时。

例如，设 RTC 时间为 2025 年 6 月 6 日中午 12:00（UTC+8）。Windows 下显示为 2025 年 6 月 6 日中午 12:00（UTC+8）；UNIX 将 RTC 中的 12:00 视为 UTC，加上 UTC+8 偏移量后得 12+8=20，因此 UNIX 下显示为 2025 年 6 月 6 日晚上 20:00。由于 UNIX 将 RTC 视为 UTC 而非本地时间，其显示时间比 Windows 快 8 小时。

```sh
RTC 时间处理差异（以 UTC+8 为例）

RTC 硬件时钟：12:00（无时区标注）
  │
  ├─ Windows：将 RTC 视为本地时间
  │    显示时间 = 12:00（UTC+8）
  │
  └─ UNIX：将 RTC 视为 UTC
       显示时间 = 12:00 + 8 = 20:00（UTC+8）

两者相差 8 小时。
```

对现代计算机网络而言，时间准确性至关重要：系统时间偏差可能导致 HTTPS 证书验证失败（TLS 证书包含有效期字段，客户端将系统时间与证书有效期比对，时钟偏移可导致握手失败），以简单实验即可验证——将系统时间调慢至证书有效期之外，打开浏览器，即可发现绝大部分网站无法访问。

计算机中的时区由 IANA 时区数据库规范，历史悠久。

中华民国二十八年（1939），民国政府将中国划分为五个时区，当时称为长白时区（UTC+8:30）、中原标准时区（UTC+8）、陇蜀时区（UTC+7）、新藏时区（UTC+6）和昆仑时区（UTC+5:30）。在 IANA 时区数据库中，这些时区分别对应 `Asia/Harbin`、`Asia/Shanghai`、`Asia/Chongqing`、`Asia/Urumqi` 和 `Asia/Kashgar`。

从实际地理时区看，新疆属于东六区（虽全国统一使用北京时间）。北京地区如果在北京时间五点日出，新疆则要到北京时间七点方见日出。

在时区数据库 2025b 中，`Asia/Harbin`、`Asia/Chongqing`、`Asia/Shanghai` 均等同于北京时间。`Asia/Urumqi` 在 IANA 时区数据库中解析为 UTC+6（新疆时间），`Asia/Kashgar` 为指向 `Asia/Urumqi` 的向后兼容链接，同样解析为 UTC+6。

在 FreeBSD 中，北京时间同样为 `Asia/Shanghai`（东八区）。部分国产操作系统自行定义 `Asia/Beijing` 时区，此举不符合国际标准与规范，可能造成严重后果——例如导致时间回退至 UTC。

> **注意**
>
> 北京（东经 116°）的地方时并不完全等于 UTC+8。北京时间不是北京的地方时，而是东经 120 度（上海东经 120°）的地方时。

> **技巧**
>
> 中国也曾实行过夏令时（1986—1991 年实行了 6 个夏天，1992 年正式暂停；在夏季将时钟调快一个小时，因夏季日出较早）。

> **思考题**
>
> 外太空（飞船，星球等）用什么时区？为什么？

## SSH 和 SCP 客户端

### WinSCP

SCP 即 Secure Copy（安全复制），是一款用于在不同设备间安全传输文件的工具，其功能类似于安全版的 `cp` 命令。

WinSCP 是 `scp` 命令的图形化封装软件，同时支持 FTP 等多种协议，可在 Windows 系统与 Linux 或 BSD 系统之间传输文件。

WinSCP 官方下载地址：<https://winscp.net/eng/download.php>

自 OpenSSH 9.0 起，`scp` 命令默认使用 `SFTP` 协议进行文件传输。WinSCP 默认使用 `SFTP`。FreeBSD 用户无需任何修改即可使用 WinSCP。

### Xshell

Xshell 是 Windows 平台上的终端工具，支持串口、SSH 和 Telnet 协议。

Xshell 下载地址（输入用户名和邮件即可）：

<https://www.netsarang.com/zh/free-for-home-school>

如提示需要重新验证，可访问上述网站重新获取安装程序。

### MobaXterm

MobaXterm 是集成了 `scp` 功能和多种网络工具的终端软件。

MobaXterm 目前不支持中文，下载地址 <https://mobaxterm.mobatek.net/download-home-edition.html>，任选其一。

![MobaXterm](/files/EyGchYDEciAQF7bIVEsH)

![MobaXterm](/files/Hnj9QCPuvZnT3IgLZYik)

鼠标操作方式与 Xshell 类似。

### PuTTY

下载地址：<https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html>

PuTTY 界面操作相对不便，不支持国际化（i18n），存在已知安全漏洞（[CVE-2024-31497](https://nvd.nist.gov/vuln/detail/CVE-2024-31497)，已在 PuTTY 0.81 中修复），通常作为其他软件的组件间接使用。历史上有中文修改版被发现注入恶意代码（[参考](https://safe.it168.com/a2012/0201/1305/000001305829.shtml)），建议用户仅从官方渠道获取。

### Termius

![Termius](/files/LMgnQLgAqxReuTyHO2cV)

Termius 下载地址：<https://termius.com/download/>

目前不支持中文，使用前需登录和注册。Termius 的鼠标操作方式与 PuTTY 类似，但右键操作与 Xshell 不同。

### 参考文献

* 中国计量科学研究院. 秒的定义\[EB/OL]. \[2026-03-26]. <https://www.nim.ac.cn/520/node/4.html>. 秒的定义，基于铯原子超精细跃迁频率。
* BIPM. SI base unit: second\[EB/OL]. \[2026-04-18]. <https://www.bipm.org/en/si-base-units/second>. 国际计量局秒的 SI 定义，铯 133 原子不受干扰的基态超精细跃迁频率取固定数值 9,192,631,770 Hz。
* IANA. Time Zone Database\[EB/OL]. \[2026-03-26]. <https://www.iana.org/time-zones>. 时区数据库，提供全球时区信息标准化。
* Eggert P. Simplify China's time zones from five to two\[EB/OL]. \[2026-04-18]. <https://github.com/eggert/tz/commit/15b01c042afa770acd5068054c50e7c5c663cbd2>. 2014 年该修订将中国时区从五个简化为两个，移除了 Asia/Urumqi 的 1980 年向 UTC+8 的转换（现为 UTC+6），并将 Asia/Harbin、Asia/Chongqing、Asia/Kashgar 改为向后兼容链接。
* 微软. Why does Windows keep your BIOS clock on local time?\[EB/OL]. \[2026-04-18]. <https://devblogs.microsoft.com/oldnewthing/20040902-00/?p=37983>. Windows 默认将硬件时钟（RTC）视为本地时间而非 UTC 的历史原因。
* 中国科学院紫金山天文台. 历书基本术语简介\[EB/OL]. \[2026-03-26]. <http://www.pmo.cas.cn/xwdt2019/kpdt2019/202203/t20220314_6389637.html#b4>. 本节所涉术语，可参考此处的精确解释。
* 新华网. “北京时间”是怎么来的\[EB/OL]. \[2026-04-18]. <https://www.xinhuanet.com/politics/2015-10/28/c_1116958394.htm>. 北京时间并非北京（东经 116.4°）地方时，而是东经 120° 经线的区时；中国曾于 1986—1991 年实行夏令时。
* IETF. RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL Profile\[EB/OL]. \[2026-04-18]. <https://www.rfc-editor.org/rfc/rfc5280>. X.509 证书包含 notBefore 与 notAfter 有效期字段（第 4.1.2.5 节：Validity）；客户端在 TLS 握手时将系统时间与证书有效期比对，时钟偏移可导致握手失败。
* IETF. RFC 6557: Procedures for Maintaining the Time Zone Database\[EB/OL]. \[2026-04-18]. <https://www.rfc-editor.org/rfc/rfc6557>. IANA 时区数据库维护程序（BCP 175），该数据库由 Arthur David Olson 于 20 世纪 80 年代中期创建（至少可追溯至 1986 年），2011 年 10 月起由 ICANN/IANA 接管托管。

## 深入阅读

### Windows

以下书籍可供读者进一步研究 Windows 操作系统设计与实现：

* Russinovich M, Solomon D, Ionescu A, 等. 深入解析 Windows 操作系统：第 7 版. 卷 1\[M]. 刘晖，译. 北京：人民邮电出版社，2021. ISBN: 978-7-115-55694-3. 微软官方教材，系统阐述 Windows 内核架构。
* Russinovich M, Solomon D, Ionescu A, 等. 深入解析 Windows 操作系统：第 7 版. 卷 2\[M]. 刘晖，译. 北京：人民邮电出版社，2024. ISBN: 978-7-115-61974-7. 微软官方教材，详解 Windows 系统组件。

### 天文历法

* 中国科学院紫金山天文台. 2026 年中国天文年历\[M]. 北京：科学出版社，2025. ISBN: 978-7-03-082584-1. 注：每年一版。一般日历会写潮起潮落太阳东升西落的时间，该书则是大全，提供精确的天文数据。
* 胡中为. 天文学教程（上）\[M]. 上海：上海交通大学出版社，2019. ISBN: 978-7-3132-1655-7. 天文学历史悠久，这是一本现代天文学入门书籍，本科生教材，系统介绍天文学基础。
* 胡中为. 天文学教程（下）\[M]. 上海：上海交通大学出版社，2020. ISBN: 978-7-3132-3572-5. 天文学是一级学科，深入讲解天体物理与宇宙学。
* Dodelson S, Schmidt F. 现代宇宙学\[M]. 于浩然，译. 第 2 版. 北京：科学出版社，2024. ISBN: 978-7-03-078693-7. 该书用数学和物理学描述宇宙宏观整体而非具体天体行星，提供现代宇宙学理论框架。
* 卢央. 中国古代星占学\[M]. 北京：中国科学技术出版社，2013. ISBN: 978-7-5046-6140-1. 中国古代天文学入门，星占学即以哲学或神秘学解释天文学，梳理古代星占文化。
* Carroll B W, Ostlie D A. 当代天体物理学导论\[M]. 姜碧沩，李庆康，高健，等，译. 第 2 版. 北京：科学出版社，2023. ISBN: 978-7-03-076666-3. 天体物理学即以物理学解释天文学，是现代天文学的核心（还有一些测量、分类、天文历法等不属于此范畴），提供天体物理系统介绍。

> **思考题**
>
> > 对于描述世界，我们有太多种方法。正如马克思所述，“哲学家们只是用不同的方式解释世界……”（《关于费尔巴哈的提纲》第十一条：马克思主义哲学的使命）
>
> 你认为通过数学和物理学解释世界的优点是什么？如果排除实用主义、实证主义和经验主义，那么还能剩下什么？
>
> 你认为通过哲学和神秘学/宗教神学解释世界的缺点是什么？如果排除实用主义和经验主义，那么还能剩下什么？
>
> > 马克思还认为只有必要的自由时间才能确保真正的自由（邓晓芒. 马克思论“存在与时间”\[J]. 哲学动态，2000(6): 11-14）：
> >
> > “必须将感性的时间从强制性的、社会一般的抽象时间中解放出来。”
> >
> > “实践也不能被曲解为异化了的生产活动，即类似于动物性的筋肉活动、体力的支出，至少不能将异化劳动当作马克思本来意义上的实践活动。”
>
> 你怎样理解这样一个事实：我们 **显然拥有充足的** 自由时间，但是我们仍 **无法拥有** 所谓的 **“自由”时间** 了解一些“无意义”的东西（非学术目的），例如天文学？
>
> 我们在不断地刷短视频阅读网络小说所花费的精力，是否在某种程度上也构成了 **生产活动**？所花费的时间是否在某种意义上构成了 **社会一般（平均）劳动时间**？换言之，这种自由时间的放松，究竟是真正的自由还是一种资本化的假象（实际上仍是另一种形式的工作）？这种自由时间往往视作对工作的放松，是为了更好地工作，而非单纯实现自由时间；并且我们通过平台获取的快乐和 **工资** 远低于平台从用户获取的算法，个性化数据，内容主体，广告等带来的价值。你如何看待这种对自由时间的资本化异化？

## 课后习题

1. 在 FreeBSD 中挂载一个 Windows NTFS 分区，使用 **converters/dos2unix** 批量转换包含 Windows 换行符的文本文件，编写 shell 脚本实现自动化处理。
2. 查阅 FreeBSD 内核源代码中 UFS/ZFS 文件系统处理大小写敏感的逻辑，分析其实现机制与 Windows NTFS 大小写不敏感设计的差异。
3. 修改 Windows 注册表使其将硬件时钟视为 UTC，记录修改前后 FreeBSD 与 Windows 双系统时间显示的差异。


# 4.2 Linux 用户迁移指南

Linux 与 FreeBSD 同属类 UNIX 操作系统，但二者在内核架构、包管理哲学及系统设计理念等方面存在根本差异。深入理解 BSD 的构建方式与构建初衷并非易事，由此产生的失望在所难免。

## 遗失的世界

许多 Linux 世界的核心概念与技术实践，最早由 BSD 系统提出并实践。这意味着 Linux 世界存在着大量的文化挪用现象，包括：

* 容器技术的原型可追溯至 FreeBSD Jail 机制；
* 发行版（distribution）概念框架；
* sudo 工具最初面向 4.1BSD；
* Gentoo 采用的 Ports 包管理方法论，技术渊源可追溯至 BSD Ports 框架；
* Gentoo 采用的 World 设置集（Portage set）概念，实际上源于 BSD 中的 World（用户空间）；
* BSD 是最早的开源理念实践者；
* BSD 许可证也是历史上最早出现的自由软件许可证之一（早于 1989 年的 GPL，但晚于 1985 年的 GNU Emacs 许可证）。

> **思考题**
>
> > “一切真历史都是当代史”。
>
> 读者如何理解这句话？如何定义“真”与“非真”？

### 参考文献

* FreeBSD Foundation. FreeBSD: The Torchbearer of the Original Operating System Distribution\[EB/OL]. \[2026-04-04]. <https://freebsdfoundation.org/blog/freebsd-the-torchbearer-of-the-original-operating-system-distribution/>. BSD 最早提出并实践了“发行版”概念框架。
* Linux Foundation. A Brief Look at the Roots of Linux Containers\[EB/OL]. \[2026-04-18]. <https://www.linuxfoundation.org/blog/blog/a-brief-look-at-the-roots-of-linux-containers>. 该文指出：“In 2000, FreeBSD extended chroot to FreeBSD Jails”，容器技术原型可追溯至 FreeBSD Jail。
* Amadio G, Xu B. Portage: Bringing Hackers' Wisdom to Science\[EB/OL]. arXiv preprint arXiv:1610.02742, 2016. \[2026-04-18]. <https://arxiv.org/abs/1610.02742>. 该论文指出：“Portage, written in Python and inspired by the ports system from FreeBSD”及“Portage is a GPLv2 package management system based on FreeBSD's ports collection”，Gentoo Portage 技术渊源可追溯至 BSD Ports。
* Gentoo Wiki. World set (Portage)\[EB/OL]. (2026-06-09)\[2027-07-27]. <https://wiki.gentoo.org/wiki/Package_sets>. 指出“@world 集合包含了系统上安装的所有软件包：即由系统管理员定义的软件包以及由 Gentoo 开发团队定义的软件包。”
* FreeBSD Project. Why you should use a BSD style license for your Open Source Project\[EB/OL]. \[2026-04-18]. <https://www.freebsd.org/doc/en/articles/bsdl-gpl/>. 该文记载了 BSD 许可证自 20 世纪 70 年代末起即以源代码自由分发的方式实践开源理念，早于 1985 年的 GNU Emacs 许可证和 1989 年的 GPL。
* Red Hat. 什么是 Linux 容器？\[EB/OL]. \[2026-04-04]. <https://www.redhat.com/zh/topics/containers/whats-a-linux-container>. 介绍 Linux 容器的基本概念与技术原理。
* Open Source Initiative. The Open Source Definition\[EB/OL]. \[2026-04-17]. <https://opensource.org/osd>. 虽然“开源”（Open Source）一词直到 1998 年才由 Christine Peterson 正式提出，但 BSD 许可证自 20 世纪 80 年代起便以源代码自由分发的方式实践了这一理念。
* Croce B. 历史学的理论和历史\[M]. 田时纲,译. 北京: 中国社会科学出版社, 2018. 提出一切真历史都是当代史的核心命题，探讨历史认识的当代性。

## 理解 FreeBSD 的操作系统本质：并非发行版

FreeBSD 是完整的操作系统，包含相互独立的两大部分：基本系统（用户空间 + 内核）和 Ports 框架。

![FreeBSD 操作系统结构图](/files/6PnJ7Yca3HvQaMQQpaE8)

### 独立自存的基本系统

freebsd-src = 基本系统存储库 = 用户空间 + 内核。

FreeBSD 版本分支分为三个主要系列：

| 分支      | 类型     | 对应分支示例      |
| ------- | ------ | ----------- |
| CURRENT | 开发版    | main        |
| STABLE  | 固定分支   | stable/15   |
| RELEASE | 正式发布版本 | releng/15.0 |

新特性首先提交到 CURRENT（main 分支），经测试后 MFC 到 STABLE 分支，再进入点版本 RELEASE。stable/ 分支从 main 分支切出，大版本（dot-zero 版本）的 releng/ 分支再从 stable/ 分支切出，点版本则从 stable/ 分支发布。

PkgBase 直接由 freebsd-src 构建：

```sh
# cd /usr/src # 需要预先拉取 freebsd-src 到该路径
# make -j8 buildworld # 世界即用户空间
# make -j8 buildkernel # 内核
# make -j8 packages # 构建 PkgBase 二进制包
```

### 安装第三方软件的 Ports 框架与 pkg 包管理器

freebsd-ports = 第三方软件集合（单个称为 Port）= Ports 框架存储库。

Port 是若干文件的集合，由源代码包校验和、说明文件、补丁等构成，其中 Makefile 是核心。Arch 的 PKGBUILD 或 Gentoo 的 ebuild 与此类似，事实上它们受 Ports 框架启发。

pkg 包直接由 freebsd-ports 通过 poudriere 构建系统构建而来。

freebsd-ports 的 main 分支即 latest 源，形如 2026Q1 的分支（最新的那个季度）即 quarter 分支。季度分支直接从 main 按季度切出。

默认基本系统不含任何 Port 软件，甚至不含 pkg 包管理器本体（传统安装模式）。大多数硬件固件也已从基本系统移至 Ports。

### init 系统

FreeBSD 使用 BSD init 而非 systemd；BSD init 与传统的 SysVinit 也有所不同，BSD 没有运行级别（runlevel），也没有 **/etc/inittab**，均由 rc 系统控制。

以用户进程身份运行 init，可模拟 AT\&T System V UNIX 的行为：超级用户可在命令行中指定所需的运行级别，该 init 进程向原始（PID 为 1 的）init 进程发送特定信号，以执行相应操作。

### Shell

FreeBSD 所有用户的默认 shell 均为 sh（14 之前 root 默认为 csh），而非 Bash（如有需要亦可切换）。

### 基本系统去 GNU 化

FreeBSD 基本系统几乎不含任何与 BSD 协议不兼容的软件。

### 参考文献

* MYSQLZOUQI. 浅析 Linux 初始化 init 系统，第 1 部分：sysvinit 第 2 部分：UpStart 第 3 部分：Systemd\[EB/OL]. \[2026-03-25]. <https://www.cnblogs.com/MYSQLZOUQI/p/5250336.html>. 是存档，原文已佚，系统介绍了各初始化系统。
* FreeBSD Project. init -- process control initialization\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=init&sektion=8>. FreeBSD init 手册页。BSD init 无 SysV 风格运行级别与 **/etc/inittab**，以及以用户进程身份运行 init 时的运行级别-信号对应关系。
* FreeBSD Project. ttys -- terminal initialization information\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=ttys&sektion=5>. 终端初始化配置文件手册页。
* Gentoo. Comparison of init systems\[EB/OL]. \[2026-03-25]. <https://wiki.gentoo.org/wiki/Comparison_of_init_systems>. 各大 init 对比图，为系统选型提供参考。
* FreeBSD Project. GPL Software in FreeBSD Base\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/GPLinBase>. FreeBSD 基本系统中的 GPL 软件，系统梳理了基本系统的许可证兼容性。
* FreeBSD Project. FreeBSD 14.0-RELEASE Release Notes\[EB/OL]. \[2026-04-18]. <https://www.freebsd.org/releases/14.0R/relnotes/>. “The default shell for the root user is now sh(1)”，FreeBSD 14 起默认 root shell 由 csh/tcsh 变更为 sh。
* FreeBSD Project. Ports Quarterly Branch\[EB/OL]. \[2026-04-18]. <https://wiki.freebsd.org/Ports/QuarterlyBranch>. “quarterly is the familiar name for ports branched from main”，main 分支即 latest 源、季度分支按 YYYYQn 命名。
* FreeBSD Core Team. Change to FreeBSD release scheduling and support period\[EB/OL]. (2024-07-16)\[2026-04-18]. <https://lists.freebsd.org/archives/freebsd-announce/2024-July/000143.html>. “the FreeBSD core team has approved reducing the stable branch support duration from 5 years to 4 years starting with FreeBSD 15”。
* FreeBSD Wiki. Desktop\[EB/OL]. \[2026-04-18]. <https://wiki.freebsd.org/Desktop>. “NetworkManager itself cannot be ported due to a monolithic architecture and extensive Linux syscall use”，NetworkManager 无法移植的真实原因。

## 基本对比

| 操作系统         | 发布/生命周期（主要版本）                                                                              | 主要包管理器（命令）                                                          | 许可证（主要）                                                      | 工具链   | Shell | 桌面    |
| ------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------ | ----- | ----- | ----- |
| Ubuntu       | [2 年/5 年（LTS 标准支持），10 年（需 Ubuntu Pro）](https://ubuntu.com/about/release-cycle)             | [apt](https://ubuntu.com/server/docs/package-management)            | [GNU](https://ubuntu.com/legal/intellectual-property-policy) | gcc   | Bash  | GNOME |
| Gentoo Linux | 滚动更新                                                                                       | [Portage（emerge）](https://wiki.gentoo.org/wiki/Portage)             | GNU                                                          | gcc   | Bash  | 可选    |
| Arch Linux   | 滚动更新                                                                                       | [pacman](https://wiki.archlinux.org/title/pacman)                   | GNU                                                          | gcc   | Bash  | 可选    |
| RHEL         | [10 年标准/约 13 年（需 ELS 附加订阅）](https://access.redhat.com/zh_CN/support/policy/updates/errata) | [RPM（yum、dnf）](https://www.redhat.com/sysadmin/how-manage-packages) | GNU                                                          | gcc   | Bash  | GNOME |
| FreeBSD      | [约 2/4 年](https://www.freebsd.org/security/)（FreeBSD 14 及以前为 5 年，自 FreeBSD 15 起缩短为 4 年）    | pkg/Ports                                                           | BSD                                                          | clang | sh    | 可选    |

Linux 广泛使用 GNU 工具，因此理论上，凡不依赖特定 Linux 函数库者，均可在 FreeBSD 上运行。

| Linux 命令/GNU 软件 | BSD Port/命令                         | 作用说明          | 备注                                                                                                                        |
| --------------- | ----------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `lsusb`         | `sysutils/usbutils`                 | 显示 USB 信息     | 也可粗略使用 `cat /var/run/dmesg.boot`                                                                                          |
| `lspci`         | `sysutils/pciutils`                 | 显示 PCI 信息     | 也可粗略使用 `cat /var/run/dmesg.boot`                                                                                          |
| `lsblk`         | `sysutils/lsblk`                    | 显示磁盘使用情况      | /                                                                                                                         |
| `free`          | `sysutils/freecolor`                | 显示内存使用情况      | `free` 命令依赖 Linux 特性（通常由 `procps` 包提供），因此 FreeBSD 未提供。如确实需要 `free`，可使用 <https://github.com/j-keck/free>，其他替代命令包括 `vmstat` |
| `lscpu`         | `sysutils/lscpu`                    | 显示处理器信息       | /                                                                                                                         |
| glibc           | FreeBSD libc                        | C 库           | /                                                                                                                         |
| GCC             | LLVM + Clang                        | 编译程序、编译链工具    | 如有特殊需要也可以安装 `devel/gcc`                                                                                                   |
| `vim`           | `editors/vim`                       | 文本编辑器         | FreeBSD 的 `vi` 不是软链接到 `vim`，而是早期的 `nvi`                                                                                   |
| `wget`          | `ftp/wget`                          | 下载器           | 系统默认的下载工具是 `fetch`                                                                                                        |
| bash            | `shells/bash`                       | Shell         | 系统默认的 shell 是 `sh`（非软链接）。可自行修改。                                                                                           |
| NetworkManager  | `net-mgmt/networkmgr`               | 网络连接工具        | NetworkManager 因其单体架构（monolithic architecture）及对 Linux 系统调用的广泛依赖而无法直接移植至 FreeBSD                                          |
| `lsmod`         | `kldstat`                           | 列出已加载的内核模块    | /                                                                                                                         |
| `strace`        | `truss`                             | 跟踪系统调用        | /                                                                                                                         |
| `modprobe`      | 加载内核模块：`kldload`；卸载内核模块：`kldunload` | 加载内核模块、卸载内核模块 | /                                                                                                                         |

### 参考文献

* FreeBSD Foundation. Navigating FreeBSD's New Quarterly and Biennial Release Schedule\[EB/OL]. \[2026-04-16]. <https://freebsdfoundation.org/blog/navigating-freebsds-new-quarterly-and-biennial-release-schedule/>. 该博文说明 FreeBSD 发布周期变更。

## FHS 与 FreeBSD 目录结构

文件系统层次标准（FHS）最初由 Linux 基金会 Linux 标准基础工作组（Linux Standard Base, LSB）维护，2025 年起由 FreeDesktop.org 托管和管理，定义了类 UNIX 操作系统中目录结构和目录内容的规范，当前版本为 FHS 3.0（最初发布于 2015 年，最新修订发布于 2026 年 4 月 8 日）。

FreeBSD 的目录层次由 hier(7) 定义。与 FHS 相比，FreeBSD 的目录结构存在以下差异：

| 项目                          | FHS                                           | FreeBSD                                          |
| --------------------------- | --------------------------------------------- | ------------------------------------------------ |
| **/usr/local**              | 供管理员本地安装软件时使用，初始为空                            | pkg/Ports 安装第三方软件默认路径                            |
| 配置文件                        | 第三方 **/etc/opt**，建议使用子目录                      | 第三方 **/usr/local/etc**，系统 **/etc**               |
| **/bin**、**/sbin**、**/lib** | 独立目录，与 **/usr** 分离                            | 独立目录，与 **/usr** 分离                               |
| **/libexec**                | 可选，与 **/usr/lib** 二选一，存放内部二进制                 | **/** 和 **/usr** 下均有，系统辅助程序                      |
| **/rescue**                 | 未定义                                           | 静态链接紧急修复工具                                       |
| **/srv**                    | 系统提供的服务数据（ftp、www 等）                          | 未定义                                              |
| **/media**                  | 可移动介质挂载点                                      | 由 automount(8) 或 bsdisks(8) 管理                   |
| **/opt**                    | 必选，**/opt/软件包**                               | 未定义，统一用 **/usr/local**                           |
| **/mnt**                    | 临时挂载点                                         | 临时挂载点                                            |
| **/run**                    | 必选（3.0），PID 文件及 UNIX 域套接字                     | 无，沿用 **/var/run**                                |
| **/sys**                    | Linux sysfs（§6.1.7）                           | 无，用 sysctl(8)                                    |
| **/proc**                   | Linux procfs（§6.1.5）                          | procfs(4) 默认不使用，仅出于兼容目的保留                        |
| 共享库                         | **/lib** 关键库，**/usr/lib** 非关键及编程库，**/lib** 兼容 | **/lib** 关键库，**/usr/lib** 共享/ar 库，**/usr/lib32** |
| 内核                          | **/** 或 **/boot**                             | **/boot/kernel/**，备用 **/boot/kernel.old/**       |
| **/home**                   | 可选，用户主目录                                      | 用户主目录                                            |
| **/var/empty**              | 未定义                                           | 由 sshd(8) 特权分离 chroot 使用                         |
| **/nonexistent**            | 未定义                                           | 无主目录账户的占位符                                       |

FHS 按可共享/不可共享、静态/可变两个维度将文件分层：**/usr** 可共享只读，**/var** 可变，根文件系统仅需满足引导、恢复、修复的最低需求。FreeBSD 遵循此原则，基本系统限定在 hier(7) 定义目录，第三方软件限定在 **/usr/local**。

POSIX（IEEE 1003.1）/SUS（UNIX 03）对目录结构无类似要求。POSIX.1-2008 明确删除了 **/bin**、**/usr/bin**、**/lib**、**/usr/lib** 等描述——理由是对应用程序并无用处。POSIX 仅要求 **/**、**/dev**（含 **/dev/null**、**/dev/tty**、**/dev/console**）、**/tmp** 存在，临时文件建议通过 `TMPDIR` 环境变量定位。FHS 仅在个别条目中注明与 POSIX 一致，其余目录规范均属 FHS 自身定义，不在 POSIX 范围内。

### 参考文献

* Linux Foundation. Filesystem Hierarchy Standard 3.0\[EB/OL]. (2015-06-03)\[2026-04-23]. <https://refspecs.linuxfoundation.org/fhs.shtml>. Filesystem Hierarchy Standard, 文件层次标准包含一套关于类 UNIX 操作系统文件和目录放置的要求和指南。这些指南旨在支持应用程序、系统管理工具、开发工具和脚本之间的互操作性，增强上述系统文档的一致性。

## 附录：GNU/Linux 发行版比较

GNU 开源运动的大规模开展与 Linux 的蓬勃发展，使多数人对开源的理解囿于 GPL 协议与 Linux 系统，对 FreeBSD 等 BSD 世界则接触较少。一些以开源为旗号的社区组织，其活动也主要围绕 Linux 领域展开，鲜有超越这一范畴的探索。

这并非说这些用户或团体有何不妥。无可指摘，“时来天地皆同力，运去英雄不自由”。李白永远无法成为盛唐的政治家，他自幼习剑道，好修仙，年少时意欲成为“十步杀一人，千里不留行”的江湖侠客；后又想成为匡扶社稷的朝廷重臣。但太白终究“剑非万人敌，文窃四海声”。操作系统的命运与时代发展的脉搏紧密相连，市场的需求也在不断塑造着今日习以为常的功能与交互模式。

> **思考题**
>
> > 心知不得语，却欲栖蓬瀛。
> >
> > 弯弧惧天狼，挟矢不敢张。
> >
> > 揽涕黄金台，呼天哭昭王。
> >
> > 无人贵骏骨，騄耳空腾骧。
> >
> > 乐毅倘再生，于今亦奔亡。
>
> 读者如何理解李白与 FreeBSD 项目及相关社区、人员在经历上的相似点。读者是否有一刻也曾感慨个人在时代面前的无力感。

本附录对比分析主流 GNU/Linux 发行版，帮助读者更全面地了解各发行版。

### 何以称为 GNU/Linux 发行版

GNU 本身并无独立内核，而以 Linux 为其内核——GNU Hurd 是例外，目前仍在开发中。

不同的操作系统/发行版，不同的世界观。对“发行版”下一个精确而统一的定义并非易事。

> **思考题**
>
> 如何理解“不同的操作系统/发行版，不同的世界观”这句话？

有观点指出，“看似纷繁复杂的 Linux 发行版，不过是假象。它们甚至可能缺乏自主决策权。例如，上游若采用 systemd 初始化系统，发行版通常也会跟进。否则可能无法继续使用部分第三方软件，后果即是自身遭消灭。Linux 发行版从未真正存在过。”

> **思考题**
>
> “Linux 发行版从未真正存在过。”这种说法固然存在一定的局限性，但它给出了一个重要启示，该如何理解？

常见的 Linux 发行版及若干基于 Linux 的国产操作系统，其维护工作的重心何在？它们通常并非文件系统、Linux 内核、GNU C 库（glibc）、systemd、桌面环境等上游项目的原始维护者，对大量第三方软件包通常以集成和适配为主。即便是包管理器和软件源，也大多基于上游工具和社区资源配置与管理。

红帽企业 Linux（Red Hat Enterprise Linux，RHEL）为长期支持与稳定性投入了大量资源。这是其区别于许多其他发行版的重要特征。RHEL 保证应用二进制接口（Application Binary Interface，ABI）和内核应用二进制接口（Kernel Application Binary Interface，kABI）的长期稳定性，提供最长可达十年的支持周期，这与许多其他发行版的支持策略存在明显差异。相关参考如下：

* Red Hat. Red Hat Enterprise Linux 10: Application Compatibility Guide\[EB/OL]. \[2026-03-25]. <https://access.redhat.com/articles/rhel10-abi-compatibility>.
* Red Hat. What is Kernel Application Binary Interface (kABI)?\[EB/OL]. \[2026-03-25]. <https://access.redhat.com/solutions/444773>.

许多发行版并不直接维护或对上述软件和工具进行全面测试，也不一定持续编写补丁或文档。直接将修改回溯并贡献至上游的发行版相对较少，Ubuntu 是其中典型的例子。同时，即使发行版维护者有意向上游贡献代码，也因其对上游项目并无直接决策权，可能面临补丁难以获上游接受的挑战。

许多商业发行版（如 RHEL）确实向上游项目（例如 Linux 内核）贡献了大量代码，这是客观事实。然而，这并未完全解决基础工具维护资源不足的广泛问题。同时，基于提交量的分析表明，商业公司在代码贡献中占据较大比重，红帽是其中的重要贡献者之一。这反映出社区与商业组织在项目贡献与治理上的结构性变化，也揭示了开源社区对开源项目主导权的实质性转移。这一现象常以 Xorg 项目作为讨论案例，目前其维护和发展方向主要由少数核心维护者和相关组织主导，项目整体重心逐步转向 Wayland 等新的显示技术路线。商业发行版对 Linux 生态的影响并非在所有情况下都是积极的，其商业目标与部分开源项目的发展方向之间可能存在张力——在这一背景下，GPL 的制度设计产生了自我消解的效果。

> **思考题**
>
> > 严肃的商业发行版力求稳定压倒一切，要求集中式的统一管理；而大多数 Linux 基础工具都强调敏捷开发策略，稳定性往往不是最高优先级，并且这些工具的控制权是极度分散的。
>
> 商业发行版对开源项目的贡献，根本上看，是为了发展项目，还是为了彻底消灭项目？为什么？

用户看似有多种发行版可选，但在兼容性、依赖和生态约束下，实际可选择的范围远比表面所见更为有限。某些场景下，甚至毫无选择余地。用户所做的选择看似自主，但可选项往往由他人预设。大多数读者有能力、甚至已在维护自己的发行版——那么，究竟在维护什么？从技术实质看，几乎不存在可独立维护的组成部分。这是当前生态结构所决定的现实。

> **思考题**
>
> > 自由意志和上帝的预定并不冲突。这信仰无关，是一个逻辑问题。
>
> 请读者讨论个人选择与社会生产力的制约关系。
>
> 分析：为什么看似自由的选择，也可能早已“预定”。

### Ubuntu

部分用户反馈 Ubuntu 系统中会出现“[内部错误（internal error）](https://www.google.com/search?q=internal+error+ubuntu+site:askubuntu.com)”提示。有观点认为这是 Ubuntu 对错误信息的统一提示方式。需要注意，Ubuntu 在开发过程中会阶段性引入 Debian SID（不稳定分支）的软件包，这可能导致其稳定性在特定阶段出现波动（无论普通版本还是 LTS）。例如，跨大版本或小版本升级时，部分用户反馈存在升级失败的风险——即便初始环境干净，也仍有可能发生。

以下命令可用于查询 Ubuntu 24.04 与 Debian 版本的关联信息：

```bash
ykla@ykla-ubuntu:~$ cat /etc/debian_version	# 查看当前 Debian 系统的版本号
trixie/sid # trixie 即 Debian 13，于 2025 年 8 月 9 日发布，为当前稳定版本。Debian 12 bookworm 为旧稳定版（oldstable）。
ykla@ykla-ubuntu:~$ cat /etc/lsb-release	# 查看当前 Linux 发行版的详细信息
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04 LTS"
```

在 VMware Workstation 17 Pro 虚拟机上测试 Ubuntu 24.04 LTS 版本（发布于伦敦当地时间 2024 年 4 月 25 日），发现其整体使用体验相较于之前版本有所下降。安装过程中即出现错误提示，且后续使用中遇到了窗口显示异常、鼠标光标消失、输入框无法获取焦点等问题。安装完成后，系统在开机后频繁弹出“内部错误”提示。

![Ubuntu 24.04 内部错误](/files/K5Uwlf4LOMjNz34tUcdt)

![Ubuntu 24.10](/files/GTp7rUyo8GwZJdo27BzB)

### Fedora Linux

Fedora 在部分社区中存在非正式的称呼“地沟油”。

Fedora 是 Red Hat Enterprise Linux（RHEL）的上游发行版，其定位侧重于技术验证和前沿特性测试，根本目的是作为 RHEL 系统新设计和新架构的试验平台（该社区由 Red Hat（红帽）公司完全主导）。特性稳定后，会引入到 RHEL 中。

因此，稳定性并非该发行版的主要设计目标。Fedora 直接跨大版本升级的失败率较高。这意味着长期使用后，用户可能需要全新安装并重新配置环境。用户难以在该发行版上获得长期的稳定性支持。与基于 Debian 的发行版不同，由于软件依赖关系变动频繁，Fedora 不同大版本之间的软件源通常无法通用。其各版本在定位上更接近于持续迭代的开发分支。其所有版本均包含大量新特性，稳定性表现与持续集成的 [nightly](https://openqa.fedoraproject.org/nightlies.html) 版本较为接近，差异不大。其稳定性特征与滚动更新发行版有相似之处。在部分测试场景下，其稳定性表现可能不及 Ubuntu。例如，在关闭屏幕保护与锁屏休眠功能后执行长时间高负载编译任务时，Fedora 系统可能在数小时后出现界面无响应，而在相同条件下，Ubuntu 系统运行正常。

部分开源软件项目采用“社区测试，成熟后进入商业或企业级产品”的开发路径，例如 Wine 与 CrossOver。

> **思考题**
>
> 如何看待这种始终由开源社区测试和反馈，待稳定后引入其商业产品，同时再引入新一轮待测试项目或组件的开发模式？这是否是一种形式主义的开源——即开源社区付出了实质性劳动力，但成果却遭资本攫取，社区用户得到的始终是残次品，且得不到任何报酬和荣誉。商业公司通过该模式将应承担的测试和客服等成本都转嫁给了开源社区。

近年来，Fedora 对系统资源的需求有所提升。在 VMware 虚拟机环境中，仅分配 4 GB 内存可能无法顺利完成安装，需要分配 6 GB 至 8 GB 内存才能避免安装过程停滞。

### CentOS/Rocky Linux/RHEL

CentOS 已从原先基于 RHEL 源代码重建的稳定发行版，转变为 RHEL 的中游开发与测试分支（即 CentOS Stream），其定位与 Fedora 有相似之处。其替代品较多，其中包括华为商业发行版 EulerOS（其开源社区版为 openEuler），EulerOS 曾通过 The Open Group 的 UNIX 03 规范认证。Rocky Linux 也是其中一个替代方案。

这类系统在服务器领域被广泛部署，其特点是以牺牲软件版本的新颖度来换取稳定性，因此所包含的软件版本通常较为陈旧。同样，它们通常不支持直接跨大版本升级，并且在安全更新策略上相对保守。

### Debian

![Debian Logo，图片来自 https://www.debian.org/](/files/Ol2t5nv9SlKaZYE2jZ1I)

Debian 的名称及 Logo 在中文语境中偶有基于谐音的非正式调侃“大便”（谐音“/ˈde.bi.ən/”）。

如果在 Debian 安装过程中设置了 root 密码，系统默认可能不会安装 sudo 工具。这一设计通常出于安全性考量。但这可能与 GNOME 等桌面环境及大多数显示管理器默认禁止 root 账户直接登录的惯例存在张力。

同时，在部分版本（如 Debian 12.6）中，虽然会安装 sudo，但创建的第一个普通用户默认未加入 `sudo` 组。这在实际使用中会带来不便，例如该普通用户无法直接通过 sudo 命令重启网络服务。用户需要切换到 tty 控制台登录 root 账户操作，这在一定程度上降低了图形界面（GUI）默认安装环境下的使用便利性。

> ```sh
> ykla@debian:~$ sudo su # 切换到 root 用户
> [sudo]ykla 的密码：
> ykla 不是 sudoers 文件。
> ykla@debian:~$ id # 显示当前用户的 UID、GID 及所属组信息
> uid=1000(ykla) gid=1000(ykla) 组=1000(ykla),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),100(users),106(netdev),111(bluetooth),113(lpadmin),116(scanner)
> ykla@debian:~$ hostnamectl # 显示或设置系统主机名及相关信息
> Static hostname: debian
>       Icon name: computer-vm
>         Chassis: vm
>      Machine ID: 9b3107b788dd461f94ca93150474946e
>         Boot ID: 081c39d5ac4748fa9ec0b2157c9a5beb
>  Virtualization: vmware
> Operating System: Debian GNU/Linux 12(bookworm)
>          Kernel: Linux 6.1.0-22-amd64
>    Architecture: x86-64
> Hardware Vendor: VMware, Inc.
>  Hardware Model: VMware Virtual Platform
> Firmware Version: 6.00
> ```

上述问题在实际安装和使用过程中较为突出。例如，安装程序在配置软件源时可能不会同步更新 `debian-security` 源，却默认尝试联网进行系统更新（此问题在 Ubuntu 中也存在，在 Debian 高级安装中可绕过该问题），有时会导致安装失败。

另外，其网络管理工具 [NetworkManager](https://wiki.debian.org/NetworkManager) 与 systemd 的部分功能集成可能存在冲突。类似的设计在实际使用中容易引发用户困扰。

普通用户向 Debian 社区提交 Bug 报告并获取及时反馈的流程较为复杂。Debian 的 [Bug 报告流程](https://www.debian.org/Bugs/Reporting) 相比一些更注重用户友好性的开源项目，对普通用户来说门槛较高。

Debian Stable 发行版的软件包策略以稳定为主，大部分软件在发布后，其主版本号在生命周期内通常不会升级，软件版本会锁定，因此应将 Stable 同时理解为“稳定”与“固定”。如果需要获取更新的软件版本，则需切换到 Testing 或 Unstable（Sid）分支，但这会牺牲系统的整体稳定性。

Debian Stable 发行版以系统稳定为特点，其软件包版本也相对较旧。在追求稳定性和软件包陈旧度方面，它与 RHEL 有相似之处。

### openSUSE

在物理机上安装完整的 openSUSE 后，部分用户反馈系统会出现卡顿现象。相关性能问题可能与默认使用的 Btrfs 文件系统的某些特性或配置有关。在多台不同代际的英特尔平台物理机上测试，均观察到了卡顿现象。安装后短时间内可能出现系统响应迟缓的情况。因此，不同用户对其使用体验的评价可能存在分歧。有用户通过将根文件系统从 Btrfs 切换为 ext4 来规避此问题。在网络上搜索“openSUSE btrfs hang”可以发现类似反馈，表明这可能并非个别现象。

openSUSE 因其 Logo 形象，在社区中昵称为“大蜥蜴”。

其版本号命名曾有一段趣事：为纪念英国作家道格拉斯·亚当斯在《银河系漫游指南》中提到的数字“42”（被誉为“生命、宇宙以及一切事物的终极答案”），openSUSE 将版本号从 13.x 跳跃至 42.x，随后又下调回 15.x。这造成了版本号逻辑上的问题：由于 42 大于 15，从 42.x 升级到 15.x 时，包管理器可能因 15 < 42 而误判为降级，从而拒绝操作。这种版本号跳跃再跌落现象在发行版中实属罕见。

openSUSE 有时会在稳定版的软件包中引入实验性功能，且可能没有明确的提示。这可能导致用户视其为软件缺陷（Bug）反馈。用户可能需要提交问题报告后，才能从维护者处得知该行为是实验性功能所致。

> **思考题**
>
> 在严肃的商业发行版中，允许出现此类版本异动和未经用户明确批准的测试行为吗？请读者思考。
>
> 这是否可以用以论述，社区发行版仅仅是企业发行版的试验田。

openSUSE 原生的包管理器是 `zypper`。有用户与 Fedora 的 `dnf` 对比，认为 `zypper` 在交互响应速度或某些场景下的性能表现有待优化 ~~例如你数数这有几个字母？~~，`zypper` 相比 `dnf` 存在明显的卡顿和延迟。且这两个包管理器在某些情况下存在竞争关系，参见：Bug 1213158 - Packages install failed with ndb backend\[EB/OL]. \[2026-03-26]. <https://bugzilla.opensuse.org/show_bug.cgi?id=1213158>。

### Gentoo Linux

Gentoo 自称是“元发行版（*Metadistribution*）”。其传统安装方式是从源代码 **编译** 所有软件。虽然近年提供了官方二进制包支持，但在依赖管理方面仍有一定复杂性，且二进制包通用性极为有限。

Gentoo 包管理系统的缺点在于，如果某个软件包编译失败，则无法安装，且编译失败的情况时有发生。如果系统长时间不更新，再次更新时可能会遇到复杂的 **循环依赖** 问题。同时，Gentoo 难以大规模标准化部署，在服务器环境中的应用也相对较少。

Gentoo 的 Portage 包管理器主要由 [Python](https://github.com/gentoo/portage) 语言编写。计算大规模软件集（如 KDE 桌面环境）的依赖时，可能会耗费较长时间。在性能有限的处理器上，此计算过程可能需要数分钟至数小时不等，性能开销较为明显。由于可能存在循环依赖等问题，依赖解析过程往往需要多次迭代计算，有时甚至无法自动解决，导致安装操作失败。随着系统中安装的软件包数量增加，包管理操作（如依赖计算）所花费的时间将呈几何增长。

Gentoo 的包管理器设计理念独特，但学习曲线较为陡峭，对普通用户而言使用门槛较高。~~Gentoo 的包管理器好玩但是不好用——这应该是最有趣的包管理器了。~~

总体而言，Gentoo 高度灵活的 USE 标记系统和从源代码编译的机制，在给予用户极大控制权的同时，也带来了较高的复杂性。依赖问题（包括循环依赖）可能影响系统稳定性，并使软件的安装、升级和卸载变得困难。

Gentoo 的高度定制化哲学要求用户投入更多精力进行系统管理和维护。

如果说 Arch Linux 可能在滚动更新中遇到问题，那么 Gentoo 则可能因为依赖冲突等问题，导致更新过程本身难以进行。如果系统长时间未更新，再次尝试更新时可能会因依赖地狱而无法继续任何软件包管理操作。复杂的 USE 标记系统，即便是经验丰富的 Gentoo 用户也需日复一日地应对这套哲学体系带来的复杂性。依赖问题的解决是 Gentoo 社区中常见的技术讨论话题。

Gentoo 哲学与 C++ 哲学有异曲同工之妙：

> “C++ 是一种语言，而不是一个完整的系统。为每种应该支持的风格提供全面支持，**不试图去强迫别人做什么。**”

> “如果工具 **强迫用户** 按照特定的方式操作，那么工具实际上是在与用户对抗，而非为用户服务。**我们都经历过工具强加自己意愿的情况。** 这是错误的，违背了 Gentoo 的哲学。”

正如世界上无人敢声称自己熟练掌握 C++ 一样，Gentoo 亦如此。自由的选择固然是人类向往的本性，但也带给人们无尽的焦虑和抑郁。

> **思考题**
>
> 强迫自由究竟是实现自由的一种可行手段，还是一种形式主义和法西斯主义？
>
> 在此基石上，请读者再理解 GPL 许可证与 BSD 许可证。

Gentoo 平台的 Bug 跟踪与反馈流程可能对普通用户不够友好。在个别情况下，相关问题可能在较长时间后，随软件移除而标记为不再适用。其 Bug 报告平台的搜索与使用体验有待优化。有时通过外部搜索引擎（如 Google）使用“site:bugs.gentoo.org”语法进行搜索，可能比直接使用平台内置搜索更为有效。[高级搜索](https://bugs.gentoo.org/query.cgi) 功能的使用也较为复杂。

### Deepin/UOS/中标麒麟

UOS 和 Deepin 的关系类似于 Red Hat Enterprise Linux（RHEL）与 Fedora 的关系，前者基于后者的社区版本商业化和深度定制。

Deepin 系统因部分更新包测试不充分而受到用户较多批评。有反馈称，某些存在问题的更新在推送后未及时撤回，官方仅通过发布修复教程应对。这种处理方式影响了用户体验。例如，有用户反馈在全新安装系统后立即升级，即遭遇了系统崩溃。

早期版本中，Deepin 系统在执行如复制文件等基础桌面操作时，曾出现界面卡顿或无响应的情况。

类似更新测试不充分的情况，在 UOS 系统中也有用户反馈。此类情况并非偶发，用户曾遇到 UOS 更新服务器宕机或配置错误导致客户端异常（如浏览器无限弹窗打开数十乃至上百个 UOS 主页）的情况，而官方状态通告有时不够及时。

UOS 服务器承载能力有限，因此 UOS 对镜像下载方式进行过限制，导致普通用户无法使用迅雷下载。有用户测试反馈，其下载服务器带宽有限，且某些网络运营商（如中国移动）的用户可能难以连接。

问题在于 UOS 的许多系统功能（如开发者模式激活）需要在线账户登录并与服务器交互，如果服务器连接不稳定，就会直接影响这些功能的使用。从技术角度来看，通过采用更高效的镜像分发方式（如 BitTorrent），有可能改善下载体验。官方也偶尔提供了百度网盘供用户使用。~~这就看你是选择 100 K/s 还是 101 K/s 了……~~

> **思考题**
>
> > “从技术角度来看，通过采用更高效的镜像分发方式（如 BitTorrent），有可能改善下载体验。”明明有更高效的分发方式（发生在 PCDN 投毒之前），为何难以推动技术兑现？
>
> 如何理解现代企业中，个人对企业是否存在一种虚无的责任感和职业道德？
>
> > 归根结底，二者只是雇佣关系。职业道德与荣誉光环究竟是一种社会建构，还是人类文明不可或缺的精神支撑。如果将一切拉平，反而有悖于常识。
>
> 怎样理解？

从默认配置策略也可观察到这一问题：UOS 早期版本的默认安装方案仅为系统盘分配约 20 GB 空间，日常使用中容易快速耗尽。用户通常需要自行研究如何自定义分区，往往在获取设备不久后即需重装系统。而剩下 50% 的未分配空间设计用于系统备份与还原功能，其机制更接近于完整的系统镜像恢复。如果用户采用自定义分区方案，则可能失去原厂提供的系统还原功能。这是一个两难选择。后续版本虽已支持调整系统分区大小，但默认安装方案在较长时期内仍未改变。

中标麒麟系统曾因未及时修复诸如 ZIP 压缩包解压乱码等常见基础问题而受到用户批评。

对于需要离线部署的内网机器，及时安装安全补丁可能存在困难。由于 Linux 系统更新（尤其是涉及底层库时）常存在复杂的依赖关系，在内网固定版本环境中单独安装某个安全补丁，可能会遇到依赖不满足的问题。这是离线环境软件维护中普遍存在的挑战，在现有依赖管理模式下较难彻底规避。其安全漏洞公告页面的呈现格式经过多次迭代才趋于规范。

> **思考题**
>
> 什么是 Linux 操作系统根社区？
>
> * 从 Linux kernel 和其他开源组件而构建，不依赖上游发行版社区
> * 采用开源社区运行模式，有大量的外部个人贡献者与企业参与
> * 被广泛认可，衍生出不同分支或下游社区
> * 与各开源组件社区沟通畅通，并持续回馈自己的能力
>
> ——white777. 深度社区全新规划：打造中国主导的桌面系统根社区！\[EB/OL]. (2022-05-19)\[2026-04-04]. <https://bbs.deepin.org/post/237175>.
>
> > ① 如果一个操作系统，长得像 Debian，运行的软件也都来自 Debian，内核也一模一样，那么凭什么说它是 Ubuntu？
> >
> > ② 根社区的“根”到底在哪？他们究竟维护着什么“根”？他们的“根”遵循 GPL 了吗？

### Arch Linux/Manjaro

Arch Linux 在中文社区中存在一些非正式的昵称：“**邪教**”和“**洗发水**”。这是一款以滚动更新模式著称的 Linux 发行版，因其高度的可定制性和软件的新颖度吸引了许多用户。

然而，滚动更新模式也意味着系统可能面临更高的不稳定风险。随着系统中安装的软件包数量增加，因依赖冲突或版本不兼容导致问题的概率也可能上升。有观点认为，通过仔细阅读官方更新公告可以规避多数问题。但这要求用户具备较高的主动维护意识和排查能力。

Arch Linux 的主要优势在于软件包版本非常新。但并非所有软件都如此，部分特定领域的工具包（如某些 R 语言包）可能不如其他发行版（如 FreeBSD）更新及时。Arch Linux 在技术社区中拥有很高的知名度。

Arch Linux 官方仓库（Official Repository）的软件包数量有限，用户通常需要启用 Arch 用户软件仓库（Arch User Repository，AUR）来获取更丰富的软件。而 AUR 源是未经过任何代码审查的。实际上缺乏系统性的集中审查机制：恶意或高风险脚本常被提交至其中。虽然构建过程在受限环境中执行，但无法保证生成的软件包本身是安全的。这类似于任何未经严格审核的软件来源（包括部分官方应用商店）都可能存在恶意软件。

这并非危言耸听，AUR 中确实曾存在恶意软件包。

正如 FreeBSD 开发者 Warner Losh 所说，“如今，开源项目的工作环境日益严峻，一些看似多余的步骤却往往是必要的。”

### NixOS

首先，读者无须因 NixOS 提出的一系列术语而感到困惑，其中部分概念在实际使用中容易产生误解。

其核心理念并非简单的“OS as Code”，其包管理与配置方式在某些方面与 Node.js 的依赖管理有相似之处。~~它并不是什么“OS as Code”，而是“OS as Node.js”。~~

对于熟悉声明式配置和函数式包管理理念的用户（尤其是有 Node.js 生态经验者），该系统的使用较大多数 Linux 发行版更为简单，而不一定如部分宣传中所描述的那样晦涩难用。

本质上，NixOS 将声明式和函数式的依赖管理范式应用到了整个操作系统层面。~~NixOS 就是把 Node.js 做成了一款系统。~~

NixOS 强调可重现的系统构建。其配置文件（如 **/etc/nixos/configuration.nix**）、依赖锁定（如 `flake.lock` 文件）等机制，在理念上与 Node.js 的 `package.json` 和 `package-lock.json` 有相似之处：在某些情况下，错误提示并不能直观反映问题本身，例如将依赖缺失提示为语法错误。

* **声明式配置**：系统的所有配置集中在一个声明式文件中（如 **/etc/nixos/configuration.nix**），类似于 Node.js 项目中的 `package.json`。
* **Flakes**：这是一个实验性功能，提供了更可重现的依赖管理和项目结构，其锁定文件（`flake.lock`）的作用类似于 `package-lock.json`。
* **可重现性**：基于声明的配置和锁定的依赖，可以精确地复现整个系统环境。
* **无依赖冲突**：通过为每个依赖创建独立存储路径来避免冲突。但这可能导致存储占用较大，且旧版本包需要手动清理。~~存在较多类似 node\_modules 的冗余存储，清理成本较高。~~
* **可回滚**：每次系统更新（通过 `nixos-rebuild switch`）都会生成新的系统代际（Generation，即新的启动选项），允许用户轻松回滚到任意历史版本。切换后通常需要重启以完全生效。

Node.js 的依赖存储在 **node\_modules** 目录，而 Nix/NixOS 的所有包则存储在 **/nix/store** 目录下。

与 Node.js 生态存在多个包管理器（如 npm、yarn、bun、pnpm）类似，Nix 生态中也出现了不同的工具和前端（如 Nix、NixOS with Flakes、Nix with Home Manager），带来了选择的多样性，也可能造成一定的生态碎片化。~~从现状看，NixOS 正在重走 Node.js 的老路。~~

~~因此，喜欢 Node.js 的人肯定很喜欢这个系统，讨厌 Node.js 的人自然也喜欢不起来 NixOS。~~

### 参考文献

* ykla. Set root password will not install sudo\[EB/OL]. (2020-02-05)\[2026-04-04]. <https://lists.debian.org/debian-cd/2020/02/msg00000.html>. 记录 Debian 安装过程中 root 密码设置与 sudo 包安装的关联。
* Debian. About Debian\[EB/OL]. \[2026-04-04]. <https://www.debian.org/intro/about>. Debian 发音。
* Debian. Debian Installation Manual, Appendix A.3\[EB/OL]. \[2026-04-18]. <https://www.debian.org/releases/bookworm/i386/apas03.en.html>.“If you do not specify a password for the 'root' user, this account will be disabled but the sudo package will be installed later”，确认 Debian 安装时设置 root 密码与 sudo 安装的关系。
* 萌娘百科. Fedora娘\[EB/OL]. (2025-05-03)\[2026-04-04]. <https://zh.moegirl.org.cn/zh-hans/Fedora%E5%A8%98>. Fedora 外号“地沟油”。
* 萌娘百科. Arch Linux 娘\[EB/OL]. (2023-08-24)\[2026-04-04]. <https://zh.moegirl.org.cn/zh-hans/Arch_Linux%E5%A8%98>. Arch Linux“邪教”说法的来历。
* Arch Linux 中文论坛. 回归洗发水\[EB/OL]. \[2026-04-04]. <https://bbs.archlinuxcn.org/viewtopic.php?id=694>. Arch Linux “洗发水”的用法例子。
* Gentoo Foundation. About Gentoo\[EB/OL]. \[2026-04-04]. <https://www.gentoo.org/get-started/about/>. Gentoo Linux 元发行版的说法来自此处。
* Bugzilla – Bug 1213157 repo <https://download.opensuse.org/update/leap/15.5/oss>. metadata expired\[EB/OL]. \[2026-03-26]. <https://bugzilla.opensuse.org/show_bug.cgi?id=1213157>.
* Arch Linux Wiki. Arch User Repository\[EB/OL]. \[2026-04-04]. <https://wiki.archlinux.org/title/Arch_User_Repository>. Wiki 指出“Warning: AUR packages are user-produced content. These PKGBUILDs are completely unofficial and have not been thoroughly vetted. Any use of the provided files is at your own risk.”，译文：“警告：AUR 中的软件包是由其他用户编写的，这些 PKGBUILD 是非官方的，未经彻底审查。使用这些文件的风险由您自行承担。”
* Linux Uprising. Malware Found On The Arch User Repository (AUR)\[EB/OL]. (2018-07-09)\[2026-04-04]. <https://www.linuxuprising.com/2018/07/malware-found-on-arch-user-repository.html?m=1>. AUR 中确实曾存在恶意软件包。
* BleepingComputer. Malware Found in Arch Linux AUR Package Repository\[EB/OL]. (2018-07-10)\[2026-04-18]. <https://www.bleepingcomputer.com/news/security/malware-found-in-arch-linux-aur-package-repository/>. 报道了 2018 年 AUR 中 acroread 等至少三个软件包被植入恶意代码。
* LWN.net. Malware found in the Arch Linux AUR repository\[EB/OL]. (2018-07-10)\[2026-04-18]. <https://lwn.net/Articles/759461/>. LWN 对同一事件的独立报道，交叉验证了 AUR 恶意软件包事实。
* openSUSE. Version naming question: 13 -> 42 -> 15 - Why?\[EB/OL]. \[2026-04-17]. <https://forums.opensuse.org/t/version-naming-question-13-42-15-why/131061>. openSUSE 社区对版本号从 42 降至 15 所引发升级问题的讨论。
* The Open Group. Register of UNIX® Certified Products\[EB/OL]. \[2026-04-17]. <https://www.opengroup.org/openbrand/register/brand3622.htm>. EulerOS（非 openEuler 社区版）通过 UNIX 03 认证。“Product Name: Huawei EulerOS 2.0, Registered on: 8-Sep-2016”。
* Gentoo. Benefits of Gentoo\[EB/OL]. \[2026-03-25]. <https://wiki.gentoo.org/wiki/Benefits_of_Gentoo>. 阐述 Gentoo 源代码编译模式在灵活性与性能优化方面的优势。
* Gentoo. The philosophy of Gentoo\[EB/OL]. \[2026-03-25]. <https://www.gentoo.org/get-started/philosophy/>. 介绍 Gentoo 以用户选择自由和编译定制为核心的设计理念。
* Arch Linux. Arch compared to other distributions\[EB/OL]. \[2026-03-25]. <https://wiki.archlinux.org/title/Arch_compared_to_other_distributions>. 对比 Arch Linux 与其他发行版在包管理和滚动更新策略上的差异。
* Stroustrup B. C++ 语言的设计和演化\[M]. 裘宗燕,译. 北京: 人民邮电出版社, 2020. ISBN: 978-7-115-49711-6. 由 C++ 语言创始人详述该语言的设计决策与演进历程。
* 统信安全应急响应中心. deepin-devicemanager命令注入漏洞安全公告(UTSA-2024-003941)\[EB/OL]. \[2026-04-04]. <https://src.uniontech.com/#/security_advisory_detail?utsa_id=UTSA-2024-003941>. 披露 deepin 设备管理器命令注入漏洞的技术细节与影响范围。
* Fedora Project. Fedora Council Charter\[EB/OL]. \[2026-04-04]. <https://docs.fedoraproject.org/en-US/council/>. Fedora 项目完全由红帽控制。
* Fedora Project. Fedora and Red Hat Enterprise Linux\[EB/OL]. \[2026-04-18]. <https://docs.fedoraproject.org/en-US/quick-docs/fedora-and-red-hat-enterprise-linux/>.“Fedora is a kind of 'upstream' of Red Hat Enterprise Linux”，Fedora 是 RHEL 的上游。
* CentOS Project. CentOS Stream documentation\[EB/OL]. \[2026-04-18]. <https://docs-centos-org-b1e6ff.gitlab.io/stream-docs/>. 该文档阐述了 CentOS Stream 作为 RHEL 中游开发分支的定位。
* mdd3135. deepin的开发人员都不测试的吗\[EB/OL]. 深度科技论坛. (2021-04-03)\[2026-04-04]. <https://bbs.deepin.org/post/218041>. 社区用户对 deepin 系统软件质量的质疑与讨论。
* Gentoo Foundation. Gentoo offers a full range of binary packages\[EB/OL]. (2023-12-29)\[2026-04-04]. <https://www.gentoo.org/news/2023/12/29/Gentoo-binary.html>. Gentoo 二进制包。
* NixOS Wiki. NixOS\[EB/OL]. \[2026-04-18]. <https://wiki.nixos.org/wiki/NixOS>. NixOS 的声明式配置模型及 nixos-rebuild switch 机制。

## 课后习题

1. 在 FreeBSD 中构建一个简单的 Port，编写 Makefile 使其能下载、编译并安装一个最小化程序，验证 Ports 框架的完整构建流程。
2. 使用 `tree` 或 `find` 命令遍历 FreeBSD 的目录树结构，与 Ubuntu 最新 LTS 版本在 **/etc**、**/usr**、**/var** 三个目录的组织方式上进行对比分析。
3. 从技术本体论角度分析：当 Linux 发行版的各组件（内核、包管理器、桌面环境等）均可独立替换时，“发行版”这一概念的同一性依据是什么？


# 4.3 macOS 用户迁移指南

macOS 与 FreeBSD 共享大量 BSD 组件，因此从 macOS 迁移到 FreeBSD，命令行入门较从 Windows 迁移更为容易。

## 共同的 BSD 血脉

从历史角度看，macOS（以及由此衍生的 iOS、iPadOS 等）的核心层（Darwin）基于 BSD 代码，并融合了其他技术。

```sh
Original Unix
        |
        V
     4.3 BSD ------------------------------------------------------+
        |                                                          |
        +----------------------+                                   | (基于 4.3 BSD)
        |                      |                                   V
        V                      V                           CMU Mach Project
   4.3BSD-Reno             386BSD 0.1                              |
        |                      |                                   V
        |                      V                                 Mach
        V                 FreeBSD 1.0                              |
   4.4BSD-Lite                 |                   +---------------+---------------+
                               |                   |                               |
                               V                   V                               V
                        FreeBSD 4.x/5.x        OSFMK 7.3                     NeXT Mach 2.5
                               |            (Based on Mach 3.0)              (Integrated 4.3 BSD)
                               |                   |                               |
                               |                   |                       +-------+
                               |                   |                       |       |
                               |                   |                       |       V
                               |                   |                       |    NeXTSTEP
                               |                   |                       |       |
                               |                   |                       |       V
                               |                   |                       |    OPENSTEP
                               |                   |                       |       |
                               |                   |                       |       V
                               |                   |                       |    Rhapsody
                               |                   |                       |       |
                               +---+               |                       |       |
                                   |               |                       |       |
                                   V               V                       V       |
                               +-----------------------------------------------+   |
                               |                   XNU Kernel                  |   |
                               |                                               |   |
                               |        (OSFMK 7.3 Based on Mach 3.0          |   |
                               |        + FreeBSD VFS/Networking)              |   |
                               +-----------------------------------------------+   |
                                                       |                           |
                                                       V                           |
                                                     Darwin                        |
                                       (XNU Kernel + FreeBSD Userland)             |
                                                       |                           |
                                                       +---------------------------+
                                                                     |
                                                                     V
                                                                   macOS
                                                      (Darwin + Aqua UI + Cocoa)
```

macOS 系列操作系统可以看作独立的、类 BSD 操作系统分支，与 OpenBSD、NetBSD 和 FreeBSD 等系统具有同等地位。

| 组件     | 来源                                                                                                  |
| ------ | --------------------------------------------------------------------------------------------------- |
| XNU 内核 | 基于 Mach 微内核（CMU）、NeXTStep/OpenStep 架构，整合 BSD 子系统（最初源自 4.3BSD，经由 NeXTSTEP 整合，苹果持续从较新 FreeBSD 版本同步代码） |
| 网络栈    | BSD/FreeBSD TCP/IP 协议栈为核心（IPv4/IPv6），包含 IOKit 驱动接口；NKE（Network Kernel Extensions，网络内核扩展）            |
| 虚拟文件系统 | 基于 BSD VFS，支持 HFS+、APFS、UFS 等文件系统                                                                   |
| 用户空间工具 | BSD 用户工具（如 ls、cp、grep 等），经过苹果改造和增强                                                                  |
| 内存管理   | Mach 虚拟内存管理（VM），受 BSD 内存管理机制部分影响，支持分页、保护和共享内存                                                       |
| 进程模型   | Mach IPC、Security Trailers、强制访问控制（MAC）机制，支持多任务和安全策略                                                 |

## 基本比较

| 功能          | macOS                   | FreeBSD                      | 说明                |
| ----------- | ----------------------- | ---------------------------- | ----------------- |
| shell       | zsh                     | sh                           | FreeBSD 可选支持 zsh  |
| 权限提升        | sudo                    | 可选                           | FreeBSD 可选支持 sudo |
| 软件管理（二进制包）  | 可选，通常为 Homebrew         | pkg                          | /                 |
| 软件管理（基于源代码） | MacPorts                | Ports                        | MacPorts 源自 Ports |
| 防火墙         | pf (Packet Filter)      | 内置 pf (Packet Filter) 等多种防火墙 | 可选支持              |
| 服务管理        | launchd（命令 `launchctl`） | BSD init + RC 系统             | /                 |
| 编译程序        | Clang + LLVM            | Clang + LLVM                 | /                 |
| 生命周期        | 3 年                     | 4 年                          | /                 |
| 文件系统        | APFS（默认）                | ZFS（默认）                      | /                 |
| UNIX 认证     | 逐版本认证                   | 未认证                          | /                 |

> **注意**
>
> macOS 中的许多命令行工具（如 `sed`、`grep`、`awk`）已是较旧版本，与 FreeBSD 当前版本相比存在差异。

## 文件系统 APFS 与 ZFS 比较

| 特性       | APFS                          | ZFS                        |
| -------- | ----------------------------- | -------------------------- |
| 校验和      | 仅元数据                          | 元数据 + 数据（端到端）              |
| 快照       | 支持                            | 支持                         |
| 写时复制     | 支持                            | 支持                         |
| 压缩       | 支持透明压缩（LZFSE 等，需手动启用），非自动实时压缩 | 支持（LZ4、GZIP、ZSTD 等）        |
| 加密       | 原生支持                          | 原生支持                       |
| 去重       | 不支持全局去重                       | 支持                         |
| 克隆       | 支持                            | 支持                         |
| RAID     | 不支持                           | RAID-Z / RAID-Z2 / RAID-Z3 |
| 空间共享     | 容器内卷共享                        | 存储池内数据集共享                  |
| 最大文件大小   | 8 EiB                         | 16 EiB                     |
| 最大池/容器大小 | 8 EiB                         | 2^128 字节（理论寻址上限）           |
| 大小写敏感性   | macOS 默认不区分                   | 默认区分（可通过属性调节）              |

macOS 的 APFS 默认不区分大小写（Case-Insensitive），而 FreeBSD 的 ZFS 和 UFS 默认均区分大小写。

## 参考文献

* Apple Inc. Darwin\[EB/OL]. \[2026-04-18]. <https://opensource.apple.com/>. Apple 开源的 Darwin 操作系统基础，包含 XNU 内核及 BSD 子系统。
* LEVIN J. 深入解析 Mac OS X & iOS 操作系统\[M]. 郑思遥, 房佩慈, 译. 北京: 清华大学出版社, 2014. ISBN: 978-7-302-34867-2.
* Jason Perlow. Apple's Open Source Roots: The BSD Heritage Behind macOS and iOS\[EB/OL]. (2024-07-08)\[2026-03-26]. <https://thenewstack.io/apples-open-source-roots-the-bsd-heritage-behind-macos-and-ios/>. 比较表格参考此处。
* Apple Inc. File System\[EB/OL]. \[2026-04-18]. <https://developer.apple.com/documentation/foundation/about-apple-file-system>. APFS 官方技术指南。
* OpenZFS. OpenZFS Documentation\[EB/OL]. \[2026-04-18]. <https://openzfs.org/wiki/Main_Page>. OpenZFS 项目文档。


# 5.1 安装前的准备工作

部署 FreeBSD 系统之前，需完成硬件兼容性评估、安装介质准备与制作等前期工作。

## 硬件兼容性

以下列出 amd64 架构的最低硬件配置与硬件兼容性查询方法。

### 最低硬件需求

amd64（又称 x86-64）是 64 位 x86 架构的扩展，广泛应用于现代个人计算机与服务器。15.0-RELEASE 版本在虚拟机环境中测得的最低硬件需求如下：

| 类别 | 场景/模式                   | 最低需求     |
| -- | ----------------------- | -------- |
| 硬盘 | 仅安装基本系统                 | 约 550 MB |
| 硬盘 | 安装 KDE 桌面环境（通过 pkg 安装后） | 约 15 GB  |
| 内存 | UEFI 模式                 | 256 MB   |
| 内存 | BIOS 模式                 | 96 MB    |
| 内存 | ZFS 文件系统（最低）            | 2 GB     |

然而，以上为启动安装程序的理论最小值；为了保证基本的系统可用性，实际内存容量应不小于 256 MB。

如果要使用 ZFS 作为文件系统，OpenZFS 项目官方建议设备至少应搭载 2 GB 内存（推荐 8 GB 以上以获得最佳性能），内存低于此值时，可能需要对 ZFS 参数手动调优。

### 实测硬件兼容性

下表列出了部分硬件的实测支持情况：

| 硬件类别      | 系列                                  | 实测型号                                         | 备注                                                                                                                                                                                                                                                                                                              |
| --------- | ----------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CPU       | Intel Alder Lake（含混合架构与纯 E-core 架构） | i7-1260P、N100                                | 可正常启动运行，但调度机制尚不完善，睿频功能受限。i7-1260P 为混合架构（P-core + E-core），N100 为纯 E-core 架构（4 颗 Gracemont 核心）                                                                                                                                                                                                                    |
| NVMe 固态硬盘 | M.2 接口                              | 英睿达 P310、Intel 600P、梵想 S530Q、S500Pro、S542PRO | 正常工作                                                                                                                                                                                                                                                                                                            |
| 无线网卡      | Intel AX 系列                         | AX200                                        | Wi-Fi 5 速率与 Windows 11 IoT Enterprise 24H2 相当（使用 iperf2 测得）                                                                                                                                                                                                                                                     |
| 有线网卡      | Realtek 2.5 G                       | RTL8125B                                     | 需要额外安装驱动程序，参见本书附录                                                                                                                                                                                                                                                                                               |
| 有线网卡      | Intel 2.5 G                         | i226-V                                       | 正常工作                                                                                                                                                                                                                                                                                                            |
| 显卡        | 近十年的 Intel 及 AMD 集成/独立显卡            | 英特尔锐炬® Xe 显卡、英特尔 HD Graphics 4000            | 支持程度与 DRM 驱动程序移植进度相关；drm-kmod 元 Port 会根据系统版本自动选择合适的驱动：在 FreeBSD 14.x 上安装 drm-61-kmod（基于 Linux 6.1），在 FreeBSD 15.0-RELEASE 及更新版本上安装 drm-66-kmod（基于 Linux 6.6），在较新的 FreeBSD 15-STABLE 上安装 drm-612-kmod（基于 Linux 6.12）。用户也可手动安装 drm-latest-kmod（追踪 Linux DRM 最新开发版本，基于 Linux 6.12，适用于较新的 FreeBSD 15 及 FreeBSD 16）。 |
| NVIDIA 显卡 | 近十多年的显卡                             | GTX 850M                                     | 受 NVIDIA 官方显卡驱动程序支持                                                                                                                                                                                                                                                                                             |

> **注意**
>
> FreeBSD 支持安全启动（Secure Boot），但需要用户手动配置密钥并签名引导组件，尚未实现开箱即用。在安装 FreeBSD 前，建议关闭安全启动（Secure Boot）。同时，FreeBSD 也不支持 Fake RAID（伪 RAID），需将控制器模式修改为 AHCI。
>
> Fake RAID 是由主板 BIOS/固件提供的软件 RAID 功能，依赖操作系统驱动程序支持，并非真正的硬件 RAID。AHCI（Advanced Host Controller Interface）是 SATA 控制器的标准工作模式，提供原生支持 SATA 设备的高级特性。
>
> 操作方法：进入 BIOS/UEFI 设置界面，找到存储控制器相关选项，将模式从 RAID 改为 AHCI 后保存重启。具体菜单位置因主板型号而异，可参考主板说明书。

#### 参考文献

* FreeBSD Project. drm-kmod: drm driver for FreeBSD\[EB/OL]. \[2026-06-05]. <https://github.com/freebsd/drm-kmod>. 该仓库提供 FreeBSD 图形驱动程序内核模块更新，追踪 Linux DRM 驱动程序移植进度。
* FreeBSD Project. SecureBoot\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/SecureBoot>. 该页面提供 FreeBSD 安全启动相关状态信息。

### 特定硬件兼容性查询

除上述实测硬件外，更多硬件的支持情况可参考以下外部资源。

[bsd-hardware.info. Hardware for BSD](https://bsd-hardware.info/?view=search) 该平台提供 BSD 系统硬件兼容性数据库，可用于查询设备支持情况。

![硬件支持查询](/files/9pJnO7UyuoSKCn75XT1r)

![硬件支持查询](/files/gVu69jM0vdCM22W4LghF)

> **注意**
>
> 因为该网站也可能出现错误（例如将 LPDDR5 误识别为 LPDDR4），建议实际测试。

## 下载 FreeBSD 镜像

了解硬件支持情况后，开始下载 FreeBSD 镜像。首先访问 FreeBSD 项目官网：<https://www.freebsd.org/>。

![FreeBSD 项目官网](/files/Gqr62KlxXSEFIXEE0CUT)

点击黄底红字的 `amd64`，页面将跳转至下载页面：

> **技巧**
>
> 随着时间推移，读者下载时可能已无 15.0-RELEASE 版本。此时只需选择列表最顶部的 `FreeBSD-X.Y-RELEASE`（该版本推荐用于生产环境）。其中，`X.Y` 应为比 `15.0` 更大的版本号，如 `15.1`、`16.0` 等。

![FreeBSD 镜像](/files/VEMluGBOtkzsZwhqdMDa)

```sh
File Name                                          File Size      Date
Parent directory/                                  -              -
CHECKSUM.SHA256-FreeBSD-15.0-RELEASE-amd64	1171	2025-Nov-28 09:05
CHECKSUM.SHA512-FreeBSD-15.0-RELEASE-amd64	1811	2025-Nov-28 09:04
FreeBSD-15.0-RELEASE-amd64-bootonly.iso	556255232	2025-Nov-28 05:15
FreeBSD-15.0-RELEASE-amd64-bootonly.iso.xz	121307196	2025-Nov-28 05:15
FreeBSD-15.0-RELEASE-amd64-disc1.iso	1359900672	2025-Nov-28 05:18
FreeBSD-15.0-RELEASE-amd64-disc1.iso.xz	905854552	2025-Nov-28 05:18
FreeBSD-15.0-RELEASE-amd64-dvd1.iso	4405243904	2025-Nov-28 06:23
FreeBSD-15.0-RELEASE-amd64-dvd1.iso.xz	3532521960	2025-Nov-28 06:23
FreeBSD-15.0-RELEASE-amd64-memstick.img	1560400384	2025-Nov-28 05:20
FreeBSD-15.0-RELEASE-amd64-memstick.img.xz	905654292	2025-Nov-28 05:20
FreeBSD-15.0-RELEASE-amd64-mini-memstick.img	689295872	2025-Nov-28 05:17
FreeBSD-15.0-RELEASE-amd64-mini-memstick.img.xz	119782720	2025-Nov-28 05:17
```

上述列表中：第一行分别为文件名、文件大小、文件构建日期（非发行日期），第二行为返回上一级目录。

| 首列                                              | 说明                                      |
| ----------------------------------------------- | --------------------------------------- |
| CHECKSUM.SHA256-FreeBSD-15.0-RELEASE-amd64      | 本页所有镜像的 SHA-256 校验和                     |
| CHECKSUM.SHA512-FreeBSD-15.0-RELEASE-amd64      | 本页所有镜像的 SHA-512 校验和                     |
| FreeBSD-15.0-RELEASE-amd64-bootonly.iso         | 网络安装镜像，安装时需要联网                          |
| FreeBSD-15.0-RELEASE-amd64-bootonly.iso.xz      | 压缩的网络安装镜像，安装时需要联网                       |
| FreeBSD-15.0-RELEASE-amd64-disc1.iso            | 标准安装镜像                                  |
| FreeBSD-15.0-RELEASE-amd64-disc1.iso.xz         | 压缩的标准安装镜像                               |
| FreeBSD-15.0-RELEASE-amd64-dvd1.iso             | DVD 镜像，相比标准安装镜像包含了更多软件包（pkg）            |
| FreeBSD-15.0-RELEASE-amd64-dvd1.iso.xz          | 压缩的 DVD 镜像，相比标准安装镜像包含了更多软件包（pkg）        |
| FreeBSD-15.0-RELEASE-amd64-memstick.img         | U 盘用的镜像（可以使用 Rufus 制作 U 盘启动盘）           |
| FreeBSD-15.0-RELEASE-amd64-memstick.img.xz      | 压缩的 U 盘用的镜像（无需解压缩，可以使用 Rufus 制作 U 盘启动盘） |
| FreeBSD-15.0-RELEASE-amd64-mini-memstick.img    | U 盘用的网络安装镜像，安装时需要联网                     |
| FreeBSD-15.0-RELEASE-amd64-mini-memstick.img.xz | 压缩的 U 盘用的网络安装镜像，安装时需要联网                 |

* **.xz** 是一种高压缩比的文件压缩格式，常用于缩小软件发行包的体积。
* **SHA-256** 和 **SHA-512** 是密码哈希函数，用于生成文件的唯一指纹，校验和（Checksum）则是通过这些函数计算出的固定长度字符串，用于验证文件完整性。

> **技巧**
>
> 网络传输可能产生错误，导致下载的文件与原始镜像不一致。因此，需要使用 **校验和** 来验证所获取的文件与官方发布的镜像完全一致。Windows 10 和 11 系统自带命令行工具 CertUtil，可用于计算校验和，无需安装额外软件。

需要说明的是，DVD 镜像仅包含部分离线软件包，而非全部，具体清单可参见源代码文件 **release/scripts/pkg-stage.sh** 该脚本定义 DVD 镜像包含的预安装软件包清单。

FreeBSD 的所有安装介质默认不提供图形界面，需在系统安装后另行安装和配置。DVD 镜像虽包含更多软件包，但由于图形界面依赖关系复杂，且 DVD 上的软件包版本可能较旧，在安装图形界面时仍可能遇到依赖冲突或版本不匹配问题，因此不建议使用 DVD 镜像。

## 开发版本及非 amd64 架构

STABLE 和 CURRENT 均为开发分支，不适用于生产环境，生产环境应选用 RELEASE。

要使用开发分支，或者为非 amd64 架构下载镜像，在主页选择“other”即可。

![下载 FreeBSD](/files/JIFUVv1dclptPa3OHsnl)

> **警告**
>
> 使用开发版本的用户应有时间和意愿关注开发动态，浏览邮件列表与问题追踪系统。同时要求用户具备一定的探索和实践能力。否则，建议使用 RELEASE 版本。

| Installer | VM         | SD Card      | Documentation |
| --------- | ---------- | ------------ | ------------- |
| 安装镜像      | 虚拟机预安装镜像   | 存储卡镜像        | 文档            |
| 适用于常规安装   | 适用于云平台和虚拟机 | 适用于单板机/嵌入式设备 | 发行说明等文档       |

> **技巧**
>
> 如果不确定选择哪种镜像，请选择 `Installer`（标准个人计算机，Apple 除外）。

> **技巧**
>
> 如果不明确 `amd64`、`aarch64`、`riscv64` 等架构的区别，请选择 `amd64`（适用于大多数标准个人计算机，Apple 电脑除外）。

选定安装镜像的主要类型后，将显示具体的下载列表。

| 版本类型                | 部署环境 | 下载地址                                                                                                        |
| ------------------- | ---- | ----------------------------------------------------------------------------------------------------------- |
| RELEASE 正式版         | 虚拟机  | <https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/15.0/FreeBSD-15.0-RELEASE-amd64-disc1.iso>    |
| RELEASE 正式版         | 物理机  | <https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/15.0/FreeBSD-15.0-RELEASE-amd64-memstick.img> |
| CURRENT 开发版（仅限专业用户） | 虚拟机  | <https://download.freebsd.org/snapshots/amd64/amd64/ISO-IMAGES/16.0/>                                       |
| CURRENT 开发版（仅限专业用户） | 物理机  | 文件名以 `-amd64-memstick.img` 或 `-amd64-memstick.img.xz` 结尾                                                    |

由于版本迭代，实际情况可能已发生变化，请自行查阅，选择合适的 RELEASE 版本用于生产环境。

### 参考文献

* FreeBSD Project. freebsd-src/UPDATING\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/blob/main/UPDATING>. 该文件记录着系统更新重大变更。
* FreeBSD Project. freebsd-src/RELNOTES\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/blob/main/RELNOTES>. 该文件提供发行版发布说明与新特性等文档。
* Dell Technologies. 如何确定用于安全应用程序的文件 SHA-256 哈希\[EB/OL]. \[2026-03-25]. <https://www.dell.com/support/kbdoc/zh-cn/000130826/%E5%A6%82%E4%BD%95%E7%A1%AE%E5%AE%9A%E7%94%A8%E4%BA%8E%E5%AE%89%E5%85%A8%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E7%9A%84%E6%96%87%E4%BB%B6-sha-256-%E5%93%88%E5%B8%8C>. 该文档介绍 Windows 系统下文件 SHA-256 哈希值计算方法。读者可参考。

## 刻录 FreeBSD 镜像

下载 FreeBSD 镜像后，需要将其刻录到 U 盘上才能安装。

### 推荐镜像格式

制作 U 盘安装介质时，建议使用 `-img` 或 `-img.xz` 格式的镜像。`.iso` 镜像采用混合启动（Hybrid）模式，该模式同时支持从光驱和 U 盘启动，但可能未完全遵循 UEFI 规范，直接写入 U 盘可能导致启动错误。详见 FreeBSD Project. FreeBSD -.iso files not support written to USB drive\[EB/OL]. \[2026-03-25]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=236786>. 该 Bug 报告记录了 ISO 镜像直接写入 USB 设备的兼容性问题。建议读者优先在使用光学介质、虚拟机或云平台安装时选用 `iso` 结尾的镜像；物理机 U 盘安装应优先使用 `img` 镜像。

然而，也存在例外情况。部分主机的 UEFI 固件支持从 `.iso` 镜像刻录的 U 盘启动（例如一些老款神舟电脑），但并非所有主机都支持此方式（例如部分小米电脑可能无法引导）。

由于设备类型多样，即使在某台主机上测试通过，FreeBSD 的两个 ISO 镜像仍可能出现兼容性问题。如果遇到引导问题，请首先尝试使用 Rufus 刻录 `img` 镜像。

### Windows 平台下 Rufus 刻录方法

不同操作系统平台有不同镜像刻录工具推荐。

Windows 平台建议优先使用 **Rufus**，Linux/FreeBSD 平台可直接使用 `dd` 命令刻录镜像：`dd if=FreeBSD-*.img of=/dev/daX bs=1M status=progress`（其中 **/dev/daX** 为目标 U 盘设备，请根据实际设备名调整；`status=progress` 显示传输进度）。

Rufus 下载地址为 <https://rufus.ie/zh>，该工具为 Windows 平台开源 USB 启动盘制作工具。

使用 Rufus 刻录镜像，无需解压缩文件，直接选择 `-img.xz` 制作启动盘。

![Rufus](/files/lGydOOuYv1W4PpSksaqH)

尽管镜像文件校验和实际正确，但 win32diskimager 在处理某些镜像格式时存在缺陷，有时会错误地报告校验失败。此外，win32diskimager 自 2017 年 3 月发布 1.0.0 版本后已停止更新超过 9 年，其可执行文件未经代码签名，不支持压缩镜像格式（如 `.img.xz`），在现代 UEFI 环境下的兼容性也不如 Rufus 和 balenaEtcher。Ventoy 的启动加载机制与 FreeBSD 镜像不完全兼容，可能导致启动失败。二者均 **不建议使用**。

**读者应优先使用 Rufus；若 Rufus 不可用，可使用 balenaEtcher 作为替代。** balenaEtcher 是一款跨平台（Windows/macOS/Linux）开源镜像刻录工具，支持直接刻录压缩镜像（如 `.img.xz`，无需解压），写入后自动校验数据完整性，且仍在积极维护中。balenaEtcher 下载地址为 <https://etcher.balena.io/>。

> **思考题**
>
> > 有时候绕远路是必须的，人生是片森林，人们终究会再次迷路，短暂相遇。正所谓“念念不忘，必有回响”。然而，人们清醒地意识到，没有什么“必有回响”，有的只是“没有结局的开始”或者“稍纵即逝的追寻”。没有任何人许诺回响，这只是某种哲学层面的寄托，让人们与这种现实“和解”。
> >
> > “念念不忘，必有回响”的完整说明并非李叔同所述，而是源于当代人的《李叔同〈晚晴集〉人生解读》（王少农. 李叔同《晚晴集》人生解读\[M]. 北京：线装书局，2008.）其中上半句“念念不忘”亦非李叔同原作，而是看似引用了南宋王龙舒《龙舒净土文卷第四》“蓋欲念念不忘也。如此久久念心成熟。”其中在清俞行敏重辑《净土全书》一书的“净土起信”中同样有类似描述“净土指归云：欲了生死，修行净业，当发十种信心，念念不忘，决生净土。”，再次索引到《净土指归集》，实际上是绕回了《佛说四谛经》，载“亦观持宿命，亦从得道行，念世间行不可悔，摄、止、度世、无为、寂然、止见、一德、无所著、如解脱意观念想念，从念念、念不忘、少言、念不离，是名为直正念，是名为道德谛。”
> >
> > 由于这是汉传佛教，在历史上被记载为安世高的翻译贡献，需考察其原始面貌。查《佛说四谛经》，实际对应于中阿含经《分别圣谛经》，即对应《巴利三藏》的《中部》的《一四一分别谛经》（段晴，范晶晶，等，译. 汉译巴利三藏·经藏·中部\[M]. 上海：中西书局，2022：963-965.）。是这样写的：“众仁友，何为正念？此谓比丘于身循观身，精勤，正知，具念，于世间戒除贪与忧；于诸受（……）于心（……）于诸法循观法，精勤，正知，具念，于世间断除贪与忧。这被称为正念。”可以清晰地看出，“念念不忘”实际上对应的是“具念”（巴利语 sati），在文献中往往又被翻译为“念”“正念”。
> >
> > 实际上，在任何早期人类宗教活动中，传递的思想都是当时最合适不过的道德思想和伦理行为，也是最质朴，最清楚明白的，任何过于复杂的理论绝不可能流传数千年。因此，有必要怀疑这种“念念不忘”说法的合理性。在不同的学术观点中对此看法存在较大差异，但是无可辩驳的是，在佛教最早期的发展中，不可能有任何超越当时信众知识结构、道德伦理、认知能力的理论被普遍认可。因此，无需考察任何文本，越是从经验出发的理解，却往往是最接近合理性的存在。念念不忘实质上接近这种说法：“厨师一定要会做饭、水一定往低处流”，即，xx 就是 xx。可以看到，“念念不忘”与当代欧陆哲学产生了深切共鸣，不是让事情回到本身，而是认识到，有些时候，事情就是本身。“大音希声”。“一切真历史都是当代史”（Croce B. 历史学的理论和历史\[M]. 田时纲，译. 北京：中国社会科学出版社，2018），但无论是玄奘短命的“法相唯识宗”，还是“念念不忘”的本义，都启示着一个深邃的事实，“一切真历史都是古代史”。“谁试图诠释历史，谁就在篡改历史。讨论真假无非是在争夺自己的话语权。”历史学是一种解释学。佛经和道教经文的文言文呈现方式仍是绝对主流，且无定本；而与此同时，基督教两会甚至出版了官方的《拼音版圣经》。但在过去，甚至如今的天主教，保守也是常态。形式上的精致化、现代化与内在的理论嬗变的平衡是大多数理论发展的痛点。后人对前人的经典论述究竟是形成了一层又一层的遮蔽，还是使其精致化顺应时代发展？今人所看到的，持有的意见，究竟有几分是最初作者的面貌？后人往往通过注解经典来阐发自己的观点，甚至托名作书。
> >
> > 念念不忘，恰好指出了一个道理，“没有回响才是常态”，这不是固执的坚持和重复，而是理解到一个无数人提及的话语，人本就一无所有，唯一重要的事情只有生或死。念念不忘，不是执着于铭记，而是发现，感知到什么，那就是什么。与其说人一生都在选择，不如说人一生都在等待，等待回响。
>
> 如何理解“念念不忘”与“必有回响”的关系？
>
> 如果一切都是临时的，短暂的。那么，会不会有一天，有那么一刻，恰巧宇宙本身也不存在了？

## 附录：FreeBSD 兼容的以太网卡

FreeBSD 对多种以太网卡支持良好。

### Realtek（螃蟹卡）

Realtek RTL8125 是一款常见的 2.5 G 以太网卡。在消费级市场中，常见的 2.5 G 网卡多采用该型号芯片。在安装 FreeBSD 前，可在 Windows 设备管理器中查看硬件标识，确认网卡型号是否为 RTL8125。

![Realtek RTL8125 2.5 G](/files/oAyfbDhtmdaurdumGDgk)

> **技巧**
>
> RTL8125 在 FreeBSD 下默认没有驱动，需手动安装。最简单的方法是通过手机 USB 共享网络临时上网，具体方法见本书其他部分。安装网卡驱动后需重启系统。

#### Realtek 以太网卡驱动安装方法

确认网卡型号在支持列表中后，按照以下步骤安装驱动。

* 使用 pkg 安装：

```sh
# pkg install realtek-re-kmod
```

* 使用 Ports 安装：

```sh
# cd /usr/ports/net/realtek-re-kmod/
# make install clean
```

在编译安装时，需确保 **/usr/src** 目录下有源代码。

```sh
/usr/
├── ports/
│   └── net/
│       └── realtek-re-kmod/  # Realtek 网卡驱动 Ports 目录
└── src/                      # 系统源代码目录（编译驱动时需要）
```

> **技巧**
>
> 如果 Realtek 网卡仍存在断流、时断时续等情况，可尝试使用 Port **net/realtek-re-kmod198** 替代 **realtek-re-kmod**。

相关文件结构：

```sh
/boot/
├── loader.conf        # 系统启动加载器配置文件
└── modules/
    └── if_re.ko       # re 网卡驱动内核模块
```

编辑 **/boot/loader.conf** 文件，写入以下两行：

```ini
if_re_load="YES"                        # 设置开机自动加载 re 网卡驱动模块
if_re_name="/boot/modules/if_re.ko"     # 指定 re 网卡驱动模块的完整路径，以覆盖内核内置的 re(4) 驱动
```

默认分配了足够接收巨型帧的缓冲区。巨型帧是指大于标准以太网帧（1500 字节）的帧，通常为 9000 字节。巨型帧可减少网络开销、提升传输效率，但在某些网络环境下可能导致兼容性问题。re 网卡相关配置参数如下：

| 参数                      | 建议值    | 作用                             |
| ----------------------- | ------ | ------------------------------ |
| `hw.re.max_rx_mbuf_sz`  | `2048` | 缩小接收缓冲区，降低内存需求，避免内存碎片导致的驱动程序挂起 |
| `hw.re.s5wol`           | `1`    | 启用 S5 休眠唤醒                     |
| `hw.re.s0_magic_packet` | `1`    | 启用魔术包唤醒（Wake-on-LAN）           |

配置方法为使用 `sysrc` 将参数写入 **/boot/loader.conf**，例如：

```sh
# sysrc -f /boot/loader.conf hw.re.max_rx_mbuf_sz="2048"
# sysrc -f /boot/loader.conf hw.re.s5wol="1"
# sysrc -f /boot/loader.conf hw.re.s0_magic_packet="1"
```

完成以上设置后，需重启系统使其生效。

参考文献：

* FreshPorts. realtek-re-kmod: Kernel driver for Realtek PCIe Ethernet Controllers\[EB/OL]. \[2026-03-25]. <https://www.freshports.org/net/realtek-re-kmod>. FreshPorts 上的 Realtek 网卡驱动页面，提供安装信息与版本更新。
* Bug 275882 - **net/realtek-re-kmod**: Problem with checksum offload since +199.00\[EB/OL]. \[2026-03-26]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=275882>.

### Intel 网卡

Intel 网卡也是常见的网络适配器类型，FreeBSD 对其支持良好。

#### 2.5 G

英特尔 i225-V 和 i226-V 2.5 G 网卡默认便可驱动，无需额外配置。已在 I226-V rev04 型号上测试通过，使用 `igc` 驱动，网卡显示为 `igc0` 样式。

参考文献：

* FreeBSD Project. igc: Intel Ethernet Controller I225 driver\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=igc&sektion=4>. 手册页，详述了 Intel I225/I226 系列网卡驱动的使用方法。

#### 千兆和百兆及其他以太网卡

除了 2.5 G 网卡外，Intel 还有其他多种型号的以太网卡。i210 和 i211 网卡由 igb 驱动，通常无需额外配置便可使用，但未经实际测试。

支持列表及更多参见：

* FreeBSD Project. em, lem, igb: Intel(R) PRO/1000 Gigabit Ethernet adapter driver\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=em&sektion=4>. 手册页，含 Intel PRO/1000 系列千兆网卡驱动说明。

## 附录：USB 网卡推荐

USB 网卡便携性强、使用方便，适合临时使用或设备没有内置网卡的情况。以下介绍 USB 网卡的相关推荐。

> **警告**
>
> 千兆和 2.5 G 网卡在 15.0-RELEASE 以前均存在间歇性断连故障。如果有更稳定的推荐，请提交 PR。
>
> 对于 2.5 G USB 网卡，目前可选的型号仅有 RTL8156 和 RTL8156B。

| 类型          | 品牌/型号                  | 芯片组/参数                       | 备注                                                                                                        |
| ----------- | ---------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| USB 以太网卡    | 绿联 USB 百兆网卡 CR110      | AX88772A 100M                | /                                                                                                         |
| USB 以太网卡    | 绿联 USB 千兆网卡 CM209      | AX88179A 1000M               | 在 15.0-RELEASE 以前断流                                                                                       |
| Type-C 以太网卡 | 绿联 Type-C 转百兆网卡 30287  | AX88772A 100M                | /                                                                                                         |
| Type-C 以太网卡 | 绿联 Type-C 转千兆网卡 CM199  | AX88179A 1000M               | 在 15.0-RELEASE 以前断流。在树莓派 5 上的测试表明，目前 15.0-RELEASE 下的 AX88179A 和 RTL8156B 网卡均可持续稳定运行，不会断流，最长连续运行时间超过 72 小时 |
| USB 无线网卡    | COMFAST CF-WU810N（已停产） | RTL8188EUS 2.4 G 150 M       | 由 rtwn 驱动                                                                                                 |
| USB 无线网卡    | COMFAST CF-912AC       | RTL8812AU 2.4 G & 5 G 1200 M | 由 rtwn 驱动                                                                                                 |
| USB 无线网卡    | COMFAST CF-915AC       | RTL8811AU 2.4 G & 5 G 600 M  | 由 rtwn 驱动，理论上支持，未经实际测试，无论是否支持，都请提交 issue                                                                  |
| USB 无线网卡    | 绿联 N300 M              | RTL8192EU 2.4 G 300 M        | 由 rtwn 驱动，理论上支持，未经实际测试，无论是否支持，都请提交 issue                                                                  |
| USB 无线网卡    | 绿联 AC 1300 M-双频        | RTL8812AU 2.4 G & 5 G 1300 M | 由 rtwn 驱动，理论上支持，未经实际测试，无论是否支持，都请提交 issue                                                                  |
| USB 以太网卡    | 绿联 USB 2.5 G 网卡 CM275  | RTL8156 2.5 G                | 在 15.0-RELEASE 以前断流                                                                                       |
| Type-C 以太网卡 | 绿联 Type-C 转 2.5 G 网卡   | RTL8156 2.5 G                | 在 15.0-RELEASE 以前断流                                                                                       |

VendorID（厂商标识）和 ProductID（产品标识）是 USB/PCI 设备的两个标准标识符，驱动程序通过这两个 ID 来识别和匹配硬件。

相同芯片组的硬件可能由不同厂商生产，使用不同的 VendorID/ProductID。

如果仅凭芯片组信息购买网卡，FreeBSD 可能不支持其 `VendorID` 和 `ProductID`，例如 DOREWIN 达而稳。

在这种情况下，需联系驱动开发者将硬件信息加入驱动，并重新编译内核才能使用。

相关 Bug 反馈：

* FreeBSD Bugzilla. Bug 166724 - if\_re(4): watchdog timeout\[EB/OL]. \[2026-03-25]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=166724>. 记载了 Realtek 网卡驱动看门狗超时问题的历史 Bug 报告。
* FreeBSD Bugzilla. Bug 267514 - AXGE(4) ASIX AX88179A ue0: link state changed to DOWN\[EB/OL]. \[2026-03-25]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=267514>. 记载了 ASIX USB 千兆网卡连接不稳定问题的 Bug 报告。
* FreeBSD Project. if\_re(4) -- Realtek PCI Ethernet driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=if_re&sektion=4>. Realtek PCI 以太网卡驱动手册页。
* FreeBSD Project. axge(4) -- ASIX USB Gigabit Ethernet driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=axge&sektion=4>. ASIX USB 千兆网卡驱动手册页。
* FreeBSD Project. rtwn(4) -- Realtek USB IEEE 802.11 wireless network driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=rtwn&sektion=4>. Realtek USB 无线网卡驱动手册页。
* FreeBSD Project. igb(4) -- Intel PRO/1000 Gigabit Ethernet adapter driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=igb&sektion=4>. Intel PRO/1000 千兆网卡驱动手册页。
* FreeBSD Project. pciconf(8) -- PCI configuration utility\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=pciconf&sektion=8>. PCI 设备配置工具手册页。
* FreeBSD Project. usbconfig(8) -- USB configuration utility\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=usbconfig&sektion=8>. USB 设备配置工具手册页。

## 附录：共享硬件数据到数据库

如果读者希望上传自己的数据到 <https://bsd-hardware.info>，与社区共享，可参照本节操作。

### 安装 hw-probe

* 使用 pkg 安装 hw-probe：

```sh
# pkg install hw-probe
```

* 或者使用 Ports 安装 hw-probe：

```sh
# cd /usr/ports/sysutils/hw-probe/
# make install clean
```

### 上传硬件数据

执行以下命令可采集硬件信息并上传到 hw-probe 数据库：

```sh
# hw-probe -all -upload
Probe for hardware ... Ok
Reading logs ... Ok
Uploaded to DB, Thank you!

Probe URL: https://bsd-hardware.info/?probe=f64606c4b1
```

访问上述链接可查看设备信息。此处上传的是 Radxa x4 的配置信息。

其他操作系统可参见 linuxhw. hw-probe/INSTALL.BSD.md\[EB/OL]. \[2026-03-25]. <https://github.com/linuxhw/hw-probe/blob/master/INSTALL.BSD.md>，该文档提供 BSD 系统上 hw-probe 工具的安装说明。

## 附录：镜像资源

FreeBSD `-RELEASE` 历史版本下载地址：

| 版本范围                           | 下载地址                                                                                      |
| ------------------------------ | ----------------------------------------------------------------------------------------- |
| 5.1-RELEASE 至 9.2-RELEASE      | <http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/amd64/ISO-IMAGES>        |
| 9.3-RELEASE 至最新的 `-RELEASE` 版本 | <http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/amd64/amd64/ISO-IMAGES/> |

FreeBSD 镜像 BT 种子下载地址（非官方，建议检查文件校验和后使用）：<https://fosstorrents.com/distributions/freebsd/>


# 5.2 FreeBSD 15 安装指南（AMD64）

FreeBSD 15.0-RELEASE 使用 bsdinstall 工具安装，流程涵盖磁盘分区、网络配置、系统组件选择与用户账户创建。本节以 AMD64 架构的 disc1.iso 镜像为例，记录从系统启动到首次登录的完整操作。

> **注意**
>
> 本节内容基于作者在特定硬件与虚拟化环境中的实际操作记录，部分结论（如内存阈值、超时时间、故障表现）来自个人测试经验，在不同硬件配置或后续版本中可能有所差异。涉及源代码行为的分析以 FreeBSD 15.0-RELEASE 发布版本的源代码为准。

以下安装说明基于 `FreeBSD-15.0-RELEASE-amd64-disc1.iso`。`-dvd1.iso` 和 `-memstick.img` 的安装流程与之类似。bsdinstall 安装流程如下：

![bsdinstall 安装流程总览](/files/DhdBfYJw4LUTw0dRh6jQ)

> **注意**
>
> 本节基于 VMware Workstation Pro 17 演示（使用 UEFI），在 VMware Workstation Pro 26H1 上测试通过。
>
> 如果在物理机上安装，可考虑使用 Rufus <https://rufus.ie/zh/> 工具配合 <https://download.freebsd.org/releases/amd64/amd64/ISO-IMAGES/15.0/FreeBSD-15.0-RELEASE-amd64-memstick.img> 镜像刻录。该文件为 FreeBSD 15.0-RELEASE amd64 架构的 U 盘安装镜像。Rufus 为第三方工具，其版本更新可能改变操作界面；镜像文件路径以 FreeBSD 官方发布页面为准。本建议基于 2026 年 3 月的工具版本与镜像发布状态。

## 启动安装盘

完成前期准备后，从安装盘启动系统，进入系统安装程序。

![启动界面](/files/dNE08HdjYDDGDUKlAiU0)

在此界面无需任何操作，等待十秒可自动进入 `1. Boot Installer [Enter]`；也可直接按 **回车键** 进入。

如果按下任意其他键将暂停启动流程，此时可按数字键继续，或按 **ESC** 键进入 **OK 提示符**。

![OK 提示符](/files/PFzXFkPSCmprUa1Ha81S)

在此界面输入 `menu` 并按 **回车键** 可返回主菜单。输入 `?` 可查看所有可用命令。

操作方式：按选项开头的数字键选定。引导菜单各选项的状态列中，`on` 表示已开启，`off` 表示已关闭。

| 选项                           | 解释                                                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `1. Boot Installer [Enter]`  | 用于安装系统                                                                                                             |
| `2. Boot Single user`        | 单用户模式，用于找回 root 密码或修复磁盘。如果启用安全加固中的 `secure_console` 选项，则进入单用户模式仍需 root 密码。此功能仅在拥有物理访问权限或远程控制台（如 IPMI/IP-KVM）的条件下可用 |
| `3. Escape to loader prompt` | 退出菜单，进入加载器命令行，输入 `reboot` 并按回车键可重启系统                                                                               |
| `4. Reboot`                  | 重启                                                                                                                 |
| `5. Cons: Video`             | 选择控制台输出模式：视频（`Video`）、串口（`Serial`）、串口优先的双模式（`Dual (Serial primary)`）或视频优先的双模式（`Dual (Video primary)`）              |
| `6. kernel (1 of 1)`         | 选择要启动的内核                                                                                                           |
| `7. Boot Options`            | 启动选项                                                                                                               |

![启动选项](/files/QL324E2LEjkHCjrCWJAX)

| `7. Boot Options`                  | 默认值    | 说明                                                                                                          |
| ---------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------- |
| `1. Back to main menu [Backspace]` | On（开）  | 按 **Backspace** 键可返回上级菜单                                                                                    |
| `2. Load System Defaults`          | off（关） | 恢复默认配置                                                                                                      |
| `3. ACPI`                          | off（关） | Advanced Configuration and Power Interface（高级配置与电源接口）。默认 off 表示此选项初始未选中。除非必要，不建议手动开启；如确需开启，通常用于 ACPI 相关故障诊断 |
| `4. Safe Mode`                     | off（关） | 安全模式                                                                                                        |
| `5. Single user`                   | off（关） | 单用户模式                                                                                                       |
| `6. Verbose`                       | off（关） | 详细模式，增加更多调试信息输出                                                                                             |

## bsdinstall 安装流程

启动安装盘后，将进入由 `bsdinstall` 工具提供的安装界面。

按回车键或等待十秒，将自动进入以下界面。

![FreeBSD 安装程序的欢迎界面](/files/na4gv8Q1A2jWofUZgE7U)

> **技巧**
>
> 此界面由 `bsdinstall` 工具提供。
>
> 本节指导用户如何使用该工具安装 FreeBSD。该工具不仅存在于安装镜像中，安装完成后在新系统中仍然存在，并且还可用于执行普通的安装流程（此要点在高级安装方式中具有重要参考价值）。
>
> `bsdinstall` 工具本质上由一系列 sh 脚本构成，其源代码位于 FreeBSD Project. freebsd-src/usr.sbin/bsdinstall\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/tree/main/usr.sbin/bsdinstall>。该仓库提供 FreeBSD 系统安装工具源代码，脚本位于“scripts”文件夹下。

安装程序显示欢迎菜单：

`欢迎使用 FreeBSD！您希望开始安装，还是使用 Live 系统？`

选中左侧的 `Install` 并按 **回车键** 开始安装；中间的 `Shell` 可进入命令行；右侧的 `Live System` 则为 LiveCD 模式。

如果没有特别说明，以下操作中可使用 **Tab 键** 或 **方向键** 切换选项，按 **回车键** 确认当前高亮选项。请注意界面中选项的红色加粗首字母（例如 `Install`、`Shell`、`Live System` 中的 **I**、**S**、**L**）。直接按下键盘上对应的字母键（不区分大小写）快速选定并进入相应界面。

选择 Live CD 选项可在安装前测试部分功能。在使用 Live CD 前应注意以下几点：

* 登录系统需要身份验证，用户名为 `root`，密码为空（直接按 **回车键** 即可）。
* 由于系统直接从安装介质运行，性能通常弱于安装在硬盘上的系统。在极端情况下（如内置硬盘为机械硬盘而外接设备为固态 U 盘），LiveCD 的 I/O 性能可能优于硬盘安装的系统，但受 USB 总线带宽限制与无缓存策略影响，此种情况在实际操作中较为罕见且不易预测。
* 此功能仅提供命令提示符，未提供图形界面。

> **警告**
>
> 在任何步骤按下 **Esc 键** 均 **无法** 返回上一级菜单，而是会直接跳至后续步骤，直至退出或完成安装流程。

## 设定键盘布局

进入安装程序后，首先需要设定键盘布局。

![键盘布局选择](/files/smIpuMJkbI0HCTFj3en3)

`FreeBSD 系统控制台驱动程序默认使用标准 US（美式）键盘布局。可以在下面选择别的键盘布局。`

此为键盘布局菜单，直接按 **回车键** 使用默认的美式（US）键盘布局（目前中国普遍使用美式键盘布局）。

## 设定主机名

设定键盘布局后，设置系统主机名。

![设置主机名](/files/Iq9OTgbFHvmJrYRBuH8A)

`请选择此机器的主机名。如果正运行在受管理的网络上，请向网络管理员询问合适的名称。`

此步骤用于设置系统主机名。

> **警告**
>
> **请勿** 在此步骤直接按 **回车键**！这将导致主机名为空，进而可能使显示管理器（如 SDDM）无法正常启动。

> **警告**
>
> FreeBSD 源代码默认假定将通过 DHCP 获取主机名，如果不设置主机名，系统不会自动分配任何值（包括“Amnesiac”），根据当前源代码逻辑，使用 DHCP 时不会有空主机名提示；仅当无网络连接时，登录信息中才会显示“Amnesiac”并伴随一条错误提示。

### 参考文献

* FreeBSD Project. Bug 286847: If the hostname is not set for the host, the value “Amnesiac” should be written to rc.conf.\[EB/OL]. \[2026-03-25]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=286847>. 该 Bug 报告提出空主机名时应写入默认值，该 Bug 报告由作者发现。
* FreeBSD Project. freebsd-src/libexec/getty/main.c\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/blob/80c12959679ab203459dc20eb9ece3a7328b7de5/libexec/getty/main.c#L178>. 该代码段包含登录提示符显示逻辑，`Amnesiac` 源代码。
* FreeBSD Project. bsdinstall: Warn if hostname is empty\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/pull/1700>. 该 PR 为空主机名添加警告。

## 选择安装类型

设定主机名后，选择系统的安装类型。FreeBSD 15 提供了两种安装方式，分别是传统的发行组件安装和新型的软件包安装。

> **注意**
>
> 在 FreeBSD 14 中，安装程序不提供软件包（PkgBase）安装方式，仅支持传统的发行组件（Distribution Sets）安装。此时安装界面标题为“选择安装组件”，直接进入组件选择步骤。

![选择安装类型](/files/v3lF12SGQuvzTrG7qIx4)

`您希望使用传统的发行组件（Distribution Sets）还是软件包（Packages，技术预览）来安装基本系统？`

### 软件包（PkgBase，技术预览）

PkgBase 是一种新型的安装方式，需注意以下要点。

> **警告**
>
> 网络与分区配置详见下文。请在通读相关章节后再选择。

![网络或离线安装](/files/JySUcAol67tcT14j323H)

`想从互联网获取软件包，还是使用此安装介质内包含的部分软件包？`

PkgBase 方案起源于 TrueOS 项目（原名 PC-BSD，由 iXsystems 赞助，约 2019—2020 年间独立维护了基于 FreeBSD 的 PkgBase 二进制仓库，为后续 FreeBSD 官方采纳该方案提供了重要参考）。TrueOS 核心项目此后停止开发，但 PkgBase 的相关工作已由 FreeBSD 项目维护者接手并持续演进。PkgBase 旨在以软件包形式管理基本系统（内核与用户空间），拆分为可由 `pkg` 工具管理的独立二进制包。

此设计思路与常见 Linux 发行版较为接近。需要注意，PkgBase 在系统稳定性与使用便利性之间有一定张力：

* 可能影响稳定性：基本系统受损风险增大（该问题在社区广泛使用后反馈增多，逐渐受到重视）；
* 提升了易用性：降低了在 FreeBSD 不同版本分支间切换的成本，开发者能更便捷地在 stable、current 等分支间更新，普通用户也无需经历 freebsd-update 工具较长的等待时间。

#### 在线安装（Network）

如果选择在线安装方式，系统将从互联网下载所需的软件包。在此步骤中，可以选择需要额外安装的组件。

![选择安装组件](/files/51FCjv1OqzIsK1uFhQ31)

`适用于多用户系统的最小软件包集将被默认安装。请选择您希望额外安装的软件包。`

| 组件               | 说明                           |
| ---------------- | ---------------------------- |
| `[X] base`       | 完整的基本系统（包含 devel 和 optional） |
| `[ ] debug`      | 所选组件的调试符号                    |
| `[ ] devel`      | C/C++ 编译程序及相关工具              |
| `[X] kernel-dbg` | 内核调试符号                       |
| `[X] lib32`      | 32 位兼容库                      |
| `[ ] optional`   | 可选软件（不含编译程序）                 |
| `[ ] src`        | 系统源代码树                       |
| `[ ] tests`      | 测试套件                         |

#### 离线安装（Offline，Limited Packages）

如果无法联网，可选择离线安装方式。离线安装使用安装介质内包含的有限软件包，无需联网即可完成安装。

![选择安装组件](/files/51FCjv1OqzIsK1uFhQ31)

`适用于多用户系统的最小软件包集始终会被安装。请选择要安装的其他软件包。`

| 组件               | 说明                           |
| ---------------- | ---------------------------- |
| `[X] base`       | 完整的基本系统（包含 devel 和 optional） |
| `[ ] debug`      | 所选组件的调试符号                    |
| `[ ] devel`      | C/C++ 编译程序及相关工具              |
| `[X] kernel-dbg` | 内核调试符号                       |
| `[X] lib32`      | 32 位兼容库                      |
| `[ ] optional`   | 可选软件（不含编译程序）                 |
| `[ ] src`        | 系统源代码树                       |
| `[ ] tests`      | 测试套件                         |

经测试，即使全部选中，也能实现完全离线安装。

### 发行组件（Distribution Sets）

除了软件包安装方式外，还可以选择传统的发行组件安装方式，该方式成熟稳定。

![选择安装组件](/files/QGoIHRKFNFPWkBhif45L)

`选择要安装的可选系统组件`

> **技巧**
>
> 如果没有特别说明，以下操作中按 **空格键** 可选中或取消选中条目（`[ ]` 变为 `[ * ]`）。
>
> 由于部分显卡驱动程序（如 `drm`）及其他程序需要源代码，且经测试 `lib32` 组件在系统安装后单独安装可能无法正常工作，建议在安装时即选中 `lib32` 和 `src`。建议在默认选项基础上，额外选中 `src` 和 `lib32`。

> **警告**
>
> **请勿** 选择 `kernel-dbg`、`lib32`、`src` 之外的组件，这些组件需要从网络下载安装，速度可能较慢。如有需要可在系统安装完成后另行安装。
>
> 如果在安装过程中出现选择镜像站的提示，通常是因为选择了需要联网下载的额外组件，请避免此操作。

| 选项           | 解释                         |
| ------------ | -------------------------- |
| `base-dbg`   | 基本系统的调试符号文件                |
| `kernel-dbg` | 内核调试符号文件                   |
| `lib32-dbg`  | 32 位兼容库的调试符号文件             |
| `lib32`      | 用于在 64 位系统上运行 32 位应用程序的兼容库 |
| `ports`      | FreeBSD Ports 集合           |
| `src`        | 系统源代码树                     |
| `tests`      | 操作系统测试套件                   |

## 分配磁盘空间

选定安装方式和组件后，为系统分配磁盘空间。

FreeBSD 15.0-RELEASE 支持选择 UFS 或 ZFS 作为根文件系统。在旧版本中，`bsdinstall` 工具仅支持 UFS；FreeBSD Project. Revision 256361: bsdinstall: add ZFS support\[EB/OL]. \[2026-03-25]. <https://svn.freebsd.org/viewvc/base?view=revision&revision=256361>。该修订记录 bsdinstall 增加 ZFS 支持，`bsdinstall` 开始支持 ZFS。通过手动安装方式，则早在 FreeBSD 8.0-CURRENT 开发阶段就已支持从 ZFS 启动（参见 delphij. ZFS 做 / 是个好主意吗？\[EB/OL]. \[2026-03-25]. <https://blog.delphij.net/posts/2008/11/zfs-1/>）。该博客讨论了早期 FreeBSD ZFS 根分区启动的技术可行性。

![磁盘分区菜单](/files/G80xYhMeRBHEy88BKcu6)

分区菜单。`您希望如何对磁盘进行分区？`

| 配置选项                                         | 中文说明                     |
| -------------------------------------------- | ------------------------ |
| `Auto (ZFS) – Guided Root-on-ZFS`            | 自动（ZFS）– 引导式 ZFS root 分区 |
| `Auto (UFS) – Guided UFS Disk Setup`         | 自动（UFS）– 引导式 UFS 磁盘设置    |
| `Manual – Manual Disk Setup (experts)`       | 手动 – 手动磁盘设置（适合专家）        |
| `Shell – Open a shell and partition by hand` | shell – 打开 shell 并手动分区   |

文件系统详情请参阅其他章节（可手动分区解压 `txz` 文件以自定义）。此处推荐选择默认的 `Auto (ZFS)` 选项。可用内存小于 8 GB 时，ZFS ARC 缓存可能与应用程序竞争内存资源，此时 UFS 可能在日常桌面或轻量服务器负载下提供更可预测的性能。8 GB 不是硬性限制，ZFS 在更小内存下仍可运行（参见下文低内存测试），但性能可能显著下降。

手动分区及通过 shell 分区的详细方法，请参见本书手动安装 FreeBSD 的相关章节。

### Auto (ZFS)（使用 ZFS 作为 **/** 文件系统）

> **技巧**
>
> 在极端实验条件下（仅执行 login 和 ls 等基本操作，无任何实际工作负载），128 MB（传统 BIOS）/256 MB（UEFI）内存下的 ZFS 系统可以完成启动，但完全不具备生产可行性。ZFS 生产环境建议至少 2 GB 内存（OpenZFS 官方建议 8 GB 以上以获得最佳性能，2 GB 以下亦可运行但不推荐）。

> **注意**
>
> 如果手动分区时反复提示分区表“损坏”（`corrupted`）等错误，请先退出安装程序，重启后进入 shell 模式，尝试刷新分区表：
>
> ```sh
> # gpart recover ada0
> ```
>
> 预期输出（示例）：
>
> ```sh
> # gpart recover ada0
> ada0 recovered
> ```
>
> 请根据实际硬盘设备确定 `ada0` 参数（如可能是 `da0`、`nda0` 等）。
>
> 如不确定当前硬盘设备名，可参考图示命令查看。
>
> <img src="/files/0sPNnqk5NZhRKfndtOGW" alt="查看硬盘设备" data-size="original">
>
> 刷新后，执行 `bsdinstall` 命令可重新进入安装程序界面。
>
> 此问题可能与分区表调整有关。

![探测设备](/files/QUTdCnmbkhAvSmaqvQzU)

`正在探测设备，请稍候（此过程可能需要一些时间）……`

![ZFS 配置](/files/AtA5ly4BscKFc1dp2QBy)

2016 年以后出厂的大多数 PC 及兼容机默认使用 UEFI 固件，应选择 `GPT (UEFI)`，请勿使用默认选项，否则将创建一个 512 KB 的 `freebsd-boot` 分区（纯 UEFI 启动并不需要此分区）。

较老的计算机（如 2013 年以前）才应考虑选择 `GPT (BIOS)` 选项，该选项仅支持 BIOS 启动；2013-2015 年间的过渡期设备可能同时支持 Legacy BIOS 与 UEFI（通过 CSM），如需同时兼容两者，应选择 `GPT (BIOS+UEFI)`。

| 配置选项                                   | 中文                 | 说明                                              |
| -------------------------------------- | ------------------ | ----------------------------------------------- |
| `>> Install Proceed with Installation` | >> 安装              | 继续安装                                            |
| `T Pool Type/Disks: stripe: 0 disks`   | 存储池类型/磁盘：条带化：0 块磁盘 | 详细说明见下                                          |
| `- Rescan Devices *`                   | - 重新扫描设备 \*        |                                                 |
| `- Disk Info *`                        | - 磁盘信息 \*          |                                                 |
| `N Pool Name zroot`                    | 存储池名称 `zroot`      | 默认池名 `zroot`                                    |
| `4 Force 4K Sectors? YES`              | 强制 4K 扇区？是         | 4K 对齐                                           |
| `E Encrypt Disks? NO`                  | 加密磁盘？否             | 加密后的登录系统方案请参考本书其他章节                             |
| `P Partition Scheme`                   | 分区方案 GPT (UEFI)    | 仅较早的计算机（2013 年以前）才需选择 `GPT (BIOS+UEFI)` 等选项     |
| `S Swap Size 2g`                       | 交换分区大小 2 GB        | 如果确实不需要交换分区，可在 `Swap Size` 处输入 `0` 或 `0G` 以跳过创建 |
| `M Mirror Swap? NO`                    | 交换分区镜像？否           | 是否在多块磁盘之间镜像交换分区，如果选否，则每块磁盘的交换分区是独立的             |
| `W Encrypt Swap? NO`                   | 加密交换分区？否           |                                                 |

> **技巧**
>
> 如果将此项设置为 `GPT (UEFI)` 而非其他，后续分区与系统更新过程将更为简单。

> **注意**
>
> 请慎重设置交换分区（`Swap Size`）的大小。如果系统用于桌面环境且需要休眠功能，交换空间至少应为物理内存的 1 倍；如果为纯服务器环境且内存大于 16 GB，交换空间在 4-8 GB 通常已足够；如果内存大于 64 GB 且不需要内核崩溃转储，交换空间可以更小甚至为零。物理内存较小的旧式系统如需运行大型应用，可视情况适当增大。因 ZFS 和 UFS 文件系统创建后不易缩小，而使用 `dd` 命令创建交换文件或后续调整可能带来性能开销或复杂度。

> **技巧**
>
> 如果无法确定后续应选择哪块磁盘，可在此步骤选择 `- Disk Info *` 查看各磁盘的详细信息：
>
> <img src="/files/zKZAQarff06nWt1bfkof" alt="磁盘信息" data-size="original">
>
> 在此界面中，选中磁盘并按 **回车键** 可查看详情；选中 `<Back>` 可返回上一菜单。
>
> <img src="/files/zH6Joh8y6DelIrJz4SkF" alt="磁盘详情" data-size="original">
>
> 此界面按 **上下方向键** 可浏览。按 **回车键** 可返回到上一菜单。

![选择虚拟设备类型](/files/JabqftfIyOVVeuHmbuny)

`选择虚拟设备类型：`

| 配置选项     | 中文             | 特点                            |
| -------- | -------------- | ----------------------------- |
| `Stripe` | 条带化，即 `RAID 0` | 无冗余，一块硬盘即可                    |
| `mirror` | 镜像，即 `RAID 1`  | n 路镜像，最少需要 2 块硬盘              |
| `raid10` | RAID 1+0       | n 组 2 路镜像，最少需要 4 块硬盘（要求偶数块硬盘） |
| `raidz1` | RAID-Z1        | 单冗余 RAID，最少需要 3 块硬盘           |
| `raidz2` | RAID-Z2        | 双冗余 RAID，最少需要 4 块硬盘           |
| `raidz3` | RAID-Z3        | 三重冗余 RAID，最少需要 5 块硬盘          |

各 vdev 类型的磁盘排列与冗余关系示意如下图所示（`D` 表示数据盘，`P` 表示校验盘，`M` 表示镜像盘）：

![磁盘排列与冗余关系](/files/Il8ayoNp5QdQUfyq9hFb)

直接按 **回车键** 使用默认的 `Stripe` 类型。

![选择目标硬盘](/files/JabqftfIyOVVeuHmbuny)

选中目标硬盘，按 **回车键** 确认选择。

> **技巧**
>
> 如果要将系统安装到 U 盘或移动硬盘但未能识别，请尝试重新插拔该设备，随后选择上方的 `- Rescan Devices *` 重新扫描设备列表。

> **注意**
>
> 如果硬盘为 eMMC 类型，可能会出现 `mmcsd0`、`mmcsd0boot0`、`mmcsd0boot1` 等选项，请选择 `mmcsd0`。此外，如果多硬盘与 eMMC 共存，且另一块硬盘的分区数量超过 5 个，安装在 eMMC 中的 FreeBSD 可能会在启动时停留在 `Mounting from zfs:zroot/ROOT/default failed with error 22: retrying for 3 more seconds` 提示处。如果手动指定参数，则可能导致内核 Panic。此问题目前尚无更详细的报告信息。如读者在类似配置下遇到此问题，建议在 FreeBSD Bugzilla 提交详细报告，包括：主板型号、eMMC 容量与版本、另一硬盘的分区表结构与分区数量、内核日志及相关 dmesg 输出。

![确认格式化](/files/ED9BD06r7yDxf1CHtMbS)

`最后确认！您确定要销毁以下磁盘上的所有现有数据吗：`

这是最终的警告与确认。请确保已备份重要数据，所选磁盘将被完全格式化。使用 **方向键** 或 **Tab 键** 将焦点切换至 `<YES>`，按 **回车键** 确认。

> **警告**
>
> 此操作将执行全盘安装，目标磁盘上的所有数据都将丢失！如需非全盘安装（如双系统），请参考本书其他相关章节。

#### 附录：geli 加密 ZFS 根分区的挂载与解密

如果在安装时通过 bsdinstall 的“Encrypt Disks”选项对 ZFS 根分区启用了加密（该选项使用 geli(8) 进行磁盘级加密），后续挂载该磁盘的方法如下。注意，此处的 geli 磁盘级加密与 ZFS 原生加密（数据集级 AES-256-GCM 加密）是不同的功能：ZFS 原生加密用于加密用户主目录数据集，相关解密操作见下文用户创建步骤中的说明。

以 NVMe 硬盘为例，启用 geli 磁盘加密（同时加密交换空间）后的磁盘结构如下：

| 分区类型         | 挂载点 | 设备                                  |
| ------------ | --- | ----------------------------------- |
| efi          |     | **/dev/nda0p1**                     |
| freebsd-zfs  | /   | **/dev/nda0p2**、**/dev/nda0p2.eli** |
| freebsd-swap |     | **/dev/nda0p3**、**/dev/nda0p3.eli** |

EFI 系统分区与正常安装一致，无特殊变化。系统启动时将提示输入密码以解密并挂载根分区。 如果需要在 LiveCD 环境中挂载该加密分区，操作较为便捷（不需要密钥文件，仅需输入密码）。假设根分区为 **/dev/nda0p2**，执行以下命令：

```sh
# geli attach /dev/nda0p2
```

预期输出：

```sh
# geli attach /dev/nda0p2
Enter passphrase:
```

输入正确的加密密码后，无任何错误消息即表示解密成功。通过命令 `# zpool import zroot` 导入 ZFS 池，再通过命令 `# zfs mount zroot/ROOT/default` 挂载根文件系统。

### Auto (UFS)（使用 UFS 作为 **/** 文件系统）

![UFS 分区菜单](/files/8KHyvzIGo83oiDSfe9G8)

`您希望如何对磁盘进行分区？`

> **技巧**
>
> 如果选择 `Partition`（分区），选项同下文。

![选择磁盘使用方式](/files/DyyR6eILgT2F7gQVHNWZ)

`您希望使用整块磁盘，还是对磁盘进行分区以与其他操作系统共存？使用整块磁盘将清除该磁盘上的所有现有数据。`

![选择分区方案](/files/eORpvLQrpe9oXHuxDpLE)

`为该卷选择分区方案`

| 英文                         | 中文            | 注释                          |
| -------------------------- | ------------- | --------------------------- |
| `APM Apple Partition Map`  | Apple 分区表     | Apple `PowerPC` 使用（2006 以前） |
| `BSD BSD Labels`           | BSD 磁盘标签      | 仅 BSD 可识别                   |
| `GPT GUID Partition Table` | GPT 全局唯一标识分区表 | 现代计算机使用（2013+）              |
| `MBR DOS Partitions`       | MBR 主引导记录分区表  | 老式计算机使用（XP、Win7 年代）         |

![审查分区设置](/files/kGgfcgBucSkcdfVHeHlE)

`请审查当前的磁盘分区设置。确认无误后，可选择 Finish（完成）`

| 英文       | 中文 |
| -------- | -- |
| `Create` | 创建 |
| `Delete` | 删除 |
| `Modify` | 调整 |
| `Revert` | 还原 |
| `Auto`   | 自动 |
| `Finish` | 完成 |

![确认提交更改](/files/KEqLQaKhxgAECbAUlRN4)

`您的更改尚未写入磁盘。若您选择了覆盖现有数据，这些数据将被永久删除。确定要提交更改吗？`

| 英文              | 中文    |
| --------------- | ----- |
| `Commit`        | 提交    |
| `Revert & Exit` | 还原并退出 |
| `Back`          | 返回    |

![初始化磁盘](/files/Ka2ZU35oDP6UC9StoDpR)

正在初始化磁盘，此界面通常在极短时间内完成。

***

如果之前选择了 PkgBase 安装方式：

![安装过程](/files/MXZrGiPIwTHoBtW2fohb)

正在校验相关分发文件：

![校验分发文件](/files/lRWLoXAUdInCZIJa2nf8)

正在解压并安装相关分发文件：

![解压安装](/files/FOHYGuhTFuRbAJLfFRJW)

## 设置 root 密码

磁盘分区完成后，为系统管理员账户设置密码。

![设置 root 密码](/files/npSihfqgwN7ti6RpZbio)

`请为系统管理员账户（root）设置密码：输入的字符将不可见。正在修改待安装系统的 root 密码。`

> **技巧**
>
> 在此界面，需使用 **上下方向键** 或 **Tab 键** 在不同密码输入框间移动焦点。输入完成后按 **回车键** 确认。

此处输入 root 密码。注意：上述界面提示“输入的字符将不可见”，但实际行为因版本或终端环境而异——部分情况下以 `*` 掩码回显，部分情况下完全无回显。无论哪种情况，输入完成后按 **回车键** 确认。

要求重复输入两次以确认一致性，如果两次输入的密码不同，将提示 `The passwords do not match`（密码不匹配）。

root 密码强度无强制要求，但不可为空。如果密码为空，将提示 `The password cannot be empty`，必须输入有效密码才能继续。

## 网络设置

设置好 root 密码后，需配置网络，使系统能够连接到互联网或局域网。

### 以太网卡

首先介绍以太网卡的配置方法。

![选择网络接口](/files/AvH7BscvK9IWeoYiLcP9)

`请选择要配置的网络接口及其配置模式`

* `Auto`：自动
* `Manual`：手动
* `Cancel`：取消

此处选择要配置的网卡。使用 **方向键** 可切换，按 **回车键** 可确认选择。

> **注意**
>
> 在 FreeBSD 14 中，网络接口选择界面仅提示“请选择一个网络接口进行配置”，不提供 Auto/Manual/Cancel 选项，直接选择网卡后进入 IPv4 配置步骤。

#### 自动（`Auto`）

![自动配置网络](/files/js9O48XBZHuhr8Le63Uj)

`正在发送路由器请求`，安装程序将自动检测并配置网络环境。

#### 手动（`Manual`）

![配置 IPv4](/files/Y8q0CQde76bvwbb8cTEX)

`希望为此接口配置 IPv4 吗？`

是否配置 IPv4。按 **回车键** 确认选择。

![使用 DHCP](/files/O29oIUgZO95ZUZl1xyQO)

`希望使用 DHCP 配置此接口吗？`

是否使用 DHCP 自动配置。按 **回车键** 确认选择。如果网络环境中无 DHCP 服务器或 DHCP 获取失败，安装程序将提示手动输入 IPv4 地址、子网掩码与默认网关，请事先确认这些信息。

![配置 IPv6](/files/fDQKZWD8GbSolte7oRO7)

`希望为此接口配置 IPv6 吗？`

是否配置 IPv6。本书不涉及 IPv6，因此选择 `No` 并按 **回车键**。如有需要可自行配置。

![配置 DNS](/files/NXpCgxrZ5V2nvV06n7Mx)

`配置解析器`

通常可保留 DHCP 分配的 DNS 设置，也可手动指定。图中示例使用了阿里云公共 DNS **223.5.5.5**。以下是常见的公共 DNS 选项：

| 服务商        | 首选地址         | 备用地址            | 特点                              |
| ---------- | ------------ | --------------- | ------------------------------- |
| 阿里云公共 DNS  | 223.5.5.5    | 223.6.6.6       | 国内节点多，解析国内域名速度快                 |
| 腾讯 DNSPod  | 119.29.29.29 | 182.254.116.116 | 国内节点多，支持 DoH/DoT                |
| Cloudflare | 1.1.1.1      | 1.0.0.1         | 全球最快，承诺不记录用户日志，支持 DoH/DoT       |
| Google     | 8.8.8.8      | 8.8.4.4         | 全球稳定可靠，支持 DoH/DoT，日志保留 24–48 小时 |
| Quad9      | 9.9.9.9      | 149.112.112.112 | 瑞士非营利运营，自动拦截恶意域名，不记录用户 IP       |

> **注意**
>
> 传统 DNS 查询以明文传输，可能被第三方监听或篡改（如 DNS 劫持、DNS 污染）。建议优先选择支持加密 DNS 协议（DoH 或 DoT）的服务商，以保护 DNS 查询的隐私与安全。国内用户访问国内网站时，阿里云或腾讯 DNS 通常延迟更低；需要访问国际网站时，Cloudflare 或 Google DNS 可能表现更优。

使用 **方向键** 切换选项，按 **回车键** 确认。

### 无线网卡/Wi-Fi 设置

> **警告**
>
> 由于已知的 Bug 289202（中国管制域缺失），当前不建议使用安装程序中的无线网络配置功能。如果需要网络连接，请优先通过以太网卡完成安装，建议在系统安装完成并重启后参考本书无线网络章节另行配置无线网络（尤其对于博通等网卡）。否则安装程序可能长时间无响应或引发内核错误（Panic）。

![选择无线网络接口](/files/OHTC6HUqfqJ4bOn42zzX)

`请选择要配置的无线网络接口`

![更改无线管制域](/files/W2X3PGh5XgeHTbyEJ3ip)

`更改无线管制域（当前为 FCC/US）？`

修改无线管制域，按回车键确认。

![选择区域码](/files/usaeUeGj5gI8wNriCGwk)

`请选择您的区域码`

此处应选择 `NONE` 或 `ROW`（Rest of World）。`ROW` 是一个通用的无线管制域选项，鉴于中国管制域尚未在 regdomain.xml 中定义（Bug 289202），选择此项可允许无线网卡在最保守的信道集上运行，避免选择特定国别引发的错误。

![选择所在地区](/files/uAXy2G0OYG6KnBHo8zkW)

`请选择您所在的地区`

选择对应的地区：

![扫描无线网络](/files/njl2Z5GaERKcYcWSzGQt)

`请等待 5 秒，正在扫描可用的无线网络……`

扫描。

> **技巧**
>
> 只要系统能识别网卡，即表明其驱动程序可用。但安装程序可能无法正确扫描到所有 Wi-Fi 网络。建议此处留空跳过，待系统安装完成后重启，再参考本书无线网络章节配置。

在列表中找到您的 Wi-Fi 网络。如果未找到，可尝试更改无线路由器的信道后重试。

![选择 Wi-Fi 网络](/files/opgRkATQyz0VwFHn5A8r)

`请选择要连接的无线网络`

输入 Wi-Fi 密码以连接：

![输入 Wi-Fi 密码](/files/kxFjERYaTGLpC3Qi7NTl)

![配置 IPv4](/files/Y8q0CQde76bvwbb8cTEX)

`想要为此接口配置 IPv4 吗？`

配置 IPv4，按 **回车键** 可选定。

![使用 DHCP](/files/O29oIUgZO95ZUZl1xyQO)

`希望使用 DHCP 配置此接口吗？`

配置使用 DHCP，按 **回车键** 可选定。

![配置 IPv6](/files/fDQKZWD8GbSolte7oRO7)

`希望为此接口配置 IPv6 吗？`

配置 IPv6，因本书未使用 IPv6，故选 `No`，按 **回车键** 可选定。如有需要可自行配置 IPv6。

![配置 DNS](/files/NXpCgxrZ5V2nvV06n7Mx)

`配置解析器`

通常可保留 DHCP 分配的 DNS 设置，也可手动指定。图中示例使用了阿里云公共 DNS **223.5.5.5**。其他常见的公共 DNS 选项见上文表格。使用 **方向键** 切换选项，按 **回车键** 确认。

### 参考文献

* FreeBSD Project. Regulatory Domain Support\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/WiFi/RegulatoryDomainSupport>. 该页面介绍 FreeBSD 无线管制域支持状态。
* FreeBSD Project. freebsd-src/lib/lib80211/regdomain.xml\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/blob/main/lib/lib80211/regdomain.xml>. 该文件定义 802.11 无线管制域配置，regdomain.xml 在源代码的位置。
* FreeBSD Project. regdomain.xml -- 802.11 wireless regulatory definitions\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=regdomain&sektion=5>. 该手册页说明无线管制域配置文件格式，对应编码请参考系统中的 **/etc/regdomain.xml** 文件。
* Alibaba Cloud. 阿里云公共 DNS\[EB/OL]. \[2026-03-25]. <https://www.alidns.com/>. 该服务提供公共 DNS 解析。
* Tencent Cloud. DNSPod 公共 DNS\[EB/OL]. \[2026-06-10]. <https://www.dnspod.cn/Products/Public.DNS>. 腾讯提供的免费公共 DNS 递归解析服务。
* Cloudflare. Cloudflare DNS\[EB/OL]. \[2026-06-10]. <https://1.1.1.1/>. Cloudflare 提供的注重隐私与速度的公共 DNS 服务。
* Google. Google Public DNS\[EB/OL]. \[2026-06-10]. <https://dns.google/>. 谷歌提供的全球公共 DNS 解析服务。
* Quad9 Foundation. Quad9 DNS\[EB/OL]. \[2026-06-10]. <https://quad9.net/>. 瑞士非营利组织运营的注重安全的公共 DNS 服务。

## 时区设置

网络配置完成后，需设置系统的时区，以确保系统时间显示正确。

![选择地区](/files/df4ESgO1BCEvXH7ryYDp)

`请选择您所在的地区`

设置系统时区。中国属于 `5 Asia`（亚洲）。使用 **方向键** 选择，按 **回车键** 确认。

![选择国家或地区](/files/PW5A7FcoIJtAqwNWDQWc)

`设置国家或地区`

选择 `9 China`（中国）。使用 **方向键** 选择，按 **回车键** 确认。

![选择时区](/files/PHKr1SyBxT21h9DDMXxI)

中国统一使用东八区时间（北京时间），请选择 `1 Beijing Time`。使用 **方向键** 选择，按 **回车键** 确认。

![确认时区](/files/meRGHrtxMUNezDVqh1Tx)

`时区缩写 'CST' 是否合适？`

CST 为中国标准时间（China Standard Time）的缩写，确认无误后按 **回车键** 选择 `Yes`。

![设置时间日期](/files/Heq5Pd8GYTOj2nbNucMd)

`设置时间与日期`

直接按 **回车键** 使用默认设置。

![确认时间日期](/files/4h1xjUwuki75rAg1Ribe)

`时间与日期`

按 **回车键** 确认。

## 启动服务设置

时区设置完成后，选择系统启动时自动运行的服务。

![选择启动服务](/files/Hb5EJbXy2SJcM9sK9er3)

`请选择您希望系统启动时自动运行的服务`

> **警告**
>
> **请勿全选！**
>
> **切勿** 选择 `local_unbound`，否则可能影响系统 DNS 解析（参见 FreeBSD Project. Bug 262290: After a normal FreeBSD installation and reboot, **/etc/resolv.conf** will be changed\[EB/OL]. \[2026-03-25]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=262290>。该 Bug 报告记录 local\_unbound 服务导致 resolv.conf 变更问题）。除非明确了解其用途。

| 选项                   | 解释                                                                   |
| -------------------- | -------------------------------------------------------------------- |
| `sshd`               | 启用 SSH 远程访问服务                                                        |
| `ntpd`               | 启用 NTP 网络时间协议守护进程，用于自动时钟同步                                           |
| `ntpd_sync_on_start` | 系统启动时立即同步时间                                                          |
| `local_unbound`      | 启用本地 Unbound DNS 缓存转发解析器。注意：启用后需手动配置 DNS，否则可能无法正常联网。不建议未充分了解其功能的用户启用 |
| `powerd`             | 启用电源管理守护进程，动态调整 CPU 频率以节约能耗                                          |
| `moused`             | 在文本控制台（tty）中启用鼠标支持                                                   |
| `dumpdev`            | 启用内核崩溃转储功能，便于系统调试                                                    |

> **注意**
>
> 在 FreeBSD 14 中，服务列表的显示顺序不同：`local_unbound` 位于列表首位，其后依次为 `sshd`、`moused`、`ntpd`、`ntpd_sync_on_start`、`powerd`、`dumpdev`。

## 安全加固

启动服务设置完成后，需配置系统安全加固选项，以增强系统的安全性。

![安全加固选项](/files/hgu0J4eSYrEtF46oDuVS)

`请选择系统安全加固方案`

此处为系统安全加固选项，可根据实际需求选择启用。

> **技巧**
>
> 在 FreeBSD 14 以前版本的安装中，此步骤会出现 `disable_sendmail` 选项，建议选定。如果不禁用该服务，每次开机时可能会延迟数分钟，且该服务主要用于邮件发送，一般用户无需使用。

| 选项                  | 解释                                  |
| ------------------- | ----------------------------------- |
| `0 hide_uids`       | 隐藏其他用户拥有的进程                         |
| `1 hide_gids`       | 隐藏其他组拥有的进程                          |
| `2 hide_jail`       | 隐藏 Jail 内的进程                        |
| `3 read_msgbuf`     | 禁止非特权用户读取内核消息缓冲区（通常通过 `dmesg` 命令访问） |
| `4 proc_debug`      | 禁用非特权用户的进程调试功能                      |
| `5 random_pid`      | 启用进程 PID 随机化                        |
| `6 clear_tmp`       | 系统启动时自动清理 **/tmp** 目录               |
| `7 disable_syslogd` | 禁用 syslogd 的网络套接字（即禁用远程日志接收）        |
| `8 secure_console`  | 启用控制台安全保护（单用户模式也需 root 密码）          |
| `9 disable_ddtrace` | 禁用 DTrace 的破坏性（destructive）操作模式     |

## 安装固件

安全加固设置完成后，安装硬件固件。

![虚拟机无固件可安装](/files/WJLiGpz77DqBHmJL8a38)

自动检测并安装所需的硬件固件。

（此图为虚拟机安装界面截图）

![物理机也许有些固件需要安装](/files/tjTBuQbPRvcw3EOCsGJA)

**（此图为使用采集卡获得的物理机安装界面截图）**

> **警告**
>
> 建议在此步骤取消所有勾选，即不安装任何固件。在线安装可能因网络问题失败或耗时过长，且此步骤不影响系统的基本启动与核心功能。取消固件安装后，无线网卡、GPU 等硬件在系统首次启动时将无法正常工作，需在安装完成并联网后通过 `fwget` 命令补充安装固件；
>
> 在 FreeBSD 14 的物理机安装中，此步骤可能会显示需要安装的固件列表（如显卡固件等），请同样取消勾选，待安装完成后使用 `fwget` 命令获取。

### 附录：视频教程

以下视频为 FreeBSD 14.2 的安装演示，FreeBSD 15.0 的安装流程与之高度相似，可供参考。视频链接的有效性以访问日期为准：

* Bilibili. FreeBSD 14.2 基础安装配置教程\[EB/OL]. \[2026-03-25]. <https://www.bilibili.com/video/BV1STExzEEhh>（物理机）
* Bilibili. 002-VMware17 安装 FreeBSD 14.2\[EB/OL]. \[2026-03-25]. <https://www.bilibili.com/video/BV1gji2YLEoC>（虚拟机）

## 创建普通用户

固件安装完成后，创建普通用户账户。

![添加用户](/files/dTpBXT5TU2coVPqAxvpd)

`现在希望向已安装的系统添加用户吗？`

如需创建，请按 **回车键** 选择 `Yes`；如果不需要创建普通用户（仅使用 root），请使用 **方向键** 选择 `No`。

> **注意**
>
> 绝大多数图形显示管理器默认禁止 root 用户直接登录。因此，如不额外配置（参见其他章节），默认可能无法使用 root 账户登录桌面环境。

![填写用户信息](/files/qq6z1Vqe9s0DrwRv4ek1)

> **警告**
>
> 如果创建普通用户，请务必同时加入 `wheel` 组（用于 `su` 权限提升）和 `video` 组（用于图形加速）。仅加入 `wheel` 组可能无法正常调用 GPU。

```sh
FreeBSD Installer # FreeBSD 安装程序
========================
Add Users # 添加用户

Username: ykla # 输入用户名。只能使用小写字母（不支持非拉丁字符）或数字，不能以连字符开头。最大长度 16 个字符（历史原因）。
Full name: # 输入用户全名 ①。可留空。不能包含英文冒号 :。
Uid (Leave empty for default):  # 用户 UID，留空则使用默认值。手动设置需小于 32000（历史原因：兼容早期 NFS 等仍使用 16 位 UID 的协议，UID 超出此范围可能导致身份映射异常。现代 NFSv4 已不再使用数值 UID，但为保持向后兼容性，建议遵循此限制）。
Login group [ykla]: # 用户主组
Login group is ykla. Invite ykla into other groups? []: wheel video operator # 邀请用户加入其他组，用空格分隔。在 16.0 中还需要加入 audio 组以获得音频支持
Login class [default]: # 用户分级
Shell (sh csh tcsh nologin) [sh]: # 用户默认 shell，默认是 sh
Home directory [/home/ykla]: # 用户主目录路径，普通用户默认在 /home 下面
Home directory permissions (Leave empty for default): # 用户主目录权限，留空使用默认值
Enable ZFS encryption? (yes/no) [no]: # 是否启用 ZFS 加密（14.1 新增）
Use password-based authentication? [yes]:  # 是否启用密码验证
Use an empty password? (yes/no) [no]:  # 是否使用空密码，即密码为空
Use a random password? (yes/no) [no]:  # 是否使用随机密码。设置 yes 将生成随机字符串并回显到标准输出。②
Enter password:  # 输入密码，密码输入时无任何回显（不会显示 **** 等掩码）
Enter password again:  # 再次输入密码以确认，同样无回显
Lock out the account after creation? [no]: #  创建后是否立即锁定账户（禁用该账户）
Username    : ykla # 设定的用户名
Password    : ***** # 设定的用户密码
Full Name   : # 设定的用户全名
Uid         : 1001 # 设定的用户 UID
ZFS dataset : zroot/home/ykla # 主目录对应的 ZFS 数据集（自 14.1 引入）
Class       :  # 设定的用户分级
Groups      : ykla wheel video # 所属的用户组
Home        : /home/ykla # 设定的用户主（家）目录路径
Home Mode   :  # 设定的用户主（家）目录权限
Shell       : /bin/sh # 设定的用户默认的 shell
Locked      : no # 是否锁定（禁用）用户
OK? (yes/no) [yes]: #  确认上述设置是否正确
adduser: INFO: Successfully added (ykla) to the user database. # 用户 ykla 已成功添加至数据库
Add another user? (yes/no) [no]: # 是否继续添加其他用户
```

* ① 如果用户全名为空（即不设置），作为早期 UNIX 系统 GECOS 字段的遗留行为，系统会分配一个默认值 `User &`。相关代码位于 FreeBSD Project. freebsd-src/usr.sbin/pw/pw\_user.c\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/pw/pw_user.c> 的 `static struct passwd fakeuser` 结构中。
* ② 如果选择使用随机密码，在最终确认信息前会显示一行：`adduser: INFO: Password for (ykla) is: D1MnujkWMv/m`，其中 `D1MnujkWMv/m` 即为生成的随机密码。

其余参数通常可保持默认。自 FreeBSD 14 起，root 用户的默认 shell 已改为 **/bin/sh**（此前为 **/bin/csh**）。

最后会询问 `Add another user? (yes/no) [no]`，按 **回车键** 可结束用户添加流程；输入 `yes` 并按 **回车键**，则可继续添加第二个用户。

### 参考文献

* FreeBSD Project. man adduser(8)\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=adduser&sektion=8>. 该手册页说明 FreeBSD 用户添加命令使用方法。

## 完成安装

普通用户创建完成后，完成安装流程。

![完成安装](/files/jdLSbQw5iRkG5SRgvK2D)

`您的 FreeBSD 系统设置即将完成。现在可以返回修改先前的配置选项。在此菜单之后，您还可以进入 Shell 进行更复杂的调整。`

按 **回车键** 选择 `Finish` 以完成安装。

| 配置选项               | 功能描述                |
| ------------------ | ------------------- |
| `Finish`           | 应用所有配置并退出安装程序       |
| `Add User`         | 添加系统用户              |
| `Root Password`    | 重新设置 root 密码        |
| `Hostname`         | 修改系统主机名             |
| `Network`          | 重新配置网络              |
| `Services`         | 调整系统启动时运行的服务        |
| `System Hardening` | 修改安全加固方案            |
| `Time Zone`        | 重新设置时区              |
| `Firmware`         | 安装固件（需要网络）          |
| `Handbook`         | 安装 FreeBSD 手册（需要网络） |

![是否进入 Shell](/files/fuwz9PiDRKtfXKxAw22R)

`安装现已完成。在退出安装程序前，您是否希望在新系统中打开 Shell 以作最终的手动调整？`

按 **回车键** 选择 `No` 以直接完成安装（或选择 `Yes` 进入 shell）。

![确认重启](/files/hx0Zf3HVWAgCmzIBZKZY)

`FreeBSD 安装完成！您现在是否希望重启并进入新安装的系统？`

按 **回车键** 确认重启。

## 欢迎进入 FreeBSD 世界

安装完成后重启，进入 FreeBSD 新系统：

![系统启动](/files/AdwhYzt4XMxKENJkOUyS)

系统完全启动后：

> **技巧**
>
> FreeBSD 基本系统默认不包含图形界面（未安装 Xorg），因此启动后将进入文本控制台界面（TTY）。

![登录界面](/files/5EGmqxHcSvR33gOWM9zb)

输入用户名 `root` 及安装时设置的 root 密码以登录系统。

> **技巧**
>
> 输入密码时，密码在屏幕上不显示，无 `****` 等掩码提示，输入完毕后直接按回车键登录。

![登录成功](/files/CaiB2ZJ2bS5sLZOAw6da)


# 5.3 安装故障排除

安装过程中最常见的阻断性问题包括无法进入安装界面、分区表错误与引导丢失。本节逐一给出排查步骤与恢复方法。

## 无法进入安装界面

如果无法进入安装界面，首先区分虚拟机环境与物理机环境，而后分别排查。

如果是虚拟机，请检查虚拟机配置。

如果是物理机，请依次检查如下项目：

* 电脑是否为标准个人计算机？
* 处理器品牌是否为 Intel 或 AMD？
* 是否已关闭 BIOS 中的安全启动（Secure Boot）？
* 镜像是否从 <https://www.freebsd.org> 下载？
* 是否下载了最新版本的 RELEASE 镜像？
* 下载的镜像文件扩展名是否为 `img`（USB 设备）或 `iso`（光盘镜像）？
* 镜像校验（SHA-256）是否通过？
* 下载的镜像是否带有 `amd64`（标准个人计算机）字样？
  * 请确认是 `amd64`（适用于标准 x86 个人计算机）**而非** `arm64`（适用于 ARM 架构设备，如树莓派等嵌入式平台）。
* U 盘是否为扩容盘（伪造容量产品）？
* 是否使用了 Ventoy 工具？
  * 如果使用 Ventoy - 多系统启动 USB 启动盘制作工具 <https://www.ventoy.net/cn/index.html> 无法启动，可尝试改用 Rufus - Create bootable USB drives the easy way <https://rufus.ie/zh/> 刻录。

如果仍出现问题，请先在 FreeBSD 官方论坛 <https://forums.freebsd.org/> 以英语提问；如未获解答，可按其他章节指引提交 Bug。

## 重启后又进入了安装界面

安装完成后重启系统时，可能再次进入安装界面，此时需要检查引导设备。

如果是虚拟机，请手动弹出或断开虚拟 DVD 光驱的自动连接，而后重启。如果是物理机，请拔出 U 盘或弹出安装光盘后重启。

## 启动时输出若干 ACPI 字样的错误信息

> **警告**
>
> 某些文章建议关闭 ACPI。该做法在现代硬件上已缺乏技术依据，关闭 ACPI 可能导致系统无法正常启动或功能受限。ACPI 与电源状态管理、设备节能、多处理器支持等功能密切相关，关闭 ACPI 的选项应视为遗留功能。

如果出现 ACPI 错误提示，大多数情况下不影响正常运行。通常可通过更新主板 BIOS 或固件解决。少数情况下可能需要修补 SSDT（Secondary System Description Table，次级系统描述表）和 DSDT（Differentiated System Description Table，差异化系统描述表）。

部分制造商建议仅在必要时升级主板 BIOS/固件。升级过程 **可能** 出现问题（如意外断电），造成 BIOS 固件不完整，导致计算机无法正常工作。

## 启动时停滞于某项服务

旧版本安装时，系统启动可能长时间停留在 sendmail 等服务；需要配置静态 IP 地址时，系统却可能持续尝试 DHCP。

此时可尝试按下 **Ctrl** + **C** 组合键中断该服务，从而继续启动系统。

### 参考文献

* FreeBSD Project. FreeBSD 14.0-RELEASE Release Notes\[EB/OL]. \[2026-04-17]. <https://www.freebsd.org/releases/14.0R/relnotes/>. FreeBSD 14.0 起将默认邮件传输代理（MTA）从 sendmail 替换为 dma（Dragonfly Mail Agent），sendmail 不再默认启动，解决了旧版本启动卡顿问题。


# 5.4 在 Windows 中将 USB 启动盘恢复为普通存储设备

USB 存储介质用作系统安装介质后，其分区表结构可能发生变化，导致操作系统无法完全识别其可用存储空间。

以下提供三种 Windows 环境下恢复 USB 存储介质的方法。

> **警告**
>
> 本节所述操作具有高风险性，可能会损坏部分或全部数据。除非已明确可接受的最坏结果、做好完整可验证的备份、并有可用的回滚方案，否则请勿执行。
>
> 如果无法自行解决，可寻求专业技术服务。

使用 Rufus、Win32DiskImager 等软件制作 U 盘启动盘用于安装系统后，用户可能会发现 U 盘的可见容量仅有约 30–100 MB（即 EFI 系统分区，具体大小因镜像而异）。

![使用 Rufus 制作的 U 盘启动盘](/files/3F08sY1kaQ7N72MEjggU)

该 U 盘容量为 64 GB。

## 使用 DiskGenius 恢复 U 盘启动盘

首先介绍使用 DiskGenius 恢复 U 盘的方法。DiskGenius 是一款磁盘管理工具，其官网为 <https://www.diskgenius.cn/>。该软件的免费版本可满足本节所述操作的需要。

### 下载 DiskGenius

首先需要下载 DiskGenius 软件。下载时，大多数用户应选择 DiskGenius. DiskGenius 下载页面\[EB/OL]. \[2026-03-25]. <https://www.diskgenius.cn/download.php>，该页面提供 DiskGenius 软件各版本下载链接。

下载后，将得到一个 ZIP 压缩包。

![下载的 DiskGenius](/files/mjb807nLCF6CiPehjR2E)

在桌面新建文件夹 `1`（路径为 **C:\Users\用户名\Desktop\1**），将压缩包内所有文件解压至该文件夹。

相关文件结构：

```powershell
C:\Users\用户名\
└── Desktop\
    └── 1\
        └── DiskGenius\
            └── DiskGenius.exe # DiskGenius 可执行文件
```

![下载的 DiskGenius](/files/JeccHFURw6vpVvYaqomM)

解压后的文件应如下图所示：

![验证 DiskGenius 解压结果](/files/gsihhrl1JLDnRQjhyHpu)

### 启动 DiskGenius

下载并解压完成后，启动 DiskGenius。只需找到并运行解压后的可执行文件。

启动 DiskGenius 时，双击 `DiskGenius.exe`（路径如 **C:\Users\用户名\Desktop\1\DiskGenius\DiskGenius.exe**，具体路径因解压位置而异）。

![DiskGenius](/files/ajORC4Wg9Icm67fe5y7R)

同意许可证：

![DiskGenius](/files/56ub1xAXXlFKcdLK8y52)

### 判断哪个是 U 盘

启动 DiskGenius 后，需要先判断哪个设备是目标 U 盘。

判断哪个是目标 U 盘，通常可根据 U 盘容量判断。如果不确定 U 盘容量，可查询购买记录或取下 U 盘查看其外壳上标注的容量。

* 通过容量判断：64 GB 的 U 盘在 Windows/Linux 中通常显示为约 57–59.6 GB（因操作系统使用二进制单位 GiB 但标注为 GB，64×10⁹÷1024³≈59.6，实际显示还受文件系统开销影响），在 macOS 中显示为 64 GB（macOS 使用十进制单位）；
* 通过盘符判断：在下图中，可通过“EFISYS(E:)”来判断（E 盘），此为使用 Rufus 制作的 U 盘启动盘；
* 通过 DiskGenius 显示的接口判断：顶部显示的“硬盘 1 接口:USB”标识表明这是 USB 设备，即目标 U 盘。

![DiskGenius](/files/xf7Vmo4FkwT3aRqfqCV9)

### 恢复 U 盘

确定目标 U 盘后，开始恢复操作。首先删除 U 盘上的所有现有分区。

确认目标 U 盘后，右键单击该 U 盘，选择“删除所有分区”：

![DiskGenius](/files/XW3zQwjhMZi8FgRxsbXD)

确认后选择“是”。

![DiskGenius](/files/u08EDyt1k77GG13MBZJp)

删除后的 U 盘状态：

![DiskGenius](/files/cqyNL3EMFX3zqE4zAAw7)

右键单击空白区域，选择“建立新分区”。

![DiskGenius](/files/AQ96sWf5n43S8e96s0dN)

参数设置如下：文件系统选择 `exFAT`（通用性好，主流操作系统均支持读写，且不受单文件 4 GB 大小限制），勾选“对齐到下列扇区数的整数倍”，并选择“4096 扇区”（实现 4K 对齐）。

![DiskGenius](/files/HaeVgQoebp6TY7PhCqNB)

点击左上角的“保存更改”按钮。

![DiskGenius](/files/BJvdqmyIrAsCpcuSW7lS)

确认后选择“是”。

![DiskGenius](/files/LhJWtiywBgktThHgr6oV)

确认后选择“是”。

![DiskGenius](/files/H3YeuaYAKSVu1Ullts87)

最后结果：

![DiskGenius](/files/Ssd6kOosi708H9vnDjmt)

打开资源管理器：

![DiskGenius](/files/ma1UtTPFEVrbwmRTc0xu)

恢复完成。

## 使用傲梅分区助手恢复 U 盘启动盘

除了 DiskGenius 外，还可以使用傲梅分区助手来恢复 U 盘。使用方法与前述 DiskGenius 方法基本相同。

### 下载并安装傲梅分区助手

首先需要下载傲梅分区助手软件。

傲梅分区助手官网：<https://www.disktool.cn/>，该网站为傲梅分区助手官方网站。

点击 AOMEI Technology. 傲梅分区助手下载页面\[EB/OL]. \[2026-03-25]. <https://www.disktool.cn/download.html>，该页面提供傲梅分区助手各版本下载链接，推荐下载“绿色版”（免安装，可直接运行）。在解压目录中找到“PartAssist.exe”（可执行文件名称可能略有不同），右键单击并选择“打开”。

![傲梅分区助手](/files/x5fr9KDncPhYAkDiKHq9)

> **技巧**
>
> 专业版会提示需要授权码，输入“1122”即可。参见 AOMEI Technology. 傲梅分区助手常见问题解答\[EB/OL]. \[2026-03-25]. <https://www.disktool.cn/faq/partition-assistant.html>，该页面提供傲梅分区助手使用常见问题解答，“分区助手使用码：1122”。
>
> <img src="/files/cg8k4Fxyg77K3PfFoZzE" alt="傲梅分区助手专业版使用码" data-size="original">

### 判断 U 盘设备

启动傲梅分区助手后，首先判断哪个设备是目标 U 盘。

可通过以下信息判断设备是否为 U 盘（如果界面显示不全，可使用鼠标滚轮向下滚动）：

![傲梅分区助手](/files/jyTMzxUP9Z16PdiF5MCM)

打开“属性与健康”：

![傲梅分区助手](/files/a38PKDSax1U8IfxW5OuB)

观察接口：

![傲梅分区助手](/files/Dr2iA1mssd16y8mt6LyF)

### 还原 U 盘启动盘

确定目标 U 盘后，开始还原操作：首先删除所有分区，随后创建新的分区。

#### 删除所有分区

首先需要删除 U 盘上的所有分区。

选中 U 盘设备，右键单击“删除所有分区”。

![傲梅分区助手](/files/ha1AqMSjxU5CSg0FBBw8)

在确认对话框中点击“确定”，以执行“删除所有分区”操作。

![傲梅分区助手](/files/JQLHVya4eCeDoHLQApl0)

操作后界面如下图所示。点击左上角的“提交”按钮以确认并应用上述修改。

![傲梅分区助手](/files/UT8HhGcuep9ypQd6ih1x)

点击“执行”。

![傲梅分区助手](/files/P4Y1CSrCets3fb9JjLEm)

确认。

![傲梅分区助手](/files/B6lmUD7mCfKnPhOloXEf)

分区删除完毕。

![傲梅分区助手](/files/jGxYHCP0I1cchfFmyFzb)

#### 创建新分区

删除所有分区后，需要为 U 盘创建新的分区。

点击底部的 U 盘，右键单击，选择“创建分区”。

![傲梅分区助手](/files/Rn7Tm8081CUBF0QQoNBl)

将文件系统设置为“exFAT”，随后点击“确定”按钮。

![傲梅分区助手](/files/ybr4isbgXfq8pK03pSlF)

随后点击左上角的“提交”。

![傲梅分区助手](/files/AZttUexnRC08dZ7fKlPz)

在随后弹出的确认窗口中：

![傲梅分区助手](/files/2SH5PJQZn67m3TsM7JhJ)

执行：

![傲梅分区助手](/files/p1DzTICZXcLQrdZuQMrY)

此时，软件已为 U 盘自动分配了盘符 E。

![傲梅分区助手](/files/wH5sVpYFWhpaOs7DwevT)

## 通过命令 diskpart 恢复

除了图形界面工具外，还可以使用 Windows 自带的命令行工具 diskpart 来恢复 U 盘。使用命令行工具恢复 U 盘，首先需要以管理员身份打开 PowerShell，随后根据 U 盘分区表类型选择相应的操作步骤。

MBR（Master Boot Record，主引导记录）和 GPT（GUID Partition Table，全局唯一标识符分区表）是两种常见的磁盘分区表格式，对比如下：

| 特性     | MBR                       | GPT                              |
| ------ | ------------------------- | -------------------------------- |
| 全称     | Master Boot Record（主引导记录） | GUID Partition Table（全局唯一标识符分区表） |
| 适用场景   | 老式计算机                     | 现代计算机                            |
| 最大磁盘容量 | 2 TB                      | 9.4 ZB                           |
| 最大分区数  | 4 个主分区                    | 128 个（Windows）                   |
| 引导方式   | BIOS/Legacy               | UEFI                             |

两种分区表在磁盘上的存储结构对比如下：

![分区表结构比较](/files/tZqbdkYAIAjqballLqjW)

打开 PowerShell：右键单击 Windows 图标，选择“Windows PowerShell（管理员）”。

### MBR 分区表

首先介绍 MBR 分区表的 U 盘恢复方法。

```powershell
PS C:\WINDOWS\system32> diskpart # 进入 diskpart

Microsoft DiskPart 版本 10.0.26100.1150

Copyright (C) Microsoft Corporation.
在计算机上: DESKTOP-M5P610N

DISKPART> list disk # 列出所有磁盘。磁盘 1 无 GPT 标识，表明其采用 MBR 分区表

  磁盘 ###  状态           大小     可用     Dyn  GPT
  --------  -------------  -------  -------  ---  ---
  磁盘 0    联机              931 GB    41 MB        *
  磁盘 1    联机               57 GB  5120 KB

DISKPART> sel disk 1 # 选中磁盘 1

磁盘 1 现在是所选磁盘。

DISKPART> clean # 清除磁盘 1 所有分区

DiskPart 成功地清除了磁盘。

DISKPART> cre part pri # 在磁盘 1 创建主分区

DiskPart 成功地创建了指定分区。

DISKPART> list part # 列出磁盘 1 的所有主分区

  分区 ###       类型              大小     偏移量
  -------------  ----------------  -------  -------
* 分区      1    主要                  57 GB  1024 KB

DISKPART> sel part 1 # 选中主分区 1

分区 1 现在是所选分区。

DISKPART> format fs=exfat quick # 快速将所选分区格式化为 exFAT 文件系统

  100 百分比已完成

DiskPart 成功格式化该卷。

DISKPART> active # 设置主分区 1 为活动分区

DiskPart 将当前分区标为活动。

DISKPART> ass letter=E # 挂载到 E 盘，也可以将 U 盘移除后再插入

DiskPart 成功地分配了驱动器号或装载点。
```

### GPT 分区表

```powershell
PS C:\WINDOWS\system32> diskpart

Microsoft DiskPart 版本 10.0.26100.1150

Copyright (C) Microsoft Corporation.
在计算机上: DESKTOP-M5P610N

DISKPART> list disk # 列出磁盘

  磁盘 ###  状态           大小     可用     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  磁盘 0    联机              931 GB    41 MB        *
  磁盘 1    联机               57 GB      0 B

DISKPART> sel disk 1 # 选中磁盘 1

磁盘 1 现在是所选磁盘。

DISKPART> list disk # 当前选中的磁盘前会有标记 *

  磁盘 ###  状态           大小     可用     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  磁盘 0    联机              931 GB    41 MB        *
* 磁盘 1    联机               57 GB      0 B

DISKPART> clean # 清空磁盘

DiskPart 成功地清除了磁盘。

DISKPART> convert gpt # 将所选磁盘转换为 GPT 分区表格式

DiskPart 已将所选磁盘成功地转更换为 GPT 格式。

DISKPART> list disk # 列出所有磁盘

  磁盘 ###  状态           大小     可用     Dyn  Gpt
  --------  -------------  -------  -------  ---  ---
  磁盘 0    联机              931 GB    41 MB        *
* 磁盘 1    联机               57 GB    57 GB        *

DISKPART> cre part pri # 创建主分区

DiskPart 成功地创建了指定分区。

DISKPART> list part # 列出磁盘 1 的所有分区

  分区 ###       类型              大小     偏移量
  -------------  ----------------  -------  -------
* 分区      1    主要                  57 GB  1024 KB

DISKPART> format fs=exfat quick # 快速将所选分区格式化为 exFAT 文件系统

  100 百分比已完成

DiskPart 成功格式化该卷。

DISKPART> ass letter=E # 将 U 盘分配到 E 盘符

DiskPart 成功地分配了驱动器号或装载点。
```


# 6.1 使用 VMware Workstation Pro 安装 FreeBSD

VMware Workstation Pro 是 Type-2 虚拟机监视器（Hypervisor），运行在宿主操作系统之上，借助二进制翻译（binary translation）和硬件辅助虚拟化（hardware-assisted virtualization，基于 Intel VT-x 或 AMD-V 技术）完成 x86 指令集的虚拟化。

> **提示**
>
> 自 2024 年 11 月 11 日起，Broadcom 宣布 VMware Workstation Pro 对所有用户（个人、教育及商业用途）免费开放，无需许可证密钥。安装时在许可证密钥界面选择免费版本即可。免费政策适用于 Workstation Pro 17.5.2 及以上版本。

## 视频教程

以下视频教程演示了在 Windows 11 上安装 VMware Workstation Pro 17 的过程：

FreeBSD 中文社区. 001-Windows 11 安装 VMware 17\[EB/OL]. \[2026-04-04]. <https://www.bilibili.com/video/BV1Qji2YLEgS>.

## 镜像下载

在开始安装之前，需要先下载 FreeBSD 的安装介质镜像。

> **提示**
>
> 虚拟机也可以使用 FreeBSD 官方构建的 [虚拟机镜像](https://download.freebsd.org/releases/VM-IMAGES/15.0-RELEASE/amd64/Latest/)，该类镜像经过预配置，使用时需要手动扩容，文件系统可选 UFS 与 ZFS。
>
> 虚拟机一般使用 `FreeBSD-15.0-RELEASE-amd64-disc1.iso` 等类似文件名和后缀的 ISO 光盘镜像，但 `FreeBSD-15.0-RELEASE-amd64-memstick.img` 并非只能用于 U 盘刻录，虚拟机同样可以使用，具体使用方法可参考其他章节。

## 配置虚拟机

镜像下载完成后，在 VMware Workstation Pro 中创建新的虚拟机。

![VMware 安装 FreeBSD](/files/uW9OiYMxv1LmGde4mnfh)

![VMware 安装 FreeBSD](/files/1J5S8hjpeJ7vSlmhDeok)

![VMware 安装 FreeBSD](/files/BLvpzbk5B3ovjEmaAzyY)

请务必选择“稍后安装操作系统”，否则可能导致启动问题。

![VMware 安装 FreeBSD](/files/fKXNZy5d0aTaaLHFl6ST)

请选择“其他”，随后选择 FreeBSD。

> **技巧**
>
> 在测试环境中，选择其他操作系统类型也能正常启动，但为保持配置一致性并避免潜在兼容性问题，建议选择 FreeBSD。对于低版本的 FreeBSD，旧版 VMware Tools（闭源版本）可能存在兼容性问题。

![VMware 安装 FreeBSD](/files/KdLurMlO3IqYxbKdq2CJ)

虚拟机通常会占用较大的磁盘空间。如果不希望系统盘（如 C 盘）空间不足，请自行调整虚拟机的存储位置。

![VMware 安装 FreeBSD](/files/mrkOdqi8BLtq35dpVzFj)

请根据实际需要调整虚拟磁盘的最大大小。默认值可能偏小。如果要安装图形化桌面环境，建议分配至少 20 GB 的磁盘空间。

![VMware 安装 FreeBSD](/files/2DjXDMVjlmUdYpAt9WGi)

![VMware 安装 FreeBSD](/files/VI2UoU6wFBirvTg4kFkv)

![VMware 安装 FreeBSD](/files/nywQlKUGemuTiSp16Rla)

默认的 256 MB 内存足以启动系统，但不适合日常使用场景。最低建议配置为 512 MB。

![VMware 安装 FreeBSD](/files/U18dYGu76hByAinwooWG)

默认的 1 个 CPU 核心可以启动，但为了获得更好的性能，建议根据宿主机资源情况调整。

![VMware 安装 FreeBSD](/files/R1iMwdzig9d9iT5D2aRs)

在“使用 ISO 映像文件”处，点击“浏览”，找到并选中下载的 `FreeBSD-15.0-RELEASE-amd64-disc1.iso` 文件。

![VMware 安装 FreeBSD](/files/0mVok1l8zyKrL9mVwmES)

> **技巧**
>
> 经过测试，FreeBSD 亦支持 UEFI 环境中的 VMware 显卡驱动。

> **警告**
>
> FreeBSD Bug 250580 – VMware UEFI guests crash in virtual hardware after r366691\[EB/OL]. (2020-10-24)\[2026-04-04]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=250580>，FreeBSD 11-RELEASE/12-RELEASE 在 VMware 的 UEFI 环境下可能无法启动。经测试，FreeBSD 13.0-RELEASE 可正常启动。

![VMware 安装 FreeBSD](/files/X80yxNBj1cYT3tkvzL8S)

![VMware 安装 FreeBSD](/files/vnZeGZ0Z6Bc3Kz9Hf5xf)

![VMware 安装 FreeBSD](/files/7bfDxvW6mmBDjYztBPce)

## 网络设置

请使用 NAT 模式（默认设置）。如果虚拟机无法与宿主机（物理机）通信，请打开 VMware 的“编辑”菜单，选择“虚拟网络编辑器”，点击“还原默认设置”，直至配置恢复正常。

> **注意**
>
> 经过测试，桥接模式下，虚拟机与宿主机之间传输文件时速率较低。

> **技巧**
>
> 如果“还原默认设置”无效，且网络适配器列表异常（例如始终只有单个模式），可尝试根据下图所示手动配置网络。

> **警告**
>
> NAT 模式的“名称”与宿主机的 `控制面板\网络和 Internet\网络连接` 中的 `VMware Network Adapter VMnet8` 绑定，默认绑定的是 `8`。换言之，NAT 模式的“名称”默认必须指定为下图所示的 `VMnet8`，否则虚拟机将无法联网。
>
> <img src="/files/LGVaiZlBqtkBmrfpoxf1" alt="VMware network on FreeBSD" data-size="original">

![VMware network on FreeBSD](/files/TBiSbE9EzQ3glbTxMVfq)

通常无需手动设置。如果虚拟机内网络接口持续提示 `no link`，请尝试重启宿主机，随后打开 VMware 的虚拟网络编辑器，再次执行“还原默认设置”操作（不推荐手动配置，可能无效）。

如果无法连接网络，可尝试在虚拟机内将 DNS 服务器设置为 **223.5.5.5**。其他网络配置方法请参阅本章其他小节。

如果配置为桥接模式后始终无法通过 DHCP 获取 IP 地址，可尝试将网络适配器的“桥接到”选项从“自动”改为宿主机当前正在使用的物理网卡。

![VMware network on FreeBSD](/files/3ZKFbLKztViHMd08b2sc)

## 虚拟机增强工具与显卡驱动

VMware 的半虚拟化驱动程序的开源实现 open-vm-tools 通过 HGFS（Host-Guest File System）等专有协议提供共享文件夹、剪贴板共享、时间同步等功能，可改善虚拟机的 I/O 性能和用户体验。

要实现虚拟机与宿主机的良好集成，需安装 xf86-video-vmware（VMware 显卡驱动）和 xf86-input-vmmouse（VMware 虚拟鼠标驱动）。pkg 命令如下：

```sh
# pkg install xf86-video-vmware open-vm-tools xf86-input-vmmouse
```

或者使用 Ports 系统编译安装：

```sh
# cd /usr/ports/x11-drivers/xf86-video-vmware/ && make install clean
# cd /usr/ports/emulators/open-vm-tools/ && make install clean
# cd /usr/ports/x11-drivers/xf86-input-vmmouse/ && make install clean
```

> **注意**
>
> 如果不需要图形界面支持，可以安装无 X11 依赖的版本（仍然是 Port `emulators/open-vm-tools`）：
>
> ```sh
> # pkg install open-vm-tools-nox11
> ```

安装完成后，通常无需额外配置便可实现虚拟机屏幕的自动缩放功能。

> **注意**
>
> 即使在 Wayland 环境中，也需要安装该驱动。

> **技巧**
>
> 如果屏幕显示不正常（过大），请尝试以下操作：编辑虚拟机设置→硬件→显示器→监视器→指定监视器设置→任意监视器的最大分辨率，设置为宿主机的分辨率或略低于宿主机分辨率。具体步骤可参考故障排除部分。

### 鼠标集成：宿主机与虚拟机鼠标自由切换

请先安装显卡驱动和虚拟机增强工具。

```sh
# service moused enable        # 启用 moused 服务并写入系统配置
# Xorg -configure             # 生成 Xorg 默认配置文件
# mv /root/xorg.conf.new /usr/local/etc/X11/xorg.conf.d/xorg.conf  # 安装 Xorg 配置文件
```

相关文件结构：

```sh
/
├── root/
│   └── xorg.conf.new # 生成的 Xorg 默认配置文件
└── usr/
    └── local/
        └── etc/
            └── X11/
                └── xorg.conf.d/
                    └── xorg.conf # 最终安装的 Xorg 配置文件
```

编辑 **/usr/local/etc/X11/xorg.conf.d/xorg.conf** 文件，修改以下段落（其他部分保持不变）：

```ini
Section "ServerLayout"
        Identifier     "X.org Configured"
        Screen          0  "Screen0" 0 0
        InputDevice    "Mouse0" "CorePointer"
        InputDevice    "Keyboard0" "CoreKeyboard"
        Option          "AutoAddDevices" "Off"  # 禁止 Xorg 自动添加输入设备
EndSection

…………此处省略一部分…………

Section "InputDevice"
      Identifier  "Mouse0"
      Driver      "vmmouse"  # 使用 VMware 虚拟鼠标驱动
      Option      "Protocol" "auto"
      Option      "Device" "/dev/sysmouse"
      Option      "ZAxisMapping" "4 5 6 7"
EndSection

…………此处省略一部分…………
```

## 共享文件夹

请先安装虚拟机增强工具（Open VM Tools）。

### 在物理机中设置共享文件夹

![FreeBSD VMware 共享文件夹](/files/a1MfoNrV0zQZpa359is0)

> **注意**
>
> 此示例中虚拟机名称显示为“Windows 11”，这是因为该虚拟机配置为 Windows 11 与 FreeBSD 双系统，属正常情况。

列出当前可用的 VMware 共享文件夹：

```sh
# vmware-hgfsclient
123pan
```

### 加载 fuse 模块

将以下内容添加到 **/boot/loader.conf** 文件中：

```sh
fusefs_load="YES"
```

可在系统启动时加载 fusefs 内核模块。

相关文件结构：

```sh
/
├── boot/
│   └── loader.conf    # 系统启动加载配置文件
├── etc/
│   └── fstab          # 文件系统挂载配置
└── mnt/
    └── hgfs/          # VMware 共享文件夹挂载点
```

### 挂载

#### 手动挂载

> **注意**
>
> 请将以下命令中的 `123pan` 替换为在 VMware 中设置的共享文件夹名称。

将 VMware 共享目录 `123pan` 挂载到 **/mnt/hgfs**：

```sh
# vmhgfs-fuse .host:/123pan /mnt/hgfs
```

#### 自动挂载

编辑 **/etc/fstab** 文件。添加以下挂载条目（请将 `123pan` 替换为实际的共享文件夹名称）：

```sh
.host:/123pan      /mnt/hgfs    fusefs  rw,mountprog=/usr/local/bin/vmhgfs-fuse,allow_other,failok 0 0
```

系统将自动挂载 VMware 共享目录。

挂载 fstab 中所有未挂载的文件系统，检查有无错误（如果没有错误输出则正常），错误的配置可能导致系统无法正常启动：

```sh
# mount -al
```

### 查看共享文件夹

列出已挂载的 VMware 共享文件夹内容：

```sh
# ls /mnt/hgfs/
Downloads
# ls /mnt/hgfs/Downloads/
零跑
```

![FreeBSD VMware 共享文件夹](/files/XFdBWoBDai13M0qMRj9B)

文件内容一致。

### 参考文献

* MaRcOGO. 解决 vmware 上 Ubuntu 共享文件夹\[EB/OL]. (2022-07)\[2026-03-26]. <https://www.cnblogs.com/MaRcOGO/p/16463460.html>. 介绍 VMware 共享文件夹配置方法。
* FreeBSD Forums. fuse: failed to open fuse device\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/fuse-failed-to-open-fuse-device.44544/>. 解决了 fuse 设备无法打开的问题（如 `fuse: failed to open fuse device: No such file or directory`），为共享文件夹配置提供了关键参考。
* FreeBSD Forums. VMware shared folders\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/vmware-shared-folders.10318/>. 详细介绍了 FreeBSD 下 VMware 共享文件夹的具体挂载方法。

## 故障排除与未竟事宜

使用 VMware 安装和运行 FreeBSD 时，可能会遇到以下问题。

> **注意**
>
> 通过 Windows 远程桌面或其他 XRDP 工具远程连接另一台 Windows 桌面，再通过其上运行的 VMware 虚拟机操作 FreeBSD，鼠标可能出现异常。此为正常现象。

* 每次进入图形界面，窗口都会异常放大。

调整虚拟机的最大分辨率可解决该问题。

![VMware 安装 FreeBSD](/files/eMkiw0q8zYIvPH5Y6cXp)

硬件→显示→监视器→指定监视器设置→任意监视器的最大分辨率 (M)，由默认最大的 `2560 x 1600`（2.5K / WQXGA）改为其他较小值，也可以自定义数值。

* 没有声音

由于默认音量较低，加载声卡后若仍无声音，请将音量调至最大值后重新测试。


# 6.2 使用 VirtualBox 安装 FreeBSD

Oracle VirtualBox 是一款 Type-2 虚拟机监视器（Hypervisor），通过虚拟设备模拟（device emulation）与半虚拟化（paravirtualization）技术为虚拟机提供计算、存储和网络资源。VirtualBox 支持多种虚拟磁盘镜像格式，默认使用 VDI（Virtual Disk Image），同时兼容 VMDK（VMware）、VHD（Microsoft）等格式。该虚拟化软件可在 Windows、macOS、Linux、Oracle Solaris 等主流操作系统上运行，FreeBSD 可通过 Ports 安装 VirtualBox OSE 作为宿主机使用。

FreeBSD 在 VirtualBox 中作为虚拟机运行稳定。本节演示环境为 VirtualBox 7.2.8 和 Windows 11 25H2。

> **注意**
>
> VirtualBox 当前维护两个并行分支：7.1.x 与 7.2.x。7.2 系列于 2025 年 8 月首次发布，新增 Windows/Arm 平台支持，为当前主线版本；7.1.x 系列仍持续接收维护更新。FreeBSD Ports 中 `emulators/virtualbox-ose`（6.1.x）已被标记为 DEPRECATED，过期日期为 2026-12-31，建议使用 `emulators/virtualbox-ose-72`。

## 下载 VirtualBox

访问官方网站 <https://www.virtualbox.org>，点击页面右侧的 `Download` 按钮，选择对应平台的安装程序完成安装。

## 安装设置

VirtualBox 安装完成后，依次创建并配置虚拟机。

![VirtualBox 主界面](/files/F6PG273MqYyoRewLwusw)

在 VirtualBox 主界面中选择“新建”。

![新建虚拟机](/files/AkC3KgewxPLJZJhdWYOJ)

在“名称”字段中输入“FreeBSD”，下方的相关选项将自动填充。

![虚拟机名称设置](/files/xF65eDniVY0YbUCAqgyq)

分配内存大小与 CPU 数量，并开启 EFI 支持选项。

> **技巧**
>
> 建议使用 UEFI 引导方式，Xorg 可自动识别显卡驱动，无需手动编写 **/usr/local/etc/X11/xorg.conf**。

![硬件设置](/files/m8Mg0pLU9wmWA3YwVCWj)

调整虚拟硬盘容量。

![硬盘大小设置](/files/7Qcaw37Y2qZhs9fjqPbR)

进入虚拟机设置。

![虚拟机设置](/files/bzqeuQ5DTqXzymmsOGuZ)

将显卡控制器设置为 `VBoxSVGA`。

> **警告**
>
> 请勿勾选“启用 3D 加速”。FreeBSD 下的 VirtualBox Guest Additions 不支持 3D 加速，启用后将导致显示异常。

![显示设置](/files/z8fUQfWC8Rk4i8iRkIZo)

如有需要，可将虚拟硬盘切换为 NVMe 控制器：

![NVMe 硬盘](/files/Tk1sVR7vKCJapr9gDd9e)

点击“启动”，开始安装 FreeBSD。

![FreeBSD 安装界面](/files/ucYZnHc9gNzPFZMQ1Rjn)

![FreeBSD 安装界面](/files/zohaibwuCp9HsoOVWQij)

![FreeBSD 安装界面](/files/qXA1rGAW9OzQ4AOJ1L4p)

安装完成后，需手动关机并在虚拟机设置中移除安装光盘（如弹出强制释放提示，选择同意），否则下次启动仍会进入安装界面。

![安装完成后弹出光盘](/files/U7x1xN7eSkT0n5nEqti9)

安装完成的 FreeBSD 虚拟机系统：

![FreeBSD 系统界面](/files/P1PzXoPalsx56coVZtCN)

## 解决 EFI 下无法正常关机

编辑 **/etc/sysctl.conf** 文件，添加以下内容：

```ini
hw.efi.poweroff=0
```

随后重启系统，再执行关机即可恢复正常。该设置禁用 EFI 电源关闭功能，使系统通过 ACPI 完成关机。

### 参考文献

* mib. 12.0-U8.1 -> 13.0-U2 poweroff problem & solution\[EB/OL]. (2022-12-23)\[2026-03-26]. <https://www.truenas.com/community/threads/12-0-u8-1-13-0-u2-poweroff-problem-solution.104813/>. 提供了 EFI 环境下 FreeBSD 关机问题的解决方案。
* FreeBSD Forums. EFI: VirtualBox computer non-stop after successful shutdown of FreeBSD\[EB/OL]. (2022-04-28)\[2026-03-26]. <https://forums.freebsd.org/threads/efi-virtualbox-computer-non-stop-after-successful-shutdown-of-freebsd.84856/>. 详细分析了 VirtualBox 中 FreeBSD 关机异常的技术原因与修复方法。

## 网络设置

在虚拟网络方面，VirtualBox 提供 NAT、桥接（Bridged）、内部网络（Internal）、仅主机（Host-Only）等多种网络模式，每种模式对应不同的网络拓扑和连通性。

### 桥接模式

> **技巧**
>
> VirtualBox 的桥接模式可实现各方向网络互通。

桥接是宿主机与虚拟机互通的便捷方式，虚拟机可获得与宿主机处于同一网段的 IP 地址。例如，如果宿主机 IP 为 **192.168.5.123**，则虚拟机 IP 将为 **192.168.5.x**。

![桥接网络设置](/files/UeTzjs73RHRJWwon5X35)

请确保上图中“名称(N)”选择的网卡是当前正在使用的网卡，否则虚拟机将无法访问网络。

设置后执行 `dhclient em0` 可立即获取 IP 地址。为保证长期有效，可在 **/etc/rc.conf** 中添加 `ifconfig_em0="DHCP"`。

如无法访问互联网，可将 DNS 设置为 **223.5.5.5**。具体操作步骤请参阅本章 DNS 配置相关小节。

### NAT 与仅主机模式

与 VMware 不同，VirtualBox 的默认 NAT 模式下，宿主机与虚拟机无法直接互通。虚拟机可以访问宿主机的特殊地址 **10.0.2.2** 及其上运行的服务，但宿主机无法访问虚拟机的端口，各虚拟机之间的网络也相互隔离。

当桥接模式无法生效时，可改用双网卡方案。如果要通过宿主机（如 Windows 11）控制虚拟机中的 FreeBSD 系统，需配置两块网卡：一块为 NAT 模式，用于连接互联网；另一块为仅主机模式，用于与宿主机互通。

首先设置 NAT 模式下的网卡，用于互联网连接：

![双网卡设置](/files/aPCc4awlllRO2FCetG38)

网卡类型下拉列表中，“网络地址转换（NAT）”与“NAT 网络”选项功能相似。两者的主要区别在于：“NAT 网络”模式下的虚拟机之间可以互通，而“网络地址转换（NAT）”模式下的虚拟机网络相互隔离。

随后设置第二块网卡（仅主机模式），用于局域网：

![仅主机模式设置](/files/6i3LxxxpZvR7O6HsKPdW)

执行 `ifconfig` 查看网络状态。如果第二块网卡 `em1` 未获取 IP 地址，可通过 DHCP 临时获取：`dhclient em1`。为保证长期有效，可在 **/etc/rc.conf** 中添加 `ifconfig_em1="DHCP"`。

![NAT 与仅主机模式](/files/kox2K9z0ZdsndgLhKLzB)

```sh
# netstat -rn -f inet | egrep 'default|10\.0\.2\.0/24|192\.168\.56\.0/24'
default            10.0.2.2           UGS             em0 # 网络地址转换（NAT）网卡，默认网关
10.0.2.0/24        link#1             U               em0
192.168.56.0/24    link#2             U               em1 # 仅主机(Host-only)网络网卡，用于与宿主机互通
```

在此配置下，虚拟机与宿主机所在局域网无法直接互通。应通过 `em1` 的 IP 地址进行 SSH 连接，通常为 `192.168.56.X`，而非 `10.0.2.X`。

双网卡方案的网络拓扑如下图所示：

![双网卡方案的网络拓扑](/files/M4qjh0pD1lSr8LV81Tah)

### 参考文献

* Oracle. Network Address Translation (NAT)\[EB/OL]. \[2026-03-26]. <https://www.virtualbox.org/manual/topics/networkingdetails.html#network_nat>. 也可以按照手册中的端口转发来连通网络。
* Oracle Corporation. 6.3. Network Address Translation (NAT)\[EB/OL]. \[2026-04-04]. <https://www.virtualbox.org/manual/topics/networkingdetails.html#network_nat>. “网络地址转换（NAT）”与“NAT 网络”选项的区别。

## 虚拟机增强工具

VirtualBox 的虚拟机增强工具（Guest Additions）是一组运行在虚拟机内部的驱动程序和系统服务，提供以下支持：

* 共享剪贴板。
* 集成鼠标指针。
* 宿主时间同步。
* 窗口缩放。
* 无缝模式。

> **注意**
>
> 以下命令在 FreeBSD 虚拟机中执行。

### 安装增强工具

* 使用 pkg 安装：

```sh
# pkg install virtualbox-ose-additions-72
```

* 或者使用 Ports 安装：

```sh
# cd /usr/ports/emulators/virtualbox-ose-additions-72/
# make install clean
```

* 安装完成后，可通过以下命令查看增强工具的配置说明：

```sh
# pkg info -D virtualbox-ose-additions-72
```

### 服务管理

安装增强工具后，需启用相关服务并设置开机自启。

启用 VirtualBox 虚拟机增强驱动：

```sh
# service vboxguest enable
```

启用 VirtualBox 服务：

```sh
# service vboxservice enable
```

将普通用户 ykla 添加到 wheel 组以获得管理权限：

```sh
# pw groupmod wheel -m ykla
```

如果使用了 ntpd(8) 时间服务，应禁用宿主时间同步，在 **/etc/rc.conf** 中添加以下内容：

```ini
vboxservice_flags="--disable-timesync"
```

### 桌面预览

在 Wayland 环境下，由于缺少对应的 DRM/KMS 驱动支持，桌面功能暂不可用。以下演示在虚拟机中安装并启动 X11 下的 KDE：

![FreeBSD 系统界面](/files/x218T7cYRVECalkp87Mo)

窗口缩放、鼠标无缝切换等功能均正常。

![FreeBSD 系统界面](/files/clLLJx32zwczKvcwK360)

视频播放较为流畅，但默认音量偏低，可适当调高系统音量。

### 共享文件夹

共享文件夹用于在宿主机与虚拟机之间传输文件，可通过 `mount_vboxvfs` 命令挂载访问。以下示例在 VirtualBox 图形界面中创建共享文件夹 **C:\Users\ykla\\**，并将其挂载至虚拟机内的 **/mnt/bsdboxshare**：

![编辑共享文件夹](/files/V0LLhIYfbjziWtrNW6J2)

注意，“文件夹名称”是操作系统（FreeBSD 虚拟机）将看到的文件名，不得包含空格。

在 FreeBSD 虚拟机中查看待挂载的文件夹：

```sh
$ dmesg | grep -i VBOXVFS
VBOXVFS[1]: sfprov_mount: path: [ykla]
```

在 FreeBSD 虚拟机中挂载共享文件夹的命令如下：

```sh
# mkdir -p /mnt/bsdboxshare # 创建共享文件夹挂载点
# mount_vboxvfs -w ykla /mnt/bsdboxshare # 以可写方式挂载共享文件夹 ykla
```

列出共享文件夹内容：

```sh
# ls /mnt/bsdboxshare/

……省略其他输出……

/mnt/bsdboxshare/SendTo/
/mnt/bsdboxshare/SiYuan/
/mnt/bsdboxshare/Templates/
```

## 故障排除与未竟事宜

### 鼠标被捕获在虚拟机窗口内，无法移出

按下右侧 `Ctrl` 键即可释放鼠标（默认设置下键盘左右各有一个 `Ctrl` 键）。如果因自动缩放需要还原屏幕或无法找到菜单栏，请按 `Home` + 右侧 `Ctrl`。

> **技巧**
>
> 标准 108 键键盘上，`Home` 键位于 `Scroll Lock` 键的下方。

### UEFI 固件设置

开机时连续按 `Esc` 键即可进入 VirtualBox 虚拟机的 UEFI 固件设置界面。


# 6.3 使用 Hyper-V 安装 FreeBSD

Hyper-V 是微软公司（Microsoft）为 Windows 和 Windows Server 开发的企业级虚拟机监视器，属于系统内置组件。本节介绍在 Hyper-V 中安装与配置 FreeBSD 的完整流程。

## Hyper-V 简介

虚拟机监视器是一种创建和运行虚拟机的软件，允许多个操作系统同时运行在同一台计算机上。按虚拟化技术的理论分类，Hyper-V 属于 Type-1 架构，虚拟化层直接管理硬件资源。

Type-1 与 Type-2 两种架构的对比如下：

```sh
Type-1（裸金属型，如 Hyper-V、ESXi）：
  ┌─────────────────────────────┐
  │        虚拟机    虚拟机     │
  ├──────────────┬──────────────┤
  │   Hypervisor（虚拟化层）    │
  ├─────────────────────────────┤
  │          硬件               │
  └─────────────────────────────┘

Type-2（寄居型，如 VMware Workstation、VirtualBox）：
  ┌─────────────────────────────┐
  │        虚拟机    虚拟机     │
  ├──────────────┬──────────────┤
  │   Hypervisor（虚拟化层）    │
  ├─────────────────────────────┤
  │        宿主操作系统         │
  ├─────────────────────────────┤
  │          硬件               │
  └─────────────────────────────┘
```

Hyper-V 分为 Gen 1（第一代）和 Gen 2（第二代）两种虚拟机架构，两种架构在硬件支持和启动方式上有所不同。Gen 1 与 Gen 2 的区别如下表所示：

| Hyper-V 代系 | 硬盘         | 启动方式                     |
| ---------- | ---------- | ------------------------ |
| Gen 1      | IDE + SCSI | 仅支持 MBR                  |
| Gen 2      | 仅 SCSI     | 仅支持 UEFI（包含安全启动及 PXE 支持） |

系统快速创建的虚拟机默认为 Gen 2 架构。

> **注意**
>
> 使用 Gen 2 时建议关闭安全启动。FreeBSD 的引导加载程序未经 Microsoft 签名，在 Hyper-V 默认的安全启动配置中无法直接通过验证。FreeBSD 提供 uefisign(8) 工具供用户手动签名引导组件以实现 Secure Boot，但需要手动配置密钥，尚未实现开箱即用。如不了解如何手动签名，安装前请关闭安全启动。

FreeBSD 通过以下内核模块实现对 Hyper-V 的集成支持：

| 模块           | 功能                                  |
| ------------ | ----------------------------------- |
| `hv_utils`   | 提供时间同步、心跳检测、关机通知等集成功能               |
| `hv_vmbus`   | 实现 Hyper-V 虚拟总线，是其他 Hyper-V 设备驱动的基础 |
| `hv_netvsc`  | 提供网络半虚拟化驱动（高性能网络通信）                 |
| `hv_storvsc` | 提供存储半虚拟化驱动（虚拟磁盘 I/O 支持）             |

## 测试环境

本节基于以下软硬件环境测试与演示，实验结果受环境影响。

| 项目         | 版本/配置               |
| ---------- | ------------------- |
| 操作系统       | Windows 11 24H2 专业版 |
| FreeBSD    | 15.0-RELEASE        |
| Hyper-V 版本 | 10.0.26100.7019     |
| 虚拟机代系      | 第二代                 |

## 安装 Hyper-V

> **注意**
>
> Windows 家庭版和家庭中文版不支持 Hyper-V。

在 Windows 系统中启用 Hyper-V 功能组件。右键单击 Windows 徽标，在弹出的菜单中选择“终端（管理员）”或者“Windows PowerShell（管理员）”。输入以下命令：

```powershell
PS C:\WINDOWS\system32> DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V
```

输出内容如下：

```powershell
Deployment Image Servicing and Management tool
Version: 10.0.26100.5074

Image Version: 10.0.26200.8246

启用一个或多个功能
[==========================100.0%==========================]
The operation completed successfully.
```

系统将提示重启，重启过程中将安装 Hyper-V。

![Hyper-V](/files/7sF4FaWpQy3jkbY8Ulv8)

## 创建虚拟机

Hyper-V 安装完成后，创建虚拟机。右键单击 Hyper-V 管理器中的主机名，选择“新建”→“虚拟机”。

![Hyper-V](/files/UFJLPjtZl6HMeQQybtTQ)

点击“下一页”。

![Hyper-V](/files/8Ld8WaG49PqEvqWMnbiy)

为虚拟机设置名称，本例中使用“FreeBSD 15.0-RELEASE”，还可以自定义虚拟机的存储路径。随后点击“下一页”。

![Hyper-V](/files/jSsiFWs2WWVHoyMGUljw)

选择“第二代”。随后点击“下一页”。

![Hyper-V](/files/IUFpspH151uj1VWqGXpw)

分配内存大小，随后点击“下一页”。

![Hyper-V](/files/EZPioYDhxRDplvOTO2Z4)

配置网络，在下拉栏选择“Default Switch”（默认交换机），随后点击“下一页”。

![Hyper-V](/files/HtaNBSLIABywH5U6Uco7)

指定虚拟硬盘的名称、大小及存储位置，随后点击“下一页”。

![Hyper-V](/files/37gv8NZC0bMkMcQ0qSTX)

点击“从可启动的映像文件安装操作系统”，点击“浏览”，找到并选中已下载的 **FreeBSD-15.0-RELEASE-amd64-dvd1.iso** 文件，随后点击“下一页”。

![Hyper-V](/files/i4BGzGapZteiLclO2a6G)

进行预览，确认无误后点击“完成”。

![Hyper-V](/files/BXFrOigF23KtZeVyQ91B)

## 虚拟机配置调整

虚拟机创建完成后，选中新建的虚拟机“FreeBSD 15.0-RELEASE”，点击右侧下方的“设置...”调整部分设置。

![Hyper-V 设置](/files/2wYt6nVpdWr5SY9ItiJv)

请务必关闭安全启动（见上文注意事项），否则将无法从安装介质启动安装程序。点击“硬件”，选中“安全”，在右侧边栏中取消选中“启用安全启动”。

![Hyper-V 安全启动](/files/9WLqbvWL2jDJhi6HS3Rv)

来宾服务（Guest Service Interface）是 Hyper-V 集成服务的一部分，用于在宿主机与虚拟机之间复制文件。时间同步由独立的时间同步服务（Time Synchronization Service）负责。其作用详见参考文献。点击“管理”，再次点击“集成服务”，在右侧边栏选中“来宾服务”。

![Hyper-V 来宾服务](/files/b30WdrrPLZpnActEtLwG)

可选择关闭“使用自动检查点”（即关闭自动快照功能）以节约空间和时间，其作用详见参考文献。点击“管理”，再次点击“检查点”，在右侧边栏取消勾选“启用检查点”。

![Hyper-V 检查点](/files/ZjukMaWwfAp2Qjyx8C8v)

## 在 Hyper-V 安装 FreeBSD

虚拟机设置调整完成后，准备安装 FreeBSD 系统。启动虚拟机“FreeBSD 15.0-RELEASE”：

![Hyper-V](/files/XUfsafWYZP9FrMPEzffO)

根据提示安装 FreeBSD。

![Hyper-V](/files/eiXsrvFSFiDVlGY9b5Ks)

安装完成后必须手动弹出 DVD，点击“媒体”，再点击“DVD 驱动器”，选中“弹出 FreeBSD-15.0-RELEASE-amd64-dvd1.iso”。否则将返回安装界面。

启动新系统：

![Hyper-V](/files/1ZJrc22qS2NsT9REWvw2)

如果因为启动顺序无法启动（需要在 IPv4 界面等待一段时间），请尝试在设置中调整：点击“硬件”，选择“固件”，在右侧边栏选中“硬盘驱动器”，选择“向上移动”，将其置顶。如此，便可直接启动 FreeBSD 虚拟机。

![Hyper-V](/files/v1GZlkNSibIOJg2ipwta)

## 桌面环境

安装完成后，测试虚拟机基本功能。

鼠标和键盘均可正常工作，可在宿主机和虚拟机间无缝切换，但虚拟机桌面分辨率无法自适应调整。

可以通过 SSH 连接到默认网络接口“hn0”分配的 IP 地址。

![Hyper-V](/files/nSv1xwEGzg0DGY98sG9A)

由于 Hyper-V 的“增强会话模式”（Enhanced Session Mode）尚不支持 FreeBSD，音频重定向功能不可用。

删除虚拟机前，必须先关闭虚拟机。

## 参考文献

* 微软. 安装 Hyper-V\[EB/OL]. (2025-05-23)\[2026-04-04]. <https://learn.microsoft.com/zh-cn/windows-server/virtualization/hyper-v/get-started/install-hyper-v?tabs=powershell&pivots=windows>. 指出家庭版并不支持 Hyper-V 虚拟化技术。
* 微软. Windows Server 和 Windows 中的 Hyper-V 虚拟化\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/zh-cn/windows-server/virtualization/hyper-v/overview>. 微软官方对 Hyper-V 的说明，详细介绍了 Hyper-V 虚拟化架构与功能特性。
* 微软. 在 Windows 上安装 Hyper-V\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/zh-cn/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v>. 微软官方教程，提供了多种 Hyper-V 启用方法。
* 微软. Hyper-V 集成服务\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/zh-cn/virtualization/hyper-v-on-windows/reference/integration-services>. 详细说明了 Hyper-V 集成服务的功能与配置方法。
* 微软. 使用检查点将虚拟机恢复到以前的状态\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/zh-cn/virtualization/hyper-v-on-windows/user-guide/checkpoints?source=recommendations&tabs=hyper-v-manager%2Cpowershell>. 介绍了 Hyper-V 检查点的创建与使用方法。
* 微软. 在 Hyper-V 中在标准检查点与生产检查点之间进行选择\[EB/OL]. \[2026-03-26]. <https://learn.microsoft.com/zh-cn/windows-server/virtualization/hyper-v/manage/choose-between-standard-or-production-checkpoints-in-hyper-v>. 对比了标准检查点与生产检查点的差异与适用场景。
* nanorkyo. FreeBSD13 を Hyper-V 環境 にインストールしてみた 所感\[EB/OL]. \[2026-03-26]. <https://qiita.com/nanorkyo/items/d33e1befd4eb9c004fcd>. 提供了 FreeBSD 在 Hyper-V 环境下的安装经验与技巧。
* FreeBSD Foundation. FreeBSD UEFI Secure Boot\[EB/OL]. \[2026-04-17]. <https://freebsdfoundation.org/freebsd-uefi-secure-boot/>. FreeBSD 安全启动的技术说明，阐述了引导加载程序签名与 UEFI 固件验证的关系。


# 6.4 基于 Apple M1 和 Parallels Desktop 安装 FreeBSD

在 macOS 15.7.3 与 Parallels Desktop 26.3.3（57507）环境下，FreeBSD 16.0 的图形界面、键盘和鼠标均可正常使用。

> **警告**
>
> 本节基于 Apple M1，因此应选择 aarch64 架构的 FreeBSD。

## 配置虚拟机

环境准备就绪后，安装 FreeBSD。下图所示为新建页面，选中“通过映像文件安装 Windows、Linux 或 macOS”，确认并继续。

![新建](/files/zDTAj8meAgX6xUBljxHK)

点击左下角“没有指定源也继续”，确认并继续。

![没有指定源也继续](/files/Iw8553xXuvPZ3EA9P2ys)

在“请选中您的操作系统”界面中，选中“其他”。

![请选中您的操作系统](/files/I68XC4asBWS1OqBaR2Aq)

预览操作系统类型，确认并继续。

![预览操作系统类型](/files/nU1Sj5yeESIsvAtclwvK)

在“名称和位置”页面中，可调整各项设置。勾选“安装前设定”，确认并继续。

![名称和位置](/files/IXCsDP1ZQoDfYt0N3ySJ)

进入配置页面后，可调整各项设置。

![名称和位置](/files/1kspAOWaZbLa7UoEFmfg)

在顶部选择“硬件”选项卡，在左侧边栏选择“CD/DVD”，在右侧“源”中选择下载的 FreeBSD 镜像。

![CD/DVD](/files/gTI9UAy7nohilvudQMMd)

预览虚拟机配置后点击继续。

![CD/DVD](/files/2MJYBn6inFN7CDBcqhRy)

> **技巧**
>
> Parallels Desktop 的默认设置通常已足够，默认使用 UEFI 引导，无需调整硬件配置。

## 安装 FreeBSD

开始安装 FreeBSD 系统。

![安装 FreeBSD 系统](/files/PQwemlyaNYd8SH3bwM2A)

安装桌面环境后的效果预览：

![桌面界面](/files/uGUOPfhsnIyVfFwWgnWQ)

安装桌面环境后，系统即可正常运行，但分辨率无法调整。

## CPU 使用率验证

手动安装 Port **sysutils/htop** 后观察，CPU 使用率正常，无需额外调整。

![htop](/files/3MZb1ILQrpQ9FNh35CnV)


# 6.5 基于 Apple M1 和 VMware Fusion Pro 安装 FreeBSD

在 macOS 15.7.3 与 VMware Fusion Professional 26H1 (25388279) 环境下，FreeBSD 16.0 可正常安装运行。

> **注意**
>
> 不建议使用 macOS 14，可能因兼容性问题导致键盘无法输入，需特别注意。

## 下载 FreeBSD

首先需下载适用于 Apple M1 架构的 FreeBSD 镜像。Apple M1 采用 ARM 架构，请下载名称中包含 `aarch64` 的镜像。**切勿** 下载 `amd64` 架构的镜像，否则虚拟机将无法正常运行。

## 配置虚拟机

镜像下载完成后，开始配置虚拟机。点击创建自定义虚拟机（Create a custom virtual machine），然后点击继续（Continue）：

![创建自定义虚拟机](/files/0T2DZFM7ml9WmjJXFdcS)

在操作系统选择界面，点击“Other”，右侧选择当前最新的“FreeBSD 15 64-bit Arm”（Fusion 目前只有 15 的模板但对 16 同样适用），然后点击继续（Continue）：

![选择操作系统](/files/jG0Irh4rIhTbKiLny18J)

选择虚拟磁盘：选中“新建虚拟磁盘”，容量稍后可调整。然后点击继续（Continue）：

![选择虚拟磁盘](/files/22taMSNJ0CavMtM7wll6)

在“完成”页面，预览配置后点击继续（Continue）：

![完成](/files/yU59O1tr7gzPU5RIOmNf)

在“命名虚拟机”页面，“存储为”可设置虚拟机名称，此处设为“FreeBSD 16 64-bit Arm”，标签和位置均可自定义。然后点击存储。

![命名虚拟机](/files/YCgy6FCMbYcTy7cVES7L)

完成创建后，打开虚拟机设置。

调整处理器数量和内存容量。默认内存配置可能不足（`4096 MB` 即 4 GB），建议适当增加。

![处理器数量和内存容量](/files/YCgy6FCMbYcTy7cVES7L)

调整虚拟磁盘容量后，点击应用（Apply）。

![调整虚拟磁盘容量](/files/izR7WloCE2owRzW0wei2)

连接 CD/DVD 设备，勾选“Connect CD/DVD Drive”。

![CD/DVD 设备](/files/y7DFdha9HKhehzlLIY9R)

点击“选择镜像”（Choose a disc or disc image），选择下载的 FreeBSD 镜像。

![选择镜像](/files/GeklqzNlg5lXUVlIi8UH)

## 安装 FreeBSD 虚拟机

![安装界面](/files/Z7WpE8ETqggNIokW7XR7)

![安装界面](/files/vnBrfxxB0XWt7OtPGZTw)

## 虚拟机增强工具

* 使用 pkg 安装：

```sh
# pkg ins open-vm-tools
```

* 使用 Ports 安装：

```sh
# cd /usr/ports/emulators/open-vm-tools/
# make install clean
```

无需额外配置。

## 调整分辨率

将 `efi_max_resolution="1080p"` 写入 **/boot/loader.conf** 文件即可将虚拟机分辨率设为 1920x1080。参见虚拟控制台和终端章节。

## 配置桌面

![桌面界面](/files/RVLRsC5tT8FAC0DVWpqE)


# 7.1 虚拟控制台和终端

虚拟控制台（Virtual Console）是 FreeBSD 提供的多终端机制，用户可在同一物理显示器和键盘上同时使用多个独立的登录会话。每个虚拟控制台拥有自己的登录提示符和 Shell，用户可通过 Alt+F1 至 Alt+F8 键组合在它们之间切换。

终端（Terminal）的概念源于早期计算机系统中用于与主机通信的物理设备（电传打字机 TTY），在现代系统中演变为软件模拟的终端设备。FreeBSD 的虚拟控制台设备名称为 ttyv0 至 ttyvf（共 16 个，使用十六进制后缀），默认启用 ttyv0 至 ttyv7，其中 ttyv0 为系统控制台（System Console），系统消息默认输出到该控制台。虚拟控制台的数量由 **/etc/ttys** 文件配置。

## 登录到 FreeBSD

FreeBSD 系统安装完成并正常启动后，用户将在屏幕上看到以下系统提示符界面：

```sh
FreeBSD/amd64 (ykla) (ttyv0)

login:
```

这一屏幕界面在计算机技术史上称作 TTY（teletypewriter，电传打字机），也可称为物理终端。TTY 是用户与操作系统内核交互的早期接口形式，在图形用户界面（GUI）普及之前是主要的人机交互（HCI）手段。

解释：

| 项目        | 说明                                    |
| --------- | ------------------------------------- |
| `FreeBSD` | 操作系统名称                                |
| `amd64`   | 体系架构，英特尔和 AMD 处理器通常使用 amd64（即 x86-64） |
| `ykla`    | 主机名，是在安装系统时用户自行设置的                    |
| `ttyv0`   | 首个 TTY，计算机中许多事物的编号序列都从 0 开始           |
| `login:`  | 指示用户登录                                |

输入用户名和密码，登录系统：

```sh
FreeBSD/amd64 (ykla) (ttyv0)

login: root # 此处输入用户名，随后按回车键 ①
Password: # 此处输入密码，随后按回车键
Last login: Tue Mar 18 17:24:48 2025 from 3413e8b6b43f
FreeBSD 15.0-CURRENT (GENERIC) main-n275981-b0375f78e32a

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List:        https://www.FreeBSD.org/lists/questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

To change this login announcement, see motd(5).
```

至此，已成功登录到 FreeBSD 操作系统。

> **注意**
>
> 密码不会回显至屏幕。FreeBSD 在涉及密码输入时，屏幕不会显示任何回显字符（UNIX 系统通常不显示星号或其他占位符），即便输入了密码，屏幕也仍是空白，直接输入后按回车即可。

* ①：root 是 UNIX 系统中的超级用户账户，拥有最高权限。常见的 Android root、Apple 越狱、Kindle 越狱等操作，均旨在获取此 root 权限。

### 故障排除与未竟事宜

* 如果用户名正确，但密码不正确：

```sh
login: root
Password:
Login incorrect # 表示登录信息不正确
login:
```

* 如果用户名和密码都不正确：

```sh
login: test # 当前系统中不存在该用户
Password:
Login incorrect
login:
```

如果无法确认用户名，建议找回 root 密码后查看系统中的用户账户列表，或直接重装系统。

### 参考文献

* ItsFOSS. What is TTY in Linux?\[EB/OL]. \[2026-03-25]. <https://itsfoss.com/what-is-tty-in-linux/>. 详细介绍 TTY 概念与历史。

## 虚拟控制台

系统控制台虽可用于交互，但系统消息默认输出至系统控制台，会覆盖用户正在操作的命令或文件，影响操作，因此习惯命令行的用户通常选择虚拟控制台而非系统控制台。

默认情况下，FreeBSD 配置了多个虚拟控制台用于输入命令。每个虚拟控制台都有自己的登录提示符和 shell，在虚拟控制台之间切换颇为便捷。这本质上提供了在图形环境中同时打开多个窗口的命令行等效功能。

FreeBSD 保留了 Alt+F1 至 Alt+F8 的组合键用于在虚拟控制台之间切换。使用 Alt+F1 切换到系统控制台（ttyv0），Alt+F2 访问第一个虚拟控制台（ttyv1），Alt+F3 访问第二个虚拟控制台（ttyv2），依此类推。当使用 Xorg 作为图形控制台时，组合键变为 Ctrl+Alt+F1 以返回基于文本的虚拟控制台。

虚拟控制台与快捷键的对应关系如下：

```sh
FreeBSD 虚拟控制台布局

  快捷键     控制台     用途
  ────────────────────────────────────────────
  Alt+F1  →  ttyv0      系统控制台（系统消息）
  Alt+F2  →  ttyv1      虚拟控制台 1
  Alt+F3  →  ttyv2      虚拟控制台 2
  Alt+F4  →  ttyv3      虚拟控制台 3
  Alt+F5  →  ttyv4      虚拟控制台 4
  Alt+F6  →  ttyv5      虚拟控制台 5
  Alt+F7  →  ttyv6      虚拟控制台 6
  Alt+F8  →  ttyv7      虚拟控制台 7
  ────────────────────────────────────────────
  ttyv8 ~ ttyvf         未默认启用（/etc/ttys 配置）

  Xorg 环境下：
  Ctrl+Alt+F1 ~ F8  →  返回文本虚拟控制台
  Ctrl+Alt+F9        →  返回图形界面（通常）
```

从一个控制台切换到另一个时，FreeBSD 管理屏幕输出，从而实现多个虚拟屏幕与键盘的并行会话效果，可供用户输入命令并交由 FreeBSD 执行。在虚拟控制台中启动的程序不会因为用户切换到另一虚拟控制台而停止运行。

在 FreeBSD 中，可用虚拟控制台的数量在 **/etc/ttys** 文件的以下部分中配置：

```ini
……其他省略……

# name	getty				type	status		comments
#
# If console is marked "insecure", init will ask for the root password
# when going to single-user mode.
console	none				unknown	off insecure
#
ttyv0	"/usr/libexec/getty Pc"		xterm	onifexists secure
# Virtual terminals
ttyv1	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv2	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv3	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv4	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv5	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv6	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv7	"/usr/libexec/getty Pc"		xterm	onifexists secure
ttyv8	"/usr/local/bin/xdm -nodaemon"	xterm	off secure

……其他省略……
```

要禁用某个虚拟控制台，在该虚拟控制台对应行的开头加上注释符号 `#`。例如，要将可用虚拟控制台的数量从八个减少到四个，在代表虚拟控制台 ttyv5 至 ttyv8 的最后四行开头加上 `#`：

```ini
……其他省略……

#ttyv5	"/usr/libexec/getty Pc"		xterm	onifexists secure
#ttyv6	"/usr/libexec/getty Pc"		xterm	onifexists secure
#ttyv7	"/usr/libexec/getty Pc"		xterm	onifexists secure
#ttyv8	"/usr/local/bin/xdm -nodaemon"	xterm	off secure

……其他省略……
```

> **技巧**
>
> 如果操作失误但已配置 SSHD 服务，仍可通过 SSH 远程连接 FreeBSD 系统，将生成一个 pts(4) 伪终端 **/dev/pts/n**。
>
> ```sh
> $ w
> 10:22PM  up 27 mins, 3 users, load averages: 0.03, 0.04, 0.00
> USER       TTY      FROM            LOGIN@  IDLE WHAT
> ykla       pts/0    192.168.179.1   9:55PM     4 su (sh)
> ykla       pts/1    192.168.179.1  10:22PM     - w
> ```

注意，最后一个虚拟控制台（ttyv8）用于访问图形环境（如果已安装并配置了 Xorg）。

有关此文件中每列的详细描述和虚拟控制台的可用选项，请参阅 ttys(5)。

## 单用户模式

FreeBSD 启动菜单提供了标记为“Boot Single User”的选项。如果选择此选项，系统将启动进入称为“单用户模式”的特殊模式。此模式通常用于修复无法启动的系统，或在不知道 root 密码时重置 root 密码。

在单用户模式下，网络和其他虚拟控制台不可用。但用户可以获得完整的 root 访问权限，并且默认情况下不需要 root 密码。出于这些原因，需要物理访问键盘才能启动进入此模式，因此在保护 FreeBSD 系统安全时，键盘的物理访问权限归属是重要的安全考量因素。

控制单用户模式的设置位于 **/etc/ttys** 文件的以下部分：

```ini
……以上省略……

# name	getty				type	status		comments
#
# If console is marked "insecure", init will ask for the root password
# when going to single-user mode.
console	none				unknown	off secure	# 注意此行
#

……以下省略……
```

默认情况下，状态设置为 `secure`（安全）。此设置假设键盘的物理访问权限归属无需顾虑，或已由物理安全策略管控。

因为任何人均可访问键盘，所以如果将此设置更改为 `insecure`（不安全），则表明物理环境本身视为不安全。当此行中的 `secure` 更改为 `insecure` 后，即：

```ini
console	none				unknown	off insecure
```

FreeBSD 将在用户选择启动进入单用户模式时提示输入 root 密码：

```sh
Enter root password, or ^D to go multi-user
Password:
```

将此设置更改为 `insecure` 时需谨慎。如果忘记了 root 密码，仍然可以借助安装介质启动进入单用户模式，但不熟悉 FreeBSD 启动过程的用户可能面临困难。

## 调整引导界面和 TTY 分辨率

### 修改“gop”（通用方法）

在出现 FreeBSD 菜单时，按 **ESC** 键退出引导，出现提示符 `OK`。输入 `gop list` 可查看所有支持的分辨率列表：

```sh
OK gop list
mode 0: 1920x1080x32, stride=1920   # 显示模式 0，分辨率 1920x1080，颜色深度 32 位，行跨度 1920
mode 1: 640x480x32, stride=640       # 显示模式 1，分辨率 640x480，颜色深度 32 位，行跨度 640
mode 2: 800x600x32, stride=800       # 显示模式 2，分辨率 800x600，颜色深度 32 位，行跨度 800
mode 3: 1024x768x32, stride=1024     # 显示模式 3，分辨率 1024x768，颜色深度 32 位，行跨度 1024
mode 4: 1280x720x32, stride=1280     # 显示模式 4，分辨率 1280x720，颜色深度 32 位，行跨度 1280
mode 5: 1280x1024x32, stride=1280    # 显示模式 5，分辨率 1280x1024，颜色深度 32 位，行跨度 1280
```

此处选择 `mode 0` 进行效果测试：

```sh
OK gop set 0
```

效果会立即显示。

确认效果合适后，继续引导：

```sh
OK menu
```

该命令表示操作确认或进入菜单界面。

将该配置写入 **/boot/loader.conf** 文件，设置 GOP 模式为 0：

```ini
exec="gop set 0"
```

### `efi_max_resolution`（UEFI）或 `vbe_max_resolution`（BIOS）

也可以通过配置文件设置 UEFI 或 BIOS 下的分辨率。根据文档 LOADER.CONF(5)，这两个变量可接受以下值：

| 值       | 分辨率       |
| ------- | --------- |
| `480p`  | 640x480   |
| `720p`  | 1280x720  |
| `1080p` | 1920x1080 |
| `1440p` | 2560x1440 |
| `2160p` | 3840x2160 |
| `4k`    | 3840x2160 |
| `5k`    | 5120x2880 |
| `宽 x 高` | 宽 x 高     |

本节测试使用 `efi_max_resolution` 变量：将 `efi_max_resolution="1080p"` 写入 **/boot/loader.conf** 文件，重启后效果与 gop 方法一致。

### 参考文献

* FreeBSD Project. loader.conf(5)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=loader.conf&sektion=5>.
* FreeBSD Forums. gop set < mode > being ignored in **/boot/loader.conf**\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/gop-set-mode-being-ignored-in-boot-loader-conf.77779/>. 讨论 loader.conf 中 GOP 模式设置未生效的原因与解决思路。
* FreeBSD Forums. How to find the valid values of efi\_max\_resolution\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/how-to-find-the-valid-values-of-efi_max_resolution.84840/>. 探讨查询 efi\_max\_resolution 有效取值的方法。

## 课后习题

1. 在 FreeBSD 中切换多个虚拟控制台（ttyv0—ttyv3），分别以不同用户登录，使用 `w` 命令记录各终端的会话信息，分析虚拟控制台与伪终端的会话管理差异。
2. 查阅 FreeBSD 内核中 TTY 子系统的核心源代码（**sys/kern/tty\*.c** 与 **sys/sys/tty\*.h**），分析其输入输出缓冲区管理和行规程的实现机制。
3. 修改 **/etc/motd.template** 的内容（**/etc/motd** 是 **/var/run/motd** 的符号链接，启动时由 **/etc/motd.template** 生成，参见 motd(5)）与显示行为（如通过 **/etc/login.conf** 的 `hushlogin` 功能控制），记录修改前后用户登录时的信息输出差异。


# 7.2 shell 基础

本节介绍什么是 Shell，如何修改默认登录环境。

## 概述

shell 是用户与操作系统内核交互的命令解释程序（command interpreter），接受用户输入的命令并传递给内核执行。用户命令在 shell 中运行，通过 shell 与系统交互。shell 提供命令行界面，从输入通道接收命令并执行。许多 shell 提供内置功能以辅助日常任务，如文件管理、文件名通配、命令行编辑、命令宏和环境变量。FreeBSD 基本系统内置多种 shell，包括扩展 POSIX shell（sh(1)）和扩展 C shell（tcsh(1)）。其他 shell 可通过 FreeBSD Ports 获得，例如 Zsh 和 Bash。

shell 在操作系统中的位置如下：

![什么是 shell](/files/6y03nfjrCaLvrbZ4HPIS)

FreeBSD root 用户默认 shell 为 sh（自 FreeBSD 14 起），但基本系统同时提供 csh/tcsh 作为替代选择。

> **技巧**
>
> csh 与 tcsh 的关系
>
> FreeBSD 中 csh 和 tcsh 是同一个二进制程序，但以不同名称调用时行为有所差异。可通过查看源代码 <https://github.com/freebsd/freebsd-src/blame/main/bin/csh/Makefile> 及执行 man csh 验证：两者均重定向至 tcsh。

> **注意**
>
> 虽然 csh 与 tcsh 本质上是同一程序，但如果以 csh 的参数调用，则部分 tcsh 扩展会被关闭，因而在使用时存在差异。

## POSIX shell 规范

POSIX（Portable Operating System Interface）是由 IEEE 和 The Open Group 制定的操作系统接口标准，旨在确保应用程序在不同 UNIX 系统间的可移植性。POSIX.1 标准中的 shell 和实用程序规范（Shell Command Language）定义了符合标准的 shell 必须实现的最小功能集，包括命令语法、变量扩展、引号规则、条件表达式、循环结构和内置命令等。当前版本为 POSIX.1-2024（IEEE Std 1003.1-2024）。

POSIX shell 规范的核心要求包括：

* **命令执行**：支持简单命令、管道、列表和复合命令的执行。
* **变量与参数扩展**：支持位置参数、特殊参数和多种变量扩展形式。
* **引号机制**：支持单引号（保留字面值）、双引号（允许变量扩展和命令替换）和反斜杠转义。
* **模式匹配**：支持文件名通配（globbing），包括 `*`、`?` 和方括号表达式。
* **条件与循环**：支持 `if`、`while`、`for`、`case` 等控制结构。
* **内置命令**：必须实现 `cd`、`echo`、`exit`、`export`、`read`、`return`、`set`、`shift`、`trap`、`unset` 等内置命令。

FreeBSD 系统默认采用的 shell 是 sh。FreeBSD 的 **/bin/sh** 并非 **Stephen R. Bourne** 在贝尔实验室为 UNIX V7 编写的原始 Bourne shell（Bourne 来自作者姓名），而是基于 Kenneth Almquist 于 1989 年发布的 Almquist shell（ash），后者旨在作为 Bourne shell 更紧凑、更高效的替代品。4.3BSD-Reno/Net/2 时期（1990—1991 年）将 ash 引入 BSD 世界，NetBSD 随后将其作为默认 /bin/sh，FreeBSD 又从 NetBSD 导入了 ash 实现，在功能上基本符合 POSIX.1-2024 标准中关于 shell 的规范要求。

Linux 中常见的 shell 是 GNU 工具 bash（作者 Brian Fox）。bash 全拼为 Bourne Again shell，是对“Born Again”即“重生”的双关，意为“重生的 Bourne shell”。

Linux 中同样提供 sh，但通常符号链接到其他 shell（如 Debian/Ubuntu 中链接到 dash，部分发行版链接到 bash），它们并不是真正的 sh。

例如 Ubuntu 24.04 LTS 默认的 shell 是 dash：

```bash
lrwxrwxrwx 1 root root 4  2 月 25 23:19 /bin/sh -> dash
$ ls -l /bin/sh # 以长格式查看 /bin/sh 这个文件的详细信息
```

dash 是 NetBSD 版本 ash（Almquist SHell）的直接后裔。而 macOS 中的默认 shell 通常是 zsh（Z shell）。

## 快捷键

> **注意**
>
> 以下快捷键的执行不受键盘大小写状态（如 Caps Lock 开启或关闭）的影响。

### 使用 Scroll Lock 键在 TTY 界面上下翻页/翻行

使用 **Scroll Lock** 键（滚动锁定键）：按下 **Scroll Lock** 键后，可以使用上 ↑/下 ↓ 方向键以及 **Page Up**/**Page Down** 键滚动屏幕。

不同点：

* 上 ↑/下 ↓ 方向键：使 TTY 界面上下滚动一行
* **Page Up**/**Page Down** 键：使 TTY 界面上下滚动一页

再次按下 **Scroll Lock** 键将退出此模式。

> **技巧**
>
> SL 键在 **HOME** 键的上方，PS 截图键 **Print Screen** 的右侧，PB 键 **Pause/Break** 的左侧。

从历史角度来看，**Scroll Lock** 键即为此类用途而设计，它能在文本界面中滚动而不影响光标位置。

### 使用 Shift 组合键在 TTY 界面上下翻页/翻行

使用 **Shift** 快捷键：

* **Shift** + 上 ↑/下 ↓ 方向键——使 TTY 界面上下滚动一行
* **Shift** + **Page Up**/**Page Down** 键——使 TTY 界面上下滚动一页

### 补全命令或目录

可使用 **Tab** 键补全命令或目录；上箭头 **↑** 用于查看上一条命令，下箭头 **↓** 用于查看下一条命令。

* 补全命令

```sh
# lo # 此时按 Tab 键可查看以 lo 开头的命令列表；继续输入更多字母后再次按 Tab 可进一步筛选
local                    localedef                login
local-unbound            locate                   logins
local-unbound-anchor     lock                     logname
local-unbound-checkconf  lockf                    look
local-unbound-control    lockstat                 lorder
local-unbound-setup      locktest                 lowntfs-3g
locale
```

* 补全文件目录或文件名

```sh
$ cp /home/ykla/ # 此处按 Tab 键，随后再重复按一次 Tab 键，观察效果
$ cp /home/ykla/test/1.txt
.cache/                 .login                  bin/                    test2
.config/                .profile                HW_PROBE/               test3
.cshrc                  .sh_history             mine
.gitconfig              .sh_history.Y8RqIDNDIv  mydir/
.k5login                .shrc
```

### 终止命令

如果要终止命令，可以使用 **Ctrl**+**C**：

```sh
# ping 163.com  # 测试与 163.com 的网络连通性
PING 163.com (59.111.160.244): 56 data bytes
64 bytes from 59.111.160.244: icmp_seq=0 ttl=52 time=27.672 ms
64 bytes from 59.111.160.244: icmp_seq=1 ttl=52 time=27.580 ms
^C # 注意这里，^C 表示此处按下了 Ctrl+C 的组合键，随后命令被终止
--- 163.com ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 27.580/27.626/27.672/0.046 ms
```

FreeBSD 的 `ping` 合并了原 `ping6` 的功能，通过 `-4`/`-6` 选项区分协议版本（Google Summer of Code 2019 项目）。Linux 支持 `-O` 报告未收到回复；FreeBSD 的 `-O` 含义不同（仅用于 IPv6 的 ICMPv6 Node Information supported query types 查询），不支持报告未收到回复的功能。`ping -y`（ICMPv6 Node Information DNS Name 查询）和 `ping -k`（Node Information Node Addresses 查询）源自 KAME 项目的 ICMPv6 Node Information 实现。

`ping` 使用 ICMP 协议的 ECHO\_REQUEST 数据报来触发主机的 ECHO\_RESPONSE。IPv4 目标使用 ICMP，IPv6 目标使用 ICMPv6（RFC 4443）。默认数据大小为 56 字节，加上 8 字节 ICMP 头共 64 字节。如果数据空间不小于 8 字节，前 8 字节用于时间戳以计算往返时间。

### 其他

* **Ctrl**+**L**（字母 L）：清空屏幕
* **Ctrl**+**A**：将光标移动到命令行首
* **Ctrl**+**E**：将光标移动到命令行尾

## 配置 csh/tcsh

对于 C shell（csh/tcsh），登录 shell 依次读取 **/etc/csh.cshrc**、**/etc/csh.login**、**\~/.tcshrc**（若不存在则读取 **\~/.cshrc**）、**\~/.login**。

* 在 **\~/.cshrc** 文件中加入下行，为 `ls` 命令设置彩色输出。

```sh
alias ls ls -G
```

并重新登录。

* 如何使 FreeBSD 的 csh 像 Bash 那样按 Tab 列出无法补全的候选文件？在 **\~/.cshrc** 文件中加入：

```sh
set filec              # 启用命令行文件名补全
set autolist           # 自动显示补全列表
```

重新加载 C shell 配置文件，刷新别名和环境设置：

```sh
# source ~/.cshrc
```

* 如何使 csh 具备类似 zsh 的命令错误修正功能？

例如，使用 emacs 编写 C 语言程序时，输入 `emacs ma` 并按 `Tab` 键再按回车键，会匹配所有以 `ma` 开头的文件。此配置可以忽略部分匹配的文件，即按 `Tab` 时不会列出被忽略的文件，便于编程，不会匹配二进制 `.o` 文件等。

```sh
set correct = cmd        # 启用命令拼写自动纠正功能，提示输入正确命令
# 例：lz/usr/bin tcsh>ls /usr/bin (y|n|e|a)?  # 当检测到命令拼写错误时的提示示例

set fignore = (.o ~)   # 设置文件名忽略模式，用于补全时排除指定文件或模式
```

## 参考文献

* The Open Group. Shell Command Language\[EB/OL]. \[2026-04-23]. <https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html>.
* Herbert. Dash\[EB/OL]. \[2026-05-08]. <http://gondor.apana.org.au/~herbert/dash/>. Dash 官网
* Almquist K. ash (Almquist shell)\[EB/OL]. (1989-05-30)\[2026-04-18]. <https://github.com/dsipher/ash>. FreeBSD 的 **/bin/sh** 基于 ash，而非 Stephen R. Bourne 的原始 Bourne shell。
* Fox B, Ramey C. Bash Reference Manual\[M]. Boston: Free Software Foundation, 2022. “Bourne Again shell”是对“Born Again”的双关。

## 课后习题

1. 在 FreeBSD 中编写一个 sh 脚本，实现文件名补全的最小示例，记录 sh 内建补全机制与 Bash 补全的功能差异。
2. 查阅 FreeBSD sh 源代码（**bin/sh/**），分析其行编辑和快捷键处理的实现方式，比较其与 Bash 在交互功能上的差距。
3. 修改 shell 的默认提示符配置（如通过 `PS1` 或 `set prompt`），记录不同 shell（sh、csh、zsh）中提示符定制的语法差异。


# 7.3 切换 shell

永久更改默认 shell 的最简单方法是使用 chsh。运行此命令会打开由 EDITOR 环境变量配置的编辑器，默认情况下为 vi(1)。

## Zsh

Zsh 是 Kali Linux 和 macOS 的默认 shell。Zsh 不仅是一款为交互式使用而设计的 Shell，它还是一种强大的脚本语言。zsh 整合了 bash、ksh 和 tcsh 等绝大多数主流 shell 的许多实用特性，同时还加入了大量原创特性。

### 安装 Zsh

* 使用 pkg 安装：

```sh
# pkg install zsh zsh-completions zsh-autosuggestions zsh-syntax-highlighting
```

软件包说明：

| 程序                        | 说明                      |
| ------------------------- | ----------------------- |
| `zsh`                     | Zsh shell               |
| `zsh-completions`         | 自动补全                    |
| `zsh-autosuggestions`     | 类 Fish shell 的 Zsh 自动补全 |
| `zsh-syntax-highlighting` | 类 Fish shell 的 Zsh 语法高亮 |

* 使用 Ports 安装：

```sh
# cd /usr/ports/shells/zsh/ && make install clean
# cd /usr/ports/shells/zsh-completions && make install clean
# cd /usr/ports/shells/zsh-autosuggestions/ && make install clean
# cd /usr/ports/shells/zsh-syntax-highlighting/ && make install clean
```

* 查看 Zsh 安装信息

```sh
# pkg info -D zsh
```

### 配置 Zsh

将当前用户的默认登录 shell 修改为 Zsh：

```sh
# chsh -s /usr/local/bin/zsh # 切换 shell 至 zsh
chsh: user information updated
```

在提示符下输入你的密码并按下 **回车键** 即可更改 shell。注销并重新登录后即可开始使用新 shell。

> **注意**
>
> `chsh`、`chfn`、`chpass` 是同一个程序，通过不同名称调用。非超级用户只能将 shell 更改为 **/etc/shells** 中列出的标准 shell；从非标准 shell 更改或更改为非标准 shell 均会拒绝。编辑器由 `EDITOR` 环境变量决定，默认使用 vi(1)。信息验证后，chpass 会自动调用 pwd\_mkdb(8) 更新用户数据库。

编辑 **\~/.zshrc** 文件，添加下面几行：

```sh
source /usr/local/share/zsh-autosuggestions/zsh-autosuggestions.zsh   # 加载 Zsh 自动建议插件
source /usr/local/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh   # 加载 Zsh 语法高亮插件
fpath+=/usr/local/share/zsh/site-functions/   # 将自定义函数目录添加到 Zsh 函数搜索路径
```

目录结构：

```sh
~/
└── .zshrc # Zsh 配置文件
/usr/local/
└── share/
    ├── zsh-autosuggestions/
    │   └── zsh-autosuggestions.zsh # Zsh 自动建议插件
    ├── zsh-syntax-highlighting/
    │   └── zsh-syntax-highlighting.zsh # Zsh 语法高亮插件
    └── zsh/
        └── site-functions/ # Zsh 自定义函数目录
```

立即使用：

```sh
# zsh                        # 切换当前 shell 到 Zsh
# source ~/.zshrc            # 重新加载 Zsh 配置文件，刷新环境变量
# rm -f ~/.zcompdump         # 删除 Zsh 补全缓存文件
# autoload -Uz compinit       # 加载 compinit 函数
# compinit                   # 初始化补全系统并强制重建缓存
```

### 使用主题美化

除了基本配置外，还可以通过主题美化 shell 界面。Powerlevel10k 是广泛使用的 Zsh 主题，安装和配置方法如下：

```sh
$ git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k   # 克隆 Powerlevel10k 主题仓库到主目录
$ echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc                    # 将 Powerlevel10k 主题加载命令追加到 ~/.zshrc
```

目录结构：

```sh
~/
├── .zshrc # Zsh 配置文件
└── powerlevel10k/ # Powerlevel10k 主题目录
    └── powerlevel10k.zsh-theme # Powerlevel10k 主题文件
```

重新加载 Zsh 配置文件，使 Powerlevel10k 主题生效：

```sh
# source ~/.zshrc
```

按照提示回答若干问题以完成配置，重启后生效。

### 参考文献

* romkatv. Powerlevel10k\[EB/OL]. \[2026-03-26]. <https://github.com/romkatv/powerlevel10k?tab=readme-ov-file#installation>. 主题项目官网。
* FreeBSD Project. csh -- a shell with C-like syntax\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=csh&sektion=1>. C 风格语法 shell 手册页。

## Bash

Bash（Bourne Again shell）是 GNU 项目开发的 shell 程序，作为 Bourne shell（sh）的增强替代品。Bash 兼容 sh 语法，并集成了 csh 和 ksh 的有用特性，包括命令行编辑、命令历史、可编程补全和作业控制等功能。Bash 是多数 Linux 发行版的默认 shell，但在 FreeBSD 中并非基本系统组件。

### 安装 Bash

* 使用 pkg 安装：

```sh
# pkg install bash bash-completion-freebsd bash-completion-zfs
```

* 使用 Ports 安装：

```sh
# cd /usr/ports/shells/bash/ && make install clean
# cd /usr/ports/shells/bash-completion-freebsd/ && make install clean
# cd /usr/ports/shells/bash-completion-zfs/ && make install clean
```

软件包说明：

| 程序                        | 说明                               |
| ------------------------- | -------------------------------- |
| `bash`                    | Bash shell 主程序                   |
| `bash-completion-freebsd` | 针对 FreeBSD 的 Bash 补全库扩展，作为依赖自动安装 |
| `bash-completion-zfs`     | 针对 OpenZFS 的 Bash 补全库扩展          |

* 查看安装后配置

```sh
# pkg info -D bash-completion # 查看作为依赖安装的 bash-completion 的配置说明
```

### 配置 Bash

安装完 Bash 及相关补全库后，需要配置才能正常运作。

```sh
chsh -s /usr/local/bin/bash   # 将当前用户的默认登录 Shell 切换为 Bash
touch ~/.bash_profile         # 创建 ~/.bash_profile 文件，用于配置 Bash 环境变量
```

相关文件结构：

```sh
~/
└── .bash_profile # Bash 配置文件
/usr/local/
└── share/
    └── bash-completion/
        ├── bash_completion.sh # Bash 补全脚本
        └── README.md # Bash 补全说明文档
```

为加载 Bash 补全功能，编辑 **\~/.bash\_profile** 文件，写入下行：

```bash
[[ $PS1 && -f /usr/local/share/bash-completion/bash_completion.sh ]] && source /usr/local/share/bash-completion/bash_completion.sh
```

立即使用：

```bash
# bash                     # 切换当前 shell 到 Bash
# source ~/.bash_profile    # 重新加载 Bash 配置文件，刷新环境变量
```


# 7.4 命令行基础

命令行界面（Command Line Interface, CLI）是类 UNIX 系统的主要交互方式，提供了直接操作系统的方法。

## 我是谁？

* 查看当前登录系统的用户名：

```sh
$ whoami
ykla
```

> **技巧**
>
> `whoami` 已由 id(1) 替代，等价于 `id -un`。

* 查看当前登录用户所属用户组的信息。

```sh
$ id
uid=1001(ykla) gid=1001(ykla) groups=1001(ykla),0(wheel)
```

* 查看当前用户登录的终端及本次登录时间。

```sh
$ who
root             pts/0        Mar 19 15:00 (3413e8b6b43f)
```

BSD who 与 GNU/Linux 的 `who` 差异较大；FreeBSD 的 `who` 不支持 Linux 的 `-d`（死进程）、`-p`（init 活动进程）、`--lookup`、`--ips` 等选项。

## 我从哪里来？

展示当前有哪些用户已登录，以及他们正在做什么：

```sh
$ w
 3:02PM  up 21:52, 1 user, load averages: 0.01, 0.01, 0.00
USER       TTY      FROM           LOGIN@  IDLE WHAT
root       pts/0    3413e8b6b43f   3:00PM     - w
```

BSD `w` 与 GNU/Linux 的 `w` 差异较大；FreeBSD 的 `w` 不支持 Linux `w` 的 `-f` 、`-s` 、`-u` 等选项。

## 我在哪？

* 查看当前所在路径。

`pwd` 即 `print working directory`，用于打印当前工作目录。

```sh
$ pwd
/usr/ports/editors/vscode
```

BSD `pwd` 与 POSIX 标准兼容；与 GNU/Linux 的 `pwd` 基本兼容。

## 我究竟是谁？

账户切换与退出登录：

```sh
root@ykla:/ # su ykla ①
ykla@ykla:/ $ ②
ykla@ykla:/ $ su ③
Password: ④
root@ykla:/ #
root@ykla:/ # exit ⑤
ykla@ykla:/ $ exit ⑥
root@ykla:/ # exit ⑦

FreeBSD/amd64 (ykla) (ttyv0)

login:
```

账户切换与退出流程如下图所示：

![账户切换与退出流程](/files/Qh7GQgdMmbd4rGrFxLef)

* ① 使用 `su空格用户名` 可以切换到用户 ykla。如果从 root 切换到 ykla，则不需要输入 ykla 的密码：
  * `root@ykla:/`：
  * `root`：当前用户是 root
  * `@`：“谁”在“xx”主机上
  * `ykla`：此处是主机名，与用户 ykla 无关。主机名可自行设定
  * `:/`：代表当前位于 `/` 路径下
* ② 注意提示符号的变化：root 是 `#`，普通用户是 `$`（csh 是 `%`）
* ③ 如果仅输入 `su` 并回车，命令的含义是从当前用户切换到 root 账户（如果已经是 root，则不会有任何变化）。非 wheel 组成员不能直接 `su` 到 root，否则系统将返回 `sorry` 错误提示，但可以 `su` 到其他用户。
* ④ 从普通用户切换到 root，需要 root 账户的登录密码。
* ⑤ 输入 `exit` 可退出当前用户，如果是唯一登录的用户，将退出登录到 TTY。

> **思考题**
>
> ⑥、⑦ 分别切换到了哪些用户或执行了哪些操作？

`su` 命令切换到目标用户在 **/etc/passwd** 中定义的登录 shell。注意：使用 `su -m` 时，如果目标用户的 shell 不在 **/etc/shells** 中且调用者非 root，则 `su` 会失败。`chsh` 命令则只能将 shell 更改为 **/etc/shells** 中列出的标准 shell。`su -` 或 `su -l` 不仅切换用户，还会将工作目录切换到目标用户的主目录，并重置环境变量。

BSD 与 GNU `su` 行为比较：

| 项目     | FreeBSD `su` 行为         | Linux `su` 行为   |
| ------ | ----------------------- | --------------- |
| `-c`   | 指定 login class（登录类）     | 执行指定命令（command） |
| `-s`   | 设置 MAC label（强制访问控制标签）  | 指定登录 shell      |
| 执行命令方式 | 将命令作为参数传递给目标用户 shell 执行 | 使用 `-c` 直接执行命令  |

## 我要去哪里？

`cd` 命令，即“change the working directory”，切换当前工作目录。

```sh
ykla@ykla:~ $ pwd
/home/ykla
ykla@ykla:~ $ cd .
ykla@ykla:~ $ pwd
/home/ykla
ykla@ykla:~ $ cd ..
ykla@ykla:/home $ pwd
/home
ykla@ykla:/home $ cd ..
ykla@ykla:/ $ pwd
/
ykla@ykla:/ $ cd /home/ykla
ykla@ykla:~ $ cd ../..
ykla@ykla:/ $ pwd
/
```

根据上面的输出，请读者思考：上面的 `.` 和 `..` 分别代表什么？

> **技巧**
>
> 在 FreeBSD 的 sh(1) 中，`cd` 的行为由 POSIX 标准规定。

## 命令行格式

大多数命令行命令的名称都具有明确含义，例如 `ls` 即 `list`（列出）、`wget` 即通过 web（网络）来 `get`（下载）；也存在少量难以从名称推断功能的命令，例如 `thefuck` 命令（用于自动纠正拼写错误）。

命令行的基本语法结构遵循 POSIX Shell Command Language 规范（[IEEE Std 1003.1](https://pubs.opengroup.org/onlinepubs/9799919799/)）。其一般格式如下：

```sh
# 命令 选项  参数 1       参数 2
# ls   -l   /home/ykla /tmp
/home/ykla:
total 317
  ……有所省略……
drwxr-xr-x  2 ykla ykla        2 Mar  9 20:45 下载
drwxr-xr-x  2 ykla ykla        2 Mar  9 20:45 桌面

/tmp:
total 6
drwxrwxrwt  2 root    wheel  3 Mar 18 17:23 .ICE-unix
-r--r--r--  1 root    wheel 11 Mar 18 17:10 .X0-lock
```

其中，`ls`（L 小写）意味着列出当前目录或指定目录下的文件；选项 `-l`（L 小写）意味着打印详细信息，输出长（*long*）格式。多个短选项可合并书写，如 `-a -l` 等价于 `-al`。

选项用于修改命令的行为；参数（argument）是命令操作的对象。

> **技巧**
>
> 命令执行后返回退出状态码（exit status）：0 表示成功，非 0 表示失败。

需要注意中英文书写习惯的差异：中文行文不使用空格分隔，而英文单词必须使用空格加以区分。正因如此，命令行中各个组成部分之间应使用空格分隔 。空格的数量一般不受限制，但最少应该为一个，即 。

> **思考题**
>
> 如果不使用空格或某种方式（例如其他符号）分隔命令行，那么软件该如何理解整个句子？
>
> 如果不加空格，从自然语言角度，从人类视角看这句话 `Whatwelovedeclarespubliclywhoexactlyweare.` 会是怎样的体验？
>
> 再看：`ls-l/home/ykla/tmp`、`ls/` 呢？
>
> ```sh
> # ls-l/home/ykla/tmp
> -sh: ls-l/home/ykla/tmp: not found
> # ls/
> -sh: ls/: not found
> ```
>
> 可以看到，shell 会将整个字符串当作一个可执行命令来解析和执行。

还需要注意，命令行本身不具备自动纠错功能，即使仅拼错一个字母或少输入一个字符，命令也无法正确执行。

```sh
# LS # 测试全大写命令名
-sh: LS: not found
# Ls # 测试混合大小写
-sh: Ls: not found
# ls /hom1 # 实际路径应为 /home
ls: /hom1: No such file or directory
# ls -z /home # 不存在选项 -z
ls: invalid option -- z
usage: ls [-ABCFGHILPRSTUWZabcdfghiklmnopqrstuvwxy1,] [--color=when] [-D format] [--group-directories=] [file ...]
```

> **技巧**
>
> Windows 不仅对文件名大小写不敏感，对命令名称的大小写也不敏感。
>
> ```powershell
> PS C:\Users\ykla> cd C:\ # 这里 cd 是小写
> PS C:\> CD D:\ # 这里 CD 是大写
> PS D:\> CD c:\ # 这里 C 盘是小写
> PS C:\> dir # 小写 dir，列出目录，等于 ls
>
>    目录：C:\
>
> ……省略一部分……
>
> PS C:\Users\ykla> TREE # 大写 tree，显示路径关系
> 文件夹 PATH 列表
> 卷序列号为 2A90-E989
> C:.
> ├─.android
> ├─.cache
> │ ├─selenium
> ……省略一部分……
> ```

> **技巧**
>
> 命令前面的 `#` 表示什么意思？`#` 在 shell 当中通常是起注释作用（由 [POSIX.1-2024](https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V3_chap02.html) 规定），相当于 C 语言中的 `//`。意味着后边的文字只起到说明作用，不起实际作用。

## 命令的执行与中断

与 Windows 及图形化界面软件不同，绝大多数命令行程序在执行过程中不会显示进度提示。通常只有以下两种结果：

* 成功执行：

```sh
# cp test /root/mydir/


```

* 执行中断：

```sh
# cp test9 /root/mydir/
cp: test9: No such file or directory
```

执行中断有很多可能的情形，以上只是其中一种（指定的文件或目录不存在）。

可以看到，只有在执行中断时，命令行才会有提示；如果执行完毕，则不会产生任何提示。这种 UNIX 设计哲学旨在保证终端输出的简洁性。

## shell 命令的来源

### Linux

在 Linux 中，大多数常用命令来自 GNU 等用户空间软件包，Linux 内核本身并不提供用户级命令。以下为验证过程：

```bash
$ dpkg -S /bin/mv
coreutils: /bin/mv
$ dpkg -S /bin/cp
coreutils: /bin/cp
$ dpkg -S /bin/ls
coreutils: /bin/ls
$ dpkg -S /bin/pwd
coreutils: /bin/pwd
$ dpkg -S /bin/cat
coreutils: /bin/cat
$ dpkg -S /usr/sbin/chroot
coreutils: /usr/sbin/chroot
$ dpkg -S /bin/kill
procps: /bin/kill
$ dpkg -S /usr/bin/free
procps: /usr/bin/free
$ dpkg -S /bin/su
util-linux: /bin/su
```

可见在 Linux 中，这些常见命令一般出自 GNU 软件 coreutils、util-linux 或 procps。这些软件在历史上是 GNU 计划对 UNIX 软件的再实现。

同时，shell 本身也内置了一些命令：

```bash
$ type cd
cd 是 shell 内建
```

列出所有 shell 内置命令：

```bash
$ compgen -b
.
:
[
alias
bg
bind
break
builtin
caller
cd
command
compgen
……省略一部分……
ulimit
umask
unalias
unset
wait
```

### FreeBSD

```sh
$ type cd
cd is a shell builtin
```

在 FreeBSD 中，除了上述 shell 内置命令外（参见：sh(1)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=sh&sektion=1>），常用命令都是基本系统自带的，不属于任何包。例如 `ls` 命令，其源代码位于 `freebsd-src/bin/ls/`\[EB/OL]. \[2026-03-26]. <https://github.com/freebsd/freebsd-src/tree/main/bin/ls>。可见 FreeBSD 系统是有机整体，而非由不同人员或团队维护的软件包简单拼接而成。

如果配置了 PkgBase，则输出类似：

```sh
# pkg which /bin/ls # 查询 /bin/ls 所属的软件包
/bin/ls was installed by package FreeBSD-runtime-15.snap20250313173555
```

如果缺少某个命令，一般可以通过安装相应的软件包来获取，例如 `lspci` 命令，来自软件包 `sysutils/pciutils`。然而也有许多命令存在 Linux 专有性问题，不兼容其他操作系统，例如 `ip` 命令，来自软件包 iproute2。

## 常用命令

### `cd` 命令

`cd`（change working directory，更改工作目录）

切换到 **/home**：

```sh
$ cd /home # 切换到 /home
$ pwd # 查看当前路径
/home
```

### `ls` 命令

`ls`（list，列出）命令的基本用法前文已经介绍，下面演示如何让 `ls` 以人类易读的方式显示文件大小：

选项 `-h`，即 `human`（人类），需要与 `-l`（`long` 长输出）结合使用。

```sh
# ls -hl /home/ykla
total 326 KB
-rw-------  1 ykla ykla   50B Mar 18 17:23 .Xauthority
drwx------  6 ykla ykla    6B Mar 10 16:21 .cache
drwx------  9 ykla ykla   12B Mar 19 15:01 .config
-rw-r--r--  1 ykla ykla  1.0K Feb 24 12:18 .shrc
drwxr-xr-x  2 ykla ykla    2B Mar  9 23:48 .themes
-rw-r--r--  1 root ykla    0B Mar 19 15:13 abc.TXT
drwxr-xr-x  3 root ykla    7B Mar 19 15:17 vscode
-rw-------  1 ykla ykla   17M Mar 18 17:09 xrdp-chansrv.core
drwxr-xr-x  2 ykla ykla    2B Mar  9 20:45 下载
……省略一部分……
```

在 UNIX 系统中，以 `.` 开头的文件或目录（如上面的 `.Xauthority`）都是隐藏的。Android 手机同样如此——可以通过 [MT 文件管理器](https://mt2.cn/) 自行查看。

选项 `-a` 可用于显示隐藏的目录和文件：

```sh
$ ls -a
.		.cshrc		.login		.profile	公共		视频
..		.dbus		.login_conf	.sh_history	图片		音乐
.Xauthority	.face		.mail_aliases	.shrc		文档
.cache		.icons		.mailrc		.themes		桌面
.config		.local		.mozilla	下载		模板
```

如果不加选项 `-a`：

```sh
ykla@ykla:~ $ ls
下载	公共	图片	文档	桌面	模板	视频	音乐
```

则不会显示隐藏文件。

### `touch` 创建文件命令

`touch` 的字面含义为“触碰”，表示轻微变动文件时间戳。

FreeBSD 的 `touch` 与 POSIX 标准兼容，最早出现于 Version 7 AT\&T UNIX。

创建一个文件，命名为 `test`：

```sh
$ touch test
```

> **技巧**
>
> 可以看到上述命令创建的是 `test`，而非 `test.txt`、`test.word`、`test.pdf` 之类的。事实上，`.txt` 这一部分称为文件后缀名，主要用于提示用户文件类型，而非供系统识别。许多我们以为清楚明白的事物，真的如我们所认为的那般吗？
>
> 即使去掉相应的后缀名，在类 UNIX 系统中也可以识别文件的类型，这是根据文件幻数（magic numbers）确定的：
>
> ```sh
> $ file book
> book: PDF document, version 1.7
> ```

`file` 命令通过三组测试依次判定文件类型：文件系统测试（基于 stat(2)）、幻数测试（基于 **/usr/share/misc/magic.mgc** 中的固定格式标识）和语言测试（基于文本模式匹配）。其中“幻数”（magic number）概念源于 UNIX 可执行文件格式，文件头部特定偏移量处存储的固定标识用于指示文件类型。

可以一次性使用多个参数创建多个文件（类似用法几乎是通用的，不再赘述）：

```sh
$ touch test test1 test2 test3
```

### `mkdir` 创建目录

`mkdir` 即 `make directories`，创建目录

创建一个目录，命名为 ykla。

```sh
$ mkdir -v ykla # -v 选项用于显示文件变动详情，是 verbose 的缩写，意为输出详细信息
ykla
```

如果文件已存在：

```sh
$ mkdir ykla
mkdir: ykla: File exists # 提示该目录已存在。
```

***

如果要创建目录 `ykla/ykla1/ykla2/ykla3`，该如何操作？

```sh
$ mkdir ykla/ykla1/ykla2/ykla3
mkdir: ykla/ykla1/ykla2: No such file or directory
```

系统返回上述错误，此时需要参数 `-p`，`p` 是英文 `parents`（父）的意思，即如果上级目录不存在，就一并创建。

```sh
$ mkdir -vp  ykla/ykla1/ykla2/ykla3
ykla/ykla1
ykla/ykla1/ykla2
ykla/ykla1/ykla2/ykla3
```

FreeBSD 的 `mkdir` 与 GNU/Linux 的 `mkdir` 基本兼容。

### `rm` 删除命令

> **警告**
>
> FreeBSD 命令行界面是没有回收站的，所有命令一经执行不可撤销。命令行操作 `rm` 具有较高风险。

`rm` 即英文 `remove` 的缩写，意为删除。

***

删除文件 `test`

```sh
$ rm test
```

如果不存在文件 `test`：

```sh
$ rm test
rm: test: No such file or directory # 报错指定的文件或目录不存在
```

***

删除路径 **/home/ykla/test**

* 如果目录为空（不含任何文件，只是空目录）

```sh
$ rm /home/ykla/test
$
```

还可使用命令 `rmdir`（remove directory，即删除目录，且只能删除空目录）：

```sh
$ rmdir /home/ykla/test
$
```

* 如果目录不为空

```sh
$ rm /home/ykla/test/
rm: /home/ykla/test/: is a directory # 提示 /home/ykla/test/ 为目录
```

使用参数 `-r`（recursively）递归，参数 `-f`（force）强制删除：

> **技巧**
>
> 什么是递归？
>
> “从前有座山，山上有座庙，庙里有个老和尚在给小和尚讲故事。老和尚说：‘从前有座山，山上有座庙……’”这就是递归的实例。
>
> 在该操作中，其含义是先进入 **/home/ykla/test/** 下最深层的子目录（如存在），删除其中的文件和子目录本身，随后向上逐层重复该过程。直至删除 **/home/ykla/test/**。即使用深度优先搜索算法（Depth-First Search，DFS）。

```sh
$ rm -rf /home/ykla/test/
```

> **警告**
>
> 使用 `rm -rf` 是相当危险的操作，是不可撤销的。如果命令中误输入空格，如将 **/home/ykla/test/** 误输为 **/home/ykla /test/**，会导致删除路径错误：
>
> ```sh
> # rm -rf /home/ykla /test
> # ls /home/ykla
> ls: /home/ykla: No such file or directory # 表明 ykla 目录已不存在
> ```

> **警告**
>
> 互联网上常有说法称使用 `sudo rm -rf /*` 是某种可以执行特定操作的命令，误导他人对系统造成不可挽回的灾难性破坏。该命令实质上是以 root 权限（~~还好 FreeBSD 默认没有 sudo~~），删除 **/** 及其子目录下的一切存在。现在展示一下结果：
>
> ```sh
> # rm -rf /*
> rm: /boot/efi: Device busy
> rm: /boot: Directory not empty
> rm: /dev/reroot: Operation not supported
> rm: /dev/input: Operation not supported
> rm: /dev/fd: Operation not supported
> ……省略一部分……
> #
> ```
>
> <img src="/files/5zQUROY3rvn96zHbfg4r" alt="引导错误" data-size="original">
>
> 重启后即可发现引导项丢失。
>
> > **思考题**
> >
> > 你是否对上面“root 是 UNIX 中的最高权限”这句话有了更深刻的体会？这是否说明了权力和责任的一致性？如果滥用权力，不仅会伤害他人，最后也会导致自己失去存在的现实性。

### `mv` 移动/重命名命令

`mv` 即英文 `move` 的缩写，意为移动。

***

将文件 `test` 移动到 **/home/ykla**：

```sh
$ mv -v test /home/ykla # -v 选项用于显示文件变动详情，是 verbose 的缩写，意为输出详细信息
test -> /home/ykla/test
```

将目录及子目录移动到 **/home/ykla**

***

* 重命名

将 `test5.pdf` 重命名为 `test5.txt`

```sh
$ mv -v  test5.pdf test5.txt
test5.pdf -> test5.txt
```

将 `test2` 重命名为 `test2.pdf`

```sh
$ mv -v test2 test2.pdf
test2 -> test2.pdf
```

### `cp` 复制命令

`cp` 即英文 `copy` 的缩写，意为复制。

***

将文件 `test` 复制到 **/home/ykla**

```sh
$ cp test /home/ykla/
```

如果缺少末尾的 **/**，且子目录 ykla 不存在，`test` 将被重命名为 `ykla`（ykla 本应为一个目录），因此末尾的 **/** 不可省略：

```sh
$ cp test /home/ykla/
cp: directory /home/ykla does not exist # 如果加上 /，会提示目录不存在
```

如果缺少末尾的 **/**：

```sh
$ cp -v test /home/ykla # -v 选项用于显示文件变动详情，是 verbose 的缩写，意为输出详细信息
test -> /home/ykla
```

> **思考题**
>
> 其他命令有没有类似的问题？请试一试。

***

在复制文件的同时修改其文件名及后缀：

```sh
$ cp -v test /home/ykla/abc.TXT
test -> /home/ykla/abc.TXT
```

该命令通常用于备份配置文件。

***

复制目录及子目录：

```sh
$ cp -v /usr/ports/editors/vscode /home/ykla
cp: /usr/ports/editors/vscode is a directory (not copied).
```

直接复制不可行，系统提示目标为目录而非文件。

因此还需要选项 `-r`。`r` 是英文 `recursively`（递归）的意思：

```sh
$ cp -vr /usr/ports/editors/vscode /home/ykla
/usr/ports/editors/vscode -> /home/ykla/vscode
/usr/ports/editors/vscode/distinfo -> /home/ykla/vscode/distinfo
……省略一部分……
```

### 通配符 `*`

有时操作需要全选，可以使用通配符 `*`。

* 删除所有文件名以 `test` 开头的文件：

```sh
$ rm test*
rm: test: is a directory
rm: test4: is a directory
```

可见：目录不会被处理。

* 删除所有文件名以 `test` 开头的文件和 **目录**：

```sh
$ ls test*  # 确认匹配的文件
$ rm -rf test*
```

* 删除所有文件和 **目录**：

```sh
$ ls *  # 确认匹配的文件
$ rm -rf *
```

### 逻辑运算符 `&&`

`&&`（逻辑与，AND）：只有 `&&` 之前的命令执行成功，才会执行后续的命令；如果 `&&` 之前的命令执行失败，后续命令就不会执行。

其语义为：仅当前一条命令执行成功（返回退出状态码 0）时，才执行后一条命令；否则跳过后续命令。

使用场景：执行一连串有依赖关系的命令。例如必须先刷新软件源才能更新系统，随后才能重启。以 Ubuntu 为例：`sudo apt update -y && sudo apt upgrade -y && sudo reboot`。只有前面的命令执行成功，才会执行后面的命令。

### 逻辑运算符 `||`

`||`（逻辑或，OR）：只有 `||` 之前的命令执行失败时，后续命令才会执行；如果 `||` 之前的命令执行成功，后续命令就不会执行。

其语义为：仅当前一条命令执行失败（返回非零退出状态码）时，才执行后一条命令；否则跳过后续命令。

使用场景：如果一条命令一直执行失败，但需要反复执行，则可连续使用多个 `||`，防止一次失败后反复手动再次执行该命令，例如：

```sh
make BATCH=yes install || make BATCH=yes install || make BATCH=yes install || make BATCH=yes install
```

当一次 `make BATCH=yes install` 失败后，仍然会执行下一个 `make BATCH=yes install`。即之前的命令执行失败，转而执行后面的命令。

> **技巧**
>
> `&&` 和 `||` 的优先级相同，且按从左到右的顺序进行求值。

> **思考题**
>
> `touch a.txt && touch b.txt || touch c.txt || reboot` 是什么意思？
>
> 如果 `touch a.txt` 失败会执行后面的哪个操作？

### dc（Desk Calculator）桌面计算器

FreeBSD 自 13 版起采用 Gavin D. Howard 开发的 bc/dc 实现，该实现将 `bc` 和 `dc` 集成在同一二进制文件中，`dc` 通过符号链接访问，不再沿用传统的预处理器架构。

#### 后缀表示法（逆波兰表示法，Reverse Polish Notation，RPN）

理解后缀表示法是使用 dc 计算器的基础。

从接触数学伊始，常用的计算表达方式就是中缀表示法。例如，要计算 3 和 4 的和，写作 `3 + 4`，操作符处于操作数的中间，这是人类最习惯的数学表达式书写方式。

后缀表示法中，操作符置于操作数之后。如上式如果改用后缀表示法，则写作 `3 4 +`。如果有多个操作符，操作符置于第二个操作数的后面，常规中缀表示法的 `3 - 4 + 5` 在后缀表示法里写作 `3 4 - 5 +`。

后缀表示法更易为计算机处理，并可利用栈结构减少内存访问，在编译程序设计与计算器实现中广泛采用。

例如，中缀表达式 `5 + ((1 + 2) * 4) - 3` 改用后缀表示法为 `5 1 2 + 4 * + 3 -`。

上述示例可使用 `dc` 计算，在终端输入以下命令：

```sh
$ dc -e '5 1 2 + 4 * + 3 - p'
```

使用 dc 计算表达式 `5 + ((1 + 2) * 4) - 3`，并输出计算结果。

计算结果为 `14`。

## 重定向输入输出

UNIX shell 还能使用户执行命令、重定向其输出、重定向其输入，并将多个命令组合在一起以优化最终输出。

shell 重定向是将命令的输出或输入发送到另一条命令或文件中的操作。例如，将 ls(1) 命令的输出捕获到一份文件中，可以这样重定向输出：

```sh
$ ls -l > test.txt
```

查看 `test.txt` 文件内容：

```sh
total 1
drw-------  2 ykla ykla 2 Apr 28 00:24 test
-rw-r--r--  1 ykla ykla 0 Apr 28 00:43 test.txt

```

此时会先清空 `test.txt` 文件原有内容（如文件存在），随后执行命令 `ls` 将列出的目录内容直接保存到 `test.txt` 文件中。

> **技巧**
>
> 有些命令可以读取输入，例如 sort(1)。要排序该列表，可以这样重定向输入：

```sh
$ sort < test.txt
-rw-r--r--  1 ykla ykla 0 Apr 28 00:43 test.txt
drw-------  2 ykla ykla 2 Apr 28 00:24 test
total 1
```

排序后的输入将显示在屏幕上。要将该输入重定向到另一份文件，可以将 sort(1) 的输出重定向出去，操作如下：

```sh
$ sort < test.txt > sorted.txt
$ cat sorted.txt
-rw-r--r--  1 ykla ykla 0 Apr 28 00:43 test.txt
drw-------  2 ykla ykla 2 Apr 28 00:24 test
total 1
```

在上述所有示例中，命令通过文件描述符进行重定向。每个 UNIX® 系统都有文件描述符，包括标准输入（stdin）、标准输出（stdout）和标准错误（stderr）。每种描述符都有其用途，例如输入可以是键盘或鼠标，用于提供输入；输出可以是屏幕或打印机中的纸张；标准错误则用于输出诊断或错误信息。这三者均视为基于 I/O 的文件描述符，有时也称流（streams）。

通过使用这些描述符，shell 允许将输出和输入在多个命令之间传递，并重定向到文件或从文件中读取。另一种重定向方法是管道操作符。

UNIX® 的管道操作符 `|` 允许将一条命令的输出直接传递或重定向到另一款程序。简单来说，管道允许一条命令的标准输出作为标准输入传递给另一条命令，例如：

```sh
$ cat test.txt | sort | less
-rw-r--r--  1 ykla ykla 0 Apr 28 00:43 test.txt
drw-------  2 ykla ykla 2 Apr 28 00:24 test
total 1
```

在此示例中，`test.txt` 的内容将被排序，随后输出传递给 less(1)。这使用户可以按自己的节奏浏览输出内容，防止其在屏幕上滚动消失。

## 关机与重启

关机：

正确的关机并断电命令是 `poweroff`，等同于命令 `shutdown -p now`。

重启：

推荐使用 `shutdown -r now` 进行重启。

> **注意**
>
> 在 FreeBSD 下，`shutdown` 可由 root 用户和 operator 组成员执行，但 `reboot` 和 `halt` 仅限 root 用户。执行 shutdown 时会向所有已登录用户广播警告信息，并在指定时间前 5 分钟创建 **/var/run/nologin** 以阻止新登录（若关机时间不足 5 分钟则立即创建）。

> **技巧**
>
> 关于 `reboot`、`halt`、`poweroff` 在 FreeBSD 与 Linux 中的行为差异，以及关机时 **/etc/rc.shutdown** 脚本的执行流程，详见其他相关章节。

## 参考文献

* FreeBSD Project. make -- maintain program dependencies\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=make&sektion=1>. BSD make 手册页，描述构建工具语法与用法。
* FreeBSD Project. grep -- file pattern searcher\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=grep&sektion=1>. 文本搜索工具手册页。
* FreeBSD Project. sed -- stream editor\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=sed&sektion=1>. 流编辑器手册页。

## 课后习题

1. 对比 BSD 风格的 sed/awk/grep 与 GNU 版本在常用选项上的差异，编写兼容性对照表，并给出在 FreeBSD 上实现跨平台脚本的策略。
2. 查阅 FreeBSD 中 `ls` 命令的源代码实现（`bin/ls/`），与 GNU coreutils 中的 `ls` 在选项解析和输出格式方面的实现进行比较。
3. 编写一个 shell 脚本，使用管道将多个 FreeBSD 基本命令（如 `ls`、`grep`、`sort`、`awk`）组合，实现一个实用的系统信息汇总功能。


# 7.5 文本编辑器

文本编辑器是类 UNIX 系统中用于创建、查看、修改纯文本文件的工具。无论是编辑 **/etc/rc.conf** 文件、编写脚本还是查看日志，均需使用文本编辑器。

按编辑范式，文本编辑器可分为两大类：**模态编辑器**（modal editor）和 **无模态编辑器**（modeless editor）。

模态编辑器的典型代表是 vi/Vim，其核心特征是将编辑操作划分为多个模式（如普通模式、插入模式、命令模式等），在不同模式下按键的含义不同，例如在普通模式下按 `i` 进入插入模式，而在插入模式下按 `i` 则输入字符 `i`。

无模态编辑器的典型代表是 ee 和 Emacs，其按键操作在所有状态下含义一致，通常直接输入字符即插入文本。模态编辑的设计源于 Bill Joy 于 1976 年开始开发的 ex 编辑器中的 visual mode（可视模式，1977—1978 年间逐步加入），该模式在 1979 年 ex 2.0 版本中独立为 vi 命令。其设计动机是通过模式切换，在 ADM-3A 终端的有限键盘上实现高效编辑，无需同时按下控制键即可执行编辑命令。

本节依次介绍 FreeBSD 中常见的几款文本编辑器，涵盖内置基础工具、经典编辑器至现代增强版本与图形化选择：

| 编辑器            | 获取途径  | 特点简述                               |
| -------------- | ----- | ---------------------------------- |
| ee             | 基本系统  | 极其简单，操作类似记事本，按 ESC 键进入菜单操作         |
| vi             | 基本系统  | 经典 modal（多模式）编辑器，BSD 原生 Nvi，轻量但命令多 |
| Vim            | Ports | vi 增强版，具有语法高亮、插件、宏等现代功能            |
| NeoVim         | Ports | Vim 重构现代版，Lua 配置、异步插件、LazyVim 发行版  |
| Emacs          | Ports | 高度可扩展，几乎是“操作系统”，Lisp 配置            |
| microsoft-edit | Ports | 微软开源，支持中文、鼠标操作、界面友好                |

CLI 编辑器无需图形界面，可在 SSH 远程连接、纯文本控制台中使用，资源占用低，适用于服务器环境和远程管理场景。GUI 编辑器提供可视化界面和鼠标支持，更适合桌面环境下的日常开发与文档编辑工作。

> **注意**
>
> 本节仅介绍 FreeBSD 上常见文本编辑器的基本用法，不涉及深入配置，有需要的读者请自行查阅相关资料。

## ee 编辑器

`ee` 是 FreeBSD 基本系统内置的编辑器，支持中文文本编辑。

`ee` 的用法比 [nano](https://www.redhat.com/zh/blog/getting-started-nano)（一种 GNU 编辑器）更为直接，从其名字“easy editor”（简单的编辑器）即可看出其设计目标。`ee` 始终处于文本插入模式，除非底部出现提示或菜单。

使用 ee 编辑器打开 `a.txt` 文件：

```sh
# ee a.txt
```

可以直接编辑，用法与 `nano` 或 Windows 记事本类似。

按 **ESC 键** 弹出菜单，可执行保存、退出等操作。再按两次 **回车键** 保存。

## vi 编辑器

FreeBSD 还内置了一款编辑器 `vi`。FreeBSD 的 `vi` 实际上是 nex/nvi，是 4BSD ex/vi 的重新实现，旨在与原始 4BSD ex/vi 保持严格的兼容性。

与大多数 Linux 发行版将 `vi` 链接到 `vim` 不同，BSD 系统提供的是原生 `nvi`，其用法较为复杂但功能强大。

`ex`、`vi`、`view` 是同一程序的不同接口，可在编辑会话中切换。`view` 等同于 `vi -R`（只读模式）。nvi 接近 POSIX 1003.2 标准中的 vi 编辑器规范。

### vi 基本使用方法

打开 `vi` 后默认处于 **命令模式**，此时输入 `i` 可以进入 **插入模式**（文本模式），从而进行文本编辑。注意：在插入模式下，**退格键** 可能不起作用（行为类似 Insert 键），需要使用 **Delete 键** 删除字符。

> **技巧**
>
> `view` 命令相当于使用 vi 的 -R（只读）选项。

空行会显示为 `~`。

编辑完成后，按 **ESC 键** 返回命令模式。

在命令模式下输入 `:` 进入底线命令模式，常用命令包括：

| 命令               | 说明               |
| ---------------- | ---------------- |
| `:q`             | 退出（如果文件有修改则失败）   |
| `:q!`            | 强制退出，不保存修改       |
| `:w`             | 保存文件             |
| `:wq` 或 `ZZ`     | 保存并退出            |
| `:wq!`           | 强制保存并退出          |
| `:/关键词` 或 `/关键词` | 搜索关键词（按 n 查找下一个） |

**示例**：

```vim
ABC
~
~
~
~
:wq
```

## Vim（增强版 vi）

Vim（vi IMproved）是 vi 的增强版本，提供了语法高亮、插件支持、多窗口等现代功能。Bram Moolenaar 于 1988 年开始开发 Vim，1991 年首次公开发布，基于 vi 的操作模型并大幅扩展了其功能。Vim 采用模态编辑（modal editing）设计：在普通模式下按键执行命令，在插入模式下输入文本，在可视模式下选择文本，在命令行模式下执行 Ex 命令。

FreeBSD Ports 中的 Vim 默认编译为 console 版本，如需 GUI 支持（gvim）需安装 Port **editors/vim** 的 GTK 或 Motif 变体；Vim 在处理超大文件时可能消耗大量内存。

### 安装 Vim

使用 pkg 安装：

```sh
# pkg install vim
```

或者使用 Ports 构建：

```sh
# cd /usr/ports/editors/vim
# make install clean
```

### 配置 Vim

安装后可使用 `vim` 命令替代 `vi`，配置更友好。基本配置放在 **\~/.vimrc** 文件中。

临时启用行号：

```vim
:set number          " 显示绝对行号（简写 :set nu）
:set relativenumber  " 显示相对行号（简写 :set rnu）
:set nonumber        " 关闭绝对行号
:set norelativenumber " 关闭相对行号
```

要永久启用行号，编辑用户配置文件 **\~/.vimrc**（如果不存在则创建）：

```vim
set number              " 或 set nu
" set relativenumber    " 可选：启用相对行号
```

## NeoVim（现代 vi 改进版）

NeoVim 是 Vim 的重构分支，更加模块化，支持 Lua 脚本，插件生态更活跃，性能更好。Thiago de Arruda 于 2014 年发起了 NeoVim，旨在解决 Vim 的技术债务并引入现代扩展机制。其核心改进包括：内置 LSP 客户端（Language Server Protocol，需配合第三方语言服务器使用）、基于 Lua 的配置与插件系统、异步 I/O 架构，以及通过 msgpack-rpc 提供的 GUI/编辑器集成接口。

### 安装 NeoVim

* 使用 pkg 安装：

```sh
# pkg install neovim
```

* 或者使用 Ports 构建：

```sh
# cd /usr/ports/editors/neovim
# make install clean
```

### NeoVim 基础配置

NeoVim 的配置文件位于 **\~/.config/nvim/init.lua**（推荐使用 Lua）。

临时启用行号的命令与 Vim 相同，如需永久启用，编辑 **\~/.config/nvim/init.lua** 文件（如果不存在则创建）：

```lua
vim.opt.number = true          -- 显示绝对行号
vim.opt.relativenumber = true  -- 显示相对行号（推荐与 number 一起用，形成混合模式）
```

### LazyVim 编辑器概述

LazyVim 是一种开箱即用的 NeoVim 配置发行版（distribution），基于 lazy.nvim 插件管理器，集成了代码补全、LSP、文件浏览器、Git 集成等 IDE 特性，非常适合需要快速获得强大编辑体验的用户。

#### 安装 LazyVim

推荐全新配置：

```sh
# 备份旧配置（如果存在）
$ mv ~/.config/nvim{,.bak} 2>/dev/null || true
$ mv ~/.local/share/nvim{,.bak} 2>/dev/null || true
$ mv ~/.local/state/nvim{,.bak} 2>/dev/null || true
$ mv ~/.cache/nvim{,.bak} 2>/dev/null || true

# 克隆 Starter 模板
$ git clone https://github.com/LazyVim/starter ~/.config/nvim

# 移除 git 历史
$ rm -rf ~/.config/nvim/.git

# 启动（首次会自动下载大量插件）
$ nvim
```

启动后按空格键可打开 LazyVim 的快捷键菜单，较为直观。

NeoVim 和 Vim 共享大部分命令，上述 `:q :q! :wq :wq! :/` 等在 LazyVim 中同样适用。

![NeoVim 主界面](/files/XWKas38wdIcLS8R8tKAg)

## Emacs 编辑器

Emacs 是历史悠久、功能极其强大的文本编辑器，以“可扩展性”闻名（几乎所有功能都可以通过 Emacs Lisp 扩展）。最初的 EMACS 由 David A. Moon 和 Guy L. Steele Jr. 于 1976 年在 MIT AI 实验室编写，是一组 TECO 编辑器的宏包。Steele Jr. 随后发起了统一各 TECO 宏包的项目，Richard Stallman 完成了关键性工作（包括加入重定义按键的宏机制），最终形成 EMACS 这一统一宏集（EMACS 最初作为“Editor MACroS”或“E with MACroS”的缩写），首个可运行的 EMACS 系统于 1976 年末投入使用。GNU Emacs 是 Stallman 于 1984 年开始开发、作为 GNU 项目核心组件之一发布的自由软件 Emacs 实现，1985 年 3 月 20 日发布首个公开版本（13 版），并以 Emacs Lisp 作为扩展语言。Emacs 的设计哲学是“编辑器即操作系统”——通过 Emacs Lisp 语言，Emacs 提供了文件管理器、邮件客户端、终端仿真器、调试器前端等超越文本编辑的功能。

### 安装 Emacs

使用 pkg 安装：

```sh
# pkg install emacs
```

或者使用 Ports 构建：

```sh
# cd /usr/ports/editors/emacs
# make install clean
```

### Emacs 基础配置

Emacs 的用户配置文件通常为 **\~/.emacs.d/init.el**。

编辑或创建 **\~/.emacs.d/init.el** 配置文件：

```elisp
;; Emacs 基础配置示例
(setq inhibit-startup-screen t)     ; 关闭启动画面
(menu-bar-mode -1)                  ; 禁用菜单栏
(tool-bar-mode -1)                  ; 禁用工具栏
(scroll-bar-mode -1)                ; 禁用滚动条
(global-display-line-numbers-mode 1); 显示行号
```

### 退出 Emacs

退出 Emacs 的常用方式是先按快捷键 Ctrl + x，再按快捷键 Ctrl + c。如果有未保存的修改，Emacs 会提示是否保存。

其他常用启动方式：

* `emacs filename.txt` — 直接打开文件
* `emacs -nw` — 在终端内不启动图形界面

Emacs 图形用户界面：

![Emacs GUI](/files/OyU1QJr6HrgSh0pU7EdB)

Emacs CLI:

![Emacs CLI](/files/ULeSEGQzrB0gM8ZvtPRF)

## microsoft-edit

microsoft-edit 是微软开源的文本编辑器，原生支持中文，交互界面简单，并支持鼠标操作。该编辑器用 Rust 编写，设计目标为提供一个轻量级、现代化的终端文本编辑器，支持语法高亮和 UTF-8 编码。

### 安装 microsoft-edit

* 使用 pkg 安装：

```sh
# pkg install microsoft-edit
```

* 还可以使用 Ports 安装：

```sh
# cd /usr/ports/editors/microsoft-edit/
# make install clean
```

### 使用 microsoft-edit

使用 msedit 编辑器打开 `abc.txt` 文件：

```sh
$ msedit abc.txt
```

![microsoft-edit 主界面](/files/HGd3TUHQMimAituzYVsx)

![microsoft-edit 界面](/files/rPegh8wzcyT5U6B0y8YB)

操作直观，本节不再展开说明。

## 编辑器配置文件结构

以下是本节介绍的编辑器配置文件路径总结：

```sh
~/.vimrc  # Vim 配置文件
~/.config/
└── nvim/
    └── init.lua  # NeoVim 配置文件
~/.emacs.d/
└── init.el  # Emacs 配置文件
```

## 课后习题

1. 使 vi 支持 UTF-8 编码与中文字体。
2. 查看 FreeBSD 中 Nvi 编辑器的源代码，比较其与早期 UNIX vi 的差异。
3. 修改 FreeBSD 中 vi 编辑器的默认配置为 ee。


# 7.6 压缩和解压缩

压缩和解压工具是计算机文件管理中的基础工具。数据压缩利用信息的统计冗余性，通过编码算法减少数据表示所需的存储空间。根据是否允许信息丢失，压缩算法可分为无损压缩（lossless compression）和有损压缩（lossy compression）两大类。本节所涉及的工具均采用无损压缩算法，即解压后的数据与原始数据完全一致。

常见的无损压缩算法及其特征如下：

| 算法         | 所用格式     | 技术基础                         | 特点         |
| ---------- | -------- | ---------------------------- | ---------- |
| DEFLATE    | zip/gzip | LZ77 + Huffman 编码            | 经典通用       |
| LZMA/LZMA2 | xz       | LZMA 链式压缩                    | 高压缩率       |
| LZ4        | lz4      | 字节级 LZ77                     | 极高速度       |
| Zstandard  | zstd     | 有限状态熵 + LZ77                 | 兼顾速度与压缩率   |
| bzip2      | bz2      | Burrows-Wheeler 变换 + Huffman | 较高压缩率，速度较慢 |

## zip

zip 格式是 PKZIP 归档格式的实现，其规范由 PKWARE 维护（APPNOTE.TXT），Info-ZIP 项目提供了开源的 zip/unzip 工具实现。zip 是一款压缩和文件打包工具，兼容 PKZIP（Phil Katz 的 ZIP for MSDOS 系统），zip 3.0 版本兼容 PKZIP 2.04 并支持 Zip64 扩展（允许归档和文件超过 2 GB 限制）。zip 使用 deflation 作为默认压缩方法，也可存储不压缩的文件，并自动为每个文件选择更优的方式。

zip 格式是 Windows 上最常用的格式，但对 Unicode 文件名支持有限（取决于 zip 工具版本和压缩设置）。在跨平台交换文件时建议使用 tar.xz 或 tar.zst 格式。

> **技巧**
>
> 在使用 zip 压缩中文或非英文字符时出现乱码是正常现象。由于编码方式不同，zip 3.0 在支持 Unicode 的平台上编译时，会额外存储路径的 UTF-8 翻译，以改善跨平台文件名兼容性。解压时可使用 `unzip -O` 选项指定文件名编码（如 `unzip -O GBK`），或使用 convmv 批量转换已解压的乱码文件名。

### 安装 zip

* 使用 pkg

```sh
# pkg install zip
```

* 使用 Ports

```sh
# cd /usr/ports/archivers/zip/
# make install clean
```

### zip 压缩

```sh
$ zip test.zip test # 压缩成 zip 文件
```

### zip 解压

zip 文件解压时，需要安装 `unzip` 工具（FreeBSD 基本系统自带的 `bsdunzip` 基于 libarchive，功能有限；如需完整功能，可通过 `pkg install unzip` 安装 Info-ZIP 版本）。

```sh
$ unzip test.zip # 解压 zip 文件到当前路径
$ unzip test.zip -d /home/ykla/test # 解压到指定路径，-d 即 directory（目录）
```

unzip 的 `-d` 选项后面跟目录名，可以有空格（如 `-d /path`），也可以紧贴（如 `-d/path`）。

## tar

基本系统自带 `tar`，无需安装。

tar 是“tape archive”（磁带归档）的缩写，最初用于在磁带上进行文件存储。FreeBSD 的 tar 实现基于 libarchive 库（即 bsdtar），替代了早期版本中的 GNU tar。该实现可从 tar、pax、cpio、zip、jar、ar、xar、rar（包括 RAR2、RAR3 及大部分 RAR5 格式，仅限读取，受专有格式限制）、rpm、7-zip 及 ISO 9660 光盘镜像中提取文件，并可创建 tar、pax、cpio、ar、zip、7-zip 和 shar 格式的归档。

GNU tar 支持自动识别多种压缩格式；bsdtar 在解压时同样会自动检测压缩格式（无需手动指定 `-z`、`-j`、`-J` 等选项），并支持从 tar、pax、cpio、zip 等多种格式中提取，GNU tar 仅支持 tar 相关格式。

> **思考题**
>
> > 归档文件包是指压缩率为 `0` 的文件集合，即将多个文件或目录打包成单一文件以便存储。单纯使用 `tar` 只打包而不压缩。压缩的本质是通过算法减小文件占用的存储空间，而非针对目录本身。因此，常见压缩软件通常先将目录归档为文件，随后再压缩。
>
> <img src="/files/pMoU2xmzxB6loosjGAmt" alt="归档与压缩" data-size="original">
>
> 如何理解归档与压缩的关系？

### tar 压缩

```sh
$ tar -cvf test.tar test # 打包成 tar 格式文件。-c 即 Create，创建
$ tar -zcvf test.tar.gz test # 压缩成 gzip 格式文件。-z 即 gzip
$ tar -jcvf test.tar.bz2 test # 压缩成 bzip2 格式文件。参数 -j 即 bzip2，请注意大小写
$ tar -Jcvf test.tar.xz test # 压缩成 xz 格式文件。参数 -J 即 xz，请注意大小写
$ tar --zstd -cvf test.tar.zst test # 压缩成 zstd 格式文件
```

### tar 解压

```sh
$ tar -xvf test.tar.其他压缩格式 # 解压 tar 格式文件，可支持如 test.tar.bz2、test.tar.gz、test.tar.xz、test.tar.zst 等格式
$ tar -xvf test.tar -C /home/ykla/mytest # 解压 test.tar 到指定路径
```

选项说明：

| 选项  | 含义               |
| --- | ---------------- |
| `x` | Extract，解压       |
| `v` | verbose，输出详细信息模式 |
| `f` | file，指定文件        |
| `C` | 即 cd，指定路径        |

## xz

基本系统自带 `xz`、`unxz`，同样无需安装。xz 格式是当前压缩率最高的格式之一，特别适合大文件归档。

### `xz` 压缩

默认压缩后会删除原文件，建议加 `-k` 选项保留原文件。

```sh
$ xz -k test.txt
```

压缩并删除原文件：

```sh
$ xz test.pdf
```

### `unxz` 解压

unxz 实际上是 xz 的硬链接，使用 `xz -d` 或直接 `unxz` 效果相同。

```sh
$ unxz -k test.tar.xz  # 解压并保留原文件，参数 -k 即 keep（保留），下同
$ unxz test.tar.xz     # 解压并删除原文件
```

## 7z

7z 格式具有极高的压缩率，特别适合大文件归档。

在 FreeBSD 操作系统中，7z 命令可通过安装 `archivers/7-zip` 包使用。

### 安装 7-zip

* 使用 pkg：

```sh
# pkg install 7-zip
```

* 通过 Ports：

```sh
# cd /usr/ports/archivers/7-zip/
# make install clean
```

### 7z 压缩

```sh
$ 7z a test.7z test # 将 test 文件压缩成 7z 文件。
```

`a` 表示 add，将要压缩的文件添加到 test.7z。

### 7z 解压

```sh
$ 7z x test.7z # 解压 7z 文件
$ 7z x test.7z -o/home/ykla/下载/test # 将 test.7z 解压到指定路径
```

`-o` 即 Output，指定输出路径。

> **警告**
>
> `-o/home/ykla/下载/test` 中 `-o` 与路径之间 **不能有空格**，这并非拼写错误，而是 7z 命令的设计方式。欢迎提交 PR 改进。

## rar

rar 是 Windows 上最流行的格式之一，但在 Unix 世界使用率较低；rar 有较好的恢复记录和分卷功能，适合大文件传输。

rar 格式是专有格式，未在基本系统内置。

### 安装 rar

* 通过 pkg 安装：

```sh
# pkg install rar unrar
```

* 通过 Ports：

```sh
# cd /usr/ports/archivers/rar/ && make install clean
# cd /usr/ports/archivers/unrar/ && make install clean
```

### rar 压缩

```sh
$ rar a archive.rar test
```

`a` 表示 add（添加），将文件添加到 `archive.rar`。

### rar 解压

```sh
$ unrar x archive.rar # 解压到当前路径。命令 x 即 Extract，解压
$ unrar x archive.rar /home/ykla/桌面/test/ # 解压到指定目录
```

## zstd

zstd 是 Meta（原 Facebook）开发的快速压缩算法，兼顾压缩速度和压缩率，是现代系统首选的压缩格式。

zstd 也是基本系统内置的压缩工具，zstd 支持多种预设级别，从最快（`-1`）到极限压缩（`--ultra -22`）。

### zstd 压缩

* 使用 zstd 压缩单个文件

```sh
$ zstd test.pdf
```

* 使用 zstd 压缩文件夹。

zstd 不直接支持压缩文件夹（参见：GitHub. How can I compress a directory?\[EB/OL]. \[2026-03-26]. <https://github.com/facebook/zstd/issues/1526>.）。该 Issue 讨论了 zstd 不支持直接压缩目录的技术原因与替代方案，因此需要先将文件夹打包为 tar 文件。

> **思考题**
>
> zstd 为什么不支持压缩文件夹？有哪些可能性？

```sh
$ tar -cf test.tar /home/ykla/test/ # 先打包成 tar。参数 -f 即 file（文件）
```

将 `test.tar` 压缩成 `test.tar.zst`

```sh
$ zstd -o test.tar.zst test.tar # 参数 -o 代表 file，用于指定输出文件
```

此外，也可直接使用 tar 的 `--zstd` 选项一步完成打包与压缩：

```sh
$ tar --zstd -cvf 输出文件 -C 起点目录 相对路径
```

示例：

```sh
$ tar --zstd -cvf test.tar.zst -C /home/ykla/ test # 打包并压缩成 zstd 格式
a test
```

查看结果：

```sh
$ ls -al
drwxr-xr-x  2 ykla ykla     2 Apr 16 11:53 test
-rw-r--r--  1 ykla ykla    98 Apr 16 11:58 test.tar.zst
```

文件结构图：

```sh
当前工作目录（命令执行所在位置，如 ~）
│
├── test.tar.zst   ← 输出文件（始终在“当前目录”生成）
│
└── （选项 -C 将在添加后续文件之前切换目录）
     ↓
     切换到：/home/ykla/
                │
                └── test   ← 被打包的对象
```

### zstd 解压

#### 解压到当前路径

```sh
$ zstd -d test.tar.zst
```

> **技巧**
>
> 这样解压出来的是 `test.tar`，还需要再用 `tar` 解压一次。

#### 解压到指定路径

```sh
$ zstd -d test.tar.zst -o /home/ykla/mytest # 参数 -d 表示 decompress（解压缩）
```

> **技巧**
>
> 同上，解压出来的是 `test.tar`，还需要再用 `tar` 解压一次。

## 课后习题

1. 使用 zip、tar、xz、7z、rar、zstd 等工具分别压缩和解压包含中文文件名的文件，对比各工具对 UTF-8 编码的处理方式，分析不同压缩格式在国际化支持上的设计差异。
2. 使用不同压缩算法（gzip、bzip2、xz、zstd）压缩同一组文件，对比压缩率、压缩时间和解压时间，分析各算法在压缩效率与计算性能之间的权衡策略。
3. 查阅 zip 格式规范中关于文件名编码的条款，分析中文文件名乱码问题的根源，评估现有补丁方案的适用范围。


# 8.1 FreeBSD 包管理器概述

## 软件源概览

FreeBSD 提供了多种类型的软件源，分别服务于不同的系统组件与软件安装需求。

对于熟悉 Linux 发行版的读者而言，可将 FreeBSD 的包管理方案类比为两大 Linux 发行版包管理器的功能组合：

* Arch Linux：Pacman，对应 pkg（同样秉持 KISS 理念）。
* Gentoo Linux：Portage，对应 Ports（Portage 本身借鉴自 Ports）。

`pkg install` 可以缩写为 `pkg ins`，其他命令同理。

FreeBSD 软件管理体系的整体架构如下：

![FreeBSD 软件管理体系](/files/I2aJqvSCKuseNJh0pcJm)

下表概括了各类软件源的基本信息：

| 软件源                   | 简介                                                                                              | 备注                                                                                                                                                                                                                                                                                                                                                                                                                         |
| --------------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pkg                   | 类似于传统 Linux 的包管理器，用于安装二进制软件包                                                                    | 如果不需要以二进制方式安装软件则无需配置。默认未安装 `pkg`，输入 `pkg` 回车会提示安装。**除 PkgBase 外的 pkg 包实际上都是由 Port 直接构建而来**                                                                                                                                                                                                                                                                                                                                 |
| Ports 框架              | 拉取 Port 的源代码目录（本身不含源代码，只是对第三方软件的描述文件、补丁集和 Makefile）。Ports 是 Port 的集合，在 `freebsd-ports` 存储库中统一维护 | Gentoo 的包管理器 Portage（命令为 `emerge`）正是借鉴于此，用于帮助用户从源代码编译安装第三方软件。也就是说，Ports（Port 集合）类似 Gentoo 的 [ebuild 数据库](https://mirrors.ustc.edu.cn/help/gentoo.html)                                                                                                                                                                                                                                                                     |
| Ports 源               | 在 Port 中的 Makefile 文件里会定义若干软件包源代码的地址，该软件源用于拉取这些源代码（因为从官方上游拉取速度有时不理想）                            | 等同于 Gentoo 的 [Distfiles 源](https://mirrors.ustc.edu.cn/help/gentoo.html)。如果不需要以源代码方式编译软件，可以不配置                                                                                                                                                                                                                                                                                                                             |
| freebsd-update        | 用于更新基本系统（内核 + 用户空间）                                                                             | 支持 ALPHA、BETA、RC、RELEASE 版本；STABLE/CURRENT 分支不提供二进制更新                                                                                                                                                                                                                                                                                                                                                                      |
| PkgBase               | 将 FreeBSD 基本系统（内核 + 用户空间）打包成 pkg 包，使用 pkg(8) 管理基本系统，是 FreeBSD 提供的新的基本系统安装与更新方式                  | FreeBSD 15.0 中作为技术预览引入：虚拟机与云镜像默认使用 PkgBase，物理机默认仍为传统方式。14.x 可手动启用供评估测试。安装时可在 bsdinstall(8) 中选择使用 PkgBase（FreeBSD-base 源），原有 freebsd-update(8) 与 distribution 集方式在 15.x 生命周期内仍受支持（计划在 FreeBSD 16 中移除，届时 PkgBase 将成为标准方式）。基本系统升级/维护使用 `pkg upgrade`。生产环境建议继续评估其稳定性。需配置 FreeBSD-base 源（见下文）。参考 [PkgBase Wiki](https://wiki.freebsd.org/PkgBase)。PkgBase 实际上由存储库 `freebsd-src` 构建而来，与 Ports 完全无关。FreeBSD 基本系统始终是独立于 Ports 而自存的 |
| kernel modules（kmods） | 内核模块源（包含无线网卡驱动、以太网卡驱动、DRM 显卡驱动等），用于解决小版本之间可能存在的 ABI 不兼容问题                                       | 参见：Possible solution to the drm-kmod kernel mismatch after upgrade from Bapt\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/possible-solution-to-the-drm-kmod-kernel-mismatch-after-upgrade-from-bapt.96058/#post-682984>、CFT: repository for kernel modules\[EB/OL]. \[2026-03-26]. <https://lists.freebsd.org/archives/freebsd-ports/2024-December/006997.html>。可以使用命令 `fwget` 自动安装所需固件                     |
| FreeBSD（pub）          | 提供 ISO 安装镜像、文档、开发资料和 `snapshots`，在系统安装、系统救援和开发参考时有很大帮助                                          | 此处的 Pub，指的是官方的 <https://ftp.freebsd.org/pub/FreeBSD/>。其性质类似于普通的镜像分发仓库，与 debian-cd、ubuntu-releases 等属于同一类型。目前已知全量同步 FreeBSD（Pub）源的镜像站：<https://mirrors.nju.edu.cn/freebsd>。其提供了完整的目录结构（如 `snapshots`、`development`），且更新较为及时，参见：FreeBSD.org ftp server\[EB/OL]. \[2026-03-26]. <https://ftp.freebsd.org/pub/FreeBSD/> 目录结构                                                                                                   |

## 理解 pkg 的 quarterly 季度分支与滚动更新的 latest 分支

FreeBSD 的 pkg 分为 quarterly（季度，由 Ports 的 XXXXQY 分支构建而来）分支和 latest（滚动更新，由 Ports 的 main 分支构建而来）分支两个源。quarterly 目前是 FreeBSD 默认的 pkg 软件分支。

```sh
# git clone https://git.FreeBSD.org/ports.git /usr/ports # 克隆 FreeBSD Ports 仓库到 /usr/ports 目录
正克隆到 '/usr/ports'...
remote: Enumerating objects: 6715646, done.
remote: Counting objects: 100% (936/936), done.
remote: Compressing objects: 100% (120/120), done.
remote: Total 6715646 (delta 923), reused 816 (delta 816), pack-reused 6714710 (from 1)
接收对象中: 100% (6715646/6715646), 1.50 GiB | 10.26 MiB/s, 完成.
处理 delta 中: 100% (4065984/4065984), 完成.
正在更新文件: 100% (168004/168004), 完成.
root@ykla:/home/ykla # cd /usr/ports/ # 切换到 git 的 Ports 路径
root@ykla:/usr/ports # git branch -a # 列出本地所有分支
* main
  remotes/origin/2014Q1
  remotes/origin/2014Q2
  remotes/origin/2014Q3
  remotes/origin/2014Q4

     ……省略一部分……

  remotes/origin/2025Q2
  remotes/origin/2025Q3
  remotes/origin/2025Q4
  remotes/origin/HEAD -> origin/main # 可以看到 main 是默认分支
  remotes/origin/main
root@ykla:/usr/ports # git for-each-ref --sort=-committerdate --format='%(committerdate:short) %(authorname) %(refname:short) %(objectname:short)' refs/remotes/ # 列出所有分支及最后提交者与时间 ①
2025-10-24 Hiroki Tagato origin be5283280c16
2025-10-24 Hiroki Tagato origin/main be5283280c16
2025-10-23 Colin Percival origin/2025Q4 060d3d65fcbb
2025-10-14 Bryan Drewery origin/2025Q3 9f09f84b2dd5
2025-07-01 FiLiS origin/2025Q2 c339266c40e5

  ……省略一部分……

2015-07-23 Palle Girgensohn origin/2015Q2 7d7c2271f6c9
2015-04-09 Alonso Schaich origin/2015Q1 5bd325869bde
2014-10-01 Bryan Drewery origin/2014Q3 a0ccd6f83108
2014-06-28 Thomas Zander origin/2014Q2 a3377806e58e
2014-03-29 Lars Engels origin/2014Q1 5f4d6e1d6b07
root@ykla:/usr/ports # git merge-base origin/main origin/2025Q4 # 查找两个分支的最近共同祖先 commit
6c256c6adb790f0588b920d41a5fe4dfa550079f
root@ykla:/usr/ports # git branch -r --contains 6c256c6adb790f0588b920d41a5fe4dfa550079f # 列出哪些远程分支历史中包含此 commit ②
  origin/2025Q4
  origin/HEAD -> origin/main
  origin/main
root@ykla:/usr/ports # for branch in $(git branch -r | grep -v HEAD); do # 查看分支创建的时间 ③
>   mb=$(git merge-base origin/main $branch)
>   date=$(git show -s --format='%ci' $mb)
>   echo "$branch created around $date"
> done

origin/2014Q1 created around 2013-12-16 08:00:15 +0000
origin/2014Q2 created around 2014-04-01 12:02:40 +0000
origin/2014Q3 created around 2014-07-01 10:13:26 +0000
origin/2014Q4 created around 2014-10-01 06:43:32 +0000
origin/2015Q1 created around 2015-01-01 14:35:03 +0000
origin/2015Q2 created around 2015-04-01 12:19:37 +0000
origin/2015Q3 created around 2015-07-01 12:12:08 +0000
origin/2015Q4 created around 2015-10-01 19:24:12 +0000

……省略一部分……

origin/2024Q4 created around 2024-10-07 20:46:12 +0200
origin/2025Q1 created around 2025-01-05 11:22:53 +0100
origin/2025Q2 created around 2025-04-01 12:58:51 +0200
origin/2025Q3 created around 2025-07-01 22:32:34 +0300
origin/2025Q4 created around 2025-10-01 21:27:17 +0200
origin/main created around 2025-10-24 12:43:02 +0900
```

其中，quarterly 的内容由 main 分支（latest）切出，每年的 1 月、4 月、7 月、10 月 ③ 会发布新的分支（从特定时间点的 main 分支切出 ①），形如 `2024Q3`、`2025Q1`。这是为了便于通过 git 直接拉取所需的分支，但 Ports 管理团队（portmgr）仅维护最新分支，旧分支不再接受任何合并。②

quarterly 实际上类似于 Debian 的 Stable 版本，此处的 Stable 不仅表示“稳定”，也包含“固定”的含义。有必要区分“稳定”和“固定”两个词语：

根据 [Merriam‑Webster](https://www.merriam-webster.com/dictionary/stable) 和 [Cambridge Dictionary](https://dictionary.cambridge.org/us/dictionary/english/stable)，Stable 有“fixed”（固定）的意思。查阅《现代汉语词典（第 7 版）》第 1374 页可知，“稳定”的第一个释义为“形容词，稳定安固，没有变动”；第 470 页载“固定”为“动词，不变动或不移动（跟‘流动’相对）”。因此，“固定”是实现“稳定”的一种手段，而“稳定”是一种目的。

> **技巧**
>
> Debian 通过 **固定** 软件包版本、仅接受安全更新而不接受功能更新来实现 **稳定**。其软件源是 **固定的**——Debian 还有 testing 等分支。常见发行版通过 **固定** 软件来实现 **Stable** 版本。由于这些软件包已经历经了从 unstable（即 sid，Ubuntu 即基于此）到 testing 等多个分支的测试和发展，软件包自然比较 **稳定**。在 **Stable** 版本的系统生命周期内，任何软件基本都不会获得大版本更新和功能更新。

quarterly 分支类似于 Debian 的 Stable 版本，固定软件包版本并仅接受安全更新和错误修复，以提供可预测且稳定的用户体验。任何功能性更新都不会回溯至 quarterly 分支。

> **注意**
>
> 并非所有源都提供 `quarterly` 和 `latest`。

### 参考文献

* FreeBSD Project. Ports/QuarterlyBranch\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/Ports/QuarterlyBranch>. 说明 Ports 季度分支的创建规则与维护策略。
* FreeBSD Project. pkg -- package manager\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=pkg&sektion=8>. FreeBSD 包管理器手册页。
* Debian. DebianStability\[EB/OL]. \[2026-03-26]. <https://wiki.debian.org/DebianStability>. 即稳定的意思
* Debian. Chapter 3. Choosing a Debian distribution\[EB/OL]. \[2026-03-26]. <https://www.debian.org/doc/manuals/debian-faq/choosing.en.html#s3.1.1>. 根据此处实际上是固定的意思
* Debian. 选择一个 Debian 发布版本\[EB/OL]. \[2026-03-26]. <https://www.debian.org/doc/manuals/debian-faq/choosing.zh-cn.html>. 第 3 章中文版。
* Debian. 2.2. Are there package upgrades in “stable”?\[EB/OL]. \[2026-03-26]. <https://www.debian.org/doc/manuals/debian-faq/getting-debian.en.html#updatestable>. 此处指出软件不会有功能性更新。
* FreeBSD Project. pkg.freebsd.org\[EB/OL]. \[2026-03-26]. <https://pkg.freebsd.org/>. 也并非所有架构都提供了 pkg 源，与平台支持等级有关。

## Ports 与 Port 概述

### Ports 历史

Ports 是一种从源代码（也支持闭源二进制包）构建软件的框架。该框架由 Jordan K. Hubbard（<jkh@FreeBSD.org>）创建，最初于 1994 年 8 月公开发布。

```sh
# git log --reverse --max-parents=0 --pretty=format:"commit: %h%nAuthor: %an%nDate: %ci%n%n%B" # 查看仓库首次提交记录
commit: d27f048e966a
Author: Jordan K. Hubbard
Date: 1994-08-21 13:12:57 +0000

Commit my new ports make macros.  Still not 100% complete yet by any means
but fairly usable at this stage.
Submitted by:   jkh
```

“提交了为 Ports 编写的新 make 宏。虽然还远未完善，但目前已经可以正常使用。”

> **技巧**
>
> 上述示例说明：对于开源项目，无论使用何种版本控制系统，保留完整的提交记录都非常重要。

NetBSD 和 OpenBSD 也使用 Ports，但实现方式并不通用。

#### 参考文献

* FreeBSD-Ports-Announce. Happy 20th birthday FreeBSD ports tree!\[EB/OL]. (2014-08)\[2026-03-25]. <https://lists.freebsd.org/pipermail/freebsd-ports-announce/2014-August/000088.html>. 纪念 FreeBSD Ports 诞生 20 周年，回顾其历史演进与发展历程。

### Ports 与 Port 释义

一款软件的相关文件（补丁文件、校验和、Makefile 等）的集合称为一个 Port，所有 Port（移植软件）的集合即 Ports Collection 或 Ports Tree，简称 Ports。从术语定义角度而言，Port 指单个软件的移植构建配置，Ports 则指整个移植软件集合。

项目结构

```sh
/usr/
└── ports/ # Ports 目录
    ├── accessibility/ # 分类目录
    ├── arabic/
    ├── archivers/
    ├── astro/
    ├── audio/
    ├── benchmarks/
    ├── biology/
    ├── cad/
    ├── chinese/
    ├── comms/
    ├── converters/
    ├── databases/ # 数据库分类
    │   ├── postgresql18-server/ # 单个 Port 示例
    │   │   ├── Makefile # 主文件
    │   │   ├── distinfo # 校验和文件
    │   │   ├── pkg-descr # 软件描述
    │   │   ├── files/ # 补丁文件目录
    │   │   └── pkg-plist-* # 安装文件列表
    │   └── ……其他 Port……
    ├── deskutils/
    ├── devel/
    ├── dns/
    ├── editors/
    ├── emulators/
    ├── filesystems/
    ├── finance/
    ├── french/
    ├── ftp/
    ├── games/
    ├── german/
    ├── graphics/
    ├── hebrew/
    ├── hungarian/
    ├── irc/
    ├── japanese/
    ├── java/
    ├── korean/
    ├── lang/
    ├── mail/
    ├── math/
    ├── misc/
    ├── multimedia/
    ├── net/
    ├── net-im/
    ├── net-mgmt/
    ├── net-p2p/
    ├── news/
    ├── polish/
    ├── portuguese/
    ├── print/
    ├── russian/
    ├── science/
    ├── security/
    ├── shells/
    ├── sysutils/
    ├── textproc/
    ├── ukrainian/
    ├── vietnamese/
    ├── www/
    ├── x11/
    ├── x11-clocks/
    ├── x11-drivers/
    ├── x11-fm/
    ├── x11-fonts/
    ├── x11-servers/
    ├── x11-themes/
    ├── x11-toolkits/
    ├── x11-wm/
    ├── ports-mgmt/
    ├── Mk/
    ├── Templates/
    ├── Tools/
    ├── Keywords/
    ├── distfiles/ # 下载源文件目录
    ├── COPYRIGHT
    ├── GIDs
    ├── UIDs
    ├── README
    ├── CHANGES
    ├── MOVED
    ├── UPDATING
    ├── Makefile
    └── CONTRIBUTING.md
```

查看 Ports 框架结构：

```sh
$ cd /usr/ports # 切换到 /usr/ports
$ ls # 列出此目录下所有文件  ①
accessibility	COPYRIGHT	GIDs		misc		README		www
arabic		databases	graphics	Mk		russian		x11
archivers	deskutils	hebrew		MOVED		science		x11-clocks
astro		devel		hungarian	multimedia	security	x11-drivers
audio		dns		irc		net		shells		x11-fm
benchmarks	editors		japanese	net-im		sysutils	x11-fonts
biology		emulators	java		net-mgmt	Templates	x11-servers
cad		filesystems	Keywords	net-p2p		textproc	x11-themes
CHANGES		finance		korean		news		Tools		x11-toolkits
chinese		french		lang		polish		UIDs		x11-wm
comms		ftp		mail		ports-mgmt	ukrainian
CONTRIBUTING.md	games		Makefile	portuguese	UPDATING
converters	german		math		print		vietnamese
$ ls databases/ # 切换到 databases 数据库分类目录下
adminer						php-xapian
adodb5						php81-dba

    ……省略一部分……

mongodb60					py-apache-arrow
mongodb70					py-apsw
mongodb80					py-asyncmy
mongosh						py-asyncpg
$ cd databases/postgresql18-server # 切换到 postgresql18-server 目录
ykla@ykla:/usr/ports/databases/postgresql18-server $ ls ②
distinfo		pkg-descr		pkg-plist-contrib	pkg-plist-pltcl
files			pkg-install-server	pkg-plist-plperl	pkg-plist-server
Makefile		pkg-plist-client	pkg-plist-plpython
```

* ① **/usr/ports** 这个文件夹整体称作 Ports，包括几十种不同的分类目录，每个目录下有若干 Port。
* ② **/usr/ports/databases/postgresql18-server** 这个文件夹整体称作一个 Port，由 `distinfo`（校验和文件）、`pkg-descr`（软件描述文件）、`Makefile`（主文件，包含构建方法、版本号及下载方式等）、`pkg-plist`（安装文件列表及其权限和属组信息）、`files`（一般为补丁文件，该 Port 下还包含安装后的说明文件 `pkg-message`）等文件构成。

之所以称为“Ports Collection”（移植集合，不应理解为“端口集合”），是因为这些软件绝大部分并不由 FreeBSD 控制、管理和维护。Port 提交者的主要工作是将 FreeBSD 上的 Port 更新到上游开发者提供的最新版本，删除上游不再维护的软件 Port。如果上游不接受 BSD 特有的 PR 补丁，或难以直接通过既有 Ports 框架构建，Port 维护者也需要自行复刻一个分支来维护。

## Ports 构建 pkg 软件包的流程

Ports 框架可以将源代码编译并打包成 pkg 格式的二进制包，完整构建流程如下图所示。

![pkg 构建流程图](/files/Xck4a3LJVbjDBsrU0MWm)

> **注意**
>
> 可以同时使用 Ports 和 pkg，多数用户也是如此。但需要注意 Ports 和 pkg 应使用同一分支：如果 Ports 使用 main 分支，则 pkg 应使用 latest 源；如果 Ports 使用 quarterly 分支，则 pkg 应使用 quarterly 源。分支不一致会导致依赖问题（例如 SSL）。latest 源也比 main 分支下的 Ports 发布更晚（其软件包由 main 构建而来），因此即使使用 latest 源，也可能会出现上述问题。遇到问题时卸载 pkg 安装的包，重新使用 Ports 编译即可。

> **警告**
>
> 如果通过 `make config` 修改了 Port 的默认构建参数，且希望保留该自定义设置，则后续不应通过 pkg 更新该软件，否则 pkg 安装的软件包将覆盖自定义参数。

下图为 Ports 构建软件包的详细流程：

![Ports 流程图](/files/oa6QAZcBh9gEcEkOx2lC)

> **技巧**
>
> Ports 的下载路径是 **/usr/ports/distfiles/**。

```sh
/usr/ports/
└── distfiles/ # Ports 的下载路径
```

## PkgBase 源分类

为了帮助读者更好地配置 PkgBase 源，下面整理了 FreeBSD 官方源的 PkgBase 信息，包括各分支的更新频率和对应的 URL 地址。

| 分支                   | 更新频率       | URL 地址                                          |
| -------------------- | ---------- | ----------------------------------------------- |
| main（16.0-CURRENT）   | 每天两次       | <https://pkg.freebsd.org/${ABI}/base_latest>    |
| stable/14            | 每天两次       | <https://pkg.freebsd.org/${ABI}/base_latest>    |
| stable/14            | 每周一次：星期日   | <https://pkg.freebsd.org/${ABI}/base_weekly>    |
| stable/15            | 每天两次       | <https://pkg.freebsd.org/${ABI}/base_latest>    |
| stable/15            | 每周一次：星期日   | <https://pkg.freebsd.org/${ABI}/base_weekly>    |
| releng/14.4（RELEASE） | 随勘误和安全更新发布 | <https://pkg.freebsd.org/${ABI}/base_release_4> |
| releng/15.0（RELEASE） | 随勘误和安全更新发布 | <https://pkg.freebsd.org/${ABI}/base_release_0> |

以上更新频率依据 freebsd-base(7) 手册页：开发分支（CURRENT 与 STABLE）每天构建两次，RELEASE 分支随勘误和安全更新发布。main 分支仅提供 base\_latest，不提供 base\_weekly（参见 Baptiste Daroussin 在 freebsd-pkgbase 邮件列表中的说明）。

如果官方源下载速度慢，可以考虑改用国内镜像。只需要替换 `https://pkg.freebsd.org` 这部分。

## 课后习题

1. 分析 Portsnap 在 FreeBSD 15 中被移除的技术原因（可从安全性、分支支持、磁盘占用、离线能力等维度展开），并说明 Git 作为替代方案的优势。
2. 比较 FreeBSD pkg 仓库、Debian APT 仓库与 Arch Linux pacman 仓库的元数据签名链机制，分析各方案在供应链攻击场景下的防护能力差异。
3. 软件源镜像体系是一种去中心化分发架构。分析镜像站志愿运营模式与商业 CDN 模式在可持续性、审查抗性与分发效率三个维度上的优劣，并提出一种混合分发方案。


# 8.2 FreeBSD 软件源

FreeBSD 的软件源分为 pkg 二进制包源、内核模块源、PkgBase 系统源和 Ports 源四类，分别配置，默认指向官方服务器，国内用户通常需要切换至镜像站以提升下载速度。

## 15.0-RELEASE 快速切换 pkg 软件源到中国科学技术大学开源软件镜像站

该配置要求读者在安装过程中使用 PkgBase 方式，可设置 pkg 二进制包源（由 Ports 构建而来）、PkgBase 源、内核模块源。

使用 ee 编辑器打开 **/usr/local/etc/pkg/repos/FreeBSD.conf** 文件。

> **技巧**
>
> 如果提示文件不存在或打开后内容并非 `FreeBSD-base: { enabled: yes }`，则本小节不适用。请按下文内容手动配置。

清空 **FreeBSD.conf** 文件中原有内容 `FreeBSD-base: { enabled: yes }`。

写入以下内容：

```sh
USTC-ports: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/quarterly",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

FreeBSD-ports: { enabled: no }

USTC-ports-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_quarterly_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}

FreeBSD-ports-kmods: { enabled: no }

USTC-base: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_release_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}",
  enabled: yes
}
```

随后运行命令 `pkg update -f` 刷新软件源即可。

> **技巧**
>
> 将上述配置中的两个 `quarterly` 都改为 `latest` 即可使用滚动更新的软件源。

## pkg 二进制包（由 Ports 构建的二进制包）切换软件源

FreeBSD 中 pkg 源分为系统级与用户级两个配置文件。**由于该文件会随基本系统的更新而改变，因此不建议** 直接修改 **/etc/pkg/FreeBSD.conf** 文件。

> **警告**
>
> 请勿同时启用多个 pkg 镜像站，无论是官方镜像站（如 `pkg.freebsd.org` 与 USTC 混用），还是境内非官方镜像站，都不建议混合使用。其后果类似于混用 FreeBSD 季度分支的 Ports 和 latest 分支的 pkg，可能会破坏软件的依赖关系。案例：[混用导致 KDE 桌面被删除](https://blog.mxdyeah.com/post/freebsd-exp-kde6)。

> **警告**
>
> 请勿同时混用 `quarterly` 和 `latest`，在所有配置文件中应保持一致。

若要获取滚动更新的包，请将 `quarterly` 修改为 `latest`。二者区别参见上文。

> **注意**
>
> 对于 `CURRENT` 只提供了 `latest`。

示例：使用命令修改系统级 `pkg` 源为 latest：

```sh
# sed -i '' 's/quarterly/latest/g' /etc/pkg/FreeBSD.conf
```

### 14.X-RELEASE

#### 创建用户级源目录和文件

创建 pkg 仓库配置目录：

```sh
# mkdir -p /usr/local/etc/pkg/repos
```

使用 `ee` 编辑器打开配置文件 **/usr/local/etc/pkg/repos/USTC.conf**（将自动创建文本文件 **USTC.conf**）:

```sh
# ee /usr/local/etc/pkg/repos/USTC.conf
```

> **注意**
>
> 在本节中，**/usr/local/etc/pkg/repos/USTC.conf** 是 pkg 二进制源、模块源和 PkgBase 源共用的配置文件。后续配置不再重复说明此步骤。

#### 中国科学技术大学开源软件镜像站

编辑 **/usr/local/etc/pkg/repos/USTC.conf** 文件，写入以下配置 **之一**：

* quarterly：

```sh
USTC: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/quarterly",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD: { enabled: no }
```

* latest：

```sh
USTC: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/latest",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD: { enabled: no }
```

### 15.0-RELEASE

自 `FreeBSD 15.0-RELEASE` 以降，`FreeBSD` 源的名称由 `FreeBSD` 变更为 `FreeBSD-ports`。

#### 官方源

更多信息参见源代码 **usr.sbin/pkg/FreeBSD.conf.quarterly-release**\[EB/OL]. \[2026-03-26]. <https://github.com/freebsd/freebsd-src/blob/releng/15.0/usr.sbin/pkg/FreeBSD.conf.quarterly-release>。下同。

这是 15.0-RELEASE 系统安装完成后默认的软件源。

#### 中国科学技术大学开源软件镜像站

编辑 **/usr/local/etc/pkg/repos/USTC.conf** 文件，写入以下配置（quarterly 分支即 2024Q3、2025Q1 等）：

```sh
USTC-ports: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/quarterly",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-ports: { enabled: no }
```

如果使用 latest 分支（滚动更新，即 Ports 的 main 分支构建而来），改为如下配置：

```sh
USTC-ports: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/latest",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-ports: { enabled: no }
```

## 内核模块源（Kernel modules, kmods）

### 14.X-RELEASE

#### 中国科学技术大学开源软件镜像站

编辑 **/usr/local/etc/pkg/repos/USTC.conf** 文件，写入以下配置（quarterly 分支即 2024Q3、2025Q1 等）：

如果使用 quarterly 分支，配置如下：

```sh
USTC-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_quarterly_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-kmods: { enabled: no }
```

如果使用 latest 分支，配置如下：

```sh
USTC-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_latest_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-kmods: { enabled: no }
```

### 15.0-RELEASE

自 `FreeBSD 15.0-RELEASE` 以降，`kmods` 源的名称由 `FreeBSD-kmods` 变更为 `FreeBSD-ports-kmods`。

#### 中国科学技术大学开源软件镜像站

编辑 **/usr/local/etc/pkg/repos/USTC.conf** 文件，写入以下配置（quarterly 分支即 2024Q3、2025Q1 等）：

如果使用 quarterly 分支，配置如下：

```sh
USTC-ports-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_quarterly_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-ports-kmods: { enabled: no }
```

如果使用 latest 分支，配置如下：

```sh
USTC-ports-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_latest_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-ports-kmods: { enabled: no }
```

> **注意**
>
> 建议保持 Ports 源和 kmods 源（如果开启 PkgBase，则还需要纳入 PkgBase 源）为同一镜像站，以避免发生潜在的依赖等问题。

## 面向基本系统的 PkgBase 源（FreeBSD 15.0 技术预览，14.x 可手动启用）

`PkgBase` 在 `FreeBSD 15.0-RELEASE` 中作为技术预览引入，虚拟机与云镜像默认使用 PkgBase，物理机默认仍为传统方式。FreeBSD 项目仍支持传统方式直至 15.X 结束（计划在 FreeBSD 16 中移除）。在生产环境中使用 `PkgBase` 升级系统时应注意备份。

> **技巧**
>
> 14.x 用户可以选择由传统安装方式直接转换为 PkgBase，参见本书其他相关章节。

### 官方源

默认路径：**/etc/pkg/FreeBSD.conf**（请勿修改，仅做展示）

```sh
FreeBSD-base: {
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/base_release_${VERSION_MINOR}",
  mirror_type: "srv",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}",
  enabled: no
}
```

> **注意**
>
> 根据 FreeBSD 源代码 [usr.sbin/bsdinstall/scripts/pkgbase.in](https://github.com/freebsd/freebsd-src/blob/releng/15.0/usr.sbin/bsdinstall/scripts/pkgbase.in) 最后几段源代码，**/etc/pkg/FreeBSD.conf** 中的 FreeBSD-base 源虽然是 `enabled: no`。但是，那些在安装中选择了 PkgBase 的用户，会在 **/usr/local/etc/pkg/repos/FreeBSD.conf** 文件中写入 `FreeBSD-base: { enabled: yes }` 这一行来显式覆盖默认配置。因此，PkgBase 用户的 FreeBSD-base 源实际上是默认启用的。

#### 中国科学技术大学开源软件镜像站

禁用默认启用的官方 FreeBSD-base 源：

```sh
# mv /usr/local/etc/pkg/repos/FreeBSD.conf /usr/local/etc/pkg/repos/FreeBSD.conf.back
```

> **技巧**
>
> 在某些环境中，文件 **/usr/local/etc/pkg/repos/FreeBSD.conf** 里也可能包含非 FreeBSD-base 仓库的定义，建议用户在重命名之前先确认文件内容。

编辑 **/usr/local/etc/pkg/repos/USTC.conf** 文件，写入以下配置：

```sh
USTC-base: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_release_${VERSION_MINOR}",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}",
  enabled: yes
}
```

> **警告**
>
> 对于 **RELEASE** 版本的系统，PkgBase 在整个生命周期内几乎是固定不变的！
>
> 仓库 `base_latest` 和 `base_weekly` 仅面向 STABLE 或 CURRENT！
>
> 请勿变动字符串 `base_release_${VERSION_MINOR}`！

> **技巧**
>
> 在从 14.X PkgBase 系统升级到 15.0 时，常遇到签名密钥问题。请确保 **/usr/share/keys/pkgbase-15** 存在（如果缺失，可从官方源手动 fetch 或参考 Release Notes 中的升级说明）。否则会出现“no trusted public keys found”错误。详见 [15.0 Release Notes - Upgrading](https://www.freebsd.org/releases/15.0R/relnotes/#upgrade) 和论坛相关讨论。

## STABLE/CURRENT 快速切换 pkg 软件源到中国科学技术大学开源软件镜像站

> **警告**
>
> STABLE/CURRENT 并非生产版本，不适用于生产环境，使用上述版本的用户被推定为具有一定的知识基础，因此此小节未列出具体步骤和过多解释。

### 内核模块源

* 对于 `FreeBSD 14.x-STABLE`

```sh
USTC-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_latest",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-kmods: { enabled: no }
```

* 对于 `FreeBSD 15.0-STABLE / FreeBSD 16.0-CURRENT`：

```sh
USTC-ports-kmods: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/kmods_latest",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkg",
  enabled: yes
}
FreeBSD-ports-kmods: { enabled: no }
```

### PkgBase 源

```sh
USTC-base: {
  url: "https://mirrors.ustc.edu.cn/freebsd-pkg/${ABI}/base_latest",
  mirror_type: "none",
  signature_type: "fingerprints",
  fingerprints: "/usr/share/keys/pkgbase-${VERSION_MAJOR}",
  enabled: yes
}
```

## Ports 源（Distfiles）

获取 Ports 本身的方法（通过 Git 或归档文件）参见其他章节。该源用于下载 Ports 框架中的软件（称为 Port）的源代码。

> **警告**
>
> Ports 源可能并不完整，这是受 Ports 框架结构的限制。详细信息可参考 <https://github.com/ustclug/discussions/issues/408>。

创建或修改文件 **/etc/make.conf**。写入以下配置 **之一**：

* 南京大学开源镜像站

```ini
MASTER_SITE_OVERRIDE?=https://mirrors.nju.edu.cn/freebsd-ports/distfiles/${DIST_SUBDIR}/
```

* 中国科学技术大学开源软件镜像站

```ini
MASTER_SITE_OVERRIDE?=https://mirrors.ustc.edu.cn/freebsd-ports/distfiles/${DIST_SUBDIR}/
```

## 故障排除与未竟事宜

### 平衡安全与便利

使用非官方镜像站虽提升了下载速度，但引入了中间人攻击的风险——镜像站管理员理论上可在软件包中注入恶意代码。FreeBSD 官方集群内部使用 `zfs send/receive` 而非 rsync 同步数据，且官方 rsync 服务不向公众开放，部分原因正是为了降低此类风险。对于安全要求较高的生产环境，建议使用官方源或自行搭建 Poudriere 构建服务器，以完全控制软件包。

### 为什么 pkg 配置文件中要写完整选项（mirror\_type / signature\_type / fingerprints）

虽然仅写 `url` 和 `enabled: yes` 时 pkg 也能正常工作（pkg 会默认 `mirror_type: "none"` 和 `signature_type: "none"`），但这样做将 **关闭签名验证**。系统不会检查 pkg 下载的包是否被篡改，可能存在安全风险（尤其是 Ports、kmods 和 PkgBase 系统包）。

其优点在于：

* 启用 `signature_type: "fingerprints"` 和 `fingerprints`：使用 FreeBSD 官方内置密钥验证包签名
* `mirror_type: "none"`：适合国内的 HTTPS 直链镜像（因为 `pkg+https://` 支持 DNS SRV，所以官方用 `"srv"`，但镜像站不需要）

推荐在生产环境中始终启用签名验证。若去除此配置则关闭签名验证，除非完全信任网络环境，否则不建议如此操作。

> **警告**
>
> 目前中国大陆境内不存在任何 FreeBSD 官方镜像站。
>
> 对于安全性要求较高的用户，应该使用默认的官方镜像 `pkg.freebsd.org`！其由 FreeBSD 项目官方构建、分发和维护。


# 8.3 使用 pkg 管理二进制包

FreeBSD 的二进制包管理器目前是 pkg（旧称 pkgng），名称来源于英文单词“Package”，即软件包的简称。

## 安装 pkg 包管理器

> **技巧**
>
> 为了避免向后兼容问题，pkg(8) 工具不会预装在基本系统中。

基本系统默认不包含 pkg，需要先下载并安装 pkg：

```sh
# pkg # 输入 pkg 后按回车
The package management tool is not yet installed on your system. # pkg 尚未安装
Do you want to fetch and install it now? [y/N]: y # 输入 y 并回车确认安装
Bootstrapping pkg from pkg+https://pkg.FreeBSD.org/FreeBSD:14:amd64/quarterly, please wait... # 观察此处，可发现默认调用的是 quarterly 分支的源
Verifying signature with trusted certificate pkg.freebsd.org.2013102301... done
Installing pkg-1.21.3...
Extracting pkg-1.21.3: 100%
pkg: not enough arguments # 这里的报错提示缺少参数，但只是为了安装 pkg 本体，可以忽略
Usage: pkg [-v] [-d] [-l] [-N] [-j <jail name or id>|-c <chroot path>|-r <rootdir>] [-C <configuration file>] [-R <repo config dir>] [-o var=value] [-4|-6] <command> [<args>]

For more information on available commands and options see 'pkg help'.
```

> **技巧**
>
> 如果长时间停留在 `Bootstrapping pkg from ……, please wait...`，请按 **Ctrl + C** 中断这一过程，换境内源后再操作。

> **技巧**
>
> 如果提示 `00206176BC680000:error:0A000086:SSL routines:tls_post_process_server_certificate:certificate verify failed:/usr/src/crypto/openssl/ssl/statem/statem_clnt.c:1890:`（SSL 证书验证失败），请先校准时间。

> ```sh
> # ntpd -q -g pool.ntp.org # 使用 pool.ntp.org 同步系统时间
> ```
>
> > **思考题**
> >
> > 在 SSL 广泛应用的背景下，任何网络问题总是需要检查本机时间是否正确。而用户往往忽略这一点（有时候甚至是 CPU 中负责加密的模块损坏导致的），并且在大多数情况下报错也极不明确。请读者思考，如何解决这个问题？

## 使用 pkg 安装软件

> **技巧**
>
> 如果需要查询某个软件包在 FreeBSD 中的具体情况，可以使用搜索引擎搜索“freebsd ports 包名”，也可以直接在 [FreshPorts](https://www.freshports.org/) 查找。

以安装 Chromium 为例：

```sh
$ pkg ins chromium # 在普通用户权限下安装 chromium 浏览器
pkg: Insufficient privileges to install packages
```

“Insufficient privileges to install packages”即“权限不足，无法安装软件包”。

再试一次：

```sh
$ su # 提升权限到 root，要求此普通用户在 wheel 组中
Password: # 这里输入的是 root 账户密码！
# pkg ins chromium # 再次安装 chromium
Updating FreeBSD repository catalogue...
Fetching data.pkg: 100%   10 MiB 768.6kB/s    00:14
Processing entries: 100%
FreeBSD repository update completed. 36822 packages processed.
Updating FreeBSD-kmods repository catalogue...
Fetching data.pkg: 100%   31 KiB  32.3kB/s    00:01
Processing entries: 100%
FreeBSD-kmods repository update completed. 213 packages processed.
All repositories are up to date.
The following 6 package(s) will be affected (of 0 checked): # 有 6 个软件包将会受到影响

New packages to be INSTALLED:
        chromium: 142.0.7444.162 [FreeBSD]
        dconf: 0.49.0 [FreeBSD]
        harfbuzz-icu: 10.3.0 [FreeBSD]
        jsoncpp: 1.9.6_1 [FreeBSD]
        sndio: 1.10.0_1 [FreeBSD]
        speex: 1.2.1_1,1 [FreeBSD]

Number of packages to be installed: 6

The process will require 463 MiB more space.
127 MiB to be downloaded.

Proceed with this action? [y/N]: # 此处输入 y 再按回车键即可安装
```

> **思考题**
>
> > [Add Concurrent Downloads of Multiple Packages](https://github.com/freebsd/pkg/issues/1628)
>
> 可见 pkg 既不支持并行下载也不支持并行安装。阅读源代码，尝试解决这个问题并提交 PR。

可能会遇到这种情况：

```sh
# pkg ins chromium  # 安装 Chromium 浏览器
Updating FreeBSD repository catalogue.
Fetching meta.conf: 100%    179 B   0.2kB/s    00:01
Fetching data.pkg: 100%   10 MiB   2.7MB/s    00:04
Processing entries: 100%
FreeBSD repository update completed. 36804 packages processed.
Updating FreeBSD-kmods repository catalogue...
FreeBSD-kmods repository is up to date.
All repositories are up to date.
pkg: No packages available to install matching 'chromium' have been found in the repositories
```

“pkg: No packages available to install matching 'chromium' have been found in the repositories”即“pkg：在仓库中找不到与 chromium 匹配的可安装软件包”。

如果前面显示了“FreeBSD repository update completed. 36804 packages processed.”（FreeBSD 仓库更新完成。处理了 36804 个包），说明当前软件源是可用的，只是找不到 `chromium` 这个软件包而已。

这就是下文所述“原子更新”缺失的体现。

此外，即使系统已设置 i18n，pkg 的输出仍然是英文。

> **思考题**
>
> > [Is it possible to add i18n multilingual support using po files?](https://github.com/freebsd/pkg/issues/2421)
> >
> > FreeBSD 基本系统中没有 gettext，所以没有计划这样做，如果后续在 pkg 中出现可用的 libintl 套件，则可能会重新考虑。
>
> 阅读 pkg 源代码，定位问题源头，尝试解决这个问题，提交 PR 让 pkg 支持 i18n。

## pkg 更新软件

```sh
# pkg upgrade
```

出现错误：`You must upgrade the ports-mgmt/pkg port first`（必须先更新 pkg 本体）。

解决（优先使用 pkg 自身升级，或通过 Ports 编译）：

```sh
# pkg bootstrap -f      # 强制从远端仓库重装 pkg，无需经过 Ports
```

或：

```sh
# cd /usr/ports/ports-mgmt/pkg
# make deinstall
# make install
```

## 查看已安装的所有软件

```sh
# pkg info
```

## 卸载软件

`pkg delete` 默认会自动将依赖关系不满足的包一并加入删除列表，不会破坏依赖关系；仅当使用 `-f` 参数时才跳过依赖检查。如果需要清理不再被其他包依赖的“叶子”包，可安装 `pkg_rmleaves`，或使用内建命令 `pkg autoremove` 移除自动安装且已无依赖的包。

```sh
# pkg install pkg_rmleaves
```

或者

```sh
# cd /usr/ports/ports-mgmt/pkg_rmleaves/
# make install
```

### 如何卸载所有自行安装的第三方软件？

```sh
# pkg delete -fa # 如果带上参数 f，会将 pkg 包管理器本身也卸载，因为 pkg 也是用户最初自行安装的软件。
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 87 packages (of 0 packages in the universe):

Installed packages to be REMOVED:
	alsa-lib: 1.2.12
	brotli: 1.1.0,1
	curl: 9.8.0
……省略一部分……
	pcre2: 10.43
	perl5: 5.36.3_1
	pkg: 1.21.3   # 如果带上参数 -f，会将 pkg 本身也删除，因为 pkg 也是用户最初自行安装的软件
	png: 1.6.43
	xorg-fonts-truetype: 7.7_1
	xorgproto: 2024.1
	zstd: 1.5.6

Number of packages to be removed: 87

The operation will free 825 MiB.

Proceed with deinstalling packages? [y/N]: # 输入 y 按回车键即可完成卸载
```

#### 参考文献

* FreeBSD Project. pkg delete -- deletes packages from the database and the system\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=pkg-delete&sektion=8>. 提供了 pkg 命令删除软件包的详细规范与参数说明。
* FreeBSD Project. pkg(7) -- a utility for manipulating packages\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=pkg&sektion=7>. FreeBSD 包管理工具手册页。

## 列出 pkg 包安装的文件

> **技巧**
>
> pkg 的下载路径是 **/var/cache/pkg/**。

```sh
/
└── var/
    └── cache/
        └── pkg/ # pkg 的下载路径
```

> **注意**
>
> 只能列出已安装软件包的文件，未安装的不能使用该命令。

```sh
# pkg info -l xrdp
xrdp-0.10.2_2,1:
	/usr/local/bin/xrdp-dis
	/usr/local/bin/xrdp-dumpfv1
	/usr/local/bin/xrdp-genkeymap
	/usr/local/bin/xrdp-keygen
	/usr/local/bin/xrdp-sesadmin
	/usr/local/bin/xrdp-sesrun
	/usr/local/etc/pam.d/xrdp-sesman
	/usr/local/etc/rc.d/xrdp
	……省略一部分……
```

## 查找缺少的 `.so` 文件（适用于 Linux 兼容层）

> **警告**
>
> 本节仅处理 Linux 兼容层缺少 `.so` 文件的问题。如果在 FreeBSD 上遇到此类问题，应首先更新系统，随后再更新软件源和软件。

### 安装 pkg-provides

```sh
# pkg install pkg-provides
```

或者：

```sh
# cd /usr/ports/ports-mgmt/pkg-provides/
# make install clean
```

### 配置使用 pkg-provides

* 查看配置说明：

```sh
# pkg info -D pkg-provides
```

目录结构：

```sh
/usr/local/
├── etc/
│   └── pkg.conf # pkg 配置文件
└── lib/
    └── pkg/ # pkg 插件目录
```

* 编辑 **/usr/local/etc/pkg.conf** 文件，找到空行，写入：

```ini
PKG_PLUGINS_DIR = "/usr/local/lib/pkg/";
PKG_ENABLE_PLUGINS = true;
PLUGINS [ provides ];
```

* 运行 `pkg plugins`：

```sh
# pkg plugins
NAME       DESC                                          VERSION
provides   A plugin for querying which package provides a particular file 0.7.4
```

* 刷新数据库：

```sh
# pkg provides -u
Fetching provides database: 100%   19 MiB   6.6MB/s    00:03
Extracting database....success
```

### 示例：查找 `libxcb-icccm.so.4`

```sh
# pkg provides libxcb-icccm.so.4
Name    : xcb-util-wm-0.4.2
Comment : Framework for window manager implementation
Repo    : FreeBSD
Filename: usr/local/lib/libxcb-icccm.so.4.0.0
          usr/local/lib/libxcb-icccm.so.4
```

## 故障排除与未竟事宜

### 在 pkg 中无法找到本书中提及的包

使用 pkg 安装教材中明确提及的软件包时若提示不存在，一般可将原因归纳为以下两种：

* 情况一：Ports 中确实不存在该 Port，可能的原因包括教材内容有误、该 Port 已从 Ports 集合中移除或已更名等。
* 情况二：Ports 中确实存在该 Port，但 FreeBSD 的 pkg 包是周期性构建的（与 Ports 自身的更新同步），因此时常出现暂时缺少对应 pkg 二进制包的情况。

具体原因建议查询 <https://www.freshports.org/>，上面会显示软件包的依赖情况和 pkg 包的构建情况。

本书中一般会同时列出 Ports 安装方式，例如要查 Port **x11/budgie**，操作方法如下：直接访问 <https://www.freshports.org/x11/budgie/>。

如果 Ports 中有该 Port，但 pkg 中暂时没有，等待 7–14 天通常即可（构建失败的包系统会自动向维护者报告错误）。如要立刻安装使用，请使用 Ports。

### `ld-elf.so.1: Shared object "libmd.so.6" not found, required by "pkg"`

该问题通常是由于软件源未及时同步基本系统 ABI 的变更。

对于一般 RELEASE，更新系统即可。对于 CURRENT/STABLE 系统，重新编译 `pkg` 即可。

#### RELEASE

请先切换到 latest 源，再使用软件源里的 pkg 包重装 pkg：

```sh
# pkg-static bootstrap -f  # 强制初始化 pkg 包管理器
```

若无效，则再：

```sh
# freebsd-update fetch        # 下载可用的 FreeBSD 更新
# freebsd-update install      # 安装下载的 FreeBSD 更新
# pkg-static update -f        # 强制更新本地软件包仓库索引
# pkg-static upgrade -f pkg   # 强制升级 pkg 工具本体
```

#### CURRENT/STABLE

```sh
# pkg-static delete -f pkg # 强制卸载当前的 pkg
# cd /usr/ports/ports-mgmt/pkg # 切换目录
# make BATCH=yes install clean # 使用 Ports 重新安装 pkg
```

### `pw: user 'package' disappeared during update`

问题示例：

```sh
[1/1] Installing package…
===> Creating groups.
Creating group 'package' with gid '000'.
===> Creating users
Creating user 'package' with uid '000'.
pw: user 'package' disappeared during update
pkg: PRE-INSTALL script failed
```

原因是用户数据库未同步。

根据 **/etc/master.passwd** 更新密码数据库：

```sh
# /usr/sbin/pwd_mkdb -p /etc/master.passwd
```

### `Shared object "x.so.x" not found, required by "xxx"`

出现该问题通常是由于 ABI 被破坏，更新即可解决。

使用 pkg 安装 `bsdadminscripts2`：

```sh
# pkg install bsdadminscripts2
```

或者使用 Ports 安装 `bsdadminscripts2`：

```sh
# cd /usr/ports/ports-mgmt/bsdadminscripts2/
# make install clean
```

检查已安装软件包的动态库依赖是否完整：

```sh
# pkg_libchk
doxygen-1.9.6_1,2: /usr/local/bin/doxygen misses libmd.so.6
jbig2dec-0.20_1: /usr/local/bin/jbig2dec misses libmd.so.6
jbig2dec-0.20_1: /usr/local/lib/libjbig2dec.so misses libmd.so.6
```

按照上述软件列表，使用 Ports 逐个重新编译即可（RELEASE 可以直接用 `pkg` 更新）。

#### 附录：`bsdadminscripts2` 扩展用法及参考文献

* lonkamikaze. BSD Administration Scripts II\[EB/OL]. \[2026-03-25]. <https://github.com/lonkamikaze/bsda2>. 提供 FreeBSD 系统管理辅助工具集，含包完整性检查等功能。

若使用了 PkgBase，`bsdadminscripts2` 可 **检查系统的完整性**，找出哪些系统文件遭到了篡改。

验证已安装软件包的完整性和一致性：

```sh
# pkg_validate
FreeBSD-pkg-bootstrap-15.snap20241004232339: checksum mismatch for /etc/pkg/FreeBSD.conf
FreeBSD-runtime-15.snap20241004232339: checksum mismatch for /etc/group
FreeBSD-runtime-15.snap20241004232339: checksum mismatch for /etc/master.passwd
```

* `bsdadminscripts2` 也可查找当前系统的过时软件：

```sh
# pkg_version -ql\<
akonadi-23.08.5_1
build2-0.17.0
chromium-128.0.6613.137
```

### `Newer FreeBSD version for package pkg`

问题示例：

```sh
Newer FreeBSD version for package pkg:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1402843
- running kernel: 1400042
Ignore the mismatch and continue? [y/N]:
```

这通常发生在已失去安全支持的系统或 CURRENT/STABLE 分支系统上，不影响使用，输入 `y` 即可。

如果要从根源上解决，需要卸载 pkg，从 Ports 安装 `ports-mgmt/pkg`；或者从源代码更新整个系统。

如果仅需屏蔽此提示，只需要按照提示将 `IGNORE_OSVERSION=yes` 写入 **/etc/make.conf** 文件中（如果文件不存在则新建）即可。

### `pkg: An error occurred while fetching package: No error`

以 root 权限执行 `certctl rehash` 刷新证书即可。

参见：pkg(8): “An error occurred while fetching package: No error”\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/pkg-8-an-error-occured-while-fetching-package-no-error.96761/>.

## 附录：FreeBSD 软件包原子更新的困难与现状分析

FreeBSD 镜像站的软件源（无论官方还是非官方）存在以下典型现象：

* 一旦某个 Port 发生更新，就会立即从软件源中撤销由该 Port 衍生的 pkg 二进制包，直到下次构建出新的 pkg 软件包，而非保留旧版本软件包；
* 只要开始一次新的构建，旧版本软件包就会立即从 pkg 软件源中删除，直到构建出新版本的 pkg 软件包。

一种可行的解决方案是：将软件包锁定在某一固定版本阶段（如季度分支），暂不更新，直接轮替版本。

问题在于 Port 更新是不定时的，复杂的依赖关系可能引发连锁问题。有能力者可尝试提出新的看法和建议，并反馈至下方或 [FreeBSD 论坛](https://forums.freebsd.org/)。

> **思考题**
>
> * 相关讨论 [the disappearing pkg issue](https://www.reddit.com/r/freebsd/comments/1nlnwtd/the_disappearing_pkg_issue/)
> * pkg 项目位于 [freebsd/pkg](https://github.com/freebsd/pkg)
> * pkg 软件包的构建系统位于 [Poudriere](https://github.com/freebsd/poudriere)
>
> 尝试：帮助 FreeBSD 项目实现 pkg 二进制软件包的原子更新？

## 课后习题

1. 阅读 pkg 源代码，定位其并行下载与安装的实现位置，尝试为其添加并行下载功能，并验证是否能显著提升安装速度。
2. 选取 pkg 的原子更新问题，设计一个实验方案，复现该问题，并提出一个可行的解决方案。
3. 为 pkg 新增 i18n 支持。


# 8.4 使用 Ports 以源代码方式安装软件

Ports 是 FreeBSD 从源代码构建软件的框架，适用于需要自定义编译选项、打补丁或安装 pkg 仓库中未收录的软件。

## 获取 Ports

> **注意**
>
> `portsnap` 自 FreeBSD 14.0 起已从基本系统中移除，FreeBSD 15.0 中已不再支持。从旧教程迁移的用户请使用下文介绍的 Git 方式获取 Ports。

使用压缩包可以规避“先有鸡还是先有蛋”的问题（例如需要安装 Git，但系统中既没有 Ports 又不想使用 pkg 的情况）。

### 使用 Ports 压缩包

可以从多个镜像源下载 Ports 压缩包，下面列出了几个常用的源地址。

* NJU:

```sh
# fetch https://mirrors.nju.edu.cn/freebsd-ports/ports.tar.gz
```

* 或 USTC

```sh
# fetch https://mirrors.ustc.edu.cn/freebsd-ports/ports.tar.gz
```

* 又或 FreeBSD 官方

```sh
# fetch https://download.freebsd.org/ftp/ports/ports/ports.tar.gz
```

#### 解压 Ports 压缩包

下载完成后，需要将压缩包解压到指定位置。

```sh
# tar -zxvf ports.tar.gz -C /usr/ # 解压至 /usr/ 目录
# rm ports.tar.gz # 删除压缩包
```

### 使用 Git 获取 Ports

Git 是获取 Ports 源代码的推荐方式，可以方便地管理版本和更新。

#### 安装 Git

首先需要安装 Git 工具，以便能够拉取源代码。

使用 pkg 安装：

```sh
# pkg install git
```

#### 拉取 Ports 存储库（USTC）的浅克隆

中国科学技术大学提供了 FreeBSD Ports 的镜像源，可以使用浅克隆的方式快速获取代码。

```sh
# git clone --filter=tree:0 https://mirrors.ustc.edu.cn/freebsd-ports/ports.git /usr/ports
```

> **注意**
>
> `--depth 1`（仅拉取最新的日志和提交记录）会给服务器带来较大计算压力，请尽量使用参数 `--filter=tree:0` 拉取。

#### 拉取 Ports 存储库（FreeBSD 官方）浅克隆

也可以直接从 FreeBSD 官方仓库获取源代码。

```sh
# git clone --filter=tree:0 https://git.FreeBSD.org/ports.git /usr/ports
```

#### 完全拉取 Ports 存储库（FreeBSD 官方）并指定分支

如果需要完整的提交历史和所有分支，可以完整克隆。

```sh
# git clone https://git.FreeBSD.org/ports.git /usr/ports
```

关于 quarterly 分支与 latest（main）分支的详细说明，参见其他相关章节。根据需要，可以切换到特定的分支，例如季度分支。

切换到 `2025Q1` 分支：

```sh
# git switch 2025Q1
正在更新文件: 100% (14323/14323), 完成.
分支 '2025Q1' 设置为跟踪 'origin/2025Q1'。
切换到一个新分支 '2025Q1'
```

切换完成后，可以查看本地分支以确认。

查看本地分支：

```sh
# git branch
* 2025Q1
  main
```

Git 分支已经切换成功。

#### 同步更新 Ports Git

获取 Ports 源代码后，需要定期同步更新以获取最新的修改。

```sh
# cd /usr/ports/ # 切换目标目录
# git pull -p # 同步更新上游 Ports（-p/--prune 用于清理远程已删除的端口）
```

如果提示本地已经修改，可以放弃本地修改后再更新：

```sh
# git restore .
# git pull -p
```

#### 附录：因时间错误导致的证书无效

在使用 Git 拉取代码时，可能会遇到 SSL 证书问题（报错形如 `SSL certificate problem: certificate is not yet valid`），常见原因是系统时间不正确。使用 `ntpd -q -g pool.ntp.org` 同步系统时间即可解决。详细说明参考本书其他相关章节。

## 使用 `whereis` 查询软件路径

`whereis` 命令可以帮助快速查找软件的可执行文件、源代码及手册页所在路径。

查找 python 可执行文件、源代码及手册页所在路径：

```sh
# whereis python
```

将输出：

```sh
python: /usr/ports/lang/python
```

## 查看软件包依赖

查看软件包依赖关系的方法如下。可在软件已安装或未安装的情况下查看其依赖。

在已安装该软件包的情况下：

```sh
# pkg info -d screen
screen-4.9.0_6:
	indexinfo-0.3.1
```

在未安装该软件包的情况下：

```sh
root@ykla:/usr/ports/sysutils/htop # make all-depends-list
/usr/ports/ports-mgmt/pkg
/usr/ports/devel/pkgconf
……省略一部分……
```

## 如何删除当前 Port 及其依赖的配置文件

如果需要清理之前配置的选项，可以使用以下命令删除当前 Port 及其所有依赖的配置文件。该命令递归遍历依赖树，逐个清除每个 Port 的 `make config` 设置，恢复为默认构建参数。

```sh
# make rmconfig-recursive
```

## 如何一次性下载所有需要的软件包

为避免编译过程中因网络问题中断，可先一次性下载所有需要的软件包。`fetch-recursive` 会递归获取主 Port 及其全部依赖的源代码包，配合 `BATCH=yes` 跳过交互式选项。

```sh
# make BATCH=yes fetch-recursive
```

## Ports 编译的软件也可以打包为 pkg 包

使用 Ports 编译安装的软件也可以打包为 pkg 格式的二进制包，方便在其他机器上部署，避免重复编译。打包后的文件默认输出至当前目录，可拷贝到目标机器后用 `pkg add` 安装。

```sh
# pkg create nginx
```

## 更新 FreeBSD 软件包/Port

更新前需要先同步更新 Ports Git。

随后列出过时的 Port 软件：

```sh
# pkg version -l '<'
chromium-127.0.6533.99             <
curl-8.9.1_1                       <
ffmpeg-6.1.2,1                     <
vlc-3.0.21_4,4                     <
w3m-0.5.3.20230718_1               <
```

### 安装 portmaster

portmaster 是一款常用的 Ports 更新工具，可以帮助管理和更新已安装的软件。

* 更新已安装的 Port：

```sh
# cd /usr/ports/ports-mgmt/portmaster && make install clean	# 安装 portmaster
# portmaster -a # 自动升级所有软件
# portmaster screen # 升级单个软件
```

若需跳过交互确认，可使用类似 BATCH=yes 的选项 `-a -G --no-confirm`：

```sh
# portmaster -a -G --no-confirm
```

### 查看 Port 依赖关系

在更新软件前，可以先查看 Port 的依赖关系，了解更新会影响哪些软件。

```sh
# portmaster sysutils/htop  --show-work

===>>> Port directory: /usr/ports/sysutils/htop

===>>> Starting check for all dependencies
===>>> Gathering dependency list for sysutils/htop from ports

===>>> Installed devel/autoconf
===>>> Installed devel/automake
===>>> NOT INSTALLED		devel/libtool
===>>> NOT INSTALLED		devel/pkgconf
===>>> NOT INSTALLED		lang/python311
===>>> Installed ports-mgmt/pkg
```

### 参考文献

更多信息可以参考以下官方文档。

* FreeBSD Project. portmaster -- manage your ports without external databases or languages\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=portmaster&sektion=8>. 无需外部数据库的 Ports 管理工具完整说明。

## 全局设置 Ports 构建选项

FreeBSD Ports 框架支持在 **/etc/make.conf** 中全局控制构建选项和依赖。

### 如何全局屏蔽 MySQL

如果不希望使用 MySQL 相关选项，可以在全局配置中屏蔽它。

```sh
# echo "OPTIONS_UNSET+= MYSQL" >> /etc/make.conf
```

完整的 OPTIONS 列表见 <https://cgit.freebsd.org/ports/tree/Mk/bsd.port.mk>。完整的 DEFAULT\_VERSIONS 列表见 <https://cgit.freebsd.org/ports/tree/Mk/bsd.default-versions.mk>。

## 附录：Port 安装示例

### 安装 python3

现在以安装 python3 为例，演示如何使用 Ports 编译安装软件。

```sh
# cd /usr/ports/lang/python
# make BATCH=yes install clean
```

其中 `BATCH=yes`（批处理）意味着按默认参数构建。

### 如何设置所有必需的依赖

在编译软件前，有时需要先设置所有依赖项的配置选项。

```sh
# make config-recursive
```

### 如何使用 pkg 安装依赖

为了节省编译时间，可以使用 pkg 来安装所需的依赖，仅使用 Ports 来编译软件包本体。

不使用 Ports 来编译依赖，仅使用 Ports 来编译软件包本体：

```sh
# make install-missing-packages
```

以 `chinese/fcitx` 为示例：

```sh
# cd /usr/ports/chinese/fcitx
# make install-missing-packages
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
Updating FreeBSD-base repository catalogue...
FreeBSD-base repository is up to date.
All repositories are up to date.
Updating database digests format: 100%
The following 2 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	e2fsprogs-libuuid: 1.47.1 [FreeBSD]
	enchant2: 2.2.15_5 [FreeBSD]

Number of packages to be installed: 2

94 KiB to be downloaded.

Proceed with this action? [y/N]:
```

## 故障排除与未竟事宜

### `autoconf-2.72 Invalid perl5 version 5.42.`

也可理解为“xxx-yy Invalid zz version aa”这一类报错。

实例，在使用 Ports 安装 openjdk21 时报错如下：

```sh
[root@Server /usr/ports/java/openjdk21]# make install clean
===> openjdk21-21.0.4+7.1 depends on executable: zip - found
===> openjdk21-21.0.4+7.1 depends on package: autoconf>0 - not found ①
===> autoconf-2.72 Invalid perl5 version 5.42. ②
*** Error code 1

Stop.
make[1]: stopped in /usr/ports/devel/autoconf
*** Error code 1

Stop.
make: stopped in /usr/ports/java/openjdk21
```

观察整个流程可知，openjdk21 依赖 autoconf，但系统中并未安装。于是递归查找 autoconf 的依赖，发现 autoconf 依赖 perl5；结合 ② 可知系统中已有 perl5，但报错 `Invalid version`，即 perl5 的版本不符合要求。

此问题一般需要先更新 Ports，随后通过 `pkg install -f perl5` 或 `pkg upgrade` 更新 perl5 版本即可解决。

#### 参考文献

* FreeBSD Forums. Invalid perl5 version 5.32\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/invalid-perl5-version-5-32.77628/>. 出现了与上文同样的问题。


# 8.5 Ports 构建调优

## FreeBSD Ports 多线程编译

为加快编译速度，可配置多线程编译选项，利用多核处理器的性能。

将以下内容写入 **/etc/make.conf** 文件，若不存在则 `touch` 新建对应文件。

```ini
FORCE_MAKE_JOBS=yes       # 强制启用并行编译
MAKE_JOBS_NUMBER=4        # 设置并行编译的作业数为 4
```

在 Linux（如 Gentoo）上，一般直接使用 `-jX` 或 `-j(X+1)`，`X` 为核心数。

`4` 表示处理器的并行编译数（通常对应核心数或线程数）。

可以通过命令查看系统检测到的 CPU 核心数量：

```sh
# sysctl kern.smp.cpus
kern.smp.cpus: 16
```

或者查看系统可用的 CPU 核心数：

```sh
# sysctl hw.ncpu
hw.ncpu: 16
```

输出值即可作为 `MAKE_JOBS_NUMBER` 取值。

搜索英特尔处理器型号加 `ARK`，可跳转至英特尔官网查询线程数。

* FreeBSD Project. SMP -- symmetric multiprocessing kernel subsystem\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=SMP&sektion=4>. SMP 子系统中 kern.smp.cpus 与 hw\.ncpu 等 sysctl 变量的文档。

## 将 /tmp 设置为内存文件系统

为提高临时文件的读写速度，可将 **/tmp** 目录挂载为内存文件系统 tmpfs。

编辑 **/etc/fstab** 文件，写入下行：

```ini
tmpfs /tmp tmpfs rw 0 0
```

`reboot` 重启即可。

### 参考文献

* FreeBSD Project. tmpfs -- in-memory file system\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=tmpfs&sektion=4>. 内存文件系统 tmpfs 的官方技术规范。

## 使用 ccache 编译缓存

ccache 是一款编译缓存工具，可加速重复编译的过程。

> **警告**
>
> 使用 ccache 可能会导致编译失败。它仅在重复编译时才有效，首次编译不仅不会加速，反而可能更慢，是一种以空间换时间的手段。

```sh
ccache 工作原理

  首次编译（Cache Miss）：
    源代码 ──► ccache ──► 编译器 ──► 目标文件
                  │
                  └──► 存入缓存

  重复编译（Cache Hit）：
    源代码 ──► ccache ──► 直接输出目标文件
                  │
                  └──► 命中缓存（跳过编译）
```

ccache3 是一个常用的版本。

### 安装 ccache3

使用 pkg 安装：

```sh
# pkg install ccache
```

* 使用 Ports 安装：

```sh
# cd /usr/ports/devel/ccache/
# make install clean
```

安装完成后，可以查看 ccache 创建的软链接：

```sh
# ls -al /usr/local/libexec/ccache
total 56
drwxr-xr-x   3 root wheel 15 Sep 20 02:02 .
drwxr-xr-x  18 root wheel 49 Sep 20 01:39 ..
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 CC -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 c++ -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 cc -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 clang -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 clang++ -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 clang++15 -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 02:02 clang++18 -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 clang15 -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 02:02 clang18 -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 cpp13 -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 g++13 -> /usr/local/bin/ccache
lrwxr-xr-x   1 root wheel 21 Sep 20 00:29 gcc13 -> /usr/local/bin/ccache
drwxr-xr-x   2 root wheel 15 Sep 20 02:02 world
```

#### 配置 ccache3

配置 ccache 以启用编译缓存：

* 修改 **/etc/make.conf** 文件，加入下面一行启用 ccache 加速编译：

```ini
WITH_CCACHE_BUILD=yes
```

为了避免缓存占用过多磁盘空间，建议设置缓存大小上限。

* 设置 ccache 编译缓存最大为 10 GB：

```sh
# ccache -M 10G
Set cache size limit to 10.0 GB
root@ykla:/usr/ports/www/chromium # ccache -s
cache directory                     /root/.ccache
primary config                      /root/.ccache/ccache.conf
secondary config      (readonly)    /usr/local/etc/ccache.conf
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                             0
cache hit rate                      0.00 %
cleanups performed                     0
files in cache                         0
cache size                           0.0 kB
max cache size                      10.0 GB
```

在使用一段时间后，可以查看 ccache 的统计信息，了解缓存的命中情况。

* 在 Ports 编译一段时间后显示 ccache 的统计信息：

```sh
# ccache -s
cache directory                     /root/.ccache
primary config                      /root/.ccache/ccache.conf
secondary config      (readonly)    /usr/local/etc/ccache.conf
stats updated                       Fri Sep 20 02:05:35 2024
cache hit (direct)                    20
cache hit (preprocessed)              17
cache miss                           918
cache hit rate                      3.87 %
called for link                      121
called for preprocessing              26
compile failed                       115
preprocessor error                    66
bad compiler arguments                15
autoconf compile/link                523
no input file                         71
cleanups performed                     0
files in cache                      2305
cache size                           0.0 kB
max cache size                      10.0 GB
```

### 安装 ccache4

ccache4 是 ccache 的较新主版本，安装与配置方式与 ccache3 相同，仅包名不同。

使用 pkg 安装：

```sh
# pkg install ccache4
```

或使用 Ports 安装：

```sh
# cd /usr/ports/devel/ccache4/
# make install clean
```

#### 配置 ccache4

软链接与 **/etc/make.conf** 配置均与 ccache3 一致，不再赘述。ccache4 的输出格式略有不同：

* 设置编译缓存最大为 20 GB：

```sh
# ccache -M 20G
Set cache size limit to 20.0 GB
```

* 在 Ports 编译一段时间后，查看编译缓存：

```sh
# ccache -s
Cacheable calls:   558 /  579 (96.37%)
  Hits:            110 /  558 (19.71%)
    Direct:        110 /  110 (100.0%)
    Preprocessed:    0 /  110 ( 0.00%)
  Misses:          448 /  558 (80.29%)
Uncacheable calls:  21 /  579 ( 3.63%)
Local storage:
  Cache size (GB): 0.0 / 20.0 ( 0.11%)
  Hits:            110 /  558 (19.71%)
  Misses:          448 /  558 (80.29%)
```

显示 ccache4 的当前配置参数：

```sh
# ccache -p
(default) absolute_paths_in_stderr = false
(default) base_dir =
(default) cache_dir = /root/.cache/ccache
……省略一部分……
```

### 参考文献

关于 ccache 的更多详细信息和使用方法，可以参考以下资料。

* FreeBSD Project. ccache-howto-freebsd.txt.in\[EB/OL]. \[2026-03-25]. <https://github.com/freebsd/freebsd-ports/blob/main/devel/ccache/files/ccache-howto-freebsd.txt.in>. FreeBSD Ports 中 ccache 的配置指南，说明如何在编译时启用缓存加速。
* FreeBSD Project. ccache - a fast C/C++ compiler cache\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=ccache&sektion=1&n=1>.

## 多线程下载

为加快 Ports 源代码的下载速度，可使用多线程下载工具。

### axel

axel 是一款轻量级的多线程下载工具，可显著提高下载速度。

使用 pkg 安装：

```sh
# pkg install axel
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/ftp/axel/
# make install clean
```

安装完成后，需要配置 Ports 框架使用 axel 作为下载工具。

新建或者编辑 **/etc/make.conf** 文件，写入以下几行：

```ini
FETCH_CMD=axel                # 设置使用 axel 作为下载工具
FETCH_BEFORE_ARGS=-n 10 -a    # 设置 axel 下载前的参数：使用 10 个线程并显示替代进度条
FETCH_AFTER_ARGS=              # 下载后执行的命令参数为空
DISABLE_SIZE=yes               # 禁用文件大小检查
```

### wget2

使用 Ports 安装：

```sh
# cd /usr/ports/www/wget2/ && make install clean
```

新建或者编辑 **/etc/make.conf** 文件，写入以下几行：

```ini
FETCH_CMD=wget2               # 设置使用 wget2 作为下载工具
FETCH_BEFORE_ARGS=-c -t 3 --max-threads=16 # 设置 wget2 下载前的参数
FETCH_AFTER_ARGS=             # 下载后执行的命令参数为空
DISABLE_SIZE=yes              # 禁用文件大小检查
```

wget2 参数说明：

* `-c` 断点续传
* `-t 3` 重试次数 3
* `--max-threads=16` 将最大并发下载线程数设为 16，默认为 5

> **技巧**
>
> 很多服务器不支持较多线程同时下载。这会给服务器带来较大压力，也可能会触发服务器的反制措施，如将下载的 IP 加入黑名单。

### 参考文献

* FreeBSD Project. ports -- contributed applications\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=ports&sektion=7>. Ports 框架的官方文档，包含 FETCH\_CMD 与 BATCH 等参数说明。


# 8.6 使用 DVD 安装软件

## 挂载 DVD

使用 DVD 安装软件前，首先需将 DVD 挂载到系统。挂载方式有两种，分别适用于本地 ISO 文件和物理 DVD 设备。

要挂载现有的文件系统镜像，请使用 `mdconfig` 为 ISO 文件的指定名称和空闲的单元编号。随后，引用该单元编号将其挂载到现有的挂载点。挂载后，ISO 文件中的文件将显示在挂载点中。

```sh
DVD 安装软件流程

  ISO 文件
      │
      │ mdconfig
      ▼
  /dev/md0
      │
      │ mount -t cd9660
      ▼
  /dist（挂载点）
      │
      │ pkg install
      ▼
  软件安装完成（离线）
```

此示例将 **FreeBSD-14.2-RELEASE-amd64-dvd1.iso** 附加到内存设备 **/dev/md0**，随后将该内存设备挂载到 **/dist**：

### 直接挂载本地 ISO

```sh
# mdconfig -f /home/ykla/FreeBSD-14.2-RELEASE-amd64-dvd1.iso  # 请替换为实际 ISO 路径，可使用 pwd 查看当前路径
md0
# mkdir -p /dist  # 创建挂载路径，必须是此路径
# mount -t cd9660 /dev/md0 /dist # 不能直接挂载 ISO，会报错 block device required
```

注意，`-t cd9660` 用于挂载 ISO 格式。

### 直接使用 DVD 设备（如通过虚拟机直接挂载的 ISO 镜像）

观察 ISO 镜像的挂载情况：

```sh
# gpart show  # 显示系统中所有磁盘分区表信息

……省略无用磁盘……

=>      9  2356635  cd0  MBR  (4.5G)
        9  2356635       - free -  (4.5G)
```

可以看到存在 `cd0`，大小符合预期。

```sh
# mkdir -p /dist # 创建挂载点
# mount -t cd9660 /dev/cd0 /dist # 挂载 ISO
# ls /dist/ # 查看挂载情况
.cshrc		bin		lib		net		root		var
.profile	boot		libexec		packages	sbin
.rr_moved	dev		media		proc		tmp
COPYRIGHT	etc		mnt		rescue		usr
```

### 故障排除与未竟事宜

因为 `packages/repos/FreeBSD_install_cdrom.conf` 中的路径是固定值，无法修改，所以如果将目录 **/dist** 改为其他路径，则使用环境变量的方法无效。

## 使用环境变量直接安装 DVD 软件

让 pkg 使用指定的软件仓库路径安装 Xorg：

```sh
# env REPOS_DIR=/dist/packages/repos pkg install xorg
Updating FreeBSD_install_cdrom repository catalogue...
FreeBSD_install_cdrom repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	xorg: 7.7_3

Number of packages to be installed: 1

Proceed with this action? [y/N]:
```

要列出 DVD 中的可用软件：

```sh
# env REPOS_DIR=/dist/packages/repos pkg rquery "%n"
```

## 更换软件源为 DVD

### 创建 DVD 软件源

将 `FreeBSD_install_cdrom.conf` 复制到 **/etc/pkg/** 目录下：

```sh
# cp /dist/packages/repos/FreeBSD_install_cdrom.conf /etc/pkg/
```

### 测试安装

安装 Xorg 图形系统：

```sh
# pkg install xorg
Updating FreeBSD_install_cdrom repository catalogue...
FreeBSD_install_cdrom repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
	xorg: 7.7_3

Number of packages to be installed: 1

Proceed with this action? [y/N]:
```

## 弹出 DVD 并释放资源

当不再使用内存磁盘时，应将其资源释放回系统。首先，卸载文件系统，随后使用 `mdconfig` 从系统中分离磁盘并释放其资源。继续此示例：

```sh
# umount /dist
# mdconfig -d -u 0
```

要确定是否仍有内存磁盘附加到系统，请输入 `mdconfig -l` 命令。

## 参考文献

* FreeBSD Project. HOWTO: Install binary package without internet access\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/howto-install-binary-package-without-internet-acces.60723/>. 无网络环境下通过 DVD 安装二进制包的方法。
* FreeBSD Project. pkg(8) -- package manager\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=pkg&sektion=8>. FreeBSD 包管理器手册页。

## 课后习题

1. 阅读 `bsdconfig` 的源代码，定位 `No pkg(8) database found!` 错误的原因，并尝试修复该问题使其能够正常利用 DVD 安装软件。
2. 分析 DVD 安装方式中路径被硬编码为 **/dist** 的设计，重构这一机制使其支持自定义路径。
3. 修改 pkg 的仓库配置机制，使其支持从本地文件系统的任意目录作为软件源，并验证其在离线环境中的可用性。


# 8.7 FreeBSD 镜像站现状

FreeBSD 官方 rsync 服务不向公众开放，且项目不接受官方二级镜像申请。本节梳理镜像站部署的政策约束、历史演变与社区实践方案，为有意参与镜像建设的读者提供背景参考。

## 镜像站现状与基本格局

### 官方未开放 rsync 服务

当前 FreeBSD 镜像站生态面临两个核心约束：

1. 官方 rsync 服务暂未对公众开放；
2. 项目未接受镜像站的官方二级镜像申请。

根据可查证的历史信息，FreeBSD 项目最迟在 2015 年 5 月就已停止公开 rsync 服务。相关文档 [Add small section explaining we are not allowing public mirrors of packages and possible workarounds.](https://reviews.freebsd.org/R9:3418e47d2f6cd8dd04ac934f38d136ba9101a5a8) 记录了项目禁止公共包镜像的决策及替代方案。官方给出的理由如下：

> Due to very high requirements of bandwidth, storage and administration the FreeBSD Project has decided not to allow public mirrors of packages.
>
> 由于对带宽、存储和管理的要求极高，FreeBSD 项目决定不允许公共镜像软件包。

***

2025 年 2 月获取的最新官方回复进一步阐明了项目立场：

> On Fri, 28 Feb 2025, at 17:45, ykla wrote:
>
> > How to mirror pkg and update from official mirror sites?
>
> As we replied on several occasions before: pkg and freebsd-update need machines under our control with internet connectivity to the rest of our cluster.
>
> At one point someone tried to offer a machine in Nanjing. That then turned into a virtual machine and the conversation went nowhere. We can't use a virtual machine. We need real hardware. With real storage. And real transit.

翻译如下：

> 2025 年 2 月 28 日星期五 17:45，ykla 写道：
>
> > 如何通过官方镜像站点进行 pkg 镜像和系统更新？
>
> 正如我们此前多次回复的，pkg 和 freebsd-update 功能需要由我们管控的物理服务器支持（注：此处指 root 权限），这些服务器需与我们的集群保持网络连接。
>
> 此前有人曾提议提供南京的一台机器，但后续方案变更为虚拟机形式后讨论便陷入停滞。我们无法使用虚拟机方案，需要真实的硬件设备（注：指裸金属）、实体存储介质和物理网络传输链路。

### 未开放的可能原因分析

#### 安全性因素

追溯历史记录，FreeBSD 基础设施集群曾于 2012 年发生安全入侵事件。项目在全面转向 pkg 分发机制后终止了外部镜像的授权，以保障软件供应链完整性与安全性。

参考文献：

* delphij. FreeBSD.org 这次的入侵事件\[EB/OL]. (2012-12-17)\[2026-03-25]. <https://blog.delphij.net/posts/2012/12/freebsdorg-2/>. 中文说明。
* FreeBSD Project. FreeBSD.org intrusion announced November 17th 2012\[EB/OL]. (2012-11-17)\[2026-03-25]. <https://www.freebsd.org/news/2012-compromise.html>. FreeBSD 项目官方说明。

#### 传输机制因素

当前集群的数据同步机制采用了基于 ZFS 文件系统的直接传输方式（据社区了解，通过 `zfs send` / `zfs receive` 命令实现），而非传统的 rsync 镜像站同步模式。这也限制了外部镜像的可行性。

#### 资源限制因素

根据 [\[NEW MIRROR\] New full mirror in Belgium](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=288631)，集群管理员 bofh 回复如下：

> There are couple of reasons:
>
> 1. Bandwidth from our central servers. Increasing number of community mirrors require more bandwidth in case everyone starts pulling altogether like just after a new quarterly branch
>
> 2. While many sites are excited to create mirrors as they think they have real bandwidth in reality they lose their moral bandwidth in couple of days and our mirrors are no longer in sync. We are often communicated regarding the problems of other community mirrors. We already operate in a tight schedule and often overseeing other mirrors is just another nail in the wall.
>
> 3. We still accept mirrors but on a different way. If people can sponsor bare metal we would be happy to deploy a new mirror. However our mirror requirements are pretty high. You can have a look at the following to understand our requirements:
>
> * <https://wiki.freebsd.org/Teams/clusteradm/generic-mirror-layout>
> * <https://wiki.freebsd.org/Teams/clusteradm/tiny-mirror>

译文：

> 有几个原因：
>
> 1. 来自我们中心服务器的带宽。社区镜像数量增加时，如果大家都同时开始拉取，例如在一个新的 quarterly 分支刚发布之后，就会需要更多带宽。
>
> 2. 许多站点在创建镜像时非常兴奋，确信自己拥有真实的带宽，但实际上，他们的“道义带宽”往往在几天后就耗尽了，也不再同步我们的镜像。我们经常收到关于其他社区镜像问题的沟通。我们本来日程就很紧，再去监督其他镜像就如同给墙上再钉一颗钉子。
>
> 3. 我们仍然接受镜像，但方式有所不同。如果有人能够赞助裸金属服务器，我们会很乐意部署新的镜像。不过，我们对镜像的要求相当高。你可以查看以下内容来了解我们的要求：
>
> * <https://wiki.freebsd.org/Teams/clusteradm/generic-mirror-layout>
> * <https://wiki.freebsd.org/Teams/clusteradm/tiny-mirror>

> **思考题**
>
> > 我认为，“不接受社区镜像”与“拒绝镜像”是两件完全不同的事情。Ubuntu 拥有大量社区镜像，而其中真正被官方认可的只是极少数。这本质上体现了用户的自由选择。用户可以选择表面看来更安全的官方镜像，也可以为了速度而牺牲部分安全与隐私。我们没有资格替用户做这个选择。
> >
> > 对于一个快要渴死的人来说，问题不是他该喝可口可乐还是污水。
>
> > 在关闭 rsync 且不提供其他同步渠道的情况下，而多数开源镜像都依赖 rsync，他们实际上阻碍了 FreeBSD 项目的自身发展。项目声称带宽不足，但我怀疑 OpenBSD 或 NetBSD 的带宽能显著更多。然而它们却通过开放与自由的方式，让用户自己掌握选择。
> >
> > 就像今天发生的事情一样：我批评了一个据说用于测试并切换不同 FreeBSD 包镜像的测速工具，可安装它却需要额外拉上 45 个依赖。这就好比在设想皇帝该穿什么衣服、用哪种金锄头锄地——或者发明一种只能在白天亮灯的灯泡。
> >
> > 我并非在批评任何个人；我真正质疑的是，这套系统及其设计本身是否合理。
> >
> > FreeBSD 只是在技术上切换到了 Git，思想还停留在 SVN 时代。SVN 是集中式的、统一的、强权限的；Git 是分布式的，去权限的，允许自由分支的。当代互联网强调的是去中心化和分享。没有为什么，正如城市化和逆城市化一样都是合理的，也都是不合理的，只是一种趋势要求我们必须这样那样做，否则就会失去自身存在的合理性。你说得有道理也是现实，他们可能同步几天就撒手不管了。而问题在于，选择权应该取决于用户而不是项目本身。我认为这是一种家长制作风的体现。这也表明了老项目转型的困难更多不是技术而是理念。
>
> > 即日已抵龙南，明日入巢，四路兵皆已如期并进，贼有必破之势。某向在横水，尝寄书仕德云：“破山中贼易，破心中贼难。”区区剪除鼠窃，何足为异？若诸贤扫荡心腹之寇，以收廓清平定之功，此诚大丈夫不世之伟绩。数日来谅已得必胜之策，捷奏有期矣。何喜如之！
> >
> > 日孚美质，诚可与共学，此时计已发舟。倘未行，出此同致意。廨中事以累尚谦，想不厌烦琐。小儿正宪，犹望时赐督责。（《王阳明全集·卷四·文录一·与杨仕德薛尚谦书》）
>
> > 结合王阳明平定南赣，改革吏治，肃清朝野，破官、民“心中贼”的史实，请读者阐述：强迫某人使之自由，这本身是一种自由还是法西斯主义？

### 中国大陆目前没有 FreeBSD 官方镜像站

经多次沟通尝试（包括通过邮件列表联系约五次，其中三次获得回应，两次未获回应），均未取得有效进展。官方主要回复为“深表歉意，但台湾地区已有镜像”，未就镜像申请的具体流程提供进一步说明。此外，曾特别向中国科学技术大学 Linux 用户协会申请镜像，反馈 FreeBSD 官方也未获回应。

目前已被关闭（Closed as not planned）的非官方 issue 镜像申请：

USTC：

* <https://github.com/ustclug/mirrorrequest/issues/172>
* <https://github.com/ustclug/mirrorrequest/issues/171>

目前已经关闭的非官方 issue 镜像申请：

TUNA: <https://github.com/tuna/issues/issues/16>

## 呼吁高校学生参与镜像 FreeBSD

如果有条件搭建非官方镜像，可以使用 USTCLUG 所提供的同步脚本：

1. USTCLUG. FreeBSD-pkg Script\[EB/OL]. \[2026-03-25]. <https://github.com/ustclug/ustcmirror-images/blob/master/freebsd-pkg/sync.sh>.
2. USTCLUG. FreeBSD-ports Script\[EB/OL]. \[2026-03-25]. <https://github.com/ustclug/ustcmirror-images/blob/master/freebsd-ports/sync-ports.sh>.

来搭建非官方镜像站。赠人玫瑰，手有余香。

优先建议高校学生使用校内资源搭建，或者直接从 USTC 的 `rsync` 服务进行同步。建议同步前先咨询 USTCLUG，以免带来不必要的麻烦，联系方式：<lug@ustc.edu.cn>。参考 [科大源同步方法与注意事项](https://mirrors.ustc.edu.cn/help/rsync-guide.html) 同步。

## 官方给出的镜像站基本要求

* 服务器的 root 权限在国内同样稀缺，开源镜像站通常不会给予；
* IPv6 及 BGP 网络——国内同样较为缺乏；其中 CN2 网络在中国大陆同样稀缺，但并非 FreeBSD 官方要求，而是国内网络环境的额外考量；
* 足够的存储空间（微型镜像约 16 TB，完整镜像需求更大）和 1 G 带宽；
* 微型镜像需要 1 台服务器，完整镜像需要多台；
* 备案问题——需要专门公司/社会组织才能给 cn.FreeBSD.org 备案；
* 还有一个最大的问题：**缺乏资金**。

细节可查看：

* 单个镜像：<https://wiki.freebsd.org/Teams/clusteradm/tiny-mirror>
* 完整镜像：<https://wiki.freebsd.org/Teams/clusteradm/generic-mirror-layout>

## 非官方镜像站

FreeBSD 在中国大陆境内没有官方镜像站；在中国台湾地区有官方镜像站（截至 2026 年第二季度，台湾镜像站处于长期中断状态，项目方正在努力恢复中）。

FreeBSD 在中国大陆境内为数不多且能正常同步的镜像站，均未使用 `rsync` 等方式同步，而是采取了一些特殊手段。

* [FreeBSD-pkg 脚本](https://github.com/ustclug/ustcmirror-images/blob/master/freebsd-pkg/sync.sh)
* [FreeBSD-ports 脚本](https://github.com/ustclug/ustcmirror-images/blob/master/freebsd-ports/sync-ports.sh)

> **技巧**
>
> 呼吁有余力者维护修订上述两个脚本，以减轻 USTC 镜像站的压力，同时为境内提供更好的 FreeBSD 镜像服务。

FreeBSD 目前在大陆有若干个非官方镜像站：

| 镜像站               | 服务类型                 | 链接                                           | 备注                                                                      |
| ----------------- | -------------------- | -------------------------------------------- | ----------------------------------------------------------------------- |
| 中国科学技术大学镜像站（USTC） | pkg、Ports、pub        | <https://mirrors.ustc.edu.cn/>               | 联系方式：<lug@ustc.edu.cn>                                                  |
| 中国科学技术大学镜像站（USTC） | FreeBSD Pub          | <https://mirrors.ustc.edu.cn/freebsd/>       | /                                                                       |
| 中国科学技术大学镜像站（USTC） | FreeBSD Packages     | <https://mirrors.ustc.edu.cn/freebsd-pkg/>   | /                                                                       |
| 中国科学技术大学镜像站（USTC） | FreeBSD Ports        | <https://mirrors.ustc.edu.cn/freebsd-ports/> | [使用文档](https://mirrors.ustc.edu.cn/help/freebsd-ports.html)             |
| 网易 163 镜像站        | pkg、Ports（上游均为 USTC） | <https://mirrors.163.com/>                   | /                                                                       |
| 网易 163 镜像站        | FreeBSD Pub          | <https://mirrors.163.com/freebsd/>           | /                                                                       |
| 网易 163 镜像站        | FreeBSD Packages     | <https://mirrors.163.com/freebsd-pkg/>       | /                                                                       |
| 网易 163 镜像站        | FreeBSD Ports        | <https://mirrors.163.com/freebsd-ports/>     | /                                                                       |
| 南京大学开源镜像站         | pkg、Ports（上游均为 USTC） | <https://mirrors.nju.edu.cn/>                | 联系方式：[GitHub Issue](https://github.com/nju-lug/NJU-Mirror-Issue/issues) |
| 南京大学开源镜像站         | FreeBSD Pub          | <https://mirrors.nju.edu.cn/freebsd/>        | /                                                                       |
| 南京大学开源镜像站         | FreeBSD Packages     | <https://mirrors.nju.edu.cn/freebsd-pkg/>    | /                                                                       |
| 南京大学开源镜像站         | FreeBSD Ports        | <https://mirrors.nju.edu.cn/freebsd-ports/>  | /                                                                       |

FreeBSD 官方联系方式：

* <mirror-admin@freebsd.org>
* <freebsd-hubs@freebsd.org>，这个邮件列表似乎已不再活跃。

## 其他思路或解决方案

自行使用 Poudriere 构建并分发。如 [RISC-V FreeBSD-pkg 软件源上线！11619+ 预编译包助力快速构建 FreeBSD 环境](https://mp.weixin.qq.com/s/ngv3eZh1TEVgk3Pn3XfRBg)（项目已停止维护）

## 课后习题

1. 查找 USTCLUG 提供的 FreeBSD-pkg 同步脚本，在本地搭建一个最小化的 pkg 镜像站，并测试其是否可以被其他 FreeBSD 系统作为软件源使用。
2. 比较 FreeBSD、OpenBSD 和 NetBSD 三个项目的镜像站授权政策差异，分析这种差异如何影响各自的用户群体规模与生态健康度。
3. 假设有一台裸金属服务器可以赞助给 FreeBSD 项目，设计一个完整的镜像站部署方案。


# 9.1 计算机网络基础

FreeBSD 是理想的互联网或内网服务器操作系统，能在极高负载下提供稳健的网络服务，并高效使用内存，在数千个并发用户进程下保持良好响应时间。

FreeBSD 网络配置涉及多个核心命令和配置文件：

| 命令/文件                | 用途                             |
| -------------------- | ------------------------------ |
| `ifconfig`           | 配置网络接口参数                       |
| `route`              | 手动操作网络路由表                      |
| **/etc/rc.conf**     | 系统启动配置的核心文件，网络接口的持久化配置均存储在此文件中 |
| **/etc/resolv.conf** | 配置 DNS 解析器信息                   |
| **/etc/hosts**       | 提供本地主机名到 IP 地址的静态映射            |

## 网络模型基础

计算机网络是将地理位置不同、具有独立功能的多台计算机及其外部设备，通过通信线路连接起来的系统。在网络操作系统、网络管理软件及网络通信协议的管理和协调下，该网络实现资源共享和信息传递。

FreeBSD 网络子系统基于 TCP/IP 协议族实现，遵循互联网协议套件的分层架构。

TCP/IP 协议族采用四层模型组织网络功能：

| 层次  | 名称                     | 功能说明                                                                                                                                                         |
| --- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 第一层 | 网络接口层（Link Layer）      | 负责在物理网络介质上发送和接收数据帧，处理硬件地址（MAC 地址）解析。该层对应 FreeBSD 中的网络接口驱动程序，其配置由 `ifconfig` 命令管理。以太网帧的发送和接收、地址解析（ARP，Address Resolution Protocol）均在该层完成                      |
| 第二层 | 互联网层（Internet Layer）   | 负责数据包的路由和转发，核心协议为 IP（Internet Protocol），同时处理逻辑寻址（IP 地址）、分片与重组、路由选择等功能。路由表管理和 `route` 命令操作均属于该层                                                               |
| 第三层 | 传输层（Transport Layer）   | 提供端到端的通信服务，主要协议为 TCP（Transmission Control Protocol）和 UDP（User Datagram Protocol）。TCP 提供可靠的面向连接传输，UDP 提供无连接的不可靠传输。FreeBSD 实现了多 TCP 栈共存架构，允许系统同时加载多个 TCP 协议栈实现 |
| 第四层 | 应用层（Application Layer） | 包含多种面向用户的网络应用协议，如 HTTP、SSH、DNS、SMTP 等。FreeBSD 通过 Ports 和 pkg 提供了大量网络服务软件                                                                                     |

TCP/IP 四层模型与数据封装过程如下：

![TCP/IP 四层模型与数据封装](/files/SeRFGqhNrFnRtC1pbygQ)

### 参考文献

* Kurose J F, Ross K W. 计算机网络：自顶向下方法（原书第 8 版）\[M]. 陈鸣，译. 北京: 机械工业出版社, 2022. ISBN: 978-7-111-71236-7.

## 识别网络适配器

FreeBSD 支持多种有线和无线网络适配器。查看所用 FreeBSD 版本的硬件兼容性列表，确认网络适配器是否受支持。

### 通过 pciconf 命令识别网络适配器

要获取系统使用的网络适配器，执行以下命令：

```sh
% pciconf -lv | grep -A1 -B3 network
```

输出示例如下：

```sh
em0@pci0:2:1:0:	class=0x020000 rev=0x01 hdr=0x00 vendor=0x8086 device=0x100f subvendor=0x15ad subdevice=0x0750
    vendor     = 'Intel Corporation'
    device     = '82545EM Gigabit Ethernet Controller (Copper)'
    class      = network
    subclass   = ethernet

iwm0@pci0:3:0:0: class=0x028000 rev=0x00 hdr=0x00 vendor=0x8086 device=0x4237 subvendor=0x8086 subdevice=0x1211
    vendor     = 'Intel Corporation'
    device     = 'PRO/Wireless 5100 AGN [Shiloh] Network Connection'
    class      = network
```

`@` 符号前的文本是控制该设备的驱动程序名称。在此示例中，分别是 em(4) 和 iwm(4)。

### 通过 ifconfig 命令识别网络适配器

使用 `ifconfig` 命令可查看系统中的网络接口列表及其状态。输出应类似于以下内容：

```sh
em0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
	options=4e504bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,LRO,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
	ether 00:0c:29:84:0f:86
	inet 192.168.5.22 netmask 0xffffff00 broadcast 192.168.5.255
	inet6 fe80::20c:29ff:fe84:f86%em0 prefixlen 64 scopeid 0x1
	inet6 240e:341:207:a600:2d60:b653:3a68:8605 prefixlen 64 autoconf pltime 101808 vltime 188208
	media: Ethernet autoselect (1000baseT <full-duplex>)
	status: active
	nd6 options=823<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL,STABLEADDR>
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
	options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
	inet 127.0.0.1 netmask 0xff000000
	inet6 ::1 prefixlen 128
	inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
	groups: lo
	nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=200001<RXCSUM,RXCSUM_IPV6>
	ether 20:0d:b0:c4:ab:59
	inet 192.168.5.23 netmask 0xffffff00 broadcast 192.168.5.255
	groups: wlan
	ssid test_5G channel 153 (5765 MHz 11a vht/80-) bssid e4:60:4d:97:00:e8
	regdomain FCC country US authmode WPA2/802.11i privacy ON
	deftxkey UNDEF AES-CCM 2:128-bit AES-CCM ucast:128-bit txpower 17
	bmiss 7 mcastrate 6 mgmtrate 6 scanvalid 60 ampdulimit 64k
	ampdudensity 2 shortgi -stbc -uapsd vht vht40 vht80 -vht160 -vht80p80
	wme roaming MANUAL
	parent interface: rtwn0
	media: IEEE 802.11 Wireless Ethernet VHT mode 11ac
	status: associated
	nd6 options=829<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL,STABLEADDR>
```

FreeBSD 采用驱动程序名称后接单元号的方式为网络接口命名。单元号表示适配器在启动时被检测到的顺序，或后续被检测到时的顺序。例如，`em0` 是系统中使用 em(4) 驱动程序的第一块网卡，`wlan0` 是使用 rtwn(4) 驱动创建的第一个无线接口。

该示例显示以下设备：

* `em0`：以太网接口。
* `lo0`：本地回环接口，用于本机内部通信，不属于物理网卡。可用于性能分析、软件测试与本地通信。
* `wlan0`：通用 WiFi 802.11 链路层接口，用于连接无线网络。

  > **技巧**
  >
  > 如果 `ifconfig` 输出中仅显示 `lo0` 接口，则表示系统未识别物理网卡，此时应检查网卡硬件连接和驱动加载状态。可通过 `dmesg | grep ether` 命令查看网卡驱动加载日志。

该示例显示 `em0`、`wlan0` 已启动且运行正常。

关键指示项：

| 指示项                 | 说明                                                                                                                                   |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **UP**              | 表示接口已被管理员启用（处于 up 状态），当前 `em0` 和 `wlan0` 均已启用                                                                                        |
| **inet**（IPv4 地址）   | 有线接口 `em0` 的地址更新为 **192.168.5.22**；无线接口 `wlan0` 的地址为 **192.168.5.23**                                                                |
| **inet6**（IPv6 地址）  | `em0` 当前拥有两个 IPv6 地址，分别是链路本地地址 `fe80::20c:29ff:fe84:f86%em0` 和全局动态地址 `240e:341:207:a600:2d60:b653:3a68:8605`                         |
| **netmask**（子网掩码）   | `em0` 和 `wlan0` 的掩码均为 `0xffffff00`，这等同于标准的 **255.255.255.0**                                                                         |
| **broadcast**（广播地址） | 两个接口当前所在网段的有效广播地址均为 **192.168.5.255**                                                                                                |
| **ether**（MAC 地址）   | 有线接口 `em0` 的物理地址是 `00:0c:29:84:0f:86`；无线接口 `wlan0` 的物理地址是 `20:0d:b0:c4:ab:59`                                                        |
| **media**（物理媒体）     | `em0` 显示为以太网自动选择模式（`Ethernet autoselect (1000baseT <full-duplex>)`）；`wlan0` 显示为无线高速模式（`IEEE 802.11 Wireless Ethernet VHT mode 11ac`） |
| **status**（链接状态）    | `em0` 的状态为 `active`，说明网线已连接且载波信号正常；`wlan0` 的状态为 `associated`，说明已成功关联到无线基站（SSID 外部显示为 `test_5G`）                                      |

此外，`wlan0` 的关键指示项如下：

| 指示项                                   | 说明                                                                                 |
| ------------------------------------- | ---------------------------------------------------------------------------------- |
| **ssid**（无线网络名称）                      | 当前连接的 Wi-Fi 名称为 `test_5G`                                                          |
| **channel**（工作信道与频率）                  | 当前工作在 153 信道，频率为 5765 MHz（属于 5GHz 频段），且启用了 80MHz 的频宽（vht/80-）                      |
| **bssid**（无线路由器 MAC 地址）               | 当前所连 Wi-Fi 热点的物理地址是 `e4:60:4d:97:00:e8`                                            |
| **country / regdomain**（国家区域代码与无线监管域） | 当前遵从美国标准（country US）以及美国联邦通信委员会（regdomain FCC）的无线电法律法规                             |
| **authmode / privacy**（认证与加密模式）       | 认证方式为 WPA2/802.11i（目前主流的安全无线认证标准），且隐私加密已开启（privacy ON），单播与传输密钥采用 AES-CCM (128-bit) |
| **txpower**（发射功率）                     | 当前无线的发射功率为 17 dBm                                                                  |

如果 ifconfig(8) 输出类似于以下内容，则表示网络接口待配置：

```sh
em0: flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
        options=4e504bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,L
RO,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
        ether 00:0c:29:84:0f:86
        inet6 fe80::20c:29ff:fe84:f86%em0 prefixlen 64 scopeid 0x1
        inet6 240e:341:207:a600:2d60:b653:3a68:8605 prefixlen 64 autoconf pltime 1018
08 vltime 188208
        media: Ethernet autoselect (1000baseT <full-duplex>)
        status: active
        nd6 options=823<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL,STABLEADDR>
lo0: flags=1008049<UP,LOOPBACK,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 127.0.0.1 netmask 0xff000000
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
```

## 网关和路由

**路由** 是系统寻找通往其他系统的网络路径的机制。每条路由由一对地址定义，分别表示“目标”和“网关”。路由表明：连接指定目标时，应经由指定网关发送数据包。目标分为三种类型：单台主机、子网和“默认”。“默认路由”在其他路由均不适用时生效。网关同样分为三种类型：单台主机、接口（也称为链路）和以太网硬件（MAC）地址。已知路由存储于路由表中。

### 路由基础

使用 netstat(1) 可查看 FreeBSD 系统的路由表。添加 `-n` 选项可避免反向 DNS 解析延迟，这在排查网络问题时尤为重要：

```sh
$ netstat -rn
Routing tables

Internet:	# IPv4
# 路径				网关			  标志			接口  过期时间
Destination        Gateway            Flags         Netif Expire
default            192.168.179.2      UGS             em0   # 默认路由，通过 em0 接口
localhost          link#3             UH              lo0   # 回环地址，使用 lo0 接口
192.168.5.0/24     link#2             U               em1   # 192.168.5.0/24
192.168.5.16       link#3             UHS             lo0   # 192.168.5.16
192.168.179.0/24   link#1             U               em0   # 192.168.179.0/24 子网
192.168.179.128    link#3             UHS             lo0   # 本地主机地址 192.168.179.128

Internet6:	# IPv6
Destination        Gateway            Flags         Netif Expire
::/96              link#3             URS             lo0   # IPv4 兼容 IPv6 地址块（已废弃，RFC 4291）
default            fe80::5%em1        UG              em1   # 默认 IPv6 路由，下一跳是链路本地地址 fe80::5，标志 UG 表示可达且为网关
localhost          link#3             UHS             lo0   # IPv6 本地回环地址 ::1
::ffff:0.0.0.0/96  link#3             URS             lo0   # IPv4 映射 IPv6 地址
240e:341:22b:ae00: link#2             U               em1   # 全球单播地址
240e:341:22b:ae00: link#3             UHS             lo0   # 本地主机路由
fe80::%lo0/10      link#3             URS             lo0   # 链路本地 IPv6 网络
fe80::%em0/64      link#1             U               em0   # em0 接口链路本地 IPv6 地址
fe80::20c:29ff:fe8 link#3             UHS             lo0   # 静态主机路由
fe80::%em1/64      link#2             U               em1   # em1 接口链路本地 IPv6 地址
fe80::20c:29ff:fe8 link#3             UHS             lo0   # 静态主机路由（与前条 fe80::20c:29ff:fe8 条目重复，属路由表缓存正常现象）
fe80::%lo0/64      link#3             U               lo0   # lo0 接口链路本地子网
fe80::1%lo0        link#3             UHS             lo0   # lo0 本地主机链路本地地址，静态主机路由
ff02::/16          link#3             URS             lo0   # IPv6 多播地址
```

该示例的条目如下：

* **default**： 默认路由。本地系统需连接远程主机时，检查路由表以确定是否存在已知路径。如果远程主机匹配表中某条目，系统即检查能否通过该条目指定的接口完成连接。 默认路由在无更具体前缀匹配时采用，不受其他路径状态的影响。对于局域网中的主机，默认路由的 `Gateway` 字段应设为可直接连接互联网的系统。读取该条目时，应确认 `Flags` 列指示网关可达（`UG`）。

  对于充当对外网关的主机，其默认路由指向与互联网服务提供商（ISP）相连的网关。

  IPv4 网络中，默认网关为 **192.168.179.2**，标记为 UGS（Up、Gateway、Static）。所有发往未知外部网络（如互联网）的 IPv4 流量均经 `em0` 接口发送至该路由器转发。

  IPv6 部分中，默认路由以链路本地地址 **fe80::5%em1** 指定下一跳，该下一跳通常为 ISP 提供的路由器。标志为 UG，所有未匹配的 IPv6 流量经 em1 接口发出。链路本地地址为 IPv6 特性，仅用于本地链路通信，不等同于公网可达地址。

  该机器具备双栈网络能力，IPv4 和 IPv6 出口分别依赖不同网卡（em0 和 em1）。
* **localhost**：第二条路由。`Netif` 列中为 `localhost` 指定的接口是 **lo0**，也称为回环设备。所有发往该目标的流量均保留于本机内部，不通过网络发送。
* **子网**

  IPv4 路由表显示该设备同时接入两个局域网：**192.168.5.0/24** 和 **192.168.179.0/24**。对应网关分别为 `link#2` 和 `link#1`，标志仅含 U（Up），表明二者均为“直连网络”。该机器与这两个网段内其他设备（如 `192.168.5.x` 范围内的计算机）通信时，数据包无须经由路由器，而是通过 ARP 解析目标 MAC 地址后，直接经 em1 和 em0 接口以链路层单播帧发送。
* **全球单播地址**

  IPv6 路由（Internet6）中，以 **240e:341:22b:ae00:** 为首的条目绑定于 em1 接口。该地址属于全球单播地址（Global Unicast Address），通常由运营商（如中国电信，以 240e 开头）分配，理论上可在互联网中路由，但实际访问能力取决于防护策略与服务配置。
* **标志**

  `Flags` 列展示各路由的属性。下表汇总了常见的路由表标志及其含义。

  **常见的路由表标志**

  | 标志 | 目的                            |
  | -- | ----------------------------- |
  | U  | 路由可用                          |
  | H  | 路由目标是单个主机                     |
  | G  | 将此目的地的任何流量转发到此网关，由网关决定如何进一步转发 |
  | S  | 该路由是静态配置的                     |
  | M  | 路由已被重定向修改                     |
  | B  | 黑洞路由：静默丢弃匹配的数据包               |
  | D  | 由重定向动态创建                      |
  | L  | 链路层路由，涉及以太网硬件地址引用             |
  | R  | 拒绝路由：目标主机或网络不可达               |
  | b  | 路由表示广播地址                      |

### 跟踪路由信息

地址空间分配给某网络后，服务提供商会配置自身路由表，确保所有流量均发往该站点链路。外部站点如何确定应将数据包发往该网络的 ISP？

互联网通过全球路由系统跟踪所有已分配地址空间，并界定其与互联网主干网（承载互联网流量的核心线路）的连接节点。每台主干路由器均保存一份主路由表，将特定网络的流量指向对应的主干运营商，再经由一系列服务提供商逐级传递至目标网络。

服务提供商必须向主干站点通告自身的连接点，使流量能够到达该网络。该过程称为路由传播。

![互联网路由传播示意](/files/YgKuV9yI67EouFti6R78)

路由传播偶尔出现故障，导致部分站点无法连通。此时，查找路由断点的常用命令是 `traceroute`（IPv6 使用 `traceroute6`），在 `ping` 失败时尤为有用。

使用 `traceroute` 必须提供远程主机的地址。输出将显示路径上的网关主机，最终抵达目标主机或因连接中断而终止。

以下为对 `freebsd.org` 域名的 IPv6 路径跟踪：

```sh
$ traceroute6 freebsd.org
traceroute6 to freebsd.org (2610:1c1:1:606c::50:15) from 240e:341:22b:ae00:f534:e5cb:2367:c033, 64 hops max, 28 byte packets
 1  * * *
 2  240e:c::201 (240e:c::201)  6.427 ms  5.508 ms  6.578 ms
 3  *
    240e:c:1:20e::2 (240e:c:1:20e::2)  6.229 ms  5.737 ms
 4  * * *
 5  240e::1:11:46:5c02 (240e::1:11:46:5c02)  10.729 ms * *
 6  240e::f:1:6601:503 (240e::f:1:6601:503)  13.093 ms *  11.332 ms
 7  240e:0:a::c9:360d (240e:0:a::c9:360d)  15.618 ms
    240e:0:a::c9:3649 (240e:0:a::c9:3649)  16.334 ms *
 8  * * *
 9  *
    zayo.ae10.mpr4.sjc7.us.zip.zayo.com (2001:438:ffff::407e:2f9)  180.002 ms  179.112 ms
10  ae34.mpr1.ewr4.us.zip.zayo.com (2001:438:ffff::407d:1455)  244.026 ms  243.263 ms *
11  2001:438:fffe::24ba (2001:438:fffe::24ba)  246.736 ms *  245.756 ms
12  cs89-cs80.nyinternet.net (2610:1c1::2502)  218.700 ms  218.396 ms  217.715 ms
13  2610:1c1::803 (2610:1c1::803)  228.099 ms  227.280 ms  226.003 ms
14  wfe0.nyi.freebsd.org (2610:1c1:1:606c::50:15)  214.724 ms  216.682 ms *
```

详细说明：

| 序号  | 节点                                                                               | 说明                                        |
| --- | -------------------------------------------------------------------------------- | ----------------------------------------- |
| 1   | `*`                                                                              | 本地网络第一跳无响应                                |
| 2   | **240e:c::201 (240e:c::201)**                                                    | 运营商接入网关                                   |
| 3、4 | `*`                                                                              | 骨干网前级节点无响应，可能丢弃了 ICMPv6                   |
| 5   | **240e::1:11:46:5c02 (240e::1:11:46:5c02)**                                      | 中国电信核心骨干路由器，国内长途汇聚节点                      |
| 6   | **240e::f:1:6601:503 (240e::f:1:6601:503)**                                      | 中国电信国际出口前的骨干节点，部分探测包丢失                    |
| 7   | **240e:0:a::c9:360d (240e:0:a::c9:360d), 240e:0:a::c9:3649 (240e:0:a::c9:3649)** | 中国电信向海外出口的跨洲骨干路由器                         |
| 8   | `*`                                                                              | 无响应节点，可能丢弃了 ICMPv6                        |
| 9   | **zayo.ae10.mpr4.sjc7.us.zip.zayo.com (2001:438:ffff::407e:2f9)**                | Zayo 美国加州圣何塞骨干网（Zip Zayo）入口节点             |
| 10  | **ae34.mpr1.ewr4.us.zip.zayo.com (2001:438:ffff::407d:1455)**                    | Zayo 美国纽瓦克骨干网节点，负责东海岸流量汇聚                 |
| 11  | **2001:438:fffe::24ba (2001:438:fffe::24ba)**                                    | Zayo 美国骨干网最后一跳，接近 NYInternet 入口           |
| 12  | **cs89-cs80.nyinternet.net (2610:1c1::2502)**                                    | NYInternet 美国运营商核心路由器，接入 freebsd.org 网络   |
| 13  | **2610:1c1::803 (2610:1c1::803)**                                                | NYInternet 核心骨干节点，负责 freebsd.org 服务器的流量分发 |
| 14  | **wfe0.nyi.freebsd.org (2610:1c1:1:606c::50:15)**                                | freebsd.org 服务器终端节点，traceroute6 的目标       |


# 9.2 基础网络管理

本节介绍网络管理基础知识与故障排除技巧。

## 配置 IPv4

### 配置动态 IPv4 地址

如果网络中有 DHCP 服务器，可使用 DHCP 动态获取 IP 地址。FreeBSD 使用 dhclient(8) 作为 DHCP 客户端，dhclient(8) 可自动获取 IP 地址、子网掩码和默认路由器。

> **注意**
>
> dhclient(8) **不支持 DHCPv6**（RFC 3315/RFC 8415），IPv6 动态地址需使用 rtsold(8)（SLAAC）或第三方 DHCPv6 客户端（如 `dhcp6c`）。

要使接口使用 DHCP，执行以下命令：

```sh
# sysrc ifconfig_em0="DHCP"
```

可以手动运行 dhclient(8)：

```sh
# dhclient em0
DHCPREQUEST on em0 to 255.255.255.255 port 67
DHCPACK from 192.168.1.1
bound to 192.168.1.19 -- renewal in 43200 seconds.
```

dhclient(8) 也可在后台启动。后台运行可能影响依赖网络的程序，但多数情况下能加快启动速度。

要在后台执行 dhclient(8)，执行以下命令：

```sh
# sysrc background_dhclient="YES"
```

随后重启网络接口：

```sh
# service netif restart
```

### 配置静态 IPv4 地址

也可在命令行通过 ifconfig(8) 配置网络接口，但若不同时将这些配置写入 **/etc/rc.conf** 文件，重启后配置将丢失。

可通过以下命令设置 IP 地址：

```sh
# ifconfig em0 inet 192.168.1.150/24
```

要使更改在重启后持久化，执行以下命令：

```sh
# sysrc ifconfig_em0="inet 192.168.1.150 netmask 255.255.255.0"
```

一次性设置默认路由：

```sh
# route add default 192.168.1.1
```

永久添加默认路由器：

```sh
# sysrc defaultrouter="192.168.1.1"
```

将 DNS 服务器地址添加到 **/etc/resolv.conf** 文件：

```ini
nameserver 223.5.5.5   # 指定首选 DNS 服务器为阿里云公共 DNS
nameserver 223.6.6.6   # 指定备用 DNS 服务器为阿里云公共 DNS
```

随后重启网络接口和路由：

```sh
# service netif restart
# service routing restart
```

可使用 ping(8) 测试连接：

```sh
$ ping -4c2 FreeBSD.org
PING FreeBSD.org (96.47.72.84): 56 data bytes
64 bytes from 96.47.72.84: icmp_seq=0 ttl=51 time=239.916 ms
64 bytes from 96.47.72.84: icmp_seq=1 ttl=51 time=236.443 ms

--- FreeBSD.org ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 236.443/238.179/239.916/1.737 ms
```

如能正常收到 ICMP 响应报文，表明网络已连通。

## 配置 IPv6

IPv6 是 IPv4 的后继协议。IPv6 相对于 IPv4 提供了多项优势和新功能：

* 其 128 位地址空间可容纳约 3.4×10^38 个地址，从而解决了 IPv4 地址短缺与耗尽问题。
* 路由器仅在路由表中存储网络聚合地址，通过地址聚合减少路由表条目，这与 IPv4 相比大幅降低了路由器的内存和 CPU 需求。
* 地址自动配置（RFC 4862）。
* 以多播取代广播地址。
* 支持 IPsec（IP 安全），但非强制要求（RFC 6434 已将 IPv6 节点对 IPsec 的实现要求由 MUST 调整为 SHOULD，因此成为推荐而非必选）。
* 简化的头部结构。
* 对移动 IP 的支持。
* IPv6 到 IPv4 的过渡机制。

FreeBSD 集成了 [KAME](https://www.kame.net/) 项目 IPv6 参考实现，并包含 IPv6 所需的全部组件。KAME 项目已于 2006 年结束，其代码由 FreeBSD 项目继续维护和演进。

IPv6 地址有三种不同类型：

| 类型                | 说明                                                                             |
| ----------------- | ------------------------------------------------------------------------------ |
| **单播（Unicast）**   | 发送到单播地址的数据包到达属于该地址的接口                                                          |
| **任播（Anycast）**   | 地址在语法上与单播地址无法区分，但指向一组接口。发往任播地址的数据包将到达最近的接口                                     |
| **多播（Multicast）** | 地址标识一组接口。发往多播地址的数据包将到达属于多播组的所有接口。IPv4 广播地址（通常为 xxx.xxx.xxx.255）在 IPv6 中由多播地址表示 |

读取 IPv6 地址时，规范形式表示为 `x:x:x:x:x:x:x:x`，其中每个 x 代表一个 16 位十六进制值。例如 **FEBC:A574:382B:23C1:AA49:4592:4EFE:9982**。

IPv6 地址中常出现连续的全零字段。`::`（双冒号）可用于替换地址中一段连续的全零字段。此外，每个十六进制值最多可省略三个前导零。例如，**fe80::1** 对应规范形式 **fe80:0000:0000:0000:0000:0000:0000:0001**。

部分 IPv6 地址为保留地址：

| IPv6 地址               | 描述               | 说明                             |
| --------------------- | ---------------- | ------------------------------ |
| **::/128**            | 未指定地址            | 等同于 IPv4 中的 **0.0.0.0**        |
| **::1/128**           | 回环地址             | 等同于 IPv4 中的 **127.0.0.1**      |
| **::ffff:0.0.0.0/96** | IPv4 映射的 IPv6 地址 | 低 32 位是 IPv4 地址                |
| **fe80::/10**         | 链路本地单播           | 等同于 IPv4 中的 **169.254.0.0/16** |
| **fc00::/7**          | 唯一本地             | 仅在协作站点集合内可路由                   |
| **ff00::/8**          | 多播               | —                              |
| **2000::/3**          | 全局单播             | 所有全局单播地址从此池分配                  |
| **2001:db8::/32**     | 文档用途             | 用于文档中的 IPv6 地址前缀               |

### 配置动态 IPv6 地址

要使用 SLAAC 动态配置接口的 IPv6 地址：

```sh
# sysrc ifconfig_em0_ipv6="inet6 accept_rtadv"
# sysrc rtsold_enable="YES"
```

注意，启用 IPv6 数据包转发（即 `ipv6_gateway_enable=YES`）后，除非将 `net.inet6.ip6.rfc6204w3` sysctl(8) 变量设置为 1，否则系统不会配置 SLAAC 地址。

### 配置静态 IPv6 地址

要将 FreeBSD 系统配置为具有静态 IPv6 地址的 IPv6 客户端，需设置 IPv6 地址：

```sh
# sysrc ifconfig_em0_ipv6="inet6 2001:db8:4672:6565:2026:5043:2d42:5344 prefixlen 64"
```

要分配默认路由器：

```sh
# sysrc ipv6_defaultrouter="2001:db8:4672:6565::1"
```

可使用 ping(8) 测试连接：

```sh
$ ping -6c2 FreeBSD.org
PING(56=40+8+8 bytes) 240e:341:228:f400:cfbe:d56:7f75:26e0 --> 2610:1c1:1:606c::50:15
16 bytes from 2610:1c1:1:606c::50:15, icmp_seq=0 hlim=47 time=223.377 ms
16 bytes from 2610:1c1:1:606c::50:15, icmp_seq=1 hlim=47 time=223.348 ms

--- FreeBSD.org ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 223.348/223.362/223.377/0.014 ms
```

如能正常收到 ICMP 响应报文，表明网络已连通。

### 参考文献

* Li Q, Jinmei T, Shima K. IPv6 详解：卷 1，核心协议实现\[M]. 陈涓，赵振平，译. 北京：人民邮电出版社，2009：846. ISBN: 978-7-115-18950-9 (英文影印版本 ISBN: 978-7-115-19551-7). 详解 IPv6 核心协议实现，基于 FreeBSD KAME 项目代码分析。
* Li Q, Jinmei T, Shima K. IPv6 详解：卷 2，高级协议实现\[M]. 王嘉祯，等，译. 北京：人民邮电出版社，2009：869. ISBN: 978-7-115-20891-0 (英文影印版本 ISBN: 978-7-115-19519-7). 详解 IPv6 高级协议与扩展机制，包含移动 IPv6 等关键技术。

## 网卡别名

FreeBSD 的常见用途之一是虚拟站点托管，即一台服务器在网络中呈现为多台服务器。其实现方式是将多个网络地址分配给单个接口。

一个网络接口可配置一个主 IP 地址（Primary Address）以及任意数量的附加 IP 地址（Secondary Addresses），它们在底层网络通信中具有同等效力。

> **技巧**
>
> “别名”（alias）地址只是早期操作系统为了方便管理而沿用的传统称呼，对于物理网卡而言并无区别。实际上，IPv6 本身即支持多地址。

这些别名通常通过在 **/etc/rc.conf** 中添加别名条目来实现，如下所示：

```sh
# sysrc ifconfig_em0_alias0="inet xxx.xxx.xxx.xxx netmask xxx.xxx.xxx.xxx"
```

别名条目必须以 `alias0` 开头，使用递增的数字，如 `alias0`、`alias1`，依此类推。配置过程将在第一个缺失的数字处停止。

别名子网掩码的计算非常重要。对于给定的接口，必须有一个地址正确表示网络的子网掩码。任何其他属于该网络的地址必须使用全 `1` 的子网掩码，表示为 **255.255.255.255** 或 **0xffffffff**。

例如，假设以下情况：`em0` 接口连接到两个网络：

* **10.1.1.0**、子网掩码为 **255.255.255.0**；
* **202.0.75.16**、子网掩码为 **255.255.255.240**。

我们需要为系统配置两个网段的 IP 地址范围：**10.1.1.1** 到 **10.1.1.5**，以及 **202.0.75.17** 到 **202.0.75.20**。

只有给定网络范围中的第一个地址应具有实际的子网掩码。其余地址（**10.1.1.2** 到 **10.1.1.5** 和 **202.0.75.18** 到 **202.0.75.20**）必须配置为子网掩码为 **255.255.255.255**。

网卡 em0 的 IP 别名结构如下图所示：

![网卡 em0 的 IP 别名结构](/files/W0IMSyMO5YAE2cEOJoMt)

以下 **/etc/rc.conf** 条目将接口配置为适应此场景：

```sh
# sysrc ifconfig_em0="inet 10.1.1.1 netmask 255.255.255.0"
# sysrc ifconfig_em0_alias0="inet 10.1.1.2 netmask 255.255.255.255"
# sysrc ifconfig_em0_alias1="inet 10.1.1.3 netmask 255.255.255.255"
# sysrc ifconfig_em0_alias2="inet 10.1.1.4 netmask 255.255.255.255"
# sysrc ifconfig_em0_alias3="inet 10.1.1.5 netmask 255.255.255.255"
# sysrc ifconfig_em0_alias4="inet 202.0.75.17 netmask 255.255.255.240"
# sysrc ifconfig_em0_alias5="inet 202.0.75.18 netmask 255.255.255.255"
# sysrc ifconfig_em0_alias6="inet 202.0.75.19 netmask 255.255.255.255"
# sysrc ifconfig_em0_alias7="inet 202.0.75.20 netmask 255.255.255.255"
```

一种更简洁的表达方式是使用以空格分隔的 IP 地址范围。第一个地址将使用指定的子网掩码，而额外的地址将使用子网掩码 **255.255.255.255**。

```sh
# sysrc ifconfig_em0_aliases="inet 10.1.1.1-5/24 inet 202.0.75.17-20/28"
```

## 主机名

主机名代表主机在网络上的完全限定域名（FQDN，Fully Qualified Domain Name）。

检查当前主机名：

```sh
$ hostname
ykla
```

临时更改主机名：

```sh
root@ykla:/home/ykla # hostname f	# 将主机名由 ykla 临时修改为 f
root@f:/home/ykla #
```

更改主机名并使其在重启后持久化：

```sh
# sysrc hostname="f"
```

## DNS

可将 DNS 类比为电话簿，其中 IP 地址与主机名相互对应。除非 **/etc/nsswitch.conf** 文件中另有说明，FreeBSD 将首先查看 **/etc/hosts** 文件中的地址，随后查看 **/etc/resolv.conf** 文件中的 DNS 信息。

相关文件结构：

```sh
/etc/
├── rc.conf              # 系统启动配置文件
├── resolv.conf          # DNS 解析服务器配置文件
└── resolvconf.conf      # resolvconf 服务配置文件
```

### 本地地址 hosts 文件

**/etc/hosts** 文件是一个简单的文本数据库，提供主机名到 IP 地址的映射。通过 LAN 连接的本地计算机条目可添加到此文件中，用于简单的主机名解析，无须设置 DNS 服务器。此外，**/etc/hosts** 文件可提供互联网域名的本地记录，减少对外部 DNS 服务器的查询需求。

例如，在本地环境中有 www/gitlab-ce 的本地实例，可以将如下行添加到 **/etc/hosts** 文件：

```ini
192.168.1.150 git.example.com git
```

### 配置 DNS 名称服务器

FreeBSD 系统访问 Internet 域名系统（DNS）的方式由 resolv.conf(5) 控制。**/etc/resolv.conf** 文件中最常见的条目是：

| 条目           | 说明                                   |
| ------------ | ------------------------------------ |
| `nameserver` | 解析器应查询的名称服务器的 IP 地址。服务器按列出的顺序查询，最多三个 |
| `search`     | 主机名查找的搜索列表。通常由本地主机名的域确定              |
| `domain`     | 本地域名                                 |

典型的 **/etc/resolv.conf** 文件如下：

```ini
search example.com
nameserver 223.5.5.5
nameserver 223.6.6.6
```

search 和 domain 选项互斥；如果两者都指定，只有最后一个生效。使用 DHCP 时，dhclient(8) 通常会用从 DHCP 服务器接收的信息重写 **/etc/resolv.conf** 文件。

由于动态主机配置协议（Dynamic Host Configuration Protocol，DHCP）客户端在获取网络配置时会通过 resolvconf 服务重写 /etc/resolv.conf，手动编辑该文件后，系统重启时配置可能被覆盖。

如需使用手动配置的 DNS 服务器而不希望系统自动更新覆盖，可禁用 resolvconf 服务。编辑 **/etc/resolvconf.conf** 文件（如不存在则创建），写入 `resolvconf=NO` 一行，该配置将禁用系统对 DNS 配置文件的自动更新。

### 参考文献

* FreeBSD Project. resolvconf\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=resolvconf&sektion=8>. man 手册，提供 resolvconf 工具的完整技术文档，为 DNS 配置管理提供重要参考。
* FreeBSD Forums. **8.8.8.8** or **1.1.1.1** if set in etc resolv conf doesn't stay as an entry in the file after a network restart\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/8-8-8-8-or-1-1-1-1-if-set-in-etc-resolv-conf-doesnt-stay-as-an-entry-in-the-file-after-a-network-restart.85951/>. 实际案例分析，提供防止覆写 DNS 配置的解决方案。

## 网络故障排除

首先检查以下基本要素：

* 电源连接是否正常？
* 路由器是否正常工作？
* 宽带或网络费用是否缴纳？
* 是否是区域性大规模网络中断事件？
* 计算机的时间是否正确？
* 网线是否连接正常？
* 网络服务是否正确配置？
* 防火墙是否正确配置？
* 网卡是否受 FreeBSD 支持？

如果网卡工作正常但性能不佳，可参阅 tuning(7)。不正确的网络设置可能导致连接缓慢，应同时检查网络配置。

“No route to host”消息表示系统无法将数据包路由到目标主机。这通常是因为未指定默认路由或网线未连接。可使用 `route get <目标地址>` 命令查看系统对特定目标的路由决策，再检查 `netstat -rn` 的输出，确保有到主机的有效路由。

错误消息 `ping: sendto: Permission denied` 通常由防火墙配置错误引起。如果直接加载了 IPFW 防火墙模块但未配置任何规则，IPFW 的默认规则 65535 会拒绝所有流量，甚至是 ping(8)。

通过 rc.conf 启用防火墙时：

* `firewall_type` 的默认值为 `"UNKNOWN"`，此时不会添加任何放行规则，仅有默认规则 65535（deny all）生效
* 若将 `firewall_type` 显式设置为 `"open"`，则 IPFW 会在规则 65000 处添加放行规则，覆盖默认的拒绝行为。

PF 和 IPFilter 无规则时默认放行。

## 查看网卡速率

如需实时监控网络接口的流量统计信息，可使用 `systat` 工具的网络接口视图。该命令以指定的刷新间隔显示各网络接口的接收和发送流量数据：

```sh
# systat -ifstat 2
```

其中 `-ifstat` 参数指定显示网络接口信息，数字 2 表示刷新间隔为 2 秒。

## 查看 FreeBSD 下载流量（bwm-ng）

如需查看更详细的网络流量统计，可安装 `bwm-ng` 工具，该工具提供多种流量显示格式和交互功能：

```sh
# pkg install bwm-ng  # 安装 bwm-ng
# bwm-ng
  bwm-ng v0.6.3 (probing every 0.500s), press 'h' for help
  input: getifaddrs type: rate
  /         iface                   Rx                   Tx                Total
  ==============================================================================
              em0:           2.04 MB/s            6.03 KB/s            2.05 MB/s
              lo0:           0.00  B/s            0.00  B/s            0.00  B/s
        vm-public:           2.04 MB/s            2.05 MB/s            4.09 MB/s
             tap0:           5.49 KB/s            2.04 MB/s            2.04 MB/s
  ------------------------------------------------------------------------------
            total:           4.09 MB/s            4.09 MB/s            8.18 MB/s
```

按字母 d 可切换流量显示格式，按 h 可查阅更多使用方法。

## 附录：/etc/rc.conf 网络配置示例

> **注意**：
>
> 修改 **/etc/rc.conf** 文件后，需重启系统或依次运行命令 `service netif restart` 与 `service routing restart` 来应用网络更改。

主机名（不得为空，否则无法使用 Xorg）：

```ini
hostname="ykla"
```

### 动态 DHCP 方式

动态 DHCP 方式：使网卡 igc0 使用 DHCP：

```ini
ifconfig_igc0="DHCP"
```

### 静态 IP 方式

静态 IP 方式：将网卡 igc0 的 IPv4 设置为 **192.168.5.77**，子网掩码为 **255.255.255.0**：

```ini
ifconfig_igc0="inet 192.168.5.77 netmask 255.255.255.0"
```

默认网关/默认路由，通常为路由器 IP 地址：

```ini
defaultrouter="192.168.5.1"
```

为网卡 igc0 设置别名 IPv4 **192.168.5.12**，子网掩码为 **255.255.255.255**（与主地址同子网时必须使用全 1 掩码）从而拥有额外的 IPv4 地址：

```ini
ifconfig_igc0_alias0="inet 192.168.5.12 netmask 255.255.255.255"
```

> **注意**：
>
> 如果别名地址与主地址位于同一子网，必须将子网掩码设为 255.255.255.255（0xffffffff），否则会产生重复路由错误。不同子网的别名则使用该子网正常的子网掩码。

静态路由：

```ini
static_routes="static1 static2" # ①
```

① 在 **/etc/rc.conf** 文件中，如果需要一次性写入多个配置项，只能使用 `ABC_XYZ="xxx yyy ccc ddd"` 这种格式。如果写成以下形式是 **错误的**：

```ini
ABC_XYZ="xxx" # 第一行
ABC_XYZ="yyy"
ABC_XYZ="ccc"
ABC_XYZ="ddd"
```

因为在这种形式下，后续的 `ABC_XYZ` 配置行会覆盖前一行，因此只有最后一行会生效。

示例：如需访问 **192.168.50.0/24** 地址块（可用主机 IP 从 **192.168.50.1** 到 **192.168.50.254**），将数据包发送给 **192.168.1.1**，由其转发：

```ini
route_static1="-net 192.168.50.0/24 192.168.1.1"
```

示例：如需访问网络 **10.88.200.0/24** 地址块（可用主机 IP 从 **10.88.200.1** 到 **10.88.200.254**），则将数据包发送至 10.10.10.254，由其转发：

```ini
route_static2="-net 10.88.200.0/24 10.10.10.254"
```

## 课后习题

1. 在 FreeBSD 系统上配置双静态 IP 地址，分别设置不同的 DNS 服务器，使用 `dig` 命令验证每个 DNS 服务器的解析行为，分析 **/etc/resolv.conf** 中多 DNS 服务器条目的查询顺序与容错机制。
2. 修改网络接口的 MTU（Maximum Transmission Unit）值为 9000（巨型帧），使用 `ping` 测试连通性，记录 MTU 变化对大包传输的影响，分析巨型帧在局域网与广域网中的适用场景。
3. 禁用 `resolvconf` 服务，手动修改 **/etc/resolv.conf** 文件并重启网络服务，验证配置是否持久化，分析 `resolvconf` 对 DNS 配置动态管理的机制。


# 9.3 无线网络管理

FreeBSD 支持多种无线网卡和认证方式。

> **技巧**
>
> Wi-Fi 并不是任何单词的缩写。该词仅为 [Wi-Fi 联盟](https://www.wi-fi.org/)（Wi-Fi Alliance）持有的注册商标，并无“Wireless Fidelity”等引申含义。（Doctorow C. WiFi isn’t short for“Wireless Fidelity”\[EB/OL]. (2005-11-08)\[2026-04-21]. <https://boingboing.net/2005/11/08/wifi-isnt-short-for.html>.）

## 快速连接（基于 COMFAST CF-912AC 1200M 802.11AC）

### 无线网络配置

基本无线网络由多个站点组成，各站点通过 2.4 GHz 与 5 GHz 频段的无线电通信实现互联（6 GHz 频段在 FreeBSD 上的支持仍处于开发阶段）。配置无线网络包含三个步骤：

1. 扫描并选择接入点
2. 认证站点
3. 配置 IP 地址或使用 DHCP

### 示例网卡

本节以 COMFAST CF-912AC 1200M 802.11AC 无线网卡为例，介绍一般无线网卡的驱动配置方法。该网卡采用 Realtek 芯片组。其他采用 Realtek 芯片的网卡配置方法类似。

### 识别无线网卡

在配置无线网络前，需确认系统是否识别了无线网卡。可查询内核无线设备列表来确认硬件识别状态：

```sh
# sysctl net.wlan.devices
net.wlan.devices: rtwn0
```

上述输出中的 `rtwn0` 是示例网卡（COMFAST CF-912AC）的设备名称，实际输出因硬件而异。若输出中冒号 `:` 后为空，表示无线网卡未被识别，此时需检查硬件连接或更换兼容性更好的无线网卡。

### 虚拟无线接口机制

在 FreeBSD 中，无线网络采用分层架构，需创建虚拟无线接口 `wlan0` 并将其绑定至物理无线网卡方可使用。

创建一个新的无线接口 `wlan0`，并将其绑定到物理设备 `rtwn0`：

```sh
# ifconfig wlan0 create wlandev rtwn0
```

上述命令中，`rtwn0` 为 `sysctl net.wlan.devices` 输出中的物理网卡名称，需根据实际硬件替换（~~除非也使用 COMFAST CF-912AC 1200M 802.11AC~~）。

> **技巧**
>
> 上述示例中的 `wlan0`、`rtwn0`、**192.168.1.100**、`freebsdap`、`freebsdcn` 为占位符，须替换为实际的值。

创建完成后，可使用 `ifconfig` 命令查看接口状态（以下输出已省略以太网卡和 `lo0` 接口）：

```sh
# ifconfig

……此处省略一部分……

wlan0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=200001<RXCSUM,RXCSUM_IPV6>
	ether 20:0d:b0:c4:ab:59
	groups: wlan
	ssid "" channel 1 (2412 MHz 11b)
	regdomain FCC country US authmode OPEN privacy OFF txpower 30 bmiss 7
	scanvalid 60 wme bintval 0
	parent interface: rtwn0
	media: IEEE 802.11 Wireless Ethernet autoselect (autoselect)
	status: no carrier
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
```

在正常情况下，输出中应包含 `wlan0` 接口。

### 扫描无线网络

在连接到无线网络之前，需先扫描周围可用的无线网络。可使用 ifconfig(8) 扫描可用的无线网络：

```sh
# ifconfig wlan0 up scan
SSID/MESH ID                      BSSID              CHAN RATE    S:N     INT CAPS

……此处省略一部分……

test_5G                           50:d6:c5:93:d7:64   36   54M  -78:-95   100 EP   APCHANREP WPA RSN WPS BSSLOAD HTCAP VHTCAP VHTOPMODE WME
```

参数说明：

| 参数               | 含义                  |
| ---------------- | ------------------- |
| **SSID/MESH ID** | 标识网络名称              |
| **BSSID**        | 标识接入点的 MAC 地址       |
| **CHAN**         | 信道                  |
| **RATE**         | 速率                  |
| **S:N**          | 信号强度和质量             |
| **INT**          | 信标间隔                |
| **CAPS**         | 标识每个网络的类型和站点支持的功能特性 |

扫描结果会显示可用的无线网络列表。

### SSID 的定义与作用

服务集标识符（Service Set Identifier，SSID）是无线网络的名称，用于区分不同的无线网络。

将 `wlan0` 接口连接到 SSID 为 `test_5G` 的无线网络（适用于无密码的开放网络）：

```sh
# ifconfig wlan0 ssid test_5G
```

上述命令中，`test_5G` 为示例 Wi-Fi 名称（SSID），需替换为实际网络名称。

如果无法扫描到 Wi-Fi 网络，可能需要修改无线区域设置或路由器信道，可按以下步骤重新配置：

```sh
# ifconfig wlan0 destroy
# ifconfig wlan0 create wlandev rtwn0
# ifconfig wlan0 country HR regdomain ETSI
```

第一条命令销毁现有 `wlan0` 接口并释放其占用的资源，避免出现 `ifconfig: SIOCS80211: Device busy` 错误；第二条命令重新创建无线接口并绑定到物理设备；第三条命令设置无线国家码为 HR 并使用 ETSI 无线频段规范，在目标网络使用大于 48 的信道（DFS 信道）时需执行此设置，如信道小于 48，可省略该步骤。

完成上述配置后，重启网络服务以接入 Wi-Fi：

```sh
# service netif restart
# dhclient wlan0
```

第一条命令重启网络接口服务，第二条命令为 `wlan0` 接口获取动态 IP 地址。

### 使用 WPA2 认证

加密无线网络需使用 Wi-Fi 保护访问（Wi-Fi Protected Access，WPA）配置文件连接。WPA2 是 FreeBSD 当前已能正常使用的无线网络安全协议，提供数据加密和身份认证功能。对于 WPA3/SAE，FreeBSD 基本系统的 `wpa_supplicant` 可通过 `CONFIG_SAE=y` 编译选项支持 SAE 协商配置，但内核 net80211 协议栈尚未完成 SAE 认证支持，客户端实际连接会因可用密钥管理类型为空（`available key_mgmt 0x0`）而失败（截至 2025 年末，多名用户在 FreeBSD 14.3、15.0 下的实测均确认此情况）。FreeBSD 基金会已将 net80211 协议栈更新列为在研工作。

无线网络中的认证过程由 wpa\_supplicant(8) 管理。可使用 wpa\_passphrase(8) 工具将 SSID 和明文密码转换为安全的 PSK 配置条目，避免在配置文件中直接书写明文密码。此外，wpa\_cli(8) 提供了 wpa\_supplicant 的交互式命令行管理接口，可用于运行时调试和状态查询。创建 **/etc/wpa\_supplicant.conf** 配置文件，内容如下：

```ini
ctrl_interface=/var/run/wpa_supplicant   # 可选，控制接口路径，用于 wpa_supplicant 与 wpa_cli 等工具通信
fast_reauth=1                             # 可选，启用快速重新认证，加快已认证网络的重连速度
network={
ssid="test_5G"
psk="freebsdcn"
}
```

配置说明：

| 参数     | 说明                                        |
| ------ | ----------------------------------------- |
| `ssid` | 指定要连接的无线网络 SSID（Wi-Fi 名称），此处示例为 `test_5G` |
| `psk`  | 指定无线网络的密码，此处示例为 `freebsdcn`               |

如果无法获取无线网络的服务集标识符（SSID）和预共享密钥（PSK，Pre-Shared Key），可联系网络管理员或重置网络设备以获取凭据。

下一步在 **/etc/rc.conf** 文件中配置无线连接。使用动态地址：

```sh
# sysrc ifconfig_wlan0="WPA DHCP"
```

随后重启网络：

```sh
# service netif restart
```

如果网络连接正常，则可永久配置。在 **/etc/rc.conf** 文件中添加或修改相关配置：

```ini
wlans_rtwn0="wlan0"                      # 将物理无线设备 rtwn0 绑定到 wlan0 接口
ifconfig_wlan0="WPA SYNCDHCP"           # 配置 wlan0 使用 WPA 并通过 DHCP 自动获取 IP 地址（SYNCDHCP 为同步模式，会暂停启动直至 DHCP 完成；如需异步/后台模式可改用 DHCP）
create_args_wlan0="country HR regdomain ETSI"  # 创建 wlan0 接口时设置无线国家码为 HR，并使用 ETSI 频段规范。如信道大于 48（DFS），则需执行此设置。
```

### 无线网络配置文件结构

FreeBSD 无线网络涉及以下配置文件。

```sh
/etc/
├── rc.conf              # 系统启动配置文件
└── wpa_supplicant.conf  # WPA 无线网络配置文件
```

完成上述配置后，重启系统或网络服务使所有配置生效。

重启后，使用 `ifconfig` 查看连接情况，在正常情况下可看到已成功连接（示例输出中 IP 为 **192.168.31.178**）：

```sh
……省略一部分输出……

wlan0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
	options=200001<RXCSUM,RXCSUM_IPV6>
	ether 11:7c:e8:c4:ab:58
	inet 192.168.31.178 netmask 0xffffff00 broadcast 192.168.31.255
	groups: wlan
	ssid test_5G channel 36 (5180 MHz 11a ht/20) bssid 50:d6:c5:93:d7:64
	regdomain NONE country CN authmode WPA2/802.11i privacy ON
	deftxkey UNDEF TKIP 2:128-bit txpower 17 bmiss 7 mcastrate 6
	mgmtrate 6 scanvalid 60 ht20 ampdulimit 64k ampdudensity 4 shortgi
	-stbc -uapsd wme roaming MANUAL
	parent interface: rtwn0
	media: IEEE 802.11 Wireless Ethernet MCS mode 11na
	status: associated
	nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
```

## 英特尔无线网卡驱动概况

英特尔（Intel）网卡是目前广泛使用的无线网卡之一。iwlwifi 驱动支持的芯片范围是 iwm 的超集：iwlwifi 目前仅移植了 Linux 上游驱动的 mvm 子驱动部分，覆盖了 iwm 支持的全部芯片以及更新的 Wi-Fi 6E/7 芯片。Linux 上游的 iwlwifi 驱动还包含 MLD/MLO 扩展功能（用于 Wi-Fi 7 MLO 多链路操作），但 MLO 等 Wi-Fi 7 新特性在 FreeBSD 上仍处于开发阶段。

在 **/etc/rc.conf** 文件中添加以下配置：

```ini
wlans_iwlwifi0="wlan0"        # 将物理无线设备 iwlwifi0 绑定到 wlan0 接口
ifconfig_wlan0="WPA SYNCDHCP"  # 配置 wlan0 使用 WPA 并通过 DHCP 自动获取 IP 地址
```

创建 **/etc/wpa\_supplicant.conf** 配置文件：

```sh
network={
ssid="WIFI 名称（SSID）"
psk="WIFI 密码"
}
```

完成配置后，执行以下命令启动 Wi-Fi 测试：

```sh
# ifconfig wlan0 create wlandev iwlwifi0
# service netif start wlan0
```

第一条命令创建 `wlan0` 接口并绑定到物理无线设备 `iwlwifi0`，第二条命令启动 `wlan0` 接口。

故障排除与未竟事宜请参考：[wiki/WiFi/Iwlwifi](https://wiki.freebsd.org/WiFi/Iwlwifi)

### 参考文献

* FreeBSD Project. iwm(4) -- Intel IEEE 802.11ac wireless network driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=iwm&sektion=4>. Intel 无线网卡驱动技术文档。
* FreeBSD Project. iwlwifi(4) -- Intel IEEE 802.11a/b/g/n/ac/ax/be wireless network driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=iwlwifi&sektion=4>. Intel 无线网卡驱动技术文档。

## 博通（Broadcom）网卡驱动

博通（Broadcom）是另一家常见的无线网卡厂商。FreeBSD 内置的 Broadcom 网卡驱动主要有两种：`bwi` 和 `bwn`。`bwi` 支持较旧型号，`bwn` 支持较新型号，两者的支持范围部分重叠，但 `bwn` 对硬件的兼容性更好。这两个驱动仅支持 802.11b/g，现代 802.11ac/ax 博通网卡在 FreeBSD 上尚无原生驱动支持。

关于驱动选择的详细信息，可参考 Fuller L. Broadcom WiFi Improvements for FreeBSD\[EB/OL]. (2018-01-22)\[2026-04-05]. <https://web.archive.org/web/20240203102135/https://www.landonf.org/code/freebsd/Broadcom_WiFi_Improvements.20180122.html>.

### 示例：BCM4301、BCM4303、BCM4306 rev 2

根据参考文献，上述型号的网卡只能使用 `bwi` 驱动。

首先，在 **/boot/loader.conf** 文件中添加以下配置，设置系统在启动时加载 `bwi` 驱动：

```sh
if_bwi_load="YES"
```

随后使用 Ports 安装 Broadcom 无线设备的固件（该固件未提供二进制包）：

```sh
# cd /usr/ports/net/bwi-firmware-kmod/
# make install clean
```

可先通过 USB 或以太网共享获取网络连接后安装，也可提前将所需依赖下载到指定目录。

在 **/etc/rc.conf** 文件中添加以下配置，将物理无线设备 `bwi0` 绑定到 `wlan0` 接口：

```ini
wlans_bwi0="wlan0"
```

完成上述配置后，重启系统。

### 示例：配置 bwn 驱动

安装 Broadcom 无线设备的固件：

```sh
# cd /usr/ports/net/bwn-firmware-kmod/
# make install clean
```

### 博通网卡驱动相关的文件结构

博通网卡驱动涉及以下文件：

```sh
/
├── boot/
│   └── loader.conf        # 系统启动加载配置文件
├── usr/
│   ├── ports/
│   │   └── net/
│   │       ├── bwi-firmware-kmod/   # Broadcom bwi 固件 Port
│   │       └── bwn-firmware-kmod/   # Broadcom bwn 固件 Port
│   └── src/
│       └── sys/
│           └── amd64/
│               └── conf/              # 内核配置文件目录
```

编辑 **/boot/loader.conf** 文件添加以下配置，设置系统在启动时加载 `bwn` 驱动：

```ini
if_bwn_load="YES"
```

在 **/etc/rc.conf** 文件中添加以下配置，将物理无线设备 `bwn0` 绑定到 `wlan0` 接口：

```ini
wlans_bwn0="wlan0"
```

## 无线网络故障排除

如果扫描时未列出接入点，可尝试切换路由器的信道，或将协议降级至 Wi-Fi 4。

如果设备无法与接入点关联，需验证配置是否与接入点上的设置匹配，包括认证方案和安全协议。建议尽可能简化配置。如果使用 WPA2 或 WPA 等安全协议，可先将接入点配置为开放认证、关闭安全功能，以验证流量能否通过。

如果系统可与接入点关联，使用 ping(8) 等工具诊断网络配置。

## 附录：更新系统版本后无法使用无线网络

### 固件与系统更新的兼容性问题

FreeBSD 中，固件（Firmware）是硬件设备正常工作所需的底层软件，提供硬件设备与操作系统内核之间的通信接口。固件接口可能随内核版本更新而变化。

### 固件重新获取方法

系统版本更新后如果无法使用无线网络，需重新获取与当前内核版本兼容的固件。FreeBSD 提供 `fwget` 工具用于自动获取和安装所需固件：

```sh
# fwget
```

如果当前系统没有网络连接，可通过 USB 网络共享等方式临时获得网络连接后再执行上述命令；也可手动从 [USTC 镜像站点](https://mirrors.ustc.edu.cn/freebsd-pkg/FreeBSD%3A14%3Aamd64/kmods_latest_3/All/) 下载所需固件包（请将 URL 中的 `14` 替换为当前系统主版本号），随后使用以下命令安装：

```sh
# pkg add /path/to/firmware.pkg
```

## 附录：特殊型号需要编译内核

特殊型号的博通无线网卡可能需重新编译内核才能获得完整支持。

FULLER L. FreeBSD Broadcom Wi-Fi Improvements\[EB/OL]. \[2026-03-26]. <https://web.archive.org/web/20240203102135/https://www.landonf.org/code/freebsd/Broadcom_WiFi_Improvements.20180122.html> 中列出的部分型号带有 `$` 注释：`The optional bwn(4) PHY driver is derived from b43 GPL code, and must be explicitly enabled.`，表示该 PHY 子模块依赖于基于 GNU 通用公共许可证（GNU General Public License，GPL）协议的代码（位于 `sys/gnu/dev/bwn/phy_n/`）。bwn(4) 驱动主体采用 BSD 2-Clause 许可证，但 FreeBSD 默认构建的内核与基本系统不编译该 GPL PHY 子模块，需在内核配置中显式开启 `BWN_GPL_PHY` 选项并重新编译内核。

```sh
# cd /usr/src/  # 此处是 FreeBSD 内核源代码安装目录
# cd sys/amd64/conf/  # 切换到 FreeBSD 内核配置文件目录，注意选择对应架构
# cp GENERIC MYKERNEL  # 复制默认内核配置文件 GENERIC 为自定义内核 MYKERNEL
# echo "options BWN_GPL_PHY" >> MYKERNEL  # 向 MYKERNEL 内核配置文件添加 BWN_GPL_PHY 选项
# cd /usr/src  # 此处是 FreeBSD 内核源代码安装目录
# make -j4 buildkernel KERNCONF=MYKERNEL  # 使用 MYKERNEL 配置并启用 4 个并行任务编译内核
# make -j4 installkernel KERNCONF=MYKERNEL  # 安装使用 MYKERNEL 配置编译的内核，并启用 4 个并行任务
```

上述命令中，**/usr/src/** 为 FreeBSD 内核源代码目录，需注意根据实际架构选择相应的配置文件目录。

随后在 **/boot/loader.conf** 文件中添加以下配置：

```ini
hw.bwn.usedma="1"               # 启用 DMA 模式（默认开启，设为 0 则使用 PIO 模式）
if_bwn_load="YES"               # 在启动时加载 bwn 驱动
bwn_v4_ucode_load="YES"         # 加载 BWN V4 无线固件
bwn_v4_lp_ucode_load="YES"      # 加载 BWN V4 低功耗模式无线固件
```

完成后重启系统，使用 `ifconfig` 检查是否存在 `wlan0` 接口，随后按照前文所述方法配置。

### 参考文献

* FreeBSD Foundation. Broadcom Wi-Fi Modernization\[EB/OL]. \[2026-03-26]. <https://freebsdfoundation.org/project/broadcom-wi-fi-modernization/>. FreeBSD 基金会资助的博通 Wi-Fi 驱动现代化项目概述。
* FreeBSD Project. Revision 326841\[EB/OL]. \[2026-03-26]. <https://svnweb.freebsd.org/base?view=revision&revision=326841>. 将博通无线驱动纳入 FreeBSD 基本系统的代码提交记录。
* FreeBSD Forums. Installing Broadcom BCM43236 WiFi on 11.3 missing firmware error\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/installing-broadcom-bcm43236-wifi-on-11-3-missing-firmware-error.76470/>. 博通无线网卡固件缺失导致无法使用的论坛讨论。
* helloSystem. ISO\[EB/OL]. \[2026-03-26]. <https://github.com/helloSystem/ISO/issues/78>. helloSystem 项目中关于 Wi-Fi 支持问题的反馈。

## 故障排除概述

### 无法连接或无法搜索到特定信道

无线网络的区域码设置会影响可用的信道列表。可尝试调整无线区域码设置。

在 **/etc/rc.conf** 文件中添加以下配置：

```ini
create_args_wlan0="country CN regdomain NONE"
```

该配置在创建 `wlan0` 接口时设置无线国家码为 CN，不设特定无线频段限制。

完成配置后，重启系统。

### 断开 Wi-Fi

禁用 `wlan0` 接口：

```sh
# ifconfig wlan0 down
```

### WPA 验证

在 **/etc/rc.conf** 文件中配置 `wlan0` 接口使用 WPA，并设置静态 IP 地址和子网掩码：

```ini
ifconfig_wlan0="WPA inet 192.168.1.100 netmask 255.255.255.0"
```

### 设置静态 IP

为 `wlan0` 接口配置静态 IPv4 地址和子网掩码：

```sh
# ifconfig wlan0 inet 192.168.0.100 netmask 255.255.255.0
```

### 开启无线热点

配置无线热点前，需确认网卡是否支持 hostap 模式。可通过以下命令列出 `wlan0` 接口支持的无线功能和能力：

```sh
# ifconfig wlan0 list caps
drivercaps=591c541<STA,FF,IBSS,HOSTAP,SHSLOT,SHPREAMBLE,MONITOR,WPA1,WPA2,WME>
cryptocaps=b<WEP,TKIP,AES_CCM>
htcaps=207002d<LDPC,SHORTGI20>
```

如果输出中包含 `HOSTAP`，则表明该网卡支持 hostap 功能。

确认网卡支持后，销毁现有 `wlan0` 接口并释放其占用的资源：

```sh
# ifconfig wlan0 destroy
```

重新创建 `wlan0` 接口并配置为热点模式：

```sh
# ifconfig wlan0 create wlandev rtwn0 wlanmode hostap
# ifconfig wlan0 inet 192.168.0.1 netmask 255.255.255.0 ssid freebsdap mode 11g channel 1
```

第一条命令创建 `wlan0` 接口，绑定到 `rtwn0` 并设置为 Host AP 模式；第二条命令配置 `wlan0` 的 IP 地址、SSID、无线模式和信道。

![创建无线热点](/files/RfbqzzbCyjvot2pRcldu)

## 附录：图形化网络配置工具

FreeBSD 提供了图形化网络管理工具，功能类似于 Linux 的 NetworkManager：

使用 pkg 安装：

```sh
# pkg install net-mgmt/networkmgr
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/net-mgmt/networkmgr/
# make install clean
```

## 课后习题

1. 使用两种不同厂商的无线网卡（如 Realtek 和 Intel），分别在 FreeBSD 上创建虚拟无线接口并连接同一 AP，使用 `systat -if` 监控两者的吞吐量与延迟差异，分析驱动实现差异对性能的影响。
2. 配置 FreeBSD 为无线热点（Host AP 模式），修改默认信道和发射功率参数，使用另一设备连接并测试信号强度与吞吐量变化，分析 Host AP 模式下的信道选择策略。
3. 查阅 FreeBSD 源代码中 `wlan` 接口的创建逻辑，分析系统采用“物理网卡 + 虚拟接口”分层架构而非直接管理物理设备的设计考量。


# 9.4 蓝牙

蓝牙是一种无线技术，用于在 2.4 GHz 免授权频段内创建个人网络，覆盖范围通常为 10 米。此类网络通常由便携设备（如手机、手持设备和笔记本电脑）按需形成。与 Wi-Fi 不同，蓝牙提供更高级别的服务协议，例如 FTP 类文件服务器、文件推送、语音传输、串行线路仿真等。

本节介绍在 FreeBSD 系统上使用 USB 蓝牙适配器的方法，以及各种蓝牙协议和实用程序。

## 加载蓝牙支持

FreeBSD 蓝牙协议栈基于 Netgraph 框架实现。USB 蓝牙适配器需加载 `ng_ubt` 内核模块。若需开机自动加载，可将以下配置写入 **/boot/loader.conf**：

```ini
ng_ubt_load="YES"
```

蓝牙功能的实现依赖多个系统服务协同工作。需在 **/etc/rc.conf** 中添加以下配置（或使用 `service` 命令启用）：

```ini
hcsecd_enable="YES"
sdpd_enable="YES"
bthidd_enable="YES"
```

也可通过以下命令启用并启动相关服务：

```sh
# service hcsecd enable  # 启用 hcsecd 服务
# service sdpd enable    # 启用 sdpd 服务
# service bthidd enable  # 启用 bthidd 服务
# service hcsecd start   # 立即启动 hcsecd 服务
# service sdpd start     # 立即启动 sdpd 服务
# service bthidd start   # 立即启动 bthidd 服务
```

相关组件说明：

| 组件          | 说明                                                                |
| ----------- | ----------------------------------------------------------------- |
| `ng_ubt`    | Netgraph USB 蓝牙驱动，为 USB 蓝牙适配器提供传输层支持，是蓝牙协议栈的基础驱动                  |
| `hcsecd`    | 管理蓝牙设备的链路密钥和 PIN 码，负责蓝牙设备的安全认证                                    |
| `sdpd`      | 蓝牙服务发现协议（Service Discovery Protocol）守护进程，负责发现和通告蓝牙服务              |
| `bthidd`    | 支持 Bluetooth HID（Human Interface Device）设备，如蓝牙鼠标、键盘等              |
| `hccontrol` | 通过 hccontrol(8) 可控制蓝牙 HCI 底层接口，包括查询设备状态、扫描附近设备、管理连接等操作，是蓝牙调试的核心工具 |

## 蓝牙鼠标配对

以罗技 M337 鼠标为例，需长按鼠标底部的配对按钮直至指示灯快速闪烁，使其进入可被发现的配对模式。

使用 root 权限运行 `bluetooth-config scan` 命令，扫描附近可用的蓝牙设备，并按提示信息完成设备配对与添加：

```sh
# bluetooth-config scan
Scanning for new Bluetooth devices (Attempt 1 of 5) ... done.
Found 1 new bluetooth device (now scanning for names):
[ 1] 34:88:5d:12:34:56  "Bluetooth Mouse M336/M337/M535" (Logitech-M337)
Select device to pair with [1, or 0 to rescan]: 1

This device provides human interface device services.
Set it up? [yes]:
```

## 附录：英特尔蓝牙

由 iwm、iwx 或 iwlwifi 驱动的 Intel 无线网卡通常集成了蓝牙功能，可通过安装 **comms/iwmbt-firmware** 固件包来加载蓝牙硬件所需的微码。

* 使用 pkg（二进制包管理器）安装：

```sh
# pkg install iwmbt-firmware
```

* 使用 Ports 安装：

```sh
# cd /usr/ports/comms/iwmbt-firmware/
# make install clean
```

蓝牙设备通过 USB 总线连接，可使用 `usbconfig` 工具查看所有 USB 设备（包括蓝牙设备）。如果系统启动时固件未自动加载，可手动加载。例如，如果蓝牙设备标识为 `ugen1.5`，则可执行：

```sh
# iwmbtfw -d ugen1.5 -f /usr/local/share/iwmbt-firmware/
```

> **注意**
>
> FreeBSD 蓝牙协议栈初始化脚本（**/etc/rc.d/bluetooth**）可能在系统服务启动阶段（蓝牙 HID 守护进程尝试打开设备时）导致设备锁定。因此，必须在启动蓝牙协议栈之前先运行 `iwmbtfw` 加载固件，否则须执行完整的断电重启或挂起恢复周期方可解锁设备。

## 故障排除与未竟事宜

### 配对连接后自动断开

此问题可能由 bthidd 服务缓存的设备信息与实际设备状态不一致所致。解决方案：删除 **/var/db/bthidd.hids** 文件中对应鼠标的 `bd_addr` 行（该行包含设备的蓝牙地址，格式为 `xx:xx:xx:xx:xx:xx`，如 `34:88:5d:12:34:56`），清除旧的配对信息。

完成上述操作后，重启蓝牙 HID 守护进程服务使更改生效：

```sh
# service bthidd restart
```


# 9.5 USB 网络共享

## 概述

USB 网络共享（USB tethering）是通过通用串行总线（USB）物理层将移动设备（如智能手机、平板电脑）的广域网（WAN）连接共享给计算机系统的技术。

以下配置方法已在红米 Note 12 5G 上完成测试验证，可支持 Android 设备和 iPhone 13 及更早型号的 iOS 设备（iPhone 14 及更新型号因 NCM 协议兼容性问题暂不可用，详见下文 Apple 设备驱动部分说明）。

### Wi-Fi 共享的流量特性

部分 Android 手机（如 Google Pixel 3 及更新机型）开启 Wi-Fi 并关闭移动数据后，可将网络共享给 FreeBSD。该功能通过将手机已建立的 Wi-Fi 连接经由 USB 接口转发给 FreeBSD 实现，不产生移动数据流量。

![USB 网络共享](/files/n82Z2ffHaQqCQykDV73U)

已获取 root 权限的 Android 设备，还可通过数据线将手机的 VPN 连接共享给 FreeBSD 设备。相关软件可参考 [VPN 热点](https://github.com/mygod/vpnhotspot)，使用方法可参考 [通过创建 Wifi 热点来共享 V2ray 代理](https://www.sainnhe.dev/post/v2ray-hotspot/)。

## 加载内核模块

首先需加载相应内核模块，使系统能识别 USB 网络共享设备（若默认未加载）。

### 通用 Android 设备驱动

一般 Android 设备使用远程网络驱动接口规范（Remote Network Driver Interface Specification，RNDIS）协议，需加载以下内核模块：

```sh
# kldload if_urndis
```

该命令加载 USB RNDIS 网络驱动，使系统能够识别使用 RNDIS 协议的 Android 设备。

### Apple 设备驱动

Apple iPhone/iPad 设备需加载以下内核模块：

```sh
# kldload if_ipheth
```

该命令加载 iPhone/iPad 以太网网络驱动，使系统能够识别 iOS 设备的 USB 网络共享功能。加载成功后，系统通常会创建类似 `ue0` 的网络接口。

> **注意**
>
> 自 iPhone 14 系列起，Apple 已将 USB 网络共享协议从传统 IP-over-USB 切换为 NCM 协议。FreeBSD 的 if\_ipheth 驱动目前不支持 NCM 模式，if\_cdce 驱动对 Apple 的 NCM 实现也存在兼容性问题（Apple 的 NCM 实现不完全符合标准），可能导致连接不可用。截至 2025 年末，此问题尚无完善的解决方案。

### 较新 Android 设备驱动（CDC NCM）

自 Google Pixel 6 系列（2021 年）起，Google 已将 Android 原生 USB 网络共享协议从 RNDIS 切换为网络控制模型（Network Control Model，NCM），其他部分厂商的新款设备也逐步跟进。此类设备需加载以下内核模块：

```sh
# kldload if_cdce
```

该命令加载 USB CDC ECM/NCM 网络驱动，使系统能够识别使用 NCM 协议的 Android 设备。加载成功后，系统通常会创建类似 `ue0` 的网络接口。

## 持久化驱动加载机制

如需系统启动时自动加载上述模块，可根据设备类型选择相应条目写入 **/boot/loader.conf** 文件：

```ini
if_urndis_load="YES"  # 设置系统启动时自动加载 USB RNDIS 网络驱动
if_cdce_load="YES"    # 设置系统启动时自动加载 USB CDC ECM/NCM 网络驱动
if_ipheth_load="YES"  # 设置系统启动时自动加载 iPhone/iPad 以太网驱动
```

编辑完成后，保存文件并重启系统使更改生效。

## 物理连接与网络共享启用

加载所需内核模块后，将 USB 数据线连接到 FreeBSD 系统与移动设备之间，随后在移动设备上开启 USB 网络共享功能。具体开启方式因设备品牌和系统版本而异，通常可在移动设备的“设置”、“网络”或“个人热点”菜单中找到相关选项。需注意，部分 Android 设备可能需先启用 USB 调试才能识别 USB 网络共享设备（大多数现代 Android 设备无需此步骤）；iOS 设备可能需在弹出的对话框中确认信任该计算机方可正常工作。

## 获取 IP 地址

移动设备开启 USB 网络共享后，FreeBSD 系统会自动创建相应的网络接口，通常接口名称为 `ue0`，可通过 `ifconfig` 命令确认实际接口名称。确认接口名称后，通过 DHCP 为该接口获取 IP 地址：

```sh
# dhclient ue0
```

该命令为 `ue0` 接口发送 DHCP 请求，从移动设备获取 IP 地址、子网掩码、默认网关和 DNS 服务器等网络配置参数。获取成功后，可使用 `ifconfig ue0` 命令查看分配的 IP 地址。

## 参考文献

* FreeBSD Project. if\_urndis -- USB Remote NDIS Ethernet device\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=if_urndis&sektion=4>. USB RNDIS 网络设备驱动手册页，用于 Android USB 网络共享。
* FreeBSD Project. if\_cdce -- Communication Device Class Ethernet device\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=if_cdce&sektion=4>. USB CDC Ethernet 设备驱动手册页。
* FreeBSD Project. if\_ipheth -- Apple iPhone USB Ethernet device\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=if_ipheth&sektion=4>. iPhone USB 网络共享驱动手册页。
* FreeBSD Project. dhclient -- Dynamic Host Configuration Protocol client\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=dhclient&sektion=8>. DHCP 客户端手册页，描述自动获取 IP 地址配置。
* FreeBSD Project. ifconfig -- configure network interface parameters\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=ifconfig&sektion=8>. 网络接口配置工具手册页。
* FreeBSD Project. loader.conf -- kernel and module configuration\[EB/OL]. \[2026-04-14]. <https://man.freebsd.org/cgi/man.cgi?query=loader.conf&sektion=5>. 内核模块加载配置文件格式手册页。


# 9.6 系统代理

代理（Proxy）技术是计算机网络中的基础概念，其核心原理是在客户端与目标服务器之间引入中间节点，由中间节点代为转发请求和响应。

## 代理工作原理

代理的工作流程可概括为：客户端发起请求 → 请求重定向至代理服务器 → 代理服务器将请求转发至目标服务器 → 目标服务器响应代理服务器 → 代理服务器将响应返回客户端。在此过程中，目标服务器获知的是代理服务器的地址，而非客户端的真实地址。

代理按部署模式可分为三类：

| 类型                          | 说明                            | 典型用途               |
| --------------------------- | ----------------------------- | ------------------ |
| **正向代理（Forward Proxy）**     | 客户端显式配置代理地址，代理代表客户端向外部服务器发起请求 | 突破网络访问限制和缓存加速      |
| **反向代理（Reverse Proxy）**     | 代理代表服务器接收客户端请求，客户端不知道真实服务器的地址 | 负载均衡、SSL 终结和静态内容缓存 |
| **透明代理（Transparent Proxy）** | 客户端无需配置，网络设备（如路由器）将流量重定向至代理   | 企业网络的内容过滤和流量监控     |

三种代理模式的数据流对比：

```sh
代理模式对比

  正向代理（Forward Proxy）
  客户端 ──→ 代理服务器 ──→ 目标服务器
  (已知代理)  (代表客户端)  (只看到代理 IP)

  反向代理（Reverse Proxy）
  客户端 ──→ 代理服务器 ──→ 真实服务器
  (不知真实服务器)  (代表服务器)  (隐藏在后端)

  透明代理（Transparent Proxy）
  客户端 ──→ 网关/路由器 ──→ 代理 ──→ 目标服务器
  (无感知)    (流量重定向)   (透明拦截)
```

配置系统代理前，需了解 FreeBSD 提供的环境变量配置方式。

## 配置 HTTP\_PROXY 代理

通过设置 HTTP\_PROXY、HTTPS\_PROXY、ALL\_PROXY 等环境变量，可使多数命令行工具通过代理转发流量。以下为配置方法。

### 临时设置

在当前 shell 会话中临时设置代理环境变量：

```sh
$ export HTTP_PROXY=http://192.168.X.X:7890
```

> **警告**
>
> 示例中的 IP 地址和端口号 **192.168.X.X:7890** 需替换为实际的代理服务端点。

取消已设置的 HTTP 代理环境变量：

```sh
$ unset HTTP_PROXY
```

### 持久化配置（用户分级方法）

通过用户分级方法持久化配置，使代理环境变量在每次登录时自动生效，且与 Shell 类型无关。编辑 **\~/.login\_conf** 文件：

```ini
me:\
	:setenv=HTTP_PROXY=http://192.168.X.X:7890,HTTPS_PROXY=http://192.168.X.X:7890:
```

编辑后，需要执行以下命令来更新登录能力数据库：

```sh
$ cap_mkdb ~/.login_conf
```

重新登录后生效。

## 配置 Git 代理

Git 支持通过 `http.proxy` 和 `core.gitProxy` 等配置项设置代理。

## 为浏览器配置代理

### Chrome 命令选项

[chromium](https://www.chromium.org/) 是 Google Chrome 浏览器的开源版本，支持多种命令行参数。

Chromium 浏览器在 **\~/.config** 等目录下并无独立的代理配置界面，但支持通过 `http_proxy`/`https_proxy` 环境变量（非 Gnome/KDE 环境下）及启动参数设置代理。

可按以下格式指定代理服务器和端口：

```sh
--proxy-server="<IP 地址>:<端口>"
```

启动 Chrome 并使用指定的本地代理服务器：

```sh
$ chrome --proxy-server="127.0.0.1:1234"
```

默认使用 HTTP 协议。指定 SOCKS 代理服务器和端口：

```sh
--proxy-server="socks://<IP 地址>:<端口>"
```

指定 SOCKS4 代理服务器和端口：

```sh
--proxy-server="socks4://<IP 地址>:<端口>"
```

要使 Chromium 在图形界面中默认通过代理启动，可修改桌面启动文件以实现持久化配置。

找到桌面环境为 Chromium 创建的 desktop 文件，通常位于 **\~/.local/share/applications/** 目录：

使用编辑器打开 Chromium desktop 文件 `chromium-browser.desktop`，找到 `Exec=chrome %U` 一行并在其后添加所需参数：

```ini
Comment[zh_CN]=Google web browser based on WebKit
Comment=Google web browser based on WebKit
Encoding=UTF-8
Exec=chrome %U
GenericName[zh_CN]=
......
```

启动 Chromium 并使用指定的代理服务器：

```sh
Exec=chrome %U --proxy-server="192.168.2.163:20172"
```

> **技巧**
>
> 上述示例中的 **192.168.2.163**、`20172` 为占位符，须替换为实际的值。

### 为 Firefox 单独配置代理

Firefox 浏览器的设置页面中，网络设置选项卡提供了图形化代理配置模块。

![Firefox 代理设置](/files/zfoMhFegLkScyqZgY7Nw)

### 参考文献

* Owynn, graudeejs, rjohn, olli@, Sevendogsbsd, kpedersen. chromium proxy settings page doesn't exist\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/chromium-proxy-settings-page-doesnt-exist.31927/>. 提供了 FreeBSD 下 Chromium 代理配置的实践解决方案。

## 课后习题

1. 修改 Chromium 的 desktop 文件，使其默认使用 SOCKS5 代理启动，验证其 DNS 查询是否通过代理转发，分析 `--proxy-server` 参数对 DNS 解析路径的影响。
2. 为 csh 和 sh 分别编写代理开关脚本，设置代理后使用 `tcpdump` 验证 git、fetch 等命令的实际网络流量路径，分析不同 shell 对环境变量大小写约定的差异及其规范来源。
3. 为 Firefox 编写一个 shell 脚本，通过修改其 `prefs.js` 配置文件实现代理自动切换，对比 Firefox 配置文件方式与 Chromium 命令行参数方式在用户可控性上的差异。


# 10.1 显卡驱动概论

使用 bsdinstall 安装的 FreeBSD 系统不会自动安装图形用户界面。本节介绍如何为图形处理器（GPU）选择和安装驱动程序。

## 何时需要安装显卡驱动？

![未安装显卡驱动的报错图](/files/fXbQs85dJIPTSzYnqMZt)

上图展示了未安装显卡驱动时可能出现的错误界面。

> **警告**
>
> 请勿使用 **sysutils/desktop-installer**，该工具在当前环境下可能引发错误和配置冲突。

## 显卡支持情况

FreeBSD 的 i915 和 AMD 显卡驱动与基本系统分离，以 Port 形式提供，这些驱动移植自 Linux 内核的直接渲染管理器（DRM，Direct Rendering Manager），采用长期支持（Long Term Support，LTS）版本。不同系统版本对应的 Linux 内核版本有所不同。

> **注意**
>
> 使用 Ports 安装时，drm 驱动需要在 **/usr/src** 中有一份当前版本的系统源代码，具体可参考系统更新章节。如果已参考本书其他章节安装，系统中通常已有一份源代码，无需再次获取。

DRM 是 Linux 内核的子系统，负责与现代显卡的 GPU 交互。FreeBSD 在内核中实现了 Linux 内核编程接口（LinuxKPI，Linux Kernel Programming Interface）并移植了 Linux DRM，部分无线网卡驱动也采用了这种移植方式。

> **注意**
>
> 这种移植并不覆盖 Linux 现有的全部 DRM GPU 驱动，目前仅包括 i915、amdgpu 和 radeon，vmwgfx、xe、virtio 等均未移植。这些未移植的 GPU 缺少 DRM KMS 驱动支持，无法在 Wayland 上运行，在 X11 上也只能使用帧缓冲驱动（如 scfb 或 vesa）而非硬件加速驱动。

显卡支持情况：

| Port 名称                      | Linux DRM 版本 | 适用 FreeBSD 版本 | 说明                                                                                               |
| ---------------------------- | ------------ | ------------- | ------------------------------------------------------------------------------------------------ |
| **graphics/drm-515-kmod**    | 5.15 LTS     | 14.0–15.x     | 不支持 FreeBSD 16.0 及以上                                                                             |
| **graphics/drm-61-kmod**     | 6.1 LTS      | 14.0 及以上      | 14.x 的默认选择                                                                                       |
| **graphics/drm-66-kmod**     | 6.6 LTS      | 15.0 及以上      | 15.0 的默认选择                                                                                       |
| **graphics/drm-612-kmod**    | 6.12 LTS     | 15.1 及以上      | 15.1 及以上的默认选择；Intel Meteor Lake 图形在 6.7 后默认启用；AMD 覆盖 GCN 到 RDNA 4 全部架构（RDNA 4 支持自 Linux 6.12 引入） |
| **graphics/drm-latest-kmod** | 跟踪最新         | 15.1 及以上      | 跟踪 drm-kmod 仓库 master 分支，当前为 Linux 6.12；可能不如 LTS 版本稳定                                            |

通过元 Port **graphics/drm-kmod** 安装时，系统会根据 OSVERSION 自动选择合适的版本：

| OSVERSION 条件 | 选择的 Port     | 对应 FreeBSD 版本 |
| ------------ | ------------ | ------------- |
| >= 1500509   | drm-612-kmod | 15.1 及以上      |
| >= 1500031   | drm-66-kmod  | 15.0          |
| 其余           | drm-61-kmod  | 14.x          |

drm-kmod 元 Port 自动选择驱动版本的逻辑如下：

```sh
drm-kmod 版本选择流程

  FreeBSD 版本
       │
       ▼
  uname -U（获取 OSVERSION）
       │
       ├── OSVERSION >= 1500509 ──► drm-612-kmod（Linux 6.12 LTS）
       │                             FreeBSD 15.1+
       │
       ├── OSVERSION >= 1500031 ──► drm-66-kmod（Linux 6.6 LTS）
       │                             FreeBSD 15.0
       │
       └── 其他 ──► drm-61-kmod（Linux 6.1 LTS）
                    FreeBSD 14.x

  也可手动安装特定版本：
    drm-515-kmod    → Linux 5.15 LTS（14.0–15.x）
    drm-latest-kmod → 跟踪最新开发版（15.1+）
```

如需指定版本，可直接安装对应的 Port。上述 OSVERSION 阈值为 Ports 树中的硬编码数值，会随 Ports 树更新而变化，以 Ports 中的实际 Makefile 为准。

可在 Ports 开发者手册的最后一章中查询 OSVERSION 对应的版本和 Git 提交。

查看本机 `OSVERSION`，显示系统版本构建标识符：

```sh
# uname -U
1500019
```

> **警告**
>
> 每次小版本或大版本升级时，可能需要重新获取系统源代码并重新编译安装显卡驱动模块，方可顺利完成升级并避免停留在黑屏界面；或也可使用“模块源”方式。

## 加入 video 组

video 组是负责访问 DRM 和 DRI 视频设备的用户组。只有加入该组的用户才能正常启用显卡的硬件加速功能以及 Wayland 会话功能。

需将指定用户添加到 video 用户组：

```sh
# pw groupmod video -m 实际用户名
```

> **警告**
>
> 即使已加入 `wheel` 组，也应再加入 `video` 组，否则视频硬件解码功能可能出现异常，且 Wayland 下普通用户将无权限调用显卡。

## 亮度调节

### 通用设置

一般计算机需要在 **/boot/loader.conf** 文件中启用 ACPI 视频支持：

```sh
# sysrc -f /boot/loader.conf acpi_video_load="YES"
```

ThinkPad 可启用 IBM ACPI 支持和 ACPI 视频支持。

* 在 **/boot/loader.conf** 文件中启用 IBM ACPI 支持：

```sh
# sysrc -f /boot/loader.conf acpi_ibm_load="YES"
```

* 在 **/boot/loader.conf** 文件中启用 ACPI 视频支持：

```sh
# sysrc -f /boot/loader.conf acpi_video_load="YES"
```

### Intel/AMD 显卡

`backlight` 工具自 FreeBSD 13 引入。

```sh
# backlight          # 打印当前亮度
# backlight -q       # 仅输出亮度数值，便于脚本使用
# backlight -i       # 查询背光设备信息（名称、类型）
# backlight decr 20  # 降低 20% 亮度
# backlight +        # 默认调整亮度增加 10%
# backlight -        # 默认调整亮度减少 10%
```

如果上述操作未生效，可检查 **/dev/backlight** 路径下的可用设备。

* 示例（使用 `ls /dev/backlight` 命令查看实际设备）：

设置 amdgpu\_bl00 背光亮度为 10：

```sh
# backlight -f /dev/backlight/amdgpu_bl00 10
```

设置 backlight0 背光亮度为 10：

```sh
# backlight -f /dev/backlight/backlight0 10
```

### 参考文献

* Vadot E. backlight -- configure backlight hardware\[EB/OL]. (2022-07-19)\[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=backlight&sektion=8>. 经测试，此部分教程适用于 Renoir 显卡。

## 状态检查

检查显卡是否已成功驱动：

```sh
$ pciconf -lv | grep -B4 VGA   # 列出系统中所有 VGA 兼容设备及其型号
$ ls -al /dev/dri/card0
lrwxr-xr-x  1 root wheel 8 Jul  2 19:39 /dev/dri/card0 -> ../drm/0

$ ls -al /dev/backlight/backlight0
crw-rw---- 1 root video 1, 177 2025年 8月22日 /dev/backlight/backlight0  # 台式机 HDMI 等输出可能没有
```

显卡驱动加载成功后，系统中将出现 `card0` 设备（默认编号为 `0`，如有第二块显卡则为 `card1`），同时还可能出现 `backlight0` 设备（HDMI 输出下通常不存在该设备）。可使用 `kldstat | grep -E "i915kms|amdgpu|radeonkms"` 进一步确认对应的内核模块已成功加载。

## 故障排除与未竟事宜

> **注意**
>
> 遇到任何问题时，请先使用 Ports 重新编译安装，尤其是在版本升级时。

* 如果显卡驱动存在问题，请直接联系维护者：<https://github.com/freebsd/drm-kmod/issues>。
* 如果笔记本出现唤醒时屏幕无法点亮的问题，可在 **/boot/loader.conf** 文件中添加 `hw.acpi.reset_video="1"` 以在唤醒时重置显示适配器。
* 普通用户可能未加入 `wheel` 组或 `video` 组。如果普通用户未加入 video 组（仅加入 wheel 组不够），KDE 设置中将始终显示显卡驱动为“llvmpipe”，这会影响 Wayland 下普通用户的显示或硬件解码功能。

### KLD XXX.ko depends on kernel - not available or version mismatch.

提示内核版本不符，请先升级系统或使用 Ports 编译安装。可使用 FreeBSD-kmods 仓库提供的内核模块（参见其他章节），应不致出现类似问题。

![AMD 驱动错误提示](/files/BHhY2UOj0JWg35iT9q2Y)

## 课后习题

1. 使用 `pciconf -lv | grep -B3 display` 查看本机显卡型号，根据显卡品牌（Intel、AMD 或 NVIDIA）安装对应的 DRM 驱动，用 `kldstat` 确认驱动模块已加载。
2. 安装显卡驱动后，检查 **/dev/dri/card0** 设备是否存在，将当前用户加入 `video` 组，重启后运行 `glxinfo | grep "OpenGL renderer"` 确认硬件加速是否生效。
3. 在 **/boot/loader.conf** 中启用 ACPI 视频支持，使用 `backlight` 命令调节屏幕亮度，记录 `backlight decr` 和 `backlight +` 的实际效果。


# 10.2 Intel 显卡驱动

本节涵盖 Intel 核芯显卡（i915 DRM 模块）的驱动安装与配置。请先阅读显卡驱动概论。

## 安装 Intel 核芯显卡

### FreeBSD 14.x

> **技巧**
>
> 如果要使用 pkg 安装，可参照本书其他章节配置的 kernel modules（kmods）内核模块源。

```sh
# cd /usr/ports/graphics/drm-61-kmod
# make BATCH=yes install clean
```

或使用 pkg 安装（如 Ports 安装有问题则使用此方法）：

```sh
# pkg install drm-61-kmod
```

### FreeBSD 15.0

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/drm-66-kmod
# make BATCH=yes install clean
```

> **注意**
>
> 英特尔三代处理器的 HD 4000 等早期核芯显卡，在未安装 DRM 驱动时，传统 BIOS 模式下仅能以 VESA 帧缓冲（无 GPU 加速）作为后备显示，在 UEFI 模式下可能出现花屏现象。安装对应版本的 DRM 显卡驱动后方可获得正常的 GPU 硬件加速。

## 配置 Intel 核芯显卡

在 **/etc/rc.conf** 文件中添加 `i915kms` 内核模块到 `kld_list`，以便系统启动时加载：

```sh
# sysrc -f /etc/rc.conf kld_list+=i915kms
```

## 视频硬解

> **警告**
>
> 如果忽略此部分，Blender 等依赖 GPU 加速的软件可能无法正常运行或产生“段错误”。

### 安装 Intel VA-API 媒体驱动

* 使用 pkg 安装：

```sh
# pkg install libva-intel-media-driver
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/multimedia/libva-intel-media-driver/
# make install clean
```

### 安装 Mesa 的 Gallium VA-API 和 VDPAU 支持包

* 使用 pkg 安装：

```sh
# pkg install mesa-gallium-va mesa-gallium-vdpau
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/graphics/mesa-gallium-va/ && make install clean
# cd /usr/ports/graphics/mesa-gallium-vdpau/ && make install clean
```

## 附录：Intel 显卡电源管理

某些显卡的功耗可能过高，FreeBSD 可通过特定的配置来降低功耗。

如果使用 **graphics/drm-kmod** 驱动的 Intel 显卡，可将以下选项添加到 **/boot/loader.conf** 文件中：

```ini
compat.linuxkpi.i915_fastboot=1  	# ①
compat.linuxkpi.i915_enable_dc=2 	# ②
compat.linuxkpi.i915_enable_fbc=1	# ③
```

功能说明：

| 配置项                               | 值   | 说明              |
| --------------------------------- | --- | --------------- |
| `compat.linuxkpi.i915_fastboot`   | `1` | 尝试跳过启动时不必要的模式设置 |
| `compat.linuxkpi.i915_enable_dc`  | `2` | 启用省电显示 C 状态     |
| `compat.linuxkpi.i915_enable_fbc` | `1` | 启用帧缓冲压缩以节省电力    |

## 参考文献

* FreeBSD Project. Graphics\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/Graphics>. FreeBSD 官方维基，是图形硬件兼容性详细列表与配置指南。

## 课后习题

1. 尝试自动化 FreeBSD 上的 DRM 移植流程。
2. 尝试从 OpenBSD 重新移植 DRM 实现。


# 10.3 AMD 显卡驱动

本节涵盖 AMD 显卡驱动的安装与配置。请先阅读显卡驱动概论。

## 安装 AMD 显卡驱动

> **注意**
>
> 在使用 GNOME 时，如果自动锁屏/熄屏，可能无法再次进入桌面。相关技术问题可参见：Bug 255049 - x11/gdm doesn't show the login screen\[EB/OL]. \[2026-03-26]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=255049>。

> **注意**
>
> 使用 Ports 安装时，drm 驱动需要在 **/usr/src** 中有一份当前版本的系统源代码，具体可参考系统更新章节。如果已参考本书其他章节安装，系统中通常已有一份源代码，无需再次获取。

### FreeBSD 14.x

```sh
# cd /usr/ports/graphics/drm-61-kmod
# make BATCH=yes install clean
```

或使用 pkg 安装（如 Ports 安装有问题则使用此方法）：

```sh
# pkg install drm-61-kmod
```

### FreeBSD 15.0

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/drm-66-kmod
# make BATCH=yes install clean
```

## AMD 显卡配置

* 基于 GCN 架构（HD 7750 及以上）及更新的 AMD 显卡，在 **/etc/rc.conf** 文件中添加 `amdgpu` 内核模块到 `kld_list`，以便系统启动时加载（多数用户应使用此驱动，如未生效，再修改为 `radeonkms`）：

```sh
# sysrc -f /etc/rc.conf kld_list+=amdgpu
```

* GCN 架构之前的 AMD 显卡，在 **/etc/rc.conf** 文件中添加 `radeonkms` 内核模块到 `kld_list`：

```sh
# sysrc -f /etc/rc.conf kld_list+=radeonkms
```

## AMD 显卡视频硬解

> **警告**
>
> 如果忽略此部分，Blender 等软件将无法运行，并会直接产生“段错误”。

### 安装 Mesa 的 Gallium VA-API 和 VDPAU 支持包

* 使用 pkg 安装：

```sh
# pkg install mesa-gallium-va mesa-gallium-vdpau
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/graphics/mesa-gallium-va/ && make install clean
# cd /usr/ports/graphics/mesa-gallium-vdpau/ && make install clean
```

### 附录：X11 设置

如果上述配置未生效，可能还需要配置 X11。

将以下内容写入 **/usr/local/etc/X11/xorg.conf.d/20-amdgpu-tearfree.conf** 文件（请自行创建该文件）：

```ini
Section "Device"
  Identifier "AMDgpu"          # 设置设备标识符为 AMDgpu
  Driver "amdgpu"              # 使用 amdgpu 驱动
  Option "TearFree" "on"       # 启用 TearFree 功能以防止屏幕撕裂
EndSection
```

配置完成后，可使用命令 `mpv --hwdec=auto xxx.mp4` 测试。需自行安装 mpv。

## 参考文献

* FreeBSD Project. Graphics\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/Graphics>. FreeBSD 官方维基，是图形硬件兼容性详细列表与配置指南。

## 课后习题

1. 尝试自动化 FreeBSD 上的 DRM 移植流程。
2. 尝试从 OpenBSD 重新移植 DRM 实现。


# 10.4 NVIDIA 显卡驱动

## NVIDIA 显卡驱动概述

台式机如果 CPU 为英特尔处理器且型号以 F（如 [i5-9400F](https://www.intel.cn/content/www/cn/zh/products/sku/190883/intel-core-i59400f-processor-9m-cache-up-to-4-10-ghz/specifications.html)）或 KF（如 [i5-12600KF](https://www.intel.cn/content/www/cn/zh/products/sku/134590/intel-core-i512600kf-processor-20m-cache-up-to-4-90-ghz/specifications.html)）结尾，则该型号无核芯显卡，无需处理核芯显卡相关配置。

如果已有独立显卡，且视频输出接口（DP 或 HDMI）直接连接至独立显卡，通常无需配置核芯显卡，仅处理独立显卡驱动即可。

不具备显卡直通能力的笔记本设备，必须先按照其他章节安装并配置英特尔核芯显卡驱动（相关 DRM 模块），随后再参照下文完成 NVIDIA 独立显卡驱动的配置。

```sh
是否笔记本？
├── 是（笔记本）→ Intel/AMD 核显 → NVIDIA（混合显卡，如有）
└── 否（台式机）
    ├── 是否有核显？
    │   ├── 否（Intel F/KF）→ NVIDIA（直连）
    │   └── 是（核显）
    │       ├── 是否使用独显输出？
    │       │   ├── 是 → NVIDIA（直连为主）
    │       │   └── 否 → Intel + NVIDIA（可选）
```

## 加入 video 组

将指定用户添加到 video 组，以便访问显卡设备：

```sh
# pw groupmod video -m 实际用户名
```

## 安装显卡驱动

使用 pkg 安装：

```sh
# pkg install nvidia-drm-kmod nvidia-settings
```

或使用 Ports 安装：

```sh
# cd /usr/ports/graphics/nvidia-drm-kmod/ && make install clean
# cd /usr/ports/x11/nvidia-settings/ && make install clean
```

列出已安装的 NVIDIA 相关软件：

```sh
# pkg info -q | grep -i nvidia
```

## 配置 NVIDIA 显卡驱动

### 启动 NVIDIA 相关内核模块

执行以下命令配置 NVIDIA 内核模块：

```sh
# sysrc -f /boot/loader.conf hw.nvidiadrm.modeset=1  # 启用 NVIDIA DRM 模式设置
# sysrc -f /etc/rc.conf kld_list+=nvidia-modeset      # 添加 nvidia-modeset 内核模块以便启动时加载
```

> **警告**
>
> X11 用户请勿尝试加载 `nvidia-drm.ko` 内核模块，该操作可能导致系统崩溃。Wayland 用户按需加载。

### 生成 X11 配置文件

需注意，如果系统可正常显示，则无需执行本节内容。执行 `Xorg -configure` 前必须确保当前无 X 服务器正在运行，否则该命令将失败。

```sh
# Xorg -configure                     # 自动生成 Xorg 配置文件
# cp /root/xorg.conf.new /usr/local/etc/X11/xorg.conf.d/xorg.conf  # 将生成的配置文件复制到配置目录
```

> **警告**
>
> 请勿尝试安装和使用 Port **x11/nvidia-xconfig**。该工具当前不适用，可能导致系统无响应。

## 硬件加速和解码器

安装 VDPAU 驱动及相关库以支持视频硬件加速。

* 使用 pkg 安装：

```sh
# pkg install libva-vdpau-driver libvdpau libvdpau-va-gl
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/multimedia/libva-vdpau-driver/ && make install clean
# cd /usr/ports/multimedia/libvdpau/ && make install clean
# cd /usr/ports/multimedia/libvdpau-va-gl/ && make install clean
```

重新启动后即可正常启用 NVIDIA 驱动。

## 查看 NVIDIA 驱动状态

列出所有 NVIDIA GPU 及其详细信息：

```sh
$ nvidia-smi
```

`nvidia-smi` 命令示例输出：

```sh
# nvidia-smi
Mon Jan 19 19:06:59 2026
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.126.09             Driver Version: 580.126.09     CUDA Version: N/A      |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA GeForce RTX 3060 Ti     Off |   00000000:01:00.0  On |                  N/A |
|  0%   39C    P8             12W /  225W |     409MiB /   8192MiB |      0%      Default |
|                                         |                        |               N/A |
+-----------------------------------------+------------------------+----------------------+

+-----------------------------------------------------------------------------------------+
| Processes:                                                                              |
|  GPU   GI   CI              PID   Type   Process name                        GPU Memory |
|        ID   ID                                                               Usage      |
|=========================================================================================|
|  No running processes found                                                             |
+-----------------------------------------------------------------------------------------+
```

* 查看 KDE 系统信息：

![KDE 系统信息](/files/LDQkf2lvpT3TDpCKGH8C)

* 使用 mpv 打开电影，可观察到显存使用量明显上升（从 3 MB 上升至数百兆），也可使用 SMPlayer 观看。

![mpv 显存使用](/files/iVkaxYc0tljBqov5aH50)

## 故障排除

### nvidia-smi 命令报错“mismatch”

![nvidia-smi 报错](/files/W7WUBUQGM6tWqvJ0gjj7)

执行 nvidia-smi 命令时出现错误提示“API mismatch”：该错误表示 API 不匹配，通常源于版本兼容性问题。可能原因包括：NVIDIA 驱动组件本身版本不匹配、NVIDIA 驱动与其他 NVIDIA 软件包版本不匹配、NVIDIA 驱动与当前 FreeBSD 基本系统版本不匹配。

建议先卸载所有 NVIDIA 软件包，随后将 FreeBSD 基本系统更新到最新版本，再重新安装驱动。

### 如何卸载现有的 NVIDIA 相关软件包

如果提示版本不符，需先卸载所有已安装的 NVIDIA 相关软件包，随后按本节配置：

先列出已安装的 NVIDIA 相关软件包，再逐个删除：

```sh
# pkg info -q | grep -i nvidia
# pkg delete nvidia-drm-kmod nvidia-driver nvidia-settings
```

### 如何阻止驱动更新

对 `pkg info -q | grep -i nvidia` 输出的相关软件包逐个使用 `pkg lock` 命令锁定即可。

例如：

```sh
# pkg lock nvidia-drm-kmod
# pkg lock nvidia-settings
```

但如果运行 `freebsd-update` 命令，或通过 PkgBase 对系统打补丁或更新，也可能影响驱动兼容性，因此需根据实际情况权衡安全需求与可用性。

## 参考文献

* Intel Corporation. 关于我们的最新处理器和命名更新的简要指南\[EB/OL]. \[2026-03-25]. <https://www.intel.cn/content/www/cn/zh/processors/processor-numbers.html>. 英特尔官方 CPU 命名规则与型号标识说明。
* NVIDIA Corporation. NVIDIA Driver Documentation\[EB/OL]. \[2026-03-25]. <https://www.nvidia.com/Download/index.aspx>. NVIDIA 官方驱动程序下载与技术文档。

## 课后习题

1. 在显卡直连的笔记本上实际测试，提交 PR。
2. 在 Linux 兼容层下调用 NVIDIA CUDA 测试。
3. NVIDIA 官方驱动以二进制闭源形式分发，而 FreeBSD 内核采用 BSD 许可证。分析闭源内核模块与 BSD 许可证的兼容性争议，并讨论 nouveau 开源驱动能否在 FreeBSD 上替代闭源方案。


# 11.1 X Window 系统概论

X Window 系统是 UNIX 平台传统的图形架构，既支持最新技术，又兼顾对历代应用程序的支持。包括桌面组件在内的应用程序由 Xorg(1) 服务器承载。该系统具有网络感知能力，其各个组件可以跨网络协同工作。目前 X Window 系统有两个分支，分别是 XLibre 和 X11。

X Window 系统采用客户端 - 服务器（Client-Server）架构：

![客户端 - 服务器架构](/files/CeCaWBIVFdAxCGsvAF7B)

对于 X11 用户，必须在安装显卡驱动后，再安装 X.org 服务器以承载桌面。还需要将用户添加到 video 组。


# 11.2 显示管理器

桌面环境通常需要显示管理器（DM）才能顺利登录桌面。

## SDDM

SDDM，即 Simple Desktop Display Manager，简易桌面显示管理器。

### 安装 SDDM

使用 pkg 安装：

```sh
# pkg ins sddm
```

或使用 Ports 安装：

```sh
# cd /usr/ports/x11/sddm/ 
# make install clean
```

启用 SDDM 显示管理器：

```sh
# service sddm enable
```

### 设置 SDDM 显示管理器的语言为简体中文

执行命令：

```sh
# sysrc sddm_lang="zh_CN"
```

![SDDM](/files/mLB5dy4FwK7WTh6p6PWT)

### 允许 root 用户登录

> **警告**
>
> root 账户拥有最高权限，不当使用 root 账户可能导致系统损坏，因此以其登录图形界面存在极高的安全风险。

更改 **/usr/local/etc/pam.d/sddm** 文件：将 `include` 之后的 `login`，改为 `system`，共计四处。

重启 SDDM 服务：

```sh
# service sddm restart
```

重启后可使用 root 登录 SDDM。

### 参考文献

* FreeBSD Forums. SDDM login screen with KDE: change language?\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/sddm-login-screen-with-kde-change-language.80535/>. 讨论 SDDM 登录界面语言设置不生效的解决方法。

### 故障排除

#### SDDM 登录闪退

如果在 VMware 虚拟机中 SDDM 底部选项未显示，请按照虚拟机配置章节的教程设置屏幕自动缩放。

#### 启动 SDDM 提示 **/usr/bin/xauth**: `(stdin):1: bad display name`，但仍可正常 `startx`

需要在 **/etc/rc.conf** 文件中检查是否已设置 `hostname="XXX"`（该条目应当存在，且不应为 `hostname=""`）：

![检查是否设置了主机名](/files/FYzA0RW1mNS4dNlmgb7G)

按需设置 `hostname` 即可。

## LightDM

LightDM，即 Light Display Manager，轻量级显示管理器。

### 安装 LightDM

使用 pkg 安装：

```sh
# pkg ins lightdm
```

使用 Ports 安装：

```sh
# cd /usr/ports/x11/lightdm/ 
# make install clean
```

设置 LightDM 显示管理器开机自启：

```sh
# service lightdm enable
```

### 中文环境

编辑 **/etc/rc.conf** 文件，加入下面一行：

```ini
lightdm_env="LC_MESSAGES=zh_CN.UTF-8"
```

设置 LightDM 环境变量，将系统消息语言指定为中文。

### 安装 greeter

greeter 提供了图形化界面，因此 LightDM 需要至少一个 greeter 才能正常工作。

#### lightdm-gtk-greeter

Port **x11/lightdm-gtk-greeter** 是使用 GTK 构建的 LightDM LightDM。Port **x11/lightdm-gtk-greeter-settings** 是一款 LightDM GTK+ 登录界面的图形配置工具。

![lightdm-gtk-greeter](/files/saeXlsfN1p9mTwUHghux)

使用 pkg 安装：

```sh
# pkg ins lightdm-gtk-greeter lightdm-gtk-greeter-settings
```

使用 Ports 安装：

```sh
# cd /usr/ports/x11/lightdm-gtk-greeter/ && make install clean
# cd /usr/ports/x11/lightdm-gtk-greeter-settings && make install clean
```

#### slick-greeter

Port **x11/slick-greeter** 是 Linuxmint 项目维护的登录界面。

使用 pkg 安装：

```sh
# pkg ins slick-greeter
```

使用 Ports 安装：

```sh
# cd /usr/ports/x11/slick-greeter/ 
# make install clean
```

Port **x11/slick-greeter** 需要编辑 **/usr/local/etc/lightdm/lightdm.conf** 文件方可启用：将 `greeter-session` 设置为 `slick-greeter`。

**slick-greeter 配置注释**

创建 **/usr/local/etc/lightdm/slick-greeter.conf** 文件，写入以下配置。

```ini
[Greeter]
# 设置登录界面的背景图片路径
background=/home/ykla/cat.png

# 是否绘制用户自定义的背景图片
draw-user-backgrounds=false

# 设置 GTK+ 主题名称
theme-name=Dracula

# 设置图标主题名称
icon-theme-name=Adwaita

# 是否显示主机名
show-hostname=true

# 设置字体名称和大小
font-name=Sans 12

# 是否显示虚拟键盘选项
show-keyboard=true

# 是否显示电源管理选项（如关机、重启）
show-power=true

# 是否显示时钟
show-clock=true

# 是否显示退出选项
show-quit=true
```

![slick-greeter](/files/9noXfGPOTjsB7bSuqvv6)

### 允许 root 用户登录

> **警告**
>
> root 账户拥有最高权限，不当使用 root 账户可能导致系统损坏，因此以其登录图形界面存在极高的安全风险。

编辑 **/usr/local/etc/pam.d/lightdm** 文件，注释掉 `account requisite pam_securetty.so` 这一行（在行首添加 `#`）。

重启 LightDM 服务：

```sh
# service lightdm restart
```

### 参考文献

* FreeBSD Forums. lightdm not reading slick-greeter.conf\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/lightdm-not-reading-slick-greeter-conf.92256/>. 解决了 LightDM 无法正确读取 slick-greeter 配置文件的技术问题。

## SLiM

SLiM, Simple Login Manager 简单的登录管理器。

> **警告**
>
> SLiM 已经不再维护，请谨慎使用。

![SLiM](/files/gHCRh0M5Gwf16nLuDHwR)

使用 pkg 安装 SLiM：

```sh
# pkg ins slim
```

使用 Ports 安装 SLiM：

```sh
# cd /usr/ports/x11/slim/ 
# make install clean
```

设置 SLiM 显示管理器开机自启：

```sh
# service slim enable
```

SLiM 默认允许 root 用户登录。

## GDM

GDM，即 GNOME Display Manager，GNOME 显示管理器。GDM 随 GNOME 安装。

### 允许 root 用户登录

> **警告**
>
> root 账户拥有最高权限，不当使用 root 账户可能导致系统损坏，因此以其登录图形界面存在极高的安全风险。

编辑配置文件 **/usr/local/etc/pam.d/gdm-password**，注释掉 `account requisite pam_securetty.so` 这一行（在行首添加 `#`）。

重启 GDM 服务：

```sh
# service gdm restart
```


# 11.3 系统字体

FreeBSD 默认字体对中文显示效果欠佳。本节介绍图形界面引入 Windows TrueType 字体的方法。

> **警告**
>
> Windows 字体的最终用户许可协议（EULA）仅授权在正版 Windows 系统内使用这些字体，将其复制到其他操作系统安装属于违反许可协议的行为。此外，部分字体（如微软雅黑）的著作权由第三方字体厂商（如方正公司）保留，未经授权的商业使用可能构成侵权。建议优先选用开源可商用的替代字体，如思源黑体（Source Han Sans）、霞鹜文楷等。

## GUI 图形界面字体

首先提取 Windows **C:\Windows\Fonts** 目录下的所有 `.ttf` 和 `.ttc` 字体文件。macOS 字体文件格式虽同为 `.ttf`，仍需特殊处理。

为管理新字体，创建一个目录存放 Windows 字体：

```sh
# mkdir -p /usr/local/share/fonts/WindowsFonts
```

将字体文件复制到 **WindowsFonts** 目录。

字体目录结构：

```sh
/usr/local/share/
└── fonts/
    └── WindowsFonts/ # Windows 字体存放目录
```

设置 Windows 字体目录及其内容的权限为 755：

```sh
# chmod -R 755 /usr/local/share/fonts/WindowsFonts
```

还需刷新字体缓存：

```sh
# fc-cache
```

## 附录：安装 Windows 11 字体（自制包）

该包亦可运行于 Debian 与低版本 Ubuntu 的 FreeBSD 兼容层下。安装方法：

```sh
# apt install git                          # 安装 Git
# git clone https://github.com/ykla/ttf-mswin11-zh-deb   # 克隆字体包仓库
# cd ttf-mswin11-zh-deb                    # 进入字体包目录
# dpkg -i ttf-ms-win11-*.deb               # 安装 Windows 11 中文字体包
```

## 课后习题

1. 从 Windows 系统提取字体文件并在 FreeBSD 中配置，测试多个 GTK 和 Qt 应用程序的字体显示效果。
2. 下载 bdf 或 hex 格式的字体文件，使用 vtfontcvt 工具将其转换为 fnt 格式，在控制台中测试显示效果。
3. 尝试使用第三方工具（如 vt-fnt）生成中文字体的 fnt 文件，验证其在 FreeBSD 控制台中的显示效果。


# 11.4 远程桌面

远程桌面访问技术可通过网络从一台设备远程控制另一台设备的桌面环境。远程桌面协议主要分为两类：基于帧缓冲区的协议（如 VNC，定义于 RFC 6143）和基于指令流的协议（如 RDP，基于 ITU-T T.120 协议族（含 T.128，即 T.share）扩展而来）。本节涵盖两种协议在 FreeBSD 下的配置。

## 目录结构

```sh
/
├── home
│   └── ykla
│       └── .vnc
│           ├── passwd              # VNC 密码文件
│           ├── xstartup             # VNC 启动脚本
│           └── config               # VNC 配置文件
│       └── .Xauthority              # X 授权文件
├── usr
│   └── local
│       └── etc
│           └── xrdp
│               ├── xrdp.ini        # XRDP 主配置文件
│               ├── sesman.ini      # XRDP 会话管理器配置
│               └── startwm.sh      # XRDP 启动桌面环境脚本
└── var
    ├── run
    │   ├── sddm                     # SDDM 授权文件目录
    │   ├── lightdm                  # LightDM 授权文件目录
    │   └── user
    │       └── 120
    │           └── gdm              # GDM 授权文件目录
    └── lib
        └── gdm                      # GDM 旧版授权文件目录
```

## x11vnc（FreeBSD 作为被控端，镜像屏幕）

x11vnc 提供屏幕镜像功能，用户操作会同步显示在物理显示器上，物理显示器上的操作在 VNC 客户端中同样可见。建议配合 SSH 隧道或 SSL 加密使用，防止 VNC 流量被嗅探。

若无物理显示器则无法使用 x11vnc，但可使用 HDMI 显卡欺骗器代替物理显示器。

### 安装 x11vnc

* 使用 pkg 安装：

```sh
# pkg install x11vnc
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/net/x11vnc/
# make install clean
```

### 创建密码

设置 x11vnc 的访问密码：

```sh
$ x11vnc -storepasswd
Enter VNC password:
Verify password:
Write password to /root/.vnc/passwd?  [y]/n y # 输入 y 并回车确认
Password written to: /root/.vnc/passwd
```

### 启动服务器（KDE 6 SDDM）

* 使用指定的密码文件和 SDDM 授权文件启动 x11vnc：

```sh
$ x11vnc -display :0 -rfbauth ~/.vnc/passwd -auth $(find /var/run/sddm/ -type f)
```

> **警告**
>
> 由于 x11vnc 尚不支持 Wayland，如果在 SDDM 左下角选择 `Wayland`，将无法进入桌面。

* 使用指定密码文件和 LightDM 授权文件启动 x11vnc：

```sh
$ x11vnc -display :0 -rfbauth ~/.vnc/passwd -auth /var/run/lightdm/root/:0
```

* 使用指定密码文件和 GDM 授权文件启动 x11vnc：

```sh
$ x11vnc -display :0 -rfbauth ~/.vnc/passwd -auth /var/lib/gdm/:0.Xauth # 或使用 /run/user/120/gdm/Xauthority，具体路径取决于 GDM 版本，可用 ls 查看
```

![SDDM X11VNC](/files/NognuZJvFJwJJuHjcDiD)

### 参考文献

* Arch Linux Wiki. X11vnc\[EB/OL]. \[2026-03-25]. <https://wiki.archlinux.org/title/X11vnc>. Arch Linux 官方维基提供的 X11vnc 配置与使用详细指南。

## TigerVNC（FreeBSD 作为被控端）

启用 VNC 服务端（Ports 中仅剩 [TigerVNC](https://www.freshports.org/net/tigervnc-server/)）。

### 安装 TigerVNC Server

使用 pkg 安装：

```sh
# pkg install tigervnc-server
```

或使用 Ports 安装：

```sh
# cd /usr/ports/net/tigervnc-server/
# make install clean
```

### 设置

创建 **\~/.vnc/** 路径：

```sh
$ mkdir -p ~/.vnc/
```

编辑 **\~/.vnc/xstartup** 文件，新增以下行：

```sh
#!/bin/sh
unset SESSION_MANAGER        # 清除 SESSION_MANAGER 环境变量
unset DBUS_SESSION_BUS_ADDRESS  # 清除 DBUS_SESSION_BUS_ADDRESS 环境变量
# 如需使用下方的桌面会话，请先注释或删除 xinitrc 的 exec 行，
# 否则 xinitrc 会替换当前进程，后续桌面会话命令不会被执行
[ -x /etc/X11/xinit/xinitrc ] && exec /etc/X11/xinit/xinitrc  # 如果 xinitrc 可执行则运行
[ -f /etc/X11/xinit/xinitrc ] && exec sh /etc/X11/xinit/xinitrc  # 否则以 sh 运行 xinitrc 文件
xsetroot -solid grey        # 设置 X 根窗口背景为灰色
#exec startplasma-x11 &      # 启动 KDE Plasma（注释示例）
#exec mate-session &         # 启动 MATE 桌面（注释示例）
#exec xfce4-session &        # 启动 XFCE4 桌面（注释示例）
#exec gnome-session &        # 启动 GNOME 桌面（注释示例）
```

删除拟启用桌面会话对应行首的 `#` 注释。

> **警告**
>
> 注意保留 `&` 字符。

设置 xstartup 脚本为可执行权限：

```sh
$ chmod 755 ~/.vnc/xstartup
```

* 在终端执行命令启动 VNC 服务器：

```sh
$ vncserver
```

在显示器 `:1` 上启动 VNC 服务器：

```sh
$ vncserver :1

You will require a password to access your desktops.

Password: # 注意，密码最少六位数！
Verify:
Would you like to enter a view-only password (y/n)? n
A view-only password is not used

New 'ykla:1 (ykla)' desktop is ykla:1

Creating default config /home/ykla/.vnc/config
Starting applications specified in /home/ykla/.vnc/xstartup
Log file is /home/ykla/.vnc/ykla:1.log
```

其中 `:1` 表示 `DISPLAY=:1`，即指定桌面显示编号为 `1`，对应 VNC 服务端口 `5901`。桌面显示编号从 0 开始，但编号 0 对应的端口已由当前桌面占用（除非是镜像 VNC），实际执行时 VNC 服务从 `5901` 开始。连接时必须指定端口 `5901`。

测试：

```sh
$ vncserver :0

Warning: ykla:0 is taken because of /tmp/.X11-unix/X0
Remove this file if there is no X server ykla:0
A VNC server is already running as :0
```

如果启动服务时未指定通信端口，系统将自动分配。

显示当前用户的进程列表：

```sh
$ ps
 PID TT  STAT    TIME COMMAND
……省略无用内容……
4769  0  S    0:02.72 /usr/local/bin/Xvnc :1 -auth /home/ykla/.Xauthority -desktop ykla:1 (ykla)
```

关闭服务请使用命令 `vncserver -kill :1`，必须指定端口号。

* 如果启用了防火墙，以 IPFW 为例，在终端输入命令：

```sh
# ipfw add allow tcp from any to me 5900-5910 in keep-state
```

上述命令表示开放端口 5900-5910，即 DISPLAY 0-10。执行 `ipfw list` 可查看当前所有防火墙规则以确认已生效。

### 参考文献

* FreeBSD Forums. Xfce4 is not displayed correctly when I connect vncviewer (in Linux) to tightvnc-server (on FreeBSD)\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/xfce4-is-not-displayed-correctly-when-i-connect-vncviewer-in-linux-to-tightvnc-server-on-freebsd.85709/>. FreeBSD 官方论坛讨论，解决了 VNC 远程连接中 Xfce4 显示异常的问题。

## XRDP（以 FreeBSD 为被控端）

### 安装 XRDP（基于 KDE6）

使用 pkg 安装：

```sh
# pkg install xorg kde xrdp wqy-fonts xdg-user-dirs pulseaudio-module-xrdp
```

或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11/kde/ && make install clean
# cd /usr/ports/net/xrdp/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
# cd /usr/ports/audio/pulseaudio-module-xrdp/ && make install clean
```

查看配置文件：

```sh
# pkg info -D xrdp
```

### 配置 XRDP

配置守护进程：

```sh
# service xrdp enable          # 设置 xrdp 服务开机自启动
# service xrdp-sesman enable   # 设置 xrdp-sesman 服务开机自启动
# service dbus enable          # 设置 D-Bus 服务开机自启动
```

编辑 **/usr/local/etc/xrdp/startwm.sh** 文件，找到 `#### start desktop environment`，修改如下：

```ini
#### start desktop environment
# exec gnome-session              # 启动 GNOME 桌面，需删除开头的 #
# exec mate-session               # 启动 MATE 桌面，需删除开头的 #
# exec start-lumina-desktop       # 启动 Lumina 桌面，需删除开头的 #
# exec ck-launch-session startplasma-x11  # 启动 KDE6 桌面，需删除开头的 #
# exec startxfce4                 # 启动 XFCE 桌面，需删除开头的 #
# exec xterm                      # 启动 XTerm，需删除开头的 #
```

重启系统后生效。

### 配置中文环境（用户使用默认的 sh）

编辑 **/usr/local/etc/xrdp/startwm.sh** 文件，添加或修改以下内容以设置环境变量：

```sh
#### set environment variables here if you want
export LANG=zh_CN.UTF-8
```

设置系统语言为中文。

### 故障排除与未竟事宜

#### XRDP 下没有声音

此问题可通过 Firefox 浏览器缓解。

## 通过 Windows 使用 TigerVNC 远程访问 FreeBSD

下载 TigerVNC 查看器：

下载地址：<https://sourceforge.net/projects/tigervnc/files/stable/>

查看 FreeBSD 的 VNC 端口：

```sh
# sockstat -4l
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
root     Xvnc        2585 4   tcp4   127.0.0.1:5910        *:*  #VNC 占用
root     xrdp        2580 13  tcp46  *:3389                *:*  #XRDP 占用
root     Xvnc        2016 5   tcp4   *:5901                *:*  #VNC 占用
root     sshd        1164 4   tcp4   *:22                  *:*  #SSH 占用
ntpd     ntpd        1127 21  udp4   *:123                 *:*
ntpd     ntpd        1127 24  udp4   127.0.0.1:123         *:*
ntpd     ntpd        1127 26  udp4   192.168.31.187:123    *:*
root     syslogd     1021 7   udp4   *:514                 *:*
```

### 故障排除与未竟事宜

#### 由于目标服务器积极拒绝，无法连接

非镜像 VNC 连接时必须指定端口，否则默认使用 5900 端口。由于非镜像 VNC 的服务端口并非 5900，连接被拒绝。

![SDDM VNC](/files/HDqK16I2dW4oB6WSD13R)

示例：

```sh
192.168.31.187:5901
```

![SDDM VNC](/files/gSetKFPv9YZBkIUQHlpU)

#### 通过 VNC 远程访问 FreeBSD 时无声音输出

该问题在本节中尚未解决。

## 通过 Windows 自带的远程桌面连接（RDP）远程访问 FreeBSD

![xrdp FreeBSD](/files/joSNTMeDjAenGPrt8zyy)

首次登录设备会有安全提示，输入 `yes`，回车后弹出远程桌面窗口。

![xrdp FreeBSD](/files/cRk8kH02fLxBakcMlOgw)

![xrdp FreeBSD](/files/Ik7KrWPdmor3ZIA73l5F)

![xrdp FreeBSD](/files/t429sTJSkY2cwiIbizZw)

![xrdp FreeBSD](/files/9QorbkiPQM3L5HLOCZo2)

### 故障排除与未竟事宜

#### 如果 Windows 的远程桌面窗口既不在左上角也未全屏显示，则显示会模糊

应取消勾选“智能调整大小”。

![智能调整大小](/files/T4LIFeF4NOYtpZKHoxg8)

## 使用 Android 通过 XRDP 远程访问 FreeBSD

下载所需软件：

由微软官方开发的手机 RDP 软件：Remote Desktop

* Microsoft Corporation. Remote Desktop\[EB/OL]. \[2026-03-25]. <https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx&hl=zh_CN>. 微软官方开发的 Android 远程桌面客户端，支持 RDP 协议连接。

该软件支持 Android 平台 RDP 连接。

将左上鼠标操作改为触摸操作。默认的鼠标操作不够便捷，也可选择通过 OTG 连接鼠标和键盘操控。

![Remote Desktop FreeBSD](/files/GNm4ieWjurGV3WBw8qIV)

连接示意图（后台正在编译 Chromium，因此占用会很高）：

![Remote Desktop FreeBSD](/files/7heBoBsGtRi2zleuWdrd)

## 通过 FreeBSD 使用 XRDP 远程访问 Windows

### freerdp3

使用 pkg 安装：

```sh
# pkg install freerdp3
```

或使用 Ports：

```sh
# cd /usr/ports/net/freerdp3/
# make install clean
```

使用 FreeBSD 通过 freerdp3 远程连接到 Windows 11 24H2：

```sh
$ xfreerdp3 /u:ykla /p:z  /v:192.168.31.213

……省略一部分……
441] [19244:dca12700] [ERROR][com.freerdp.crypto] - [tls_print_new_certificate_warn]: Host key verification failed.
Certificate details for 192.168.31.213:3389 (RDP-Server):
        Common Name: DESKTOP-U72I6SS
        Subject:     CN = DESKTOP-U72I6SS
        Issuer:      CN = DESKTOP-U72I6SS
        Valid from:  Mar  4 12:39:28 2025 GMT
        Valid to:    Sep  3 12:39:28 2025 GMT
        Thumbprint:  36:b9:be:66:ab:2b:54:32:28:46:b6:98:68:8d:6f:20:a5:d1:58:8c:09:de:cc:3d:30:e1:06:6f:4f:62:54:de
The above X.509 certificate could not be verified, possibly because you do not have
the CA certificate in your certificate store, or the certificate has expired.
Please look at the OpenSSL documentation on how to add a private CA to the store.
Do you trust the above certificate? (Y/T/N) y # 输入 y 并回车确认连接
```

> **警告**
>
> 通过 `/p` 参数在命令行中直接传递密码，密码会出现在进程列表中（可通过 `ps` 等命令查看），存在安全隐患。
>
> 上述示例中的 **192.168.31.213**、`ykla` 为占位符，须替换为实际的值。示例中省略 `/p` 参数后，执行后程序会交互式提示输入密码，这比在命令行中明文写出密码更安全。

`xfreerdp3 /u:ykla /p:z /v:192.168.31.213` 参数说明：

| 参数                  | 含义           | 说明                            |
| ------------------- | ------------ | ----------------------------- |
| `xfreerdp3`         | 命令           | 注意其前缀为 `x`                    |
| `/u:ykla`           | Username 用户名 | `ykla` 是 Windows 的登录名         |
| `/p:z`              | Password 密码  | `z` 是 Windows 用户 `ykla` 的登录密码 |
| `/v:192.168.31.213` | Server 服务器   | 替换为实际的 Windows 主机地址           |

![freerdp](/files/TBwanXagZWBJj1oeUwXi)

#### 参考文献

* Awakecoding. FreeRDP User Manual\[EB/OL]. \[2026-03-25]. <https://github.com/awakecoding/FreeRDP-Manuals/blob/master/User/FreeRDP-User-Manual.markdown>. GitHub 提供的 FreeRDP 用户手册，包含完整命令说明与实用示例。

#### 故障排除与未竟事宜

测试过程中发现未输入用户名即成功连接，这可能与 FreeBSD 用户名和 Windows 用户名相同有关。

### rdesktop（不支持 NLA）

**net/xrdesktop2** 是 rdesktop 的图形化前端，测试中在打开键盘设置时出现无响应。

***

使用 pkg 安装 rdesktop：

```sh
# pkg install rdesktop
```

或用 Ports 安装：

```sh
# cd /usr/ports/net/rdesktop/
# make install clean
```

rdesktop 无前端 GUI，需在终端输入命令：

```sh
# rdesktop ip:端口 # 例如 192.168.31.155:3389
```

如果未手动更改 Windows 配置，无须加 `:端口号`。

在测试的 Windows 11 24H2 上会报错：

```sh
$ rdesktop 192.168.31.213
Failed to connect, CredSSP required by server (check if server has disabled old TLS versions, if yes use -V option).
```

根据 rdesktop team. CredSSP does not work\[EB/OL]. \[2026-04-04]. <https://github.com/rdesktop/rdesktop/issues/71>. 此问题由来已久。

> **危险**
>
> 禁用网络级身份验证（NLA）会使 RDP 服务暴露于严重安全威胁之下，包括但不限于：
>
> * **凭据转发攻击**：禁用 NLA 后，用户凭据将被发送至远程主机并存储于其内存中，攻击者可利用 pass-the-hash 等技术窃取凭据并在会话断开后继续冒充用户。
> * **暴力破解攻击**：缺少会话前身份验证，攻击者可无限制地尝试登录。
> * **拒绝服务攻击**：服务器在未验证身份的情况下即为每个连接分配会话资源。
>
> **强烈建议优先使用支持 NLA/CredSSP 的 freerdp3（见上文），而非禁用 NLA。** 若确需禁用，请在操作完成后立即重新启用，并确保 RDP 端口不直接暴露于公网。

禁用 NLA 的操作步骤如下，在需要远程连接的 Windows 上执行：

```powershell
PS C:\Users\ykla> reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0 /f  # 导入相关注册表
操作成功完成。
PS C:\Users\ykla> gpupdate /force  # 强制刷新组策略
正在更新策略...

计算机策略更新成功完成。
用户策略更新成功完成。
```

再测试连接：

```sh
$ rdesktop 192.168.31.213

ATTENTION! The server uses and invalid security certificate which can not be trusted for
the following identified reasons(s);

 1. Certificate issuer is not trusted by this system.

     Issuer: CN=DESKTOP-U72I6SS


Review the following certificate info before you trust it to be added as an exception.
If you do not trust the certificate the connection atempt will be aborted:

    Subject: CN=DESKTOP-U72I6SS
     Issuer: CN=DESKTOP-U72I6SS
 Valid From: Tue Mar  4 20:39:28 2025
         To: Wed Sep  3 20:39:28 2025

  Certificate fingerprints:

       sha1: 599c0e8bbc57c5ee8de8993d5241fb0f0d70e98d
     sha256: 36b9be66ab2b54322846b698688d6f20a5d1588c09decc3d30e1066f4f6254de


Do you trust this certificate (yes/no)? # 输入 yes 并回车
```

![rdesktop](/files/6h2YGvRPHjAYeXKTs0nt)

![rdesktop](/files/S8NYwt95gY2hXpfWWYye)

#### 故障排除与未竟事宜

**视频播放无声音**

尚未解决。

#### 参考文献

* Microsoft Corporation. 使用 RDP 连接到 Azure VM 时排查身份验证错误\[EB/OL]. (2024-07-30)\[2026-03-25]. <https://learn.microsoft.com/zh-cn/troubleshoot/azure/virtual-machines/windows/cannot-connect-rdp-azure-vm>. Microsoft 官方文档提供的 RDP 网络级身份验证（NLA）配置方法与故障排除指南。

## AnyDesk

使用 AnyDesk 可远程访问，FreeBSD 上支持 amd64 和 i386 架构：

由于版权原因（专有软件未经许可禁止分发），必须由用户使用 Ports 自行构建安装：

```sh
# cd /usr/ports/deskutils/anydesk/
# make install clean
```

由于需要接受许可协议才能使用，不可使用 `BATCH=yes` 参数：

![anydesk](/files/Bpb83TZOhWL69AoGqE7S)

查看 AnyDesk 安装后的说明：

```sh
# pkg info -D anydesk
```

提示需要挂载 proc 文件系统，经测试未挂载该文件系统时程序无法正常启动。

```sh
# mount -t procfs proc /proc # 临时挂载，持久化配置可参照上文说明
```

root 用户无法运行 AnyDesk，必须以普通用户身份运行：

```sh
$ anydesk

(<unknown>:18311): Gtk-WARNING **: 21:07:13.540: 无法在模块路径中找到主题引擎：“adwaita”，

……省略一部分……
```

执行命令后弹出的 AnyDesk 主界面：

![AnyDesk 主界面](/files/XZLJJl5QqZOMFS3N4EJk)

被连接方必须“接受”（Accept）才能继续连接。

### Windows 通过 AnyDesk 远程访问 FreeBSD

![Windows 通过 AnyDesk 远程 FreeBSD](/files/qNTghBrP010appOkArDB)

### FreeBSD 通过 AnyDesk 远程访问 Windows

![FreeBSD 通过 AnyDesk 远程 Windows](/files/J2jNTiR1vluYT6VcCnvY)

### 故障排除与未竟事宜

#### 通过 AnyDesk 从 FreeBSD 远程连接 Windows 时，无法在 Windows 中移动鼠标

待解决。

## RustDesk 中继服务器

> **注意**
>
> 这是中继 ID 服务器，本身无法被远程控制。

无法使用 RustDesk 控制 FreeBSD。

* 使用 pkg 安装：

```sh
# pkg install rustdesk-server
```

或使用 Ports 安装：

```sh
# cd /usr/ports/net/rustdesk-server/
# make install clean
```

配置 RustDesk 中继服务器：

创建专用用户运行 RustDesk 中继服务，避免以 root 身份运行：

```sh
# pw useradd rustdesk -s /bin/sh -c "RustDesk Server"
# pw lock rustdesk
```

* 启动 hbbs：

```sh
# su -m rustdesk -c '/usr/local/bin/hbbs'
[2024-08-10 23:02:13.782550 +08:00] INFO [src/common.rs:122] Private key comes from id_ed25519
[2024-08-10 23:02:13.782587 +08:00] INFO [src/rendezvous_server.rs:1191] Key: mgRwOWJy9Vnz3LqQYjtNHwZQYg73uhdj9iCTMmIyoP4=  #	此处是 Key
[2024-08-10 23:02:13.782655 +08:00] INFO [src/peer.rs:84] DB_URL=./db_v2.sqlite3
[2024-08-10 23:02:13.786349 +08:00] INFO [src/rendezvous_server.rs:99] serial=0
[2024-08-10 23:02:13.786381 +08:00] INFO [src/common.rs:46] rendezvous-servers=[]
[2024-08-10 23:02:13.786388 +08:00] INFO [src/rendezvous_server.rs:101] Listening on tcp/udp :21116
[2024-08-10 23:02:13.786391 +08:00] INFO [src/rendezvous_server.rs:102] Listening on tcp :21115, extra port for NAT test
[2024-08-10 23:02:13.786395 +08:00] INFO [src/rendezvous_server.rs:103] Listening on websocket :21118
[2024-08-10 23:02:13.786430 +08:00] INFO [libs/hbb_common/src/udp.rs:35] Receive buf size of udp [::]:21116: Ok(42080)
[2024-08-10 23:02:13.786581 +08:00] INFO [src/rendezvous_server.rs:138] mask: None
[2024-08-10 23:02:13.786594 +08:00] INFO [src/rendezvous_server.rs:139] local-ip: ""
[2024-08-10 23:02:13.786603 +08:00] INFO [src/common.rs:46] relay-servers=[]
[2024-08-10 23:02:13.786703 +08:00] INFO [src/rendezvous_server.rs:153] ALWAYS_USE_RELAY=N
[2024-08-10 23:02:13.786734 +08:00] INFO [src/rendezvous_server.rs:185] Start
[2024-08-10 23:02:13.786793 +08:00] INFO [libs/hbb_common/src/udp.rs:35] Receive buf size of udp [::]:0: Ok(42080)
[2024-08-10 23:09:11.043094 +08:00] INFO [src/peer.rs:102] update_pk 1101115918 [::ffff:192.168.31.90]:37057 b"\x06\xef\x81\xb4\xe2\x9e\xff(\xcb\xd7\x985S\x95)~1O\xe2\xfcu\xeeE\x91\xf1\xf2\xa1\xbe\rk\xcd\xc1" b"\x06\xef\x81\xb4\xe2\x9e\xff(\xcb\xd7\x985S\x95)~1O\xe2\xfcu\xeeE\x91\xf1\xf2\xa1\xbe\rk\xcd\xc1" #	代表设备接入
^C[2024-08-10 23:10:06.746255 +08:00] INFO [src/common.rs:176] signal interrupt
```

* 再启动 hbbr：

```sh
# su -m rustdesk -c '/usr/local/bin/hbbr'
[2024-08-10 22:58:26.593397 +08:00] INFO [src/relay_server.rs:61] #blacklist(blacklist.txt): 0
[2024-08-10 22:58:26.593439 +08:00] INFO [src/relay_server.rs:76] #blocklist(blocklist.txt): 0
[2024-08-10 22:58:26.593445 +08:00] INFO [src/relay_server.rs:82] Listening on tcp :21117
[2024-08-10 22:58:26.593449 +08:00] INFO [src/relay_server.rs:84] Listening on websocket :21119
[2024-08-10 22:58:26.593452 +08:00] INFO [src/relay_server.rs:87] Start
[2024-08-10 22:58:26.593546 +08:00] INFO [src/relay_server.rs:105] DOWNGRADE_THRESHOLD: 0.66
[2024-08-10 22:58:26.593556 +08:00] INFO [src/relay_server.rs:115] DOWNGRADE_START_CHECK: 1800s
[2024-08-10 22:58:26.593559 +08:00] INFO [src/relay_server.rs:125] LIMIT_SPEED: 4Mb/s
[2024-08-10 22:58:26.593564 +08:00] INFO [src/relay_server.rs:136] TOTAL_BANDWIDTH: 1024Mb/s
[2024-08-10 22:58:26.593567 +08:00] INFO [src/relay_server.rs:146] SINGLE_BANDWIDTH: 16Mb/s
^C[2024-08-10 23:10:04.393365 +08:00] INFO [src/common.rs:176] signal interrupt
```

在其他设备上打开 RustDesk 客户端，双方都需填写相同的“ID 服务器（FreeBSD 的 IP 地址或域名）”和“Key”，其余项留空，在控制端输入被控端显示的 ID 即可连接。

### 参考文献

* FreshPorts. rustdesk-server Self hosted RustDesk server\[EB/OL]. \[2026-03-25]. <https://www.freshports.org/net/rustdesk-server/>. FreshPorts 提供的 RustDesk 中继服务器 Port 详情与安装指南。
* Safe Rabbit. 远程控制软件 RustDesk 自建服务器全平台部署及使用教程\[EB/OL]. (2024-02-20)\[2026-03-25]. <https://www.cnblogs.com/safe-rabbit/p/18020812>. 博客园提供的 RustDesk 自建中继服务器全平台部署与使用详细教程。

## 课后习题

1. 适配更多 VNC Server 到 Ports。
2. 适配 Wayland。
3. 远程桌面协议的多样性（RDP、VNC、SPICE、X11 Forwarding）反映了图形栈的不同抽象层次。比较各协议在带宽效率、安全性与会话持久性上的设计取舍，并分析 FreeBSD 作为远程桌面服务端时在协议选择上的技术制约。


# 12.1 Wayland 概论

Wayland 是一种旨在取代 Xorg 等显示服务器的通信协议。它与 Xorg 在多个重要方面有所不同。

首先，Wayland 只是一个协议，它通过某种机制在客户端之间充当中介，从而去除了对 X 服务器的依赖。Xorg 同时包含 X11 协议（用于运行远程显示）和 X 服务器（用于接受连接并显示窗口）。而在 Wayland 下，合成器或窗口管理器提供显示服务器，而不是传统的 X 服务器。

由于 Wayland 不是 X 服务器，传统的 X 屏幕连接需要使用其他方法，如 VNC 或 RDP 进行远程桌面管理。其次，Wayland 可以作为一个独立的实体管理客户端与合成器之间的复合通信，而无需支持 X 协议。

X11 架构：

```sh
  网络
   │
X 客户端(远程) ──(X11)───┐
X 客户端(本地) ──(X11)───┴──> X 服务器
                         (显示服务器)
                              │
                              ▼
                             内核
                         (GPU 与输入)
```

Wayland 架构：

```sh
Wayland 协议本身不提供网络透明，远程客户端不能直接连接到本地混成器显示窗口。

Wayland 客户端 ──(Wayland)──> Wayland 混成器
(应用)                  (显示服务器 + 窗口管理器 + 混成器功能)
                                │
                                ▼
                               内核
                           (GPU 与输入)
                                │
                        (远程需要 VNC / RDP)
```

FreeBSD DRM 驱动移植仅覆盖了 Intel、AMD 和 NVIDIA 等 GPU，vmwgfx 和 virtio 等虚拟化 GPU 驱动尚不支持。

在 VMware、VirtualBox 或基于 Virtio 的虚拟环境中无法使用 Wayland，建议在虚拟环境中使用 X.org 而不是 Wayland。

无法移植到 Wayland 的传统 X11 应用程序将自动使用 Xwayland 作为 X11 传统客户端和 Wayland 混成器之间的代理。

## 参考文献

* freebsd/drm-kmod. Request to restore support for vboxvideo, vmwgfx and virtio DRM drivers #356\[EB/OL]. \[2026-04-04]. <https://github.com/freebsd/drm-kmod/issues/356>


# 12.2 Wayland 显示管理器

## SDDM

SDDM 基于 QML，不仅支持 X11，还支持 Wayland 会话。在默认情况下，SDDM 界面左下角为 Wayland，如不是可手动修改。

还需要修改配置文件 **/usr/local/etc/sddm.conf** 启用 Wayland，查找下列文字：

```ini
#[General]
#DisplayServer=wayland
#GreeterEnvironment=QT_WAYLAND_SHELL_INTEGRATION=layer-shell

#[Wayland]
#CompositorCommand=dbus-run-session ck-launch-session -- kwin_wayland --drm --no-lockscreen --no-global-shortcuts
```

将其注释全部取消掉，即为：

```ini
[General]
DisplayServer=wayland
GreeterEnvironment=QT_WAYLAND_SHELL_INTEGRATION=layer-shell

[Wayland]
CompositorCommand=dbus-run-session ck-launch-session -- kwin_wayland --drm --no-lockscreen --no-global-shortcuts
```

然后重新启用 SDDM 服务即可：

```sh
# service sddm restart
```

## Ly

Ly 是 TUI 界面的登录管理器，界面较为简洁。

通过 pkg 安装：

```sh
# pkg install ly
```

通过 Ports 安装：

```sh
# cd /usr/ports/x11/ly/ 
# make install clean
```

使用 `pkg info -D ly` 获取最新的安装说明。

将以下行加入 **/etc/gettytab**，设置 Ly 条目：

```sh
Ly:\
	:lo=/usr/local/bin/ly_wrapper:\
	:al=root:
```

编辑 **/etc/ttys**，将以下行：

```sh
ttyv1	"/usr/libexec/getty Pc"		xterm	onifexists secure
```

修改为

```sh
ttyv1   "/usr/libexec/getty Ly"		xterm   on secure
```

重启系统即可。


# 13.1 KDE 6 桌面环境（X11 会话）

KDE Plasma 是一款易于使用的现代化桌面环境，提供外观与操作体验一致的应用程序集合，包括统一的菜单与工具栏、快捷键、配色方案、本地化支持，以及集中式、对话框驱动的桌面配置工具。

KDE 桌面环境借鉴了 Windows 等多种桌面环境的交互范式，二者界面设计有相似之处。~~也可能是 Windows 借鉴 KDE 桌面较多。~~

> **技巧**
>
> 视频教程可参见：FreeBSD 中文社区. 003-FreeBSD14.2 安装 KDE6\[EB/OL]. \[2026-03-26]. <https://www.bilibili.com/video/BV12zAYeKEej>.

## 安装完整的 KDE 桌面环境

> **技巧**
>
> 不希望捆绑安装大量附加工具和软件的用户可使用下方的最小化安装方案，无需自定义配置的用户可继续使用本方案。

* 使用 pkg 安装：

```sh
# pkg install xorg kde wqy-fonts
```

> **技巧**
>
> 如果提示 `pkg` 未找到该命令或未提供 kde 软件包，可能是二进制包尚未构建完成，或需切换软件源分支。参考本书其他相关章节。如无二进制包，则需使用 Ports 编译安装。

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11/kde/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
```

登录管理器可考虑使用 SDDM。

### 软件包说明

| 包名          | 作用       |
| ----------- | -------- |
| `xorg`      | X 窗口系统   |
| `kde`       | KDE 桌面环境 |
| `wqy-fonts` | 文泉驿中文字体  |

## 启动项设置

D-Bus 用于桌面环境的进程间通信，作为依赖项自动安装。

启用 D-Bus：

```sh
# service dbus enable
```

![KDE 6 界面](/files/b4GDSdWWwHXCWbEjbfDM)

## startx

```sh
$ echo "exec ck-launch-session startplasma-x11" > ~/.xinitrc
```

> **注意**
>
> 如果之前以 root 身份执行过上述命令，新用户仍需再执行一次，方可正常执行 startx（无需 root 权限或 sudo）。

## 权限设置

普通用户还须加入 `wheel` 组与 `video` 组，否则部分设置无法显示，图形界面功能可能受限：

```sh
# pw groupmod wheel -m 用户名
# pw groupmod video -m 用户名
```

将“用户名”替换为实际用户名。

## 配置中文环境

除了通过用户分级设置中文环境外，还可以通过以下方式设置中文环境。

![KDE 6](/files/zaEUGNFJLF8UkO1sF0Ok)

### 通过 KDE 系统设置中文环境

点击应用程序启动器 → System Settings → Language & Time，在 Region & Language 的 Language 栏点击 Modify，找到并选择“简体中文”。如果显示为 `□□□□`，请检查中文字体是否已安装。随后单击 Apply 按钮；注销后重新登录，此时系统语言将切换为中文。

![KDE 6](/files/AK3WcCqa8A1RDy0Pf98A)

![KDE 6](/files/DwmhnDtLkLeaoafa5Kfb)

### 参考文献

* silversack. デスクトップ 環境 の 構築 - 4-7. LXQT のインストールと 設定 (LXQT 2.0.0)\[EB/OL]. \[2026-03-25]. <https://silversack.my.coocan.jp/bsd/fbsd11x_bde-4-7_lxqt.htm>. 日文 FreeBSD 桌面环境构建指南中 LXQt 的安装与配置部分。

## 附录：最小化 KDE 桌面安装方案

直接安装 **x11/kde** 会将 Plasma 桌面各组件和 **x11/kde-baseapps** 作为依赖一并安装，其中捆绑了大量工具软件，在某些场景下不便于部署和使用。

### 使用 pkg 安装

基础桌面安装方案。

```sh
# pkg install xorg sddm plasma6-plasma-desktop plasma6-sddm-kcm wqy-fonts plasma6-kactivitymanagerd plasma6-kscreen plasma6-systemsettings
```

| 软件包                           | 作用                                         |
| ----------------------------- | ------------------------------------------ |
| **plasma6-kactivitymanagerd** | 管理用户活动、跟踪使用模式等的系统服务。缺少该服务可能导致 KDE 桌面无法正常显示 |
| **plasma6-kscreen**           | KDE 屏幕管理器。**未安装该软件将无法调整分辨率**               |
| **plasma6-sddm-kcm**          | SDDM 配置模块，用于在系统设置中配置 SDDM                  |
| **plasma6-systemsettings**    | 系统设置                                       |

与上文重复的软件包在此不再列出。

可选软件包：

```sh
# pkg install konsole dolphin kate plasma6-plasma-systemmonitor plasma6-plasma-pa plasma6-discover kdeconnect-kde plasma6-plasma-workspace-wallpapers plasma6-plasma-disks ark
```

| 软件包                                     | 作用                 |
| --------------------------------------- | ------------------ |
| **konsole**                             | 终端命令行工具            |
| **dolphin**                             | 文件管理器              |
| **kate**                                | 文本编辑器              |
| **plasma6-plasma-systemmonitor**        | 系统监视器              |
| **plasma6-plasma-pa**                   | 音频管理               |
| **plasma6-discover**                    | 软件管理               |
| **kdeconnect-kde**                      | 移动设备与桌面互联          |
| **plasma6-plasma-workspace-wallpapers** | 桌面壁纸               |
| **plasma6-plasma-disks**                | 磁盘健康（S.M.A.R.T.）监测 |
| **ark**                                 | 解压缩软件              |

### 使用 Ports 安装

基础桌面安装方案。

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11/plasma6-plasma-desktop/ && make install clean
# cd /usr/ports/deskutils/plasma6-sddm-kcm/ && make install clean
# cd /usr/ports/x11/sddm/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/x11/plasma6-kscreen/ && make install clean
# cd /usr/ports/x11/plasma6-kactivitymanagerd/ && make install clean
# cd /usr/ports/sysutils/plasma6-systemsettings/ && make install clean
```

可选 Ports：

```sh
# cd /usr/ports/x11/konsole/ && make install clean # 终端
# cd /usr/ports/x11-fm/dolphin/ && make install clean # 文件管理器
# cd /usr/ports/editors/kate/ && make install clean # 文本编辑器
# cd /usr/ports/sysutils/plasma6-plasma-systemmonitor/ && make install clean # 系统监视器
# cd /usr/ports/audio/plasma6-plasma-pa/ && make install clean # 音频管理器
# cd /usr/ports/sysutils/plasma6-discover/ && make install clean # 软件管理器
# cd /usr/ports/deskutils/kdeconnect-kde/ && make install clean # 移动设备与桌面互联
# cd /usr/ports/x11-themes/plasma6-plasma-workspace-wallpapers/ && make install clean # 桌面壁纸
# cd /usr/ports/sysutils/plasma6-plasma-disks/ && make install clean # 磁盘健康（S.M.A.R.T.）监测
# cd /usr/ports/archivers/ark/ && make install clean # 解压缩软件
```

### xinitrc

> **注意**
>
> 如果采用 KDE 最小化安装方案，必须配置 **.xinitrc** 文件。

### 最小化安装 KDE 图示

> **技巧**
>
> 使用此方案安装的 KDE 桌面缺少较多功能，可参照 [x11/plasma6-plasma](https://www.freshports.org/x11/plasma6-plasma/) 的“Runtime dependencies”（运行时依赖）和“Library dependencies”（库依赖）来补全功能。

未安装可选包：

![最小化安装的 KDE 界面](/files/LPSL5Bp3QvgqHlQQlyCp)

## 附录：展开任务栏图标

右键单击桌面空白处，点击“进入编辑模式”。

![进入编辑模式](/files/AlT1kawjmMyxFXjG2NxJ)

点击任务栏中间的空白处，随后点击“显示替代部件”。

![显示替代部件](/files/X8LsSrScLKHlDg511Lu4)

在弹出窗口中选择“图标和文本任务管理器”。

![图标和文本任务管理器](/files/FrmH12vfTj2bXmv8csFg)

## 附录：解决开机时自动打开特定程序

打开设置，选择“会话”→“桌面会话”，在右侧的“会话恢复”中，修改为“启动为空会话”。最后点击右下角的“应用”保存即可。

![启动为空会话](/files/vXe5AP3ATBTY8P09La8R)

## 桌面主题美化

以下安装 [WhiteSur](https://www.pling.com/p/1398840/) 主题。

1. 下载主题源代码包：`git clone https://github.com/vinceliuice/WhiteSur-kde`
2. 进入主题包目录：`cd WhiteSur-kde`
3. 修改 shebang：编辑 `install.sh` 文件，修改第一行为 `#!/usr/local/bin/bash`，随后保存。
4. 执行安装：`bash install.sh`

### 背景图片

[下载地址](https://github.com/vinceliuice/WhiteSur-kde/tree/master/wallpaper)。

## 故障排除与未竟事宜

### 菜单缺少关机、重启等选项

修改 **/etc/sysctl.conf** 文件，将其中 `security.bsd.see_other_uids` 的值改为 `1`。重启后即可。`1` 为开启，该值默认为 `1`，可能由于在安装过程中错误地设置了该安全加固选项。

如果无效，请检查是否在 SDDM 界面选择了“用户会话”（读取 `.xinitrc` 文件），应选择 `plasma-x11`。

#### 参考文献

* FreeBSD Forums. Missing power buttons when logged in from SDDM\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/missing-power-buttons-when-logged-in-from-sddm.88231/>. FreeBSD 官方论坛讨论，解决 SDDM 登录后电源按钮缺失的技术问题。

### 解除自动锁屏

单击“设置”→“安全和隐私”→“锁屏”→“自动锁定屏幕”选择“不自动锁屏”，随后点击“应用”。（休眠唤醒后锁定屏幕可按需设置）

注销后重新登录即可。

![关闭 KDE 6 锁屏](/files/lKIll23LM3GCNGyClQzo)

### 状态栏不显示时间和日期

打开时区设置，选择“Asia/Shanghai”时区即可。如果仍无效，请先更新相关软件包。


# 13.2 KDE 6 桌面环境（Wayland 会话）

## 概述

Wayland 是取代 X11 的显示服务器协议，KDE Plasma 自 Plasma 5.4 起逐步完善了 Wayland 支持，至 5.27 LTS 时已相当成熟，KDE 6 在此基础上进一步增强。

NVIDIA 显卡尚未经过测试。本节以 Intel 第 12 代处理器（i7-1260P）的集成显卡为测试环境。

参照前述章节安装 DRM、KDE 6、Fcitx 5、Firefox 浏览器等软件包，**并配置 DRM 显卡驱动。** 其余软件包仅安装，暂不配置。请确保将用户加入 video 组。

## 用户权限配置

将指定用户加入相关组，获取调用设备的权限：

```sh
# pw groupmod video -m 实际用户名
# pw groupmod operator -m 实际用户名
# pw groupmod audio -m 实际用户名
```

## seatd 相关

### 安装 seatd

seatd 是一款 seat 管理守护进程，用于非 systemd 环境下管理 Wayland 会话和设备访问。

* 使用 pkg 安装：

```sh
# pkg install seatd
```

* 或通过 Ports 安装：

```sh
# cd /usr/ports/sysutils/seatd/
# make install clean
```

### 配置 seatd 服务

添加并启用服务：

```sh
# service dbus enable # 设置 D-Bus 服务开机自启
# service seatd enable # 设置 Seatd 服务开机自启
```

## 启动 KDE 6

有多种方法可以启动 Wayland KDE。登录显示器建议使用 SDDM 或 Ly。

使用显示管理器启动 KDE 时，在登录界面对应位置需要选择“Wayland”会话。还需参见 Wayland 登录管理器章节进行修改。

### 通过脚本启动桌面

* 在 **\~/** 下新建脚本 `kde.sh`：

```sh
#! /bin/sh
/usr/local/bin/ck-launch-session /usr/local/lib/libexec/plasma-dbus-run-session-if-needed /usr/local/bin/startplasma-wayland # 启动桌面的命令
```

* 授予 **\~/kde.sh** 可执行权限：

```sh
$ chmod 755 ~/kde.sh
```

> **注意**
>
> 需要停止 SDDM 服务才能使用该脚本。检查 **/etc/rc.conf** 是否有 `sddm_enable="YES"` 字样，如有则删除。按快捷键 Ctrl+Alt+F2 进入 TTY，登录 root 后输入 `service sddm stop` 停止 SDDM 服务。

* 进入 KDE

此时应在 TTY 界面以普通用户身份登录，且没有任何 X11 会话正在运行（如存在，请禁用相关服务并重启再试）。

```sh
$ sh ~/kde.sh
```

## 图示

![在 FreeBSD 上通过 Wayland 运行 KDE6](/files/3KvuFNlU2TLwXH97EfmJ)

> **技巧**
>
> 上图显示为“Intel UHD Graphics”而非“Iris Xe Graphics”，这是因为系统未启用某些硬件加速特性（与内存配置有关）。~~无力购买第二根 DDR5 内存条。~~ 参见：Intel® Iris® Xe Graphics Shows As Intel® UHD Graphics in the Intel® Graphics Command Center and Device Manager\[EB/OL]. \[2026-03-26]. <https://www.intel.com/content/www/us/en/support/articles/000059744/graphics.html>（网站对应页面的中文翻译不准确）。

* 显示当前会话类型（如 X11 或 Wayland）

```sh
# echo $XDG_SESSION_TYPE
```

![检查当前是否位于 Wayland](/files/YZZ5ClOD0rQH8MwTlZbl)

## 配置 Fcitx 5 输入法框架

配置 Fcitx 5 自动启动：

```sh
$ mkdir -p ~/.config/autostart/ # 创建自启动目录
$ cp /usr/local/share/applications/org.fcitx.Fcitx5.desktop ~/.config/autostart/ # 系统启动时自动启动 Fcitx 5
```

初次进入 KDE Wayland 桌面时，KDE 会在右下角提示需在系统设置的虚拟键盘中完成配置后方可启用输入法。须留意该提示。如未完成此设置，将无法切换输入法或输入中文。

![KDE Wayland 设置](/files/a3LkfrXXM0nOCLBVsOqr)

打开 KDE 系统设置：找到“键盘”→“虚拟键盘”

![虚拟键盘](/files/JLvWRwEysNRAIFbdmju7)

选择“Fcitx 5 Wayland 启动器（实验性）”

![Fcitx 5 Wayland 启动器（实验性）](/files/m4enbXEGMKHWHPZrgfa6)

在 Konsole 终端、Firefox 和 Chromium（使用 `chrome --no-sandbox` 启动）中均可输入中文。

![Wayland Fcitx 5 演示](/files/wt38WdGN9cU0B3P1aURj)

## 视频播放测试

![Wayland 视频播放测试](/files/Ai2e5TbOnLVppxSCMUjV)

## 故障排除与未竟事宜

### 以 root 账户登录时没有声音

表现为右下角声音控件提示“未连接到音频服务”。可设置 PulseAudio 自启动：于 KDE 设置中添加该服务并赋予可执行权限。

## 参考文献

* Euroquis. KDE Plasma 6 Wayland on FreeBSD\[EB/OL]. \[2026-03-25]. <https://euroquis.nl/kde/2025/09/07/wayland.html>. 提供了在 FreeBSD 上配置 KDE Plasma 6 Wayland 会话的技术指南，明确指出 seatd 服务的必要性。


# 13.3 MATE

## MATE 桌面环境概述

MATE 是从 GNOME 2 复刻（fork）发展而来的桌面环境，设计理念保持了 GNOME 2 的传统交互风格。“Mate”亦指巴拉圭冬青（Ilex paraguariensis），由其制成的马黛茶在南美地区广受欢迎。

## 安装 MATE 桌面环境

* 使用 pkg 安装：

```sh
# pkg install mate xorg wqy-fonts xdg-user-dirs
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/mate/ && make install clean
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

登录管理器可考虑使用 LightDM。

### 软件包说明

| 包名              | 功能说明             |
| --------------- | ---------------- |
| `mate`          | MATE 桌面环境        |
| `xorg`          | X 窗口系统           |
| `wqy-fonts`     | 文泉驿中文字体          |
| `xdg-user-dirs` | 自动管理主目录子目录（可选安装） |

## 安装后启用服务

设置 D-Bus 服务开机自启：

```sh
# service dbus enable
```

## startx 配置文件

在 **\~/.xinitrc** 文件内添加以下内容，以便使用命令 startx 启动 MATE 桌面会话：

```sh
exec mate-session
```

## 输入法

![FreeBSD 安装 MATE](/files/lLDaDrKFJnPJ1MC08AWI)

IBus 输入法框架经测试可用，参见输入法相关章节完成具体配置。

## 桌面欣赏

![FreeBSD 安装 MATE](/files/uHoXSk3kOzUCAZYZW2Li)

![FreeBSD 安装 MATE](/files/GF7oUBq5wXo7jjUdpHK8)


# 13.4 Xfce

Xfce 是一款基于 GTK+ 的轻量级桌面环境，提供简洁、高效、易于使用的桌面体验。它完全可配置，拥有包含菜单、小程序和应用程序启动器的主面板，提供文件管理器和声音管理器，并支持主题。由于其快速、轻巧、高效的特性，非常适合配置较低或内存受限的计算机。

值得一提的是，Xfce 的 Logo 是一只老鼠 🐀。曾有用户反馈一则轶事，称因 Xfce 的默认壁纸是一只老鼠 🐀，导致电脑屏幕被猫 🐈 抓坏（SanjaytheToilet. \[joke] The default desktop startup screen causes damage to monitor!\[EB/OL]. (2015-08-04)\[2026-04-04]. <https://bugzilla.xfce.org/show_bug.cgi?id=12117>.）。

## 安装 Xfce 桌面环境

* 通过 pkg 安装

```sh
# pkg install xorg xfce wqy-fonts xdg-user-dirs xfce4-goodies 
```

* 或通过 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11-wm/xfce4 && make install clean # 注意包名中的数字 4
# cd /usr/ports/x11/xfce4-goodies/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

登录管理器可考虑使用 LightDM。

### 软件包说明

| 包名              | 作用说明           |
| --------------- | -------------- |
| `xorg`          | X 窗口系统         |
| `xfce`          | Xfce 桌面环境      |
| `wqy-fonts`     | 文泉驿中文字体        |
| `xdg-user-dirs` | 管理用户主目录        |
| `xfce4-goodies` | Xfce 附加组件和插件集合 |

## startx 命令

将 Xfce 启动脚本写入 **\~/.xinitrc** 文件，以便使用 startx 命令启动 Xfce：

```sh
$ echo "/usr/local/etc/xdg/xfce4/xinitrc" > ~/.xinitrc
```

## 启动服务

设置 D-Bus 服务开机自启：

```sh
# service dbus enable
```

## 图片欣赏

![FreeBSD 安装 Xfce](/files/4C1m6TLZiogEg66AokVg)

![FreeBSD 安装 Xfce](/files/mhhAskyyhentmQbFlC8H)

## 全局菜单（可选）

使用 pkg 安装：

```sh
# pkg install xfce4-appmenu-plugin appmenu-gtk-module appmenu-registrar
```

或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xfce4-appmenu-plugin/ && make install clean
# cd /usr/ports/x11/gtk-app-menu/ && make install clean
# cd /usr/ports/x11/appmenu-registrar/ && make install clean
```

查看安装后的说明并据此配置。

```sh
$ xfconf-query -c xsettings -p /Gtk/ShellShowsMenubar -n -t bool -s true  # 启用 GTK 菜单栏显示
$ xfconf-query -c xsettings -p /Gtk/ShellShowsAppmenu -n -t bool -s true  # 启用 GTK 应用菜单显示
$ xfconf-query -c xsettings -p /Gtk/Modules -n -t string -s "appmenu-gtk-module"  # 设置 GTK 模块为 appmenu-gtk-module
```

## XTerm 终端动态标题

### sh

编辑 **\~/.shrc** 文件，写入：

```sh
if [ -t 1 ]; then
  while :; do
    printf '\033]0;%s\007' "$PWD"
    printf '\n$ '
    if ! IFS= read -r cmd; then
      break
    fi
    printf '\033]0;%s\007' "$cmd"
    eval "$cmd"
  done
  exit
fi
```

> **警告**
>
> 此脚本使用 `eval` 存在注入风险！请谨慎使用。

### csh

编辑 **\~/.cshrc** 文件，写入：

```sh
if ( $?TERM && $TERM =~ xterm* ) then
    set host = `hostname`
    alias postcmd 'rehash; printf -- "\033]2;%s\007" "${user}@${host}: ${cwd}"'
endif
```

### tcsh

编辑 **\~/.tcshrc** 文件，写入：

```sh
switch ($TERM)
case xterm*:
    set prompt="%{\033]0;%n@%m: %~\007%}%# "
    breaksw
default:
    set prompt="%# "
    breaksw
endsw
```

### Bash

编辑 **\~/.bashrc** 文件，写入：

```sh
case $TERM in
         xterm*)
             PS1="\[\033]0;\u@\h: \w\007\]bash\\$ "
             ;;
         *)
             PS1="bash\\$ "
             ;;
     esac
```

### Zsh

编辑 **\~/.zshrc** 文件，写入：

```sh
autoload -Uz add-zsh-hook

function xterm_title_precmd () {
	print -Pn -- '\e]2;%n@%m %~\a'
	[[ "$TERM" == 'screen'* ]] && print -Pn -- '\e_\005{2}%n\005{-}@\005{5}%m\005{-} \005{+b 4}%~\005{-}\e\\'
}

function xterm_title_preexec () {
	print -Pn -- '\e]2;%n@%m %~ %# ' && print -n -- "${(q)1}\a"
	[[ "$TERM" == 'screen'* ]] && { print -Pn -- '\e_\005{2}%n\005{-}@\005{5}%m\005{-} \005{+b 4}%~\005{-} %# ' && print -n -- "${(q)1}\e\\"; }
}

if [[ "$TERM" == (Eterm*|alacritty*|aterm*|foot*|gnome*|konsole*|kterm*|putty*|rxvt*|screen*|wezterm*|tmux*|xterm*) ]]; then
	add-zsh-hook -Uz precmd xterm_title_precmd
	add-zsh-hook -Uz preexec xterm_title_preexec
fi
```

### 参考文献

* Oracle Corporation. 6.1 动态设置标题不起作用\[EB/OL]. \[2026-03-25]. <https://docs.oracle.com/cd/E19683-01/817-1951/6mhl8aiii/index.html>. bash 配置来自此处。
* Wamphyre. BSD-XFCE\[EB/OL]. \[2026-03-25]. <https://web.archive.org/web/20260121072214/https://github.com/Wamphyre/BSD-XFCE>. 配置参考集合。
* Arch Linux Project. Zsh\[EB/OL]. \[2026-03-25]. <https://wiki.archlinux.org/title/Zsh>. 该文档提供 Zsh 配置的详细教程，本节 Zsh 配置源自此。

## 故障排除与未竟事宜

如需进一步动态显示当前进程，目前仅 sh 支持该功能。


# 13.5 Cinnamon

Cinnamon 是 Linux Mint 项目的核心组件，沿用传统桌面交互风格，同时融入创新特性与原有用户体验。其桌面布局类似于 GNOME 2，底层技术源自 GNOME Shell。Cinnamon 注重用户熟悉感，提供易于使用且舒适的桌面体验。

## 安装 Cinnamon 桌面环境

* 使用 pkg 安装：

```sh
# pkg install xorg cinnamon wqy-fonts xdg-user-dirs
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11/cinnamon/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

登录管理器可考虑使用 LightDM 或 SDDM。

### 软件包说明

| 包名              | 功能说明                                 |
| --------------- | ------------------------------------ |
| `xorg`          | X 窗口系统                               |
| `cinnamon`      | 从 GNOME Shell 分支而来的桌面环境，布局类似 GNOME 2 |
| `wqy-fonts`     | 文泉驿中文字体                              |
| `xdg-user-dirs` | 管理用户目录，如“桌面”、“下载”等                   |

## 配置 startx

编辑 **\~/.xinitrc** 文件，添加：

```sh
exec cinnamon-session
```

可通过 startx 命令启动 Cinnamon 桌面。

## 挂载 proc 文件系统

编辑 **/etc/fstab** 文件，添加：

```ini
proc /proc procfs rw 0 0
```

以读写模式将 `procfs` 文件系统挂载到 **/proc**。

## 服务管理

设置 D-Bus 服务开机自启：

```sh
# service dbus enable
```

## 桌面欣赏

![cinnamon on FreeBSD](/files/vsAN39J1G0I8RVujxsM7)

![cinnamon on FreeBSD](/files/n9uJ6lI5hGkaoOFVolZA)

注意：默认壁纸为黑色，这是正常现象。

![cinnamon on FreeBSD](/files/bBXCWBdueqBI3jiLv73t)

自定义壁纸。

## 附录：Cinnamon：肉桂、桂皮、桂枝、烟桂概念辨析

Cinnamon 指肉桂（锡兰肉桂/斯里兰卡肉桂），与日常烹饪用的桂皮不同（二者虽均为肉桂树的树皮，但所属树种不同），是一种常用于制作冰红茶或西式糕点、咖啡的香料。

锡兰肉桂主要产地是斯里兰卡，具有柑橘香甜的复合气味。桂皮（烟桂为去掉青皮的优质桂皮）主要产地是中国南方及越南，气味呈辛辣刺激的中药味。

《中国药典·一部·药材和饮片》（2025 年版）对肉桂的定义为：“本品为樟科植物肉桂 Cinnamomum cassia Presl 的干燥树皮。多于秋季剥取，阴干。”此处所指并非锡兰肉桂，而是桂皮。肉桂树的细嫩幼枝则为桂枝。锡兰肉桂实为“樟科植物锡兰肉桂 Cinnamomum zeylanicum Bl. 的树皮。”在植物分类中，锡兰肉桂和桂皮同属肉桂组（Cinnamomum sect. Cinnamomum）。

锡兰肉桂一般磨成粉出售，价格通常是桂皮的数倍至数百倍不等。


# 13.6 LXQt

LXQt 是一款基于 Qt 的轻量级桌面环境，由 LXDE-Qt 与 Razor-qt 两个项目合并而成（2013 年 7 月宣布合并，2014 年 5 月发布首个版本 0.7.0），专为注重简洁、速度和直观界面的用户设计。与大多数桌面环境不同，LXQt 在性能较弱的计算机上同样运行良好。

## 安装 LXQt 桌面环境

* 通过 pkg 安装：

```sh
# pkg install xorg lxqt gvfs wqy-fonts xdg-user-dirs
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11-wm/lxqt/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/filesystems/gvfs/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

登录管理器可考虑使用 LightDM。

### 软件包说明

| 包名              | 功能说明                                                                    |
| --------------- | ----------------------------------------------------------------------- |
| `xorg`          | X 窗口系统                                                                  |
| `lxqt`          | LXQt 桌面环境                                                               |
| `gvfs`          | GNOME 虚拟文件系统，LXQt 需要此组件才能打开“计算机”和“网络”位置，否则会提示 `Operation not supported` |
| `wqy-fonts`     | 文泉驿中文字体                                                                 |
| `xdg-user-dirs` | 管理用户目录，如“桌面”“下载”等，并处理目录名称的本地化                                           |

## 服务管理

设置 D-Bus 服务开机自启：

```sh
# service dbus enable
```

## 挂载 proc 文件系统

编辑 **/etc/fstab** 文件，加入下行：

```ini
proc	/proc	procfs	rw	0	0
```

将 `procfs` 文件系统以读写模式挂载到 **/proc**。

## 通过 startx 启动 LXQt

将启动命令写入 **\~/.xinitrc** 文件，即可启动 LXQt 桌面环境：

```sh
$ echo "exec ck-launch-session startlxqt" > ~/.xinitrc
```

应以实际登录的账户身份执行上述命令。

## 桌面图片

![FreeBSD 安装 LXQt](/files/3xxN0L0oBtsLF6qJmx9e)

![FreeBSD 安装 LXQt](/files/I0w2isgOLr96UJOQ4WSJ)

![FreeBSD 安装 LXQt](/files/nSaWhCkFvgE2b09VufOG)

## 为 LXQt 桌面环境设置中文环境

进入 LXQt 后，点击菜单 → “Preferences” → “LXQt Settings” → “Locale” → “Region”，在下拉菜单中选择中文。

![FreeBSD 安装 LXQt](/files/7RTjAakKmignKklfMtwI)

![FreeBSD 安装 LXQt](/files/mfs8EJStcq6IJFZThIMQ)

## 故障排除与未竟事宜

### 桌面图标不显示

需事先安装所需图标主题。随后：菜单 → “Preferences” → “LXQt Settings” → “Appearance” → “Icons Theme”，选择已安装的图标主题，点击“Apply”后重新登录。

## 附录：LXDE 桌面环境

> **注意**
>
> LXDE 已进入维护模式，开发基本停滞，主要开发者已转向 LXQt。LXDE 最后主要版本为 0.10 系列（约 2021 年发布），此后仅有极少量维护性更新，缺乏新功能开发。建议新用户优先选用 LXQt。

LXDE 是一款轻量级桌面环境，专注于资源利用效率与简洁的交互体验，在低配置硬件平台上表现优异。然而，随着 LXQt 的迁移，LXDE 获得的维护逐渐减少。

### 安装 LXDE 桌面环境

* 使用 pkg 安装：

```sh
# pkg install lxde-meta xorg wqy-fonts xdg-user-dirs
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/lxde-meta/ && make install clean
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

登录管理器可考虑使用 LightDM。

#### 软件包说明

| 包名              | 作用说明               |
| --------------- | ------------------ |
| `xorg`          | X 窗口系统             |
| `lxde-meta`     | LXDE 桌面环境的元包       |
| `wqy-fonts`     | 文泉驿中文字体            |
| `xdg-user-dirs` | 管理用户目录，如“桌面”、“下载”等 |

### startx

编辑 **\~/.xinitrc** 文件，添加以下内容，以便通过 startx 命令启动 LXDE 桌面环境：

```sh
exec startlxde
```

### 启动项

设置 D-Bus 服务开机自启：

```sh
# service dbus enable
```

### 挂载 proc 文件系统

编辑 **/etc/fstab** 文件，加入下行：

```ini
proc           /proc       procfs  rw  0   0
```

### 桌面欣赏

![FreeBSD 安装 LXDE](/files/sLRpBhHJKK9l1zp5wg9A)

![FreeBSD 安装 LXDE](/files/uf24XiUacWmpASfCq4QC)

![FreeBSD 安装 LXDE](/files/gLQmgkspGTvCjjcBfnA7)

### 参考文献

* FreeBSD Project. Install & Configure a Desktop Environment: LXDE\[EB/OL]. \[2026-03-25]. <https://wiki.freebsd.org/LXDE>. LXDE 桌面环境安装与配置指南。


# 13.7 GNOME

GNOME 是一款面向用户的桌面环境。它包括用于启动应用和显示状态的面板、桌面、本地工具和应用程序，以及一套使应用程序协同工作并保持一致的设计规范。

## GNOME 桌面环境概述

> **警告**
>
> 目前因 FreeBSD Bugzilla Bug 287955 - x11/gdm: The user cannot log in; the system hangs at the login screen in gdm 47\[EB/OL]. \[2026-04-04]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=287955>. GDM 无法正常运行，将停留在登录界面，`startx` 正常。
>
> 在虚拟机中可正常运行。

GNOME 曾是 GNU 项目的组成部分，旨在构建功能完备的桌面环境，目前主要由 Red Hat 主导开发维护。GNOME 是 Linux 和类 UNIX 系统中的主流桌面环境，设计简洁现代。GNOME 是 GNU Network Object Model Environment 的缩写，源自 GNU 项目，其首字母 G 应发音，读作 /ɡəˈnoʊm/（类似“guh-nome”）。

## 安装完整的 GNOME 桌面环境

* 使用 pkg 安装：

```sh
# pkg install xorg gnome noto-sans-sc
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11/gnome/ && make install clean
# cd /usr/ports/x11-fonts/noto-sans-sc/ && make install clean
```

### 软件包说明

| 软件           | 用途         |
| ------------ | ---------- |
| xorg         | X11        |
| gnome        | GNOME 主程序  |
| noto-sans-sc | 思源黑体（简体中文） |

## 配置

还需配置 procfs 文件系统的自动挂载。

需在 **/etc/fstab** 文件中添加如下内容：

```ini
proc /proc procfs rw 0 0
```

设置 D-Bus 服务开机自启：

```sh
# service dbus enable
```

设置 GDM 显示管理器开机自启：

```sh
# service gdm enable
```

执行以下命令，将 GNOME 会话命令写入 **\~/.xinitrc** 文件，以便使用命令 startx 启动 GNOME：

```sh
$ echo "/usr/local/bin/gnome-session" > ~/.xinitrc
```

![FreeBSD GNOME](/files/4yOFQPcRDBJ4m6eDkDFQ)

默认禁止 root 登录。

![FreeBSD GNOME](/files/4y2zbFqKXP6uqDGLmhkK)

此为默认壁纸。

![FreeBSD GNOME](/files/0T52Cy34PB7RftTobtYz)

## 为 GNOME 桌面环境配置中文环境

本小节的配置参数与用户 shell 无关，即使使用 csh 也应按此方式配置。

使用文本编辑器打开 GDM 本地化配置文件 **/usr/local/etc/gdm/locale.conf**，修改语言设置。将原有内容替换如下：

```ini
LANG="zh_CN.UTF-8"         # 设置系统默认语言为简体中文 UTF-8
LC_CTYPE="zh_CN.UTF-8"     # 设置字符类型和编码为简体中文 UTF-8
LC_MESSAGES="zh_CN.UTF-8"  # 设置系统消息显示语言为简体中文 UTF-8
```

## 中文输入法

IBus、Fcitx 5 二选一即可。

### IBus

GNOME 默认使用的输入法框架是 IBus。

使用 pkg 安装：

```sh
# pkg install zh-ibus-libpinyin
```

或使用 Ports 安装：

```sh
# cd /usr/ports/chinese/ibus-libpinyin/
# make install clean
```

安装后运行初始化命令 `ibus-setup`。随后：设置 → 键盘 → 输入源，点击“添加输入源”，选择“汉语（中国）”，加入“中文（智能拼音）”。

### Fcitx 5

参见输入法相关章节。

> **警告**
>
> IBus 是 GNOME 的依赖项，即使不使用 IBus，也不能将其卸载，否则将一并卸载 GNOME。

![FreeBSD GNOME](/files/9uVosZiKsvuRp99JgQPb)

## 与常规习惯不同的设置调整

GNOME 的设计理念与部分用户的操作习惯存在差异，例如桌面不允许放置图标、右上角无系统托盘等。~~是否与垃圾桶不能有垃圾、人不能在床上、门不能关、桌子上不能放东西有异曲同工之妙？~~

### 系统优化工具

使用 pkg 安装：

```sh
# pkg install gnome-tweaks
```

或使用 Ports 安装：

```sh
# cd /usr/ports/deskutils/gnome-tweaks/
# make install clean
```

### 恢复 GNOME 顶栏的托盘图标

需要安装 Firefox 浏览器 **www/firefox** 及 Port **www/chrome-gnome-shell**。

[TopIcons Plus](https://extensions.gnome.org/extension/1031/topicons/) 已长期未更新，因此只能使用 [AppIndicator and KStatusNotifierItem Support](https://extensions.gnome.org/extension/615/appindicator-support/)。

![GNOME 恢复 GNOME 顶栏的托盘图标](/files/dZBMMdNJ7rqVzMFUyOIQ)

![GNOME 恢复 GNOME 顶栏的托盘图标](/files/wrwFy2Vdxsi0QZQTgKz4)

![GNOME 恢复 GNOME 顶栏的托盘图标](/files/t3FhiByCQyYhd6tbdgk1)

![GNOME 恢复 GNOME 顶栏的托盘图标](/files/ZLyTfyWw6zBWG3QBw87S)

![GNOME 恢复 GNOME 顶栏的托盘图标](/files/zPrJus4jY7iZ3Dou746w)

![GNOME 恢复 GNOME 顶栏的托盘图标](/files/7Lr4jEUhCcSp1gEbJuZl)

#### 参考文献

* Abhishek Prakash. Getting the Top Indicator Panel Back in GNOME\[EB/OL]. \[2026-03-25]. <https://itsfoss.com/enable-applet-indicator-gnome>. 提供了恢复 GNOME 顶栏托盘图标显示的详细步骤与扩展安装指南。

### 在桌面上放置图标

扩展 [gnome-shell-extension-desktop-icons](https://extensions.gnome.org/extension/1465/desktop-icons/) 已经长期未更新，项目地址为：[Desktop Icons](https://gitlab.gnome.org/World/ShellExtensions/desktop-icons)。

可使用 [Desktop Icons NG (DING)](https://extensions.gnome.org/extension/2087/desktop-icons-ng-ding/) 解决。安装方式同上。

![GNOME 在桌面放图标](/files/5ahqynjI9c2d2qIChzOm)

壁纸为自定义设置，其余均为默认配置。

## 桌面主题美化

FreeBSD 安装桌面环境后采用简洁风格，以下内容适用于基于 GTK 库的桌面环境。

以下收录部分图标和主题，如需获取更多资源，可访问 [FreshPorts](https://www.freshports.org)。

* GTK 桌面主题

| 主题     | 安装命令                                  |
| ------ | ------------------------------------- |
| matcha | `# pkg install matcha-gtk-themes`     |
| Qogir  | `# pkg install qogir-gtk-themes`      |
| Pop    | `# pkg install pop-gtk-themes`        |
| Flat   | `# pkg install flat-remix-gtk-themes` |
| Numix  | `# pkg install numix-gtk-theme`       |
| Sierra | `# pkg install sierra-gtk-themes`     |
| Yaru   | `# pkg install yaru-gtk-themes`       |
| Canta  | `# pkg install canta-gtk-themes`      |

* GTK 桌面图标

| 图标       | 安装命令                                    |
| -------- | --------------------------------------- |
| papirus  | `# pkg install papirus-icon-theme`      |
| Qogir    | `# pkg install qogir-icon-themes`       |
| Pop      | `# pkg install pop-icon-theme`          |
| Flat     | `# pkg install flat-remix-icon-themes`  |
| Numix    | `# pkg install numix-icon-theme`        |
| Numix 圆形 | `# pkg install numix-icon-theme-circle` |
| Yaru     | `# pkg install yaru-icon-theme`         |
| Canta    | `# pkg install canta-icon-theme`        |

### GNOME 主题美化

以下安装 [WhiteSur](https://www.pling.com/p/1403328/) 主题。

1. 下载主题源代码包：`git clone https://github.com/vinceliuice/WhiteSur-gtk-theme`
2. 进入主题包目录：`cd WhiteSur-gtk-theme`
3. 修改 shebang：编辑 `install.sh` 文件，修改第一行为 `#!/usr/local/bin/bash`，随后保存。
4. 执行安装：`bash install.sh`

### WhiteSur 图标

[图标](https://www.pling.com/p/1405756/)

1. 下载图标：`git clone https://github.com/vinceliuice/WhiteSur-icon-theme`
2. 进入软件目录：`cd WhiteSur-icon-theme`
3. 修改 shebang：编辑 `install.sh` 文件，修改第一行为 `#!/usr/local/bin/bash`，随后保存。
4. 执行安装：`bash install.sh`

### 光标

[光标](https://www.pling.com/p/1355701/)

1. 下载光标：`git clone https://github.com/vinceliuice/McMojave-cursors`
2. 进入软件目录：`cd McMojave-cursors`
3. 修改 shebang：编辑 `install.sh` 文件，修改第一行为 `#!/usr/local/bin/bash`，随后保存。
4. 执行安装：`bash install.sh`

### 思考题

按照下面的步骤，在终端安装 [Papirus 图标](https://www.gnome-look.org/p/1166289/)：

```sh
$ git clone https://github.com/PapirusDevelopmentTeam/papirus-icon-theme
$ cd papirus-icon-theme
$ ./install.sh
```

## 附录：GNOME 桌面环境精简安装

* 使用 pkg 安装：

```sh
# pkg install xorg-minimal gnome-lite wqy-fonts xdg-user-dirs
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg-minimal/ && make install clean
# cd /usr/ports/x11/gnome/ && make FLAVOR=lite install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

### 软件包说明

| 包名             | 作用           |
| -------------- | ------------ |
| `xorg-minimal` | 精简版 X 图形环境   |
| `gnome-lite`   | 精简版 GNOME 桌面 |

### 精简现有的 GNOME 完整版本

如果已安装完整版本，也可使用 pkg 卸载附带的游戏软件：

```sh
# pkg delete gnome-2048 gnome-klotski gnome-tetravex gnome-mines gnome-taquin gnome-sudoku gnome-robots gnome-nibbles lightsoff tali quadrapassel swell-foop gnome-mahjongg five-or-more iagno aisleriot four-in-a-row
```

![GNOME 精简安装](/files/AsroCWX9XcfCWBVUvQIM)


# 13.8 IceWM

## IceWM 窗口管理器概述

IceWM 是基于 X 窗口系统的窗口管理器。设计目标是快速响应、结构简洁，不干扰用户操作流程。它内置分页任务栏、全局及窗口级快捷键绑定，并提供动态菜单系统。可通过键盘和鼠标组合管理窗口。用户可将窗口图标化到任务栏、系统托盘或桌面区域，也可将其隐藏。窗口管理支持快速窗口切换（Alt+Tab）或窗口列表。多种可配置的窗口焦点模式均可通过菜单选择。通过 RandR 和 Xinerama 扩展支持多显示器环境。IceWM 可高度定制，支持自定义主题，并提供完善的文档。IceWM 提供可选的外部壁纸管理器（支持透明效果）、简易会话管理器和系统托盘。IceWM 可在主流 Linux 发行版及多数 \*BSD 系统上运行。（引自 [IceWM Window Manager](https://ice-wm.org/)）

## 安装 IceWM 窗口管理器

* 使用 pkg 安装：

```sh
# pkg install xorg icewm icewm-extra-themes wqy-fonts xdg-user-dirs
```

* 使用 Ports 安装：

```sh
# cd /usr/ports/x11-wm/icewm/ && make install clean
# cd /usr/ports/x11-themes/icewm-extra-themes/ && make install clean
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

IceWM 的显示管理器建议使用 SLiM。

### 软件包说明

| 包名                   | 作用说明               |
| -------------------- | ------------------ |
| `xorg`               | X 窗口系统             |
| `icewm`              | 轻量级窗口管理器           |
| `icewm-extra-themes` | IceWM 额外主题集合       |
| `wqy-fonts`          | 文泉驿中文字体            |
| `xdg-user-dirs`      | 管理用户目录，如“桌面”、“下载”等 |

## startx

编辑 **\~/.xinitrc** 文件并添加以下内容（应以当前登录用户的身份修改）：

```ini
exec icewm-session
```

由此可在 TTY 中使用 startx 命令启动 IceWM 会话。

## 启动项

设置 D-Bus 服务开机自启（作为依赖自动安装）：

```sh
# service dbus enable
```

## 挂载 proc 文件系统

编辑 **/etc/fstab** 文件，加入下行：

```ini
proc           /proc       procfs  rw  0   0
```

将 procfs 文件系统以读写模式挂载到 **/proc**。

## 桌面欣赏

![FreeBSD 安装 icewm](/files/8Sm61sVHcOiPLKImcTiY)

安装后的默认界面如上图所示，可选择更换主题：

![FreeBSD 安装 icewm](/files/smO4U1Ry9PltM8Xw7gKy)

![FreeBSD 安装 icewm](/files/9VGyY8IXJaDGqWhucK5Y)

## 故障排除与未竟事宜

### 中文环境不完整

该问题已反馈至 [Many UI Strings Are Missing from .po Files](https://github.com/bbidulock/icewm/issues/821)。

## 参考文献

* FreeBSD Project. icewm-preferences(5)\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=icewm-preferences&sektion=5>. IceWM 窗口管理器配置选项的官方手册页，详细说明了各项配置参数。


# 13.9 CDE（拟删除）

## CDE 桌面环境概述

CDE（Common Desktop Environment，通用桌面环境）是 20 世纪 90 年代商业 UNIX 系统的标准桌面环境，曾广泛应用于 Solaris、HP-UX 和 AIX 等商业发行版。

## 安装 CDE 桌面环境

* 使用 pkg 安装：

```sh
# pkg install xorg cde wqy-fonts xdg-user-dirs
```

* 或使用 Ports 安装：

```sh
# cd /usr/ports/x11/xorg/ && make install clean
# cd /usr/ports/x11/cde/ && make install clean
# cd /usr/ports/x11-fonts/wqy/ && make install clean
# cd /usr/ports/devel/xdg-user-dirs/ && make install clean
```

登录管理器可考虑使用 SLiM。

### 软件包说明

| 包名              | 作用说明              |
| --------------- | ----------------- |
| `xorg`          | X 窗口系统            |
| `cde`           | 提供传统的 CDE 桌面环境    |
| `wqy-fonts`     | 文泉驿中文字体           |
| `xdg-user-dirs` | 管理用户目录，如“桌面”“下载”等 |

* 查看安装后的信息

```sh
# pkg info -D cde
```

## 配置服务与文件

* 配置服务

```sh
# service rpcbind enable  # 设置 RPC 绑定服务开机自启
# service dtcms enable  # 设置 DTCMS 服务开机自启
# service inetd enable  # 设置 inetd 守护进程开机自启
# service dtlogin enable  # 设置 DTLogin 显示管理器开机自启
```

* 配置 X 服务器允许任意用户启动：

```sh
# echo "allowed_users=anybody" > /usr/local/etc/X11/Xwrapper.config
```

* 为当前用户创建 Xsession 的符号链接，用于启动桌面会话：

```sh
$ ln -s /usr/local/dt/bin/Xsession ~/.xinitrc
```

* 配置 dtspcd 服务通过 TCP 启动，将以下内容添加到 **/etc/inetd.conf** 文件：

```ini
dtspc	stream	tcp	nowait	root	 /usr/local/dt/bin/dtspcd	/usr/local/dt/bin/dtspcd
```

* 为 dtspc 服务指定 TCP 端口 6112，将以下内容添加到 **/etc/services** 文件：

```ini
dtspc		6112/tcp
```

### 中文配置

编辑 **/etc/login.conf** 文件：找到 `default:\` 部分，将 `:lang=C.UTF-8` 修改为 `:lang=zh_CN.UTF-8`。

根据 **/etc/login.conf** 文件重建能力数据库，使配置生效：

```sh
# cap_mkdb /etc/login.conf
```

## 桌面欣赏

![dtlogin](/files/IQs3sL6M16qBIfgOcZGD)

![FreeBSD 安装 CDE](/files/Ey6tTgH1QqwEG4pMdUMH)

每次启动时均会在此阶段暂停数分钟。

![FreeBSD 安装 CDE](/files/fd6urPh1I6RblNTKogB0)

![终端](/files/NJrNQrumqMSgZUEXx3mn)

## 故障排除与未竟事宜

### 无法设置中文环境

CDE 整体界面无法切换为中文，仅日历组件可显示中文。

根据源代码 <https://sourceforge.net/p/cdesktopenv/code/ci/master/tree/cde/imports/motif/localized/>，CDE 不存在简体中文支持。然而根据 [简体中文 Solaris 用户指南](https://docs.oracle.com/cd/E19683-01/816-0668/6m7500nqp/index.html)，Solaris 版本确实包含简体中文支持，该本地化支持可能在开源过程中丢失，或 Solaris 版本为未合并的分支。已反馈至 [Missing Simplified Chinese locale support under cde/imports/motif/localized](https://sourceforge.net/p/cdesktopenv/discussion/general/thread/c51abcd846/)。

## 参考文献

* FreshPorts. cde Common Desktop Environment\[EB/OL]. \[2026-03-25]. <https://www.freshports.org/x11/cde>. FreshPorts 提供的 CDE 桌面环境 Port 详情与安装指南。
* FreeBSD Project. Setting up Common Desktop Environment for modern use\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/setting-up-common-desktop-environment-for-modern-use.69475/>. 详细配置可参考 FreeBSD 论坛相关讨论。
* CDE Project. CDE - Common Desktop Environment Wiki\[EB/OL]. \[2026-03-25]. <https://sourceforge.net/p/cdesktopenv/wiki/FreeBSDBuild/>. CDE 项目官方 Wiki 提供的 FreeBSD 平台构建与配置指南。


# 14.1 声卡

FreeBSD 默认自动检测系统使用的声卡。

FreeBSD 内核通过 snd\_hda 模块支持 Intel HDA 规范声卡，本节说明声音设备检测与音量控制方法。回顾其发展历程，FreeBSD 的声音支持始于 1993 年，Jordan K. Hubbard 将通用 Linux 声卡驱动移植到 FreeBSD，该驱动后来被称为 VoxWare 声卡驱动。1997 年，Luigi Rizzo 构建了现代 FreeBSD 声音系统的基础。1999 年，Cameron Grant 为 FreeBSD 4.0 重写了声卡系统，利用 newbus 接口支持大量硬件。2005 年，Ariff Abdullah 接管了 FreeBSD 声音代码的维护工作，此后声音支持经历了重大变化和多项设备驱动重构。

FreeBSD 的声音 API 被称为 OSS，即“Open Sound System”（开放声音系统）。它曾是 Linux 的默认声音 API，后来被 ALSA 取代。FreeBSD 仍在使用 OSS，它通过标准设备文件提供了简单清晰的接口（**/dev/dsp\*** 对应声卡，**/dev/mixer\*** 对应混音器），并通过少量常用 POSIX 系统调用进行操作。

> **警告**
>
> FreeBSD Ports 中的 KDE 6 默认音频管理组件（plasma-pa）使用 PulseAudio 作为音频后端。PulseAudio 作为音频服务器会接管系统音频输出管理，形成全局音频路由。如果不充分了解配置细节，请勿手动切换到其他音频后端（如 PipeWire），以免造成音频系统工作异常。

## 加入音频组

普通用户还需要加入 audio 组以及 operator 组方有权限调用声卡。

```sh
# pw groupmod operator -m 用户名
# pw groupmod audio -m 用户名
```

## HDA 声卡驱动

`snd_hda` 是 FreeBSD 内核中用于支持 Intel High Definition Audio（HDA）规范声卡的驱动模块，适用于绝大多数现代集成声卡。该驱动通常会在系统启动时自动加载。可使用 `kldstat` 命令检查驱动是否已加载。

> **注意**
>
> 仅当 FreeBSD 未能正确检测到声卡时，才需要加载声卡模块。

为确认系统识别的音频设备，使用以下命令查看当前声卡设备列表：

```sh
# cat /dev/sndstat
Installed devices:
pcm0: <NVIDIA (0x0083) (HDMI/DP 8ch)> (play)
pcm1: <NVIDIA (0x0083) (HDMI/DP 8ch)> (play)
pcm2: <NVIDIA (0x0083) (HDMI/DP 8ch)> (play)
pcm3: <NVIDIA (0x0083) (HDMI/DP 8ch)> (play)
pcm4: <Realtek ALC892 (Rear Analog 5.1/2.0)> (play/rec) default
pcm5: <Realtek ALC892 (Front Analog)> (play/rec)
pcm6: <Realtek ALC892 (Rear Digital)> (play)
No devices installed from userspace.
```

如果未列出任何 `pcm` 设备，请检查是否已加载正确的设备驱动。

输出中标注为 `default` 的设备是 OSS（Open Sound System，开放声音系统）的默认音频设备。OSS 是 FreeBSD 原生的音频子系统，提供直接的音频设备访问接口。如果软件使用 OSS 作为音频输出接口且输出设备设置为默认值，音频将从该设备输出。

如需获取更详细的声卡信息用于深度诊断，可通过调整内核参数提高调试输出等级：

```sh
# sysctl hw.snd.verbose=4  # 设置 FreeBSD 声卡驱动调试输出等级为 4
```

该命令将声卡驱动的调试输出等级设置为 4。调试等级范围为 0 至 4，数值越高输出信息越详细，等级 4 会输出最完整的调试信息。此设置临时生效，系统重启后将恢复默认值。

FreeBSD 中大部分软件的音频输出接口为 OSS。部分软件默认使用 PulseAudio（如 Firefox 浏览器），相关设置参见后文说明。Firefox 可通过 `about:support` 页面查看当前使用的音频后端。Firefox 支持多种音频后端，其自动探测顺序为：pulse-rust（PulseAudio Rust 后端，需安装 PulseAudio）、JACK（需安装 jackit）、sndio（需安装 sndio）、ALSA（需安装 alsa-lib）、OSS（始终可用）。也可通过 `about:config` 中的 `media.cubeb.backend` 配置项手动指定。

以下命令可设置默认 OSS 音频设备单元号为 5，其中数字对应 `pcm` 后的设备编号：

```sh
# sysctl hw.snd.default_unit=5
```

该设置临时生效，系统重启后将恢复默认值。要永久生效，须将配置写入 **/etc/sysctl.conf** 文件。

上文中的 `pcm6: <Realtek ALC892 (Rear Digital)> (play)` 为数字输出接口。集成声卡的模拟接口采样率通常为 48 kHz，部分 HDA 编解码器可支持 96 kHz 或更高；数字接口则绕过了板载 DAC 的采样率限制，可使用支持更高采样率的外部 DAC。S/PDIF 接口基于 IEC 60958 标准，可直接传输最高 192 kHz/24 bit 的 PCM 立体声信号；IEC 61937 标准用于在 IEC 60958 帧结构中封装压缩音频比特流（如 Dolby Digital、DTS 等）。部分 TOSLINK 光纤接口实现可能受带宽限制仅支持至 96 kHz。

如果存在数字输出但机箱面板无对应接口，而主板提供 S/PDIF（Sony/Philips Digital Interface Format，索尼/飞利浦数字接口格式）插针，可安装 S/PDIF 挡板（通常包含光纤接口和同轴接口），连接后即可使用。

## 自动切换到耳机

FreeBSD 可在 **/boot/device.hints** 中配置音频自动切换。

通过执行以下命令，识别系统枚举的音频输出：

```sh
% dmesg | grep pcm
```

输出可能类似于以下内容：

```sh
pcm0: <Realtek ALC892 Analog> at nid 23 and 26 on hdaa0
pcm1: <Realtek ALC892 Right Analog Headphones> at nid 22 on hdaa0
```

将以下行添加到 **/boot/device.hints** 文件：

```ini
hint.hdac.0.cad0.nid22.config="as=1 seq=15 device=Headphones"
hint.hdac.0.cad0.nid26.config="as=2 seq=0 device=speakers"
```

> **注意**
>
> 上述示例中的配置值仅适用于对应硬件环境，不同系统的节点编号可能存在差异，须根据实际情况调整。

## 配置文件示例

```sh
# cat /dev/sndstat 
Installed devices:
pcm0: <Realtek ALC897 (Analog)> (play/rec) default
pcm1: <Realtek ALC897 (Rear Analog Line-in)> (rec)
No devices installed from userspace.
```

该设备并非复合音频接口（Combo Jack，即非扬声器与麦克风的二合一接口），当前仅插入了一台音响。默认配置下，该设备不会输出声音。

```sh
# sysctl -a | grep hdaa.0.nid | grep config
dev.hdaa.0.nid31_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid30_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid29_config: 0x4024c601 as=0 seq=1 device=Headphones conn=None ctype=RCA loc=0x00 color=Res.C misc=6
dev.hdaa.0.nid28_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid27_config: 0x02214010 as=1 seq=0 device=Headphones conn=Jack ctype=1/8 loc=Front color=Green misc=0
dev.hdaa.0.nid26_config: 0x01813040 as=4 seq=0 device=Line-in conn=Jack ctype=1/8 loc=Rear color=Blue misc=0
dev.hdaa.0.nid25_config: 0x02a1903f as=3 seq=15 device=Mic conn=Jack ctype=1/8 loc=Front color=Pink misc=0
dev.hdaa.0.nid24_config: 0x01a19030 as=3 seq=0 device=Mic conn=Jack ctype=1/8 loc=Rear color=Pink misc=0
dev.hdaa.0.nid23_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid22_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid21_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid20_config: 0x01014020 as=2 seq=0 device=Line-out conn=Jack ctype=1/8 loc=Rear color=Green misc=0
dev.hdaa.0.nid18_config: 0x411111f0 as=15 seq=0 device=Speaker conn=None ctype=1/8 loc=Rear color=Black misc=1
dev.hdaa.0.nid17_config: 0x40000000 as=0 seq=0 device=Line-out conn=None ctype=Unknown loc=0x00 color=Unknown misc=0
```

为解决此问题，可使用以下命令实时调试音频配置（命令立即生效，但在系统重启后失效）：

```sh
# 1. 将背部绿色扬声器设为关联组 1 的主输出
# sysctl dev.hdaa.0.nid20_config="as=1 seq=0"

# 2. 将前面板耳机设为关联组 1 的次输出（插入时静音主输出）
# sysctl dev.hdaa.0.nid27_config="as=1 seq=15"

# 3. 强制音频驱动销毁并应用新配置重建音频树
# sysctl dev.hdaa.0.reconfig=1
```

* `as=1`：将两者归入同一关联组。
* `seq=0`：主输出（扬声器），优先级最高。
* `seq=15`：耳机，插入耳机时会自动静音扬声器。

此时音频输出已恢复正常，编辑 **/boot/device.hints** 文件，加入以下行，将其固化为永久设置：

```ini
hint.hdaa.0.nid20.config="as=1 seq=0"    # 配置 HDA 声卡节点 20 的音频流为通道 1，序列号 0
hint.hdaa.0.nid27.config="as=1 seq=15"   # 配置 HDA 声卡节点 27 的音频流为通道 1，序列号 15
```

## 附录：音量调节

可使用系统自带的命令行工具 `mixer` 调整系统音量。

例如以下命令可将系统音量提高 5%：

```sh
$ mixer vol=+5%  # 将音量增加 5%
```

## 故障排除与未竟事宜

### 编译内核启用特殊声卡

部分特殊声卡需自行编译内核。详见 Open Sound System for BSD\[EB/OL]. \[2026-03-25]. <http://www.opensound.com/bsd.html>.

### obs-studio

OSS 作为底层音频接口存在一定技术限制：其设计未提供音频流回环机制，因此在使用 `obs-studio` 等软件时无法直接录制 OSS 的输出音频。根据官方论坛说明，可使用 `virtual_oss` 工具模拟音频设备实现该功能（借助 `virtual_oss` 的 `-M` 参数完成声道路由，将 OSS 输出重定向到 OSS 输入）。

`obs-studio` 可录制 PulseAudio 的输出音频（默认的“桌面音频”输入源对应 PulseAudio 输出），因此部分软件可配置为使用 PulseAudio 作为音频输出接口。使用 PulseAudio 的软件，其音频输出不受上述 OSS 命令控制，需使用 PulseAudio 混音器管理设备。

### AMD APU 显示驱动 mode 2 reset

由于驱动对空渲染上下文的初始化存在问题，在使用 AMD APU（加速处理单元，Accelerated Processing Unit）且配合 `drm-kmod` 图形驱动时，打开未加载媒体内容的空播放器窗口可能触发显示驱动的 mode 2 reset 报错（即驱动重置机制），严重时可能导致 Kernel Panic。

避免打开未加载任何媒体内容的播放器或音频播放器窗口，建议通过终端命令行播放音频文件。

## 参考文献

* FreeBSD Project. snd\_hda -- Intel High Definition Audio driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=snd_hda&sektion=4>. Intel HDA 声卡驱动手册页。


# 14.2 打印机

CUPS（通用 Unix 打印系统，Common Unix Printing System）是模块化打印系统架构，支持多种打印协议和打印机设备，可将打印机通过 IPP（互联网打印协议，Internet Printing Protocol）或 SMB（服务器消息块，Server Message Block）协议共享到网络。

打印机通过 USB（通用串行总线，Universal Serial Bus）总线接入打印服务器（即 FreeBSD 系统）。打印服务器将打印机共享到局域网中。局域网内其他计算机可通过发送多播数据包，利用零配置网络技术自动查询可用打印机。

已在 Android、macOS、Debian 等平台上测试通过，上述系统均可正常发现并使用该打印服务器。

## 安装 CUPS（通用 Unix 打印系统）

安装 CUPS：

* 使用 pkg（二进制包管理器）安装：

```sh
# pkg install cups cups-filters
```

* 或通过 Ports（源代码包管理器）安装：

```sh
# cd /usr/ports/print/cups/ && make install clean
# cd /usr/ports/print/cups-filters/ && make install clean
```

> **技巧**
>
> 如果使用桌面环境，请在 Ports 选项界面中选中 `x11` 编译选项，可在系统中生成添加和配置打印机的图形化应用图标。

## 软件包说明

| 软件包            | 作用说明                                                  |
| -------------- | ----------------------------------------------------- |
| `cups`         | 用于提供 CUPS 核心打印服务                                      |
| `cups-filters` | 提供 CUPS 所需的附加后端、过滤器及其他软件，包括免驱动打印（IPP Everywhere 协议）支持 |
| `dbus`         | Avahi 需要，作为 CUPS 依赖自动安装                               |
| `avahi-app`    | Avahi 所需组件，作为 CUPS 的依赖自动安装，用于局域网中的打印机自动发现             |

> **技巧**
>
> 本节介绍将 FreeBSD 配置为打印服务器。如果 FreeBSD 仅作为打印客户端，通过 USB 本地连接打印机打印，而不需要共享打印服务，avahi-app 和 dbus 并非必需组件。

> **注意**
>
> 如果打印机不支持免驱动打印，则需要安装对应的厂商驱动程序。

## 添加服务

将 D-Bus（Desktop Bus，桌面总线）、avahi‑daemon（Avahi 守护进程）和 cupsd（CUPS 守护进程）服务设置为系统启动时自动启用，以确保打印服务及其自动发现功能在系统重启后仍可正常运行：

```sh
# service dbus enable           # 设置 D‑Bus 服务开机自启动
# service avahi-daemon enable   # 设置 Avahi 守护进程开机自启动（用于网络服务发现）
# service cupsd enable          # 设置 CUPS 打印服务开机自启动
```

立即启动上述服务：

```sh
# service dbus start
# service avahi-daemon start
# service cupsd start
```

启动服务后，其他设备应能够自动发现内网中的共享打印机。可打印测试页以验证功能是否正常。

## 向局域网共享打印服务

如果未设置“允许局域网访问”，则除本地回环地址 `localhost` 外的其他主机将无法使用该打印服务。

相关文件结构：

```sh
/
├── usr/
│   └── local/
│       └── etc/
│           └── cups/
│               └── cupsd.conf       # CUPS 主配置文件
└── var/
    └── run/
        └── cups/
            └── cups.sock            # CUPS UNIX 套接字
```

编辑 CUPS 主配置文件 **/usr/local/etc/cups/cupsd.conf**：

* 在现有的监听配置段

```ini
Listen localhost:631
Listen /var/run/cups/cups.sock
```

后面添加以下配置（将其中 IP 替换为 FreeBSD 系统的局域网 IP 地址）：

```ini
Listen IP:631
```

该配置指定 CUPS 打印服务监听的网络接口 IP 地址和端口号（631 是 IPP 协议的标准端口）。

* 再将

```apache
# Restrict access to the server...
<Location />
  Order allow,deny
</Location>

# Restrict access to the admin pages...
<Location /admin>
  AuthType Default
  Require user @SYSTEM
  Order allow,deny
</Location>
```

改为：

```apache
# Restrict access to the server...
<Location />
  Allow from 192.168.0.0/24   # 允许访问的 IP 网段
  Order allow,deny
</Location>

# Restrict access to the admin pages...
<Location /admin>
  Allow from 192.168.0.0/24   # 允许访问的 IP 网段
  AuthType Default             # 使用默认认证类型
  Require user @SYSTEM         # 仅系统用户可访问
  Order allow,deny
</Location>
```

> **技巧**
>
> 上述示例中的 **192.168.0.0/24** 为占位符，须替换为实际的值。

完成配置后，CUPS 管理页面即可从局域网内访问。

## 添加打印机

在浏览器中输入 `http://IP:631`，该地址为打印服务器的管理页面。

![CUPS 管理页面](/files/G5oh22a9uW0PVs2Eb00O)

点击 `Administration-Add Printer`，根据提示创建打印机。

该步骤将提示输入账号和密码，使用 `root` 用户或 `wheel` 组内的用户登录（输入其在 FreeBSD 系统中的账户密码）即可。

![添加打印机](/files/Zivbcn4FJXobFtH6Qimn)

点击 `Add Printer`，添加打印机。

![选择打印机](/files/VWYCB7WJ7XFNzWlk9LbK)

本节中使用的打印机型号为 Brother HL-L3228CDW。

![打印机详情](/files/GqbQdp9ImwblzexRYNTj)

在创建时务必勾选 `Share This Printer`。

![共享打印机](/files/efPIJi3if8Zcon5xVtRn)

选择型号。

![选择型号](/files/QO1SDH7ihpOshXL8ughz)

如果打印机支持免驱动打印，`Model` 请选择 `Generic IPP Everywhere Printer (en)`；否则需要安装相应驱动，并选择对应的打印机型号。

![打印机配置](/files/dB34cyBAMuDHyaPocXKq)

打印机添加成功。

![添加成功](/files/41CyDOb9qzipZ1FFIaen)

## 在 KDE 桌面添加打印机

无需额外操作，需要打印的设备通常可自动发现打印服务器，并自动将其加入打印机列表，打印文件时即可选择。例如在 KDE 桌面上：

![KDE 打印机列表](/files/L0yRPcjN03ZpblQG4AZx)

![KDE 打印机详情](/files/pJSNQCdeVYVsz183eiaJ)

## 打印测试页

从内网的 Debian 机器打印测试页：

![测试页打印](/files/jHepplnQ3NMB6Sa0c1Z3)

## 故障排除与未竟事宜

### 打印机免驱动支持问题

如需确认打印机是否支持免驱动打印，可在 [OpenPrinting](https://openprinting.github.io/printers/) 查询。以本节使用的打印机为例：

![OpenPrinting 查询](/files/azP68LijDxvPdhDlb5F7)

惠普（HP）打印机可通过安装 Port `print/hplip` 获得支持。

### FreeBSD 打印的测试页示例

在 CUPS 管理页面中选择打印机，点击“Print Test Page”即可打印测试页，验证打印功能是否正常。


# 14.3 摄像头

本节将介绍如何为 FreeBSD 系统配置摄像头。

Video for Linux 2（V4L2）是第二代 V4L。V4L2 是 Linux 内核中视频设备的内核驱动框架。

FreeBSD 访问和配置摄像头需要安装以下工具：

| Port                 | 说明                                                                  |
| -------------------- | ------------------------------------------------------------------- |
| multimedia/webcamd   | 守护进程，从 Linux USB 网络摄像头和 DVB 驱动程序移植而来，支持使用数百种不同的 USB 摄像头和 DVB USB 设备 |
| multimedia/pwcview   | 可用于查看摄像头的视频流                                                        |
| multimedia/mpv       | 也可用于查看摄像头的 V4L2 视频流                                                 |
| multimedia/v4l-utils | 用于配置和测试 Video4Linux 设备                                              |

## 安装摄像头软件

要使用 pkg 安装所需的实用工具，请执行：

```sh
# pkg install webcamd pwcview mpv v4l-utils
```

使用 Ports 安装：

```sh
# cd /usr/ports/multimedia/webcamd && make install clean
# cd /usr/ports/multimedia/pwcview && make install clean
# cd /usr/ports/multimedia/mpv && make install clean
# cd /usr/ports/multimedia/v4l-utils && make install clean
```

## 服务管理

启用 webcamd 服务，以便在系统启动时自动启动：

```sh
# service webcamd enable
```

重新加载设备状态服务：

```sh
# service devd restart
```

## 用户管理

用户必须属于 `webcamd` 组。要将用户 ykla 添加到 `webcamd` 组，请执行以下命令：

```sh
# pw groupmod webcamd -m ykla
```

## 获取摄像头列表

安装完这些工具后，可以使用 webcamd 显示可用的摄像头列表：

```sh
# webcamd -l
```

输出应该类似于以下内容：

```sh
webcamd [-d ugen1.2] -N Jieli-Technology-USB-Composite-Device -S unknown -M 0
```

发现了可用的摄像头“Jieli-Technology-USB-Composite-Device”。

临时测试摄像头：

```sh
$ webcamd -d ugen1.2
```

请保持其在前台运行，便于后续配置。

将生成设备文件 **/dev/video0** 和 **/dev/video1**。

## 查看摄像头配置

使用 **v4l2-ctl** 工具列出摄像头支持的参数：

```sh
$ v4l2-ctl --list-formats-ext -d /dev/video0

ioctl: VIDIOC_ENUM_FMT

        Type: Video Capture



        [0]: 'MJPG' (Motion-JPEG, compressed)

                Size: Discrete 1920x1080

                        Interval: Discrete 0.033s (30.000 fps)

                        Interval: Discrete 0.040s (25.000 fps)

                Size: Discrete 1280x720

                        Interval: Discrete 0.033s (30.000 fps)

                        Interval: Discrete 0.040s (25.000 fps)

                Size: Discrete 640x480

                        Interval: Discrete 0.033s (30.000 fps)

                        Interval: Discrete 0.040s (25.000 fps)

                Size: Discrete 640x360

                        Interval: Discrete 0.033s (30.000 fps)

                        Interval: Discrete 0.040s (25.000 fps)

                Size: Discrete 352x288

                        Interval: Discrete 0.033s (30.000 fps)

                        Interval: Discrete 0.040s (25.000 fps)

        [1]: 'YUYV' (YUYV 4:2:2)

                Size: Discrete 640x480

                        Interval: Discrete 0.033s (30.000 fps)

                Size: Discrete 640x360

                        Interval: Discrete 0.033s (30.000 fps)

                Size: Discrete 352x288

                        Interval: Discrete 0.033s (30.000 fps)

                Size: Discrete 320x240

                        Interval: Discrete 0.033s (30.000 fps)
```

以上详细列出了该摄像头支持的视频格式、分辨率以及在不同分辨率下的帧率（FPS）。

## 检查摄像头

### 使用 multimedia/pwcview 检查摄像头

可以使用 multimedia/pwcview 检查摄像头是否正常工作。

临时禁用 SDL 的 Xv 硬件加速，避免黑屏等意外情况，如果测试通过可移除该环境变量。

```sh
$ export SDL_VIDEO_YUV_HWACCEL=0
```

再次运行 pwcview（分辨率 1600x1200\@30 帧）：

```sh
$ pwcview -f 30 -s uxga
```

此后 multimedia/pwcview 将显示摄像头画面：

![pwcview 显示的摄像头画面](/files/5A3Y3WbvRIQZeOtIinpU)

### 使用 mpv 检查摄像头

可以使用 multimedia/mpv 检查摄像头是否正常工作。

```sh
$ mpv av://v4l2:/dev/video0 --vo=x11
```

以上命令使用 `--vo=x11` 禁用硬件加速，避免意外情况，如果测试通过可移除该参数。

此后 multimedia/mpv 将显示摄像头画面：

![mpv 显示的摄像头画面](/files/EdHTLAjoZ4GiRVBaFUVn)

## 永久设置摄像头

确认摄像头工作正常后，可以固化上述配置。

通过执行以下命令配置可用的摄像头：

```sh
# sysrc webcamd_0_flags="-d ugen1.2"
```

> **注意**
>
> 如果这是即插即用的 USB 摄像头，在其连接的 USB 端口发生变动后，`webcamd -l` 的输出（尤其是设备标识符）将发生变化，可能需要同步更新 **/etc/rc.conf**。

必须通过执行以下命令启动 webcamd 服务：

```sh
# service webcamd restart
```

输出应类似于以下内容：

```sh
Starting webcamd.
webcamd 2652 - - Attached to ugen1.2[0]
```

## 在线测试摄像头

使用“摄像头测试”网站在线测试摄像头：<https://www.onlinemictest.com/webcam-test>。

![在线测试摄像头的显示画面](/files/PQqoXrZNCJONxoDonQwm)


# 14.4 人机输入设备

FreeBSD 原生支持 I²C 和 USB 接口的触摸板。本节介绍关闭触摸板的方法。

## 触摸板

### 关闭触摸板

如需关闭触摸板，首先需查找触摸板在 X Window（X 窗口）系统中的设备标识。不同系统的设备名称可能不同，通常触摸板设备名称中会包含 `Touchpad` 或类似标识：

```sh
$ xinput list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ Windows pointer                         	id=6	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ Windows keyboard                        	id=7	[slave  keyboard (3)]
```

找到触摸板对应的设备 ID（示例中为 6）后，关闭方式如下（其中 `1` 表示开启，`0` 表示关闭）：

```sh
$ xinput set-prop 6 "Device Enabled" 0    # 禁用 ID 为 6 的输入设备
```

#### 参考文献

* fygar256. FreeBSD タッチパッドを off にする\[EB/OL]. Qiita, (2023-03-16)\[2026-03-25]. <https://qiita.com/fygar256/items/35100d43b096470631d6>. 详细介绍使用 xinput 工具禁用 FreeBSD 触摸板的方法，提供实用命令示例。

### Apple Magic Trackpad

Apple Magic Trackpad 2（妙控板 2）基于 Force Touch 压力感应技术提供精确的操作体验。

在 FreeBSD 上，Apple 妙控板通过 USB 连接时，现代版本（15.0 及以上）由新的 HID 驱动栈（usbhid/hms）自动识别和支持，无需额外加载内核模块。

该触摸板需要配合 `libinput` 输入库使用，在 X Window（通过 xf86-input-libinput 驱动）和 Wayland 桌面环境下均可使用。当前不支持通过蓝牙无线方式使用。

## 附录：解决 15.0 及更高版本中键鼠无法驱动的问题

如果 USB 键盘、鼠标或触摸板在 15.0 以下版本中工作正常，但在系统更新到 15.0 后发生驱动故障，可参考以下解决方案：

在系统启动配置文件 **/boot/loader.conf.local** 中加入如下一行配置：

```ini
hw.usb.usbhid.enable="0"
```

该配置禁用 usbhid 驱动栈以回退至旧驱动，随后重启系统即可。

问题分析：ums（USB Mouse）和 ukbd（USB Keyboard）驱动在多数架构的通用内核中默认编译进内核，同时也以可加载模块形式存在（如 `ukbd_load="YES"`）。在 15.0 版本之后，usbhid 驱动成为默认选择，其优先级高于传统的 ums 和 ukbd 驱动。

usbhid 驱动最早出现于 FreeBSD 15.0。[FreeBSD 代码审查 D45658](https://reviews.freebsd.org/D45658) 将 usbhid、hidbus 和 hkbd 加入各架构的 GENERIC 内核配置，并将 hms 加入 arm 和 powerpc 架构的配置，使新 HID 栈驱动默认可用；而将 `hw.usb.usbhid.enable` 默认值由 0 改为 1 的变更由 [D45659](https://reviews.freebsd.org/D45659) 提出。usbhid 自 15.0 起成为系统默认启用的驱动。

鉴于项目正在逐步迁移至新的 HID 驱动栈（hkbd/hms），此问题仍需进一步研究其根本原因，并应向 FreeBSD 项目提交 Bug 报告。具体可参考 FreeBSD 期刊 2021/0708 期的相关报道。

## 附录：Fn 键设置

* David Schlachter. Adjusting acpi\_video brightness increments on FreeBSD\[EB/OL]. (2020-03-12)\[2026-03-25]. <https://www.davidschlachter.com/misc/freebsd-acpi_video-thinkpad-display-brightness>. 介绍在 FreeBSD 上调整 ACPI 视频亮度增量的具体方法，适用于 ThinkPad 等笔记本电脑。


# 14.5 音频播放器

FreeBSD 上主要的音频播放器包括 Audacious、VLC 和 MPD。本节给出 pkg 安装方法，并介绍 MPD 播放 DSD 音频的配置流程。

## Audacious

### 安装 Audacious

* 使用 pkg（二进制包管理器）安装：

```sh
# pkg install audacious audacious-plugins
```

> **注意**
>
> `audacious-plugins` 插件包是 Audacious 主程序运行的必要依赖，不安装该插件包则无法正常启动 `audacious` 主程序。

* 或者使用 Ports（源代码包管理器）编译安装：

```sh
# cd /usr/ports/multimedia/audacious/ && make install clean
# cd /usr/ports/multimedia/audacious-plugins/ && make install clean
```

### 使用 Audacious

测试 `.m4a`（MPEG-4 音频容器格式）、`.flac`（无损音频压缩编码）、`.av3a`（AVS3 音频裸码流格式）等音乐格式的兼容性。`.m4a` 为容器格式，可包含多种编码（如 AAC、ALAC 等）；`.av3a` 为裸码流，实际应用中 AVS3 音频也常封装在 MP4 容器中以 `.m4a` 扩展名存储。

> **技巧**
>
> 经测试，在上述格式中 Audacious 默认构建支持 `.flac` 和 `.m4a`（AAC 编码）格式，目前不支持 `.av3a`（AVS3 音频裸码流）等编码格式，须安装相应插件或另行配置。

![Audacious](/files/03GEXrH1xAXQ2kPnB5aG)

## VLC

VLC（最初为 VideoLAN Client）播放器的安装方法可参见本书视频播放器相关章节。FreeBSD 中的 `ffmpeg` 多媒体框架（名称中的“FF”意为“Fast Forward”，“mpeg”指 MPEG 标准）默认构建配置未启用 libuavs3d（AVS3 解码）和 libdavs2（AVS2 解码）支持，本节不再展开重新编译的配置方法。

经过实际测试，在已安装 `ffmpeg` 且编译时启用了 AC-4 解码支持的情况下，VLC 播放器可播放 AC-4 编码的 m4a 格式音频（需注意标准 `ffmpeg` 构建默认未启用 AC-4 解码，需自行打补丁编译）：

![播放 AC-4 编码的 m4a 格式音频](/files/UOwupr6DTtmIX29aWbig)

## 用 MPD 播放 DSD

Music Player Daemon（MPD）是一款音乐播放器守护进程，可运行于服务器或个人计算机上，并通过多种客户端程序进行远程控制。

MPD 的主要功能包括：支持多种音频格式解码、采用客户端—服务器分离架构、提供播放列表管理、支持流媒体传输与跨平台运行。

### 硬件准备

需要准备硬件支持 DSD（直接比特流数字，Direct Stream Digital）格式的声卡或 DAC（数模转换器，Digital-to-Analog Converter），以及一段 DSD 编码的音频文件用于测试。

以下配置说明基于 FreeBSD 14.0 操作系统，外置 DAC 使用海贝 R3 作为示例设备（其他类似声卡的配置方法基本相同），并采用 OSS（开放声音系统，Open Sound System）音频驱动。

### 安装 Music Player Daemon

```sh
# pkg install musicpd
```

或者通过 Ports 源代码编译安装：

```sh
# cd /usr/ports/audio/musicpd/
# make install clean
```

### 硬件设置

当前系统声卡和音频设备状态如下：

```sh
# cat /dev/sndstat
pcm0: <Realtek ALC269 (Analog 2.0+HP/2.0)> (play/rec) default
pcm1: <Intel Cougar Point (HDMI/DP 8ch)> (play)
pcm2: <USB audio> (play)
No devices installed from userspace.
```

本实例使用的是 pcm2 设备，其对应的设备文件路径为 **/dev/dsp2**，下文配置中会使用该路径。

可使用 `sysctl -d dev.pcm.2` 命令查看相关硬件参数的详细含义，摘录关键的三项参数如下：

```sh
dev.pcm.2.bitperfect: bit-perfect playback/recording (0=disable, 1=enable)
dev.pcm.2.play.vchanrate: virtual channel mixing speed/rate
dev.pcm.2.play.vchanmode: vchan format/rate selection: 0=fixed, 1=passthrough, 2=adaptive
```

按照如下所示设置参数（可将这些配置写入 `sysctl.conf` 文件以使配置在系统重启后永久生效）：

```sh
# sysctl dev.pcm.2.bitperfect=1           # 设置声卡 2 为位完美模式
# sysctl dev.pcm.2.play.vchanrate=352800  # 设置声卡 2 播放采样率为 352800 Hz
# sysctl dev.pcm.2.play.vchanmode=1       # 设置声卡 2 播放通道模式为 passthrough
```

参数说明：

* 由于使用的是 OSS 音频驱动，Music Player Daemon 只能采用 DoP（DSD over PCM）传输模式，而 DoP 模式要求启用 bit-perfect 比特完美模式。
* 采样率（vchanrate）：DSD 音频的采样率为 44.1 kHz 的整数倍，因此不应设置为 48 kHz 的整数倍，否则可能产生音频杂音；在硬件条件允许的情况下应设置为尽可能高的数值，此处示例设置为 352.8 kHz。
* `dev.pcm.2.play.vchanmode` 虚拟通道模式参数说明：

| 值 | 模式                | 说明                                 |
| - | ----------------- | ---------------------------------- |
| 0 | fixed（固定模式）       | 音频设备使用固定的采样率和格式处理多路音频流             |
| 1 | passthrough（直通模式） | 音频设备尽可能保持输入音频流的原始采样率和格式，不进行额外的转换处理 |
| 2 | adaptive（自适应模式）   | 音频设备会根据需要自动适配并转换输入音频流的采样率和格式       |

> **技巧**
>
> 可使用 `dmesg` 命令查看内核日志中硬件所支持的可用采样率。播放非 DSD 文件时，将采样率设置为与音频文件本身采样率相同（或其整数倍）较为合适，如此可避免重采样造成的音质损失。采样率并非越高越好，须经多次测试以确定适合当前硬件配置的值。

查看内核消息中与 pcm2 声卡相关的日志：

```sh
# dmesg | grep -i pcm2

pcm2 on uaudio0

# dmesg | grep -i uaudio0

uaudio0 on uhub0
uaudio0: <HiBy R3, class 239/2, rev 2.00/ff.ff, addr 1> on usbus1
uaudio0: Play[0]: 384000 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer. (selected)
uaudio0: Play[0]: 352800 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 192000 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 176400 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 96000 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 88200 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 48000 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 44100 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: Play[0]: 32000 Hz, 2 ch, 32-bit S-LE PCM format, 2x4ms buffer.
uaudio0: No recording.
uaudio0: No MIDI sequencer.
pcm2 on uaudio0
uaudio0: No HID volume keys found.
```

### Music Player Daemon 基本设置

Music Player Daemon（musicpd）的配置文件为 **/usr/local/etc/musicpd.conf**。

其中默认使用的部分目录结构如下：

```sh
/
├── var
│   └── mpd
│       ├── music                     # MPD 音乐存放目录
│       └── .mpd
│           └── playlists            # MPD 播放列表目录
├── usr
│   ├── ports
│   │   └── audio
│   │       └── musicpd              # MPD 音频播放器 Port
│   └── local
│       └── etc
│           └── musicpd.conf          # MPD 配置文件
└── dev
    ├── sndstat                        # 声卡设备状态文件
    └── dsp2                           # 音频设备文件（示例）
```

MPD 默认使用的部分目录需要自行创建：

```sh
# mkdir -p /var/mpd/music            # 创建 MPD 音乐存放目录
# mkdir -p /var/mpd/.mpd/playlists  # 创建 MPD 播放列表目录
# chown -R mpd:mpd /var/mpd  # 用于将目录的所有者设置为 mpd 用户，避免出现权限问题
# chmod 777 /var/mpd/music  # 用于存放音乐文件，设置为 777 仅为方便增删文件，实际使用中可根据需要自行调整权限。
```

修改 **/usr/local/etc/musicpd.conf** 文件，在 `"Default OSS Device"` 一节后面增加一节：

```ini
audio_output {
        type            "oss"
        name            "OSS Device（dop mode）"
        device          "/dev/dsp2"     # 指定使用的设备，无需将 DAC 或声卡等设置为默认设备，dsp2 可专用于音乐播放，默认设备可用于其他用途
        dop             "yes"           # 开启 dop 模式
}
```

> **技巧**
>
> 可指定多个输出设备，并在各类客户端中按需启用或禁用相应的输出设备。

开启 musicpd 服务：

```sh
# service musicpd enable  # 设置 MPD 服务开机自启动
# service musicpd start  # 启动 MPD 服务
```

### 客户端使用

可以使用 ncmpc（字符界面）、MaximumMPD（iPhone）等多种客户端，客户端种类较为丰富。

PC 端的 GUI 客户端建议使用 Cantata（Port **audio/cantata**）。Cantata 原作者已于 2022 年停止开发，但社区 fork（nullobsi/cantata）已接手维护并移植至 Qt6，FreeBSD Ports 中的 `audio/cantata` 已切换至该活跃维护的 fork。

命令行环境下建议安装 ncmpc（Port **audio/ncmpc**），适合用于绑定桌面环境的全局快捷键。


# 14.6 视频播放器

FreeBSD 上主要的视频播放器包括 VLC、SMPlayer 和 Kodi，均支持 pkg 安装。本节另附 mpv 在 TTY 下直接播放视频的配置方法。

## VLC

### 安装 VLC

* 使用 pkg（二进制包管理器）安装：

```sh
# pkg install vlc
```

* 或者使用 Ports（源代码包管理器）编译安装：

```sh
# cd /usr/ports/multimedia/vlc/
# make install clean
```

### 使用 VLC 播放视频

经测试，常用视频格式均能在 VLC 中正常播放。

![VLC 播放器](/files/thZEUYkymzCOGoVOx3kT)

![VLC 视频播放](/files/DJGi4qgBBIenSbX3B8Uo)

## SMPlayer

SMPlayer 是 MPlayer（一款命令行视频播放器）和 mpv 的 Qt 图形前端。

### 安装 SMPlayer

* 使用 pkg 二进制包管理器安装：

```sh
# pkg install smplayer
```

* 或者使用 Ports 源代码编译安装：

```sh
# cd /usr/ports/multimedia/smplayer/
# make install clean
```

### 使用 SMPlayer 播放视频

经测试，常用视频格式均能在 SMPlayer 中正常播放。

![SMPlayer](/files/AZN8UE5HvDexlSmCJHza)

![SMPlayer](/files/q9jRvuXZezHQdogUmKG7)

![SMPlayer](/files/fEp0ll6PueglUsIQWYOy)

## Kodi

Kodi 是一款开源媒体中心软件，其曾用名为 XBMC（Xbox Media Center）。

### 安装 Kodi

* 使用 pkg 二进制包管理器安装：

```sh
# pkg install kodi
```

* 或者使用 Ports 源代码编译安装：

```sh
# cd /usr/ports/multimedia/kodi/
# make install clean
```

### 为 Kodi 设置中文环境

首先打开 Kodi 主界面中的 `interface`（界面）设置选项：

![Kodi 设置界面](/files/7oo2P2rwSMONQprC9f0t)

点击 `Skin`（皮肤）选项，随后点击界面左下角的设置级别按钮，将当前的 `Basic`（简单）级别改为 `Expert`（专家）或 `Standard`（标准）级别，否则无法看到 `Fonts`（字体）等高级设置选项。随后将 `Fonts`（字体）设置为 `Arial based`，否则中文可能显示为乱码。

![Kodi 字体设置界面](/files/m5Cc2guhMm0Po5VEhmaR)

返回上一级菜单后，依次选择 `Regional`（区域）→ `Language`（语言）→ `Chinese (Simplified)`（简体中文）选项以完成语言切换。

![Kodi 语言设置界面](/files/65CDl1k3knH3yHN7r7Bl)

中文界面设置完成后的效果如下：

![Kodi 中文界面](/files/S6xoFjSHCKp2usUPayd7)

### 使用 Kodi 播放视频

经测试，常用视频格式均能在 Kodi 媒体中心中正常播放。

![Kodi 播放视频测试](/files/lDqXrQzERiraL7brMieJ)

## 附录：直接在 TTY 播放视频（mpv）

可直接在 Linux/FreeBSD 的 TTY（电传打字机，Teletypewriter，即纯文本终端）环境中使用 mpv 命令播放视频文件。

* 使用 pkg（二进制包管理器）安装：

```sh
# pkg install mpv
```

* 还可通过 Ports 源代码编译安装：

```sh
# cd /usr/ports/multimedia/mpv/
# make install clean
```

切换到 TTY 终端环境后，使用 mpv 播放器播放视频文件 `1.mp4`：

```sh
$ mpv 1.mp4
```

> **注意**
>
> 此功能依赖 DRM（Direct Rendering Manager，直接渲染管理器）图形子系统，在虚拟机环境中可能无法正常运作。


# 14.7 多媒体处理

FreeBSD 支持 Audacity（音频剪辑）、Kdenlive/FFmpeg（视频与字幕处理）、Inkscape（矢量图形处理）、MuseScore（制谱）、Blender（3D 建模）及 Krita（数字绘画）等工具。本节按类别给出安装与基本使用方法。

## 视频串流与直播录制

### OBS Studio

OBS Studio 是一款自由且开源的视频串流与直播录制软件。

使用 pkg 安装：

```sh
# pkg install obs-studio
```

或者使用 Ports 编译安装：

```sh
# cd /usr/ports/multimedia/obs-studio/
# make install clean
```

调整 OBS Studio 视频输入源：

![OBS Studio](/files/KdZiweovgQWGXJ2j6AAH)

麦克风可自适应，调整后的主界面：

![OBS Studio 主界面](/files/AgXqJ73eo9Mdn8CLgBZn)

## 音频剪辑

### Audacity

Audacity 是一款开源跨平台音频编辑软件。

使用 pkg 安装：

```sh
# pkg install audacity
```

或者使用 Ports 编译安装：

```sh
# cd /usr/ports/audio/audacity/
# make install clean
```

![Audacity](/files/lmVkPQj2sMEmSa49pmNZ)

## 视频剪辑

### Kdenlive

Kdenlive 是一款开源的非线性视频编辑软件。

使用 pkg 安装 Kdenlive：

```sh
# pkg install kdenlive
```

或者使用 Ports 编译安装：

```sh
# cd /usr/ports/multimedia/kdenlive/
# make install clean
```

## 字幕

### FFmpeg

FFmpeg 是一款开源多媒体处理框架，可用于将字幕烧录到视频中。

使用 pkg 安装 FFmpeg：

```sh
# pkg install ffmpeg
```

或者使用 Ports 编译安装：

```sh
# cd /usr/ports/multimedia/ffmpeg/
# make install clean
```

使用 FFmpeg 将 ASS（Advanced SubStation Alpha）格式字幕烧录到视频中的示例命令：

```sh
$ ffmpeg -i 视频文件.mp4 -vf subtitles=对应字幕.ass 输出视频.mp4
```

其中：

* `-i` 指定输入视频文件；
* `-vf subtitles=` 应用字幕滤镜并指定字幕文件路径；
* `输出视频.mp4` 指定了输出视频文件的名称。

![烧录后的字幕](/files/Z1JVG0lyREb1zolPvEYa)

## 抠图

Inkscape 是矢量制图程序，本节介绍基本抠图操作。

### 安装 Inkscape

* 使用 pkg 安装 Inkscape：

```sh
# pkg install inkscape
```

* 或者使用 Ports 源代码编译安装：

```sh
# cd /usr/ports/graphics/inkscape/
# make install clean
```

### Inkscape 基本抠图方法

1. 使用快捷键 `Ctrl` + `O`（字母 `o`）打开待处理的图片文件；
2. 使用快捷键 `Shift` + `F6` 切换到贝塞尔曲线和直线绘制模式；
3. 用贝塞尔曲线沿目标区域边缘绘制封闭路径（回到起始点闭合路径）；
4. 按住 `Shift` 键，依次点击选中图片和封闭路径（路径需位于图片上方）；
5. 在菜单栏中选择 **对象** → **裁剪** → **设置裁剪** 选项，以实现抠图效果。

### 参考文献

* Inkscape. Inkscape Tutorials\[EB/OL]. \[2026-03-25]. <https://inkscape.org/zh-hans/learn/tutorials/>. 提供 Inkscape 矢量绘图软件的详细中文教程，涵盖基础操作与高级功能。

## 音乐

### 制谱软件 MuseScore

MuseScore 是一款开源的音乐制谱软件，支持乐谱创作、编辑和播放。

使用 pkg 安装：

```sh
# pkg install musescore
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/audio/musescore/
# make install clean
```

![MuseScore 界面](/files/AXpbdFWeDYW9HsxHYR1F)

## 三维图像

### 3D 建模 Blender

Blender 是一款开源的 3D 建模和动画制作软件，支持建模、渲染、动画等功能。

使用 pkg 安装：

```sh
# pkg install blender
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/graphics/blender/
# make install clean
```

软件支持简体中文。通过菜单 **Edit** → **Preferences** → **Interface** → **Translation**，在 **Language** 下拉菜单中选择 **Simplified Chinese（简体中文）** 即可切换界面语言。

![Blender 界面](/files/GXSyKFpwgBFHmHwe2CFx)

## 绘画

### Krita

Krita 是一款开源的数字绘画软件，专为插画师和概念艺术家设计。

使用 pkg 安装：

```sh
# pkg install krita
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/graphics/krita/
# make install clean
```

![Krita 界面](/files/0dSquGzvASbLkfIM15BJ)


# 14.8 文档查看器

自 UNIX 问世以来，许多新的文档格式逐渐流行，如 PDF、DjVu、MOBI、AZW3、EPUB 等，而这些格式所需的查看器在基本系统中或许并不存在。本节介绍如何安装文档查看器。

## Calibre 文档管理（PDF、EPUB、MOBI、AZW3 等格式）

Calibre 是电子书管理工具，支持多种电子书格式的阅读、转换和组织，还支持自定义 CSS 样式。

使用 pkg 安装 Calibre：

```sh
# pkg install calibre
```

使用 Ports 安装：

```sh
# cd /usr/ports/deskutils/calibre/
# make install clean
```

Calibre 的主界面如下。

![Calibre 界面](/files/K6aGj05tuWACO5atq6zn)

## Okular

Okular 是一款通用文档查看器，属于 KDE Gear（KDE 应用程序合集），会随 KDE 桌面环境一道安装。Okular 支持多种文档格式，如 PDF、PostScript、DjVu、CHM、XPS、ePub 等。

使用 pkg 安装 Okular：

```sh
# pkg install okular
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/okular/
# make install clean
```

![Okular 界面](/files/L0QNIT4I1wRb5W1DKZMs)

## Evince

Evince 是一款支持 PDF、PostScript 等多种文档格式的文档查看器，属于 GNOME 项目的一部分，会随 GNOME 桌面环境一道安装。

使用 pkg 安装 Evince：

```sh
# pkg install evince
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/evince/
# make install clean
```

![Evince 界面](/files/ePWJ06ZmnRX4KQlE9LmO)

## ePDFView

ePDFView 是一款轻量级的 PDF 文档查看器，仅使用 Gtk+ 和 Poppler 库。ePDFView 的目标是提供简单的 PDF 文档查看器，类似于 Evince，但不使用 GNOME 库。

使用 pkg 安装 ePDFView：

```sh
# pkg install epdfview
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/epdfview/
# make install clean
```

![ePDFView 界面](/files/zas9NHQ8KPCu0DaDvX8E)

## Xpdf

Xpdf 是一款 PDF 查看器。当前 `graphics/xpdf` 已是 `graphics/xpdf4` 的 slave Port，默认依赖 Qt5 工具包，不再是传统的纯 X11 轻量版本，不再适合偏好轻量级应用的用户。

使用 pkg 安装 Xpdf：

```sh
# pkg install xpdf
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/xpdf/
# make install clean
```

![xpdf 界面](/files/OhX7xSZ4Ts643Usu0kWS)

## Zathura

Zathura 是一款高度可定制的文档查看器。它提供简约、节省空间的界面，主要专注于键盘交互。

### PDF 支持（MuPDF 后端）

**zathura-pdf-mupdf** 使用 MuPDF 库作为后端，更加轻量化。

使用 pkg 安装支持 PDF 的 Zathura：

```sh
# pkg install zathura-pdf-mupdf
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/zathura-pdf-mupdf/
# make install clean
```

![zathura-pdf-mupdf 界面](/files/40uUtyR4PkMxDmvepc78)

### PDF 支持（Poppler 后端）

此外，还可以安装使用了 Poppler 库的 **graphics/zathura-pdf-poppler** 作为 PDF 支持的替代选择：

使用 pkg 安装支持 PDF 的 Zathura：

```sh
# pkg install zathura-pdf-poppler
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/zathura-pdf-poppler/
# make install clean
```

![zathura-pdf-poppler 界面](/files/QT4KGaYaqSalDwQTOm1F)

### DjVu 支持

使用 pkg 安装支持 DjVu 的 Zathura：

```sh
# pkg install zathura-djvu
```

使用 Ports 安装：

```sh
# cd /usr/ports/graphics/zathura-djvu/
# make install clean
```

![Zathura DjVu 界面](/files/As1ze6T0qDyBwfoALoy6)


# 14.9 Web 浏览器

本节介绍如何在 FreeBSD 系统上安装和配置一些主流的 Web 浏览器。

## Firefox

Firefox 是一款开源浏览器，具有符合标准的 HTML 渲染引擎、标签页浏览、弹出式窗口拦截、扩展功能、增强的安全性等特点。Firefox 基于 Mozilla 代码库。

### 安装最新版本的 Firefox

* 使用 pkg 安装：

```sh
# pkg install firefox
```

* 或者使用 Ports：

```sh
# cd /usr/ports/www/firefox/
# make install clean
```

![火狐浏览器](/files/kvZfevRqqWiSMpdSKExf)

### 安装 Firefox 扩展支持版本 (ESR)

* 使用 pkg 安装：

```sh
# pkg install firefox-esr
```

* 或者使用 Ports：

```sh
# cd /usr/ports/www/firefox-esr/
# make install clean
```

## Chromium

Chromium 是一个开源浏览器项目，旨在提供更安全、更快速、更稳定的 web 浏览体验。Chromium 具有标签页浏览、弹出式窗口拦截、扩展支持等功能。Chromium 是 Google Chrome 浏览器的开源基石。

Chromium 不同于 Chrome，但是在 FreeBSD 中 Chromium 的启动命令为 `chrome`。

* 使用 pkg 安装 Chromium

```sh
# pkg install chromium
```

* 或者使用 Ports 安装 Chromium

```sh
# cd /usr/ports/www/chromium/
# make install clean
```

> **警告**
>
> 要编译 Chromium，需要至少 8 GB 内存（Release 构建），或等量的交换分区与内存之和。如果启用 LTO 优化则需要 16 GB，如果启用 Debug 构建则需要 32 GB。Chromium 仅支持 amd64 和 aarch64 架构。

## ungoogled-chromium

Chromium 仍保留了对 Google 网络服务和二进制文件的依赖，因此 ungoogled-chromium 项目在此基础上移除了所有与 Google 相关的组件，包括后台请求、域名追踪和预编译二进制文件等。

* 使用 pkg 安装 ungoogled-chromium

```sh
# pkg install ungoogled-chromium
```

* 或者使用 Ports 安装 ungoogled-chromium

```sh
# cd /usr/ports/www/ungoogled-chromium/
# make install clean
```

## Chrome（Linux 兼容层）

Chrome（Linux 兼容层）基于 FreeBSD 的 Linuxulator 运行，需先启用 Linux 二进制兼容层。

* 使用 pkg 安装 Chrome

```sh
# pkg install linux-chrome
```

* 或者使用 Ports 安装 Chrome

```sh
# cd /usr/ports/www/linux-chrome/
# make install clean
```

## 附录：让 Chromium 使用 Google 账号同步

作为开源项目，Chromium 与 Google Chrome 的关系类似于 AOSP 与 Pixel UI 的关系。Chromium 无法直接从 Google Chrome 的在线插件商店下载安装插件，只能手动从本地安装 crx（同步启用后可自动同步浏览器插件）。Chromium 也不自带 Google 翻译插件等功能。更多差异可参见：The Chromium Project. Chromium Browser vs Google Chrome\[EB/OL]. \[2026-03-26]. <https://chromium.googlesource.com/chromium/src/+/main/docs/chromium_browser_vs_google_chrome.md>. 该文档比较了 Chromium 与 Google Chrome 在功能和授权上的差异。

`Chromium` 并非 `Google Chrome`，前者是 The Chromium Project 发布的开源与自由软件，其顶层许可证为 [BSD 3-Clause “New” or “Revised” License](https://github.com/chromium/chromium/blob/main/LICENSE)，同时包含 LGPL 2.1 及 MPL 1.1 等许可的代码；后者是 Google LLC 的专有软件。

在 [Chromium 89](https://archlinux.org/news/chromium-losing-sync-support-in-early-march/) 版本发布前后，Google 限制了对私有同步 API 的访问，各发行版因此移除了之前打包时自带的与 Chrome 相同的默认 API 密钥。该公告说明了此变更的原因与影响。

在开始获取 token 之前，需要先加入以下两个 Google 邮件列表：

* [Google browser sign-in test account](https://groups.google.com/u/0/a/chromium.org/g/google-browser-signin-testaccounts)
* [Chromium-dev](https://groups.google.com/a/chromium.org/g/chromium-dev)

![加入邮件列表](/files/LPfmxDMADZzBdbQNTP0H)

由于仅需 Chrome Google API 的访问权限，必须关闭这两个邮件列表的消息通知（即“不接收电子邮件”），否则将收到大量邮件通知。

![关闭邮件通知](/files/yDOAPXRylBpUKiVgEjMM)

![邮件列表设置](/files/6SofH0p4WapxSL2VgfOT)

加入 Google browser sign-in test account 群组后，会看到“您无权访问此内容”等提示，此属正常现象，无需担心。

![join-mail-list-for-google-api-error2](/files/UQgGSFgbBmS4mRd76Zd0)

在浏览器中打开 [谷歌云控制台网站](https://console.cloud.google.com/)。

> **注意**
>
> 登录控制台时使用的谷歌账户必须与之前加入邮件列表的账户一致。

![谷歌云控制台首页](/files/JiaJ9CqEcW9uGSpCPPpR)

点击左上角的“My First Project”，随后在弹出窗口的右上角选择“新建项目”即可。

![新建项目选项](/files/SqVGHn2mcbofaQggK9Sz)

项目名称可自行填写，组织保持默认设置。

![填写项目信息](/files/7FdP00XG7XQVgiVJRIg5)

点击左上角的“My First Project”，随后在弹出窗口中选择刚才创建的项目（此处为 google-sync）。

![选择项目](/files/c1sSieQeUIWCtvhkJXA5)

点击上图中的“API 和服务”，再点击“+ 启用 API 和服务”

![启用 API 和服务](/files/Sfy7AiEEoIPytXmDenIG)

搜索“chrome-sync”找到下列内容。

![搜索 Chrome Sync](/files/Ys48wjPnnqjdsv2JdZ1e)

点击启用“Chrome Sync API”

![启用 Chrome Sync API](/files/PxIGJ93f2cKJ6rdHLotP)

之后会在已启用的 API 和服务列表中显示下列状态

![已启用 API 列表](/files/YvjM2DRgC3JzfetfBXTb)

选择“OAuth 权限请求页面”：

![OAuth 权限页面](/files/Hy7HDWteDkSaIKBGSJXb)

创建外部应用：

![创建外部应用](/files/QbcdZaWKl7knrvjpt5HU)

![填写应用信息](/files/2yvfraBjvLdgrocDUqDi)

![应用信息填写](/files/v6VNNlFMUmYi3B6d90RG)

![应用详细信息](/files/oOQ3xQhqcpkmFDmc5onC)

创建后如图：

![应用创建完成](/files/zR3aoe4WpZF8M5d1M3o0)

点击“客户端”，创建 OAuth 客户端 ID，应用类型为“桌面应用”：

![创建 OAuth 客户端](/files/Ozi3MSiHiHQayCW57223)

创建后如图：

![OAuth 客户端创建](/files/75J4GSJKXWBzQSuAExcC)

点击创建的“桌面客户端 1”

![查看客户端详情](/files/K6DwStVlgzIlrBEawNyE)

获取以下凭据（此为示例，必须自行生成）：

* 客户端 ID `502882456359-okloi0a7k6vjodss69so97tmqmv0jjj5.apps.googleusercontent.com`
* 客户端密钥 `GoCSPX-iKHEKZmP4w_zdq0Z8nwOqz6SF2_M`

返回“API 和服务”，点击“+ 创建凭据”，再点击“API 密钥”。

![创建 API 密钥](/files/3a40VM3pWoz4MKFNQPMw)

即可获得一个 API 密钥（此为示例，读者必须自行生成）：`AIzaSyDVpYvJQUn9HTjAiD89y3xBDOG3oaxV5_E`

![API 密钥生成](/files/8m2ShbDxJAZ1oCc8qXW8)

打开凭据概览：

![凭据概览](/files/txzZug1kurIOkLTVZI85)

编辑 **\~/.profile** 文件，加入：

```sh
export GOOGLE_API_KEY=AIzaSyDVpYvJQUn9HTjAiD89y3xBDOG3oaxV5_E  # 填写 API 密钥
export GOOGLE_DEFAULT_CLIENT_ID=502882456359-okloi0a7k6vjodss69so97tmqmv0jjj5.apps.googleusercontent.com  # 填写客户端 ID
export GOOGLE_DEFAULT_CLIENT_SECRET=GoCSPX-iKHEKZmP4w_zdq0Z8nwOqz6SF2_M  # 填写客户端密钥
```

> **注意**
>
> 本节仅在默认 shell sh 和 KDE 6 下测试通过。其他环境下的配置欢迎提交反馈。

重启系统，再启动 Chromium。

点击“开启同步功能”：

![开启同步功能](/files/x5TgU3MDo3NdYnwtpF3i)

输入账户：

![输入账户](/files/RcagyRaa3n1qRAyQt2WH)

输入账户密码：

![输入密码](/files/2ggVEJZa4p3nf5EFhVNV)

![登录确认](/files/qDHQw1oo1pUbSmMfmevq)

查看同步情况：

![同步状态](/files/5dW9mXIh5gvAhVHPXpIi)

### 参考文献

* LearningToPi. Chromium Sync - Learning to Pi\[EB/OL]. \[2026-03-25]. <https://www.learningtopi.com/sbc/chromium-sync>. 该教程详细介绍了 Chromium 同步功能的配置步骤。
* 凌莞. 为 Chromium 恢复登录功能\[EB/OL]. \[2026-03-25]. <https://nyac.at/posts/google-sync-in-chromium>. 该文章提供了 Chromium 恢复 Google 账号登录的方法。

## 故障排除与未竟事宜

### 缓解 Chromium 磁盘缓存过大及 GPU 加速异常的问题

将参数添加至启动图标（其本质为文本文件）中：

```sh
chrome --disk-cache-size=0 --disable-gpu
```

> **注意**
>
> `--disk-cache-size=0` 并非禁用磁盘缓存，而是让 Chromium 使用默认计算值。如需限制缓存大小，请指定具体字节数（如 `--disk-cache-size=104857600` 表示 100 MB）。`--disable-gpu` 用于禁用 GPU 硬件加速。


# 15.1 本地化环境变量

本地化环境变量（`LANG`、`LC_*`、`MM_CHARSET`）决定系统界面语言、字符编码与排序规则，本节阐述各场景下的配置方法。

## 本地化环境变量配置文件路径

### 显示管理器配置路径

| 显示管理器            | 配置文件路径           |
| ---------------- | ---------------- |
| SDDM、LightDM、GDM | **\~/.xprofile** |
| LightDM、GDM      | **\~/.profile**  |
| SDDM             | 用户登录 Shell 的配置文件 |

### Shell 配置路径

| Shell | 配置文件路径                                  |
| ----- | --------------------------------------- |
| sh    | **\~/.profile**                         |
| bash  | **\~/.bash\_profile** 或 **\~/.profile** |
| zsh   | **\~/.zprofile**                        |
| csh   | **\~/.cshrc**                           |

## 本地化相关的环境变量

`LC_*` 系列变量是 UNIX 及类 UNIX 操作系统中用于实现国际化（Internationalization，i18n）与本地化（Localization，l10n）的核心环境变量。`LC_COLLATE`、`LC_CTYPE`、`LC_MESSAGES`、`LC_MONETARY`、`LC_NUMERIC`、`LC_TIME` 以及 `LC_ALL` 和 `LANG` 由 POSIX（IEEE Std 1003.1，即 ISO/IEC 9945）标准定义。`LC_ADDRESS`、`LC_NAME`、`LC_PAPER`、`LC_TELEPHONE`、`LC_MEASUREMENT`、`LC_IDENTIFICATION` 为 glibc 的 GNU 扩展（自 glibc 2.2 起引入），ISO/IEC TR 30112:2014（技术报告，已 withdrawn，后由 ISO/IEC 30112:2020 国际标准替代）制定时参考了这些既有实践（参见 Debian manpages. locale(7)\[EB/OL]. \[2026-04-17]. <https://manpages.debian.org/unstable/manpages/locale.7.en.html>）。这些变量控制文本字符编码、日期时间格式、货币符号、界面语言等多个维度的本地化行为。

| 变量                  | 说明                                        |
| ------------------- | ----------------------------------------- |
| `LC_COLLATE`        | 定义字符串排序的规则                                |
| `LC_CTYPE`          | 定义字符集和字符类型判断规则，例如字母、数字、标点符号等              |
| `LC_MONETARY`       | 定义货币格式和货币符号                               |
| `LC_MESSAGES`       | 定义程序运行时输出信息的语言                            |
| `LC_NUMERIC`        | 定义数字格式，例如小数点和千位分隔符                        |
| `LC_TIME`           | 定义日期和时间格式                                 |
| `LC_ADDRESS`        | 定义地址的格式                                   |
| `LC_NAME`           | 定义人名的格式                                   |
| `LC_PAPER`          | 定义默认纸张尺寸                                  |
| `LC_TELEPHONE`      | 定义电话号码的格式                                 |
| `LC_MEASUREMENT`    | 定义度量衡单位的格式（公制或英制）                         |
| `LC_IDENTIFICATION` | 定义 locale 自身的元数据（locale 名称、语言、地域、货币等标识信息） |
| `MM_CHARSET`        | 设置 MIME 字符集，供应用程序在处理多语言内容时确定字符编码          |

### 特殊变量说明

| 变量         | 说明                                                                                                                                                                                                                                                               |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LC_ALL`   | 设置该变量将同时覆盖所有其他 `LC_*` 变量的值                                                                                                                                                                                                                                       |
| `LANG`     | 用于设置默认的语言和字符集，通常在没有其他 `LC_*` 变量设置时提供区域设置信息。如果同时设置了 `LANG` 和 `LC_*` 变量，`LC_*` 变量将覆盖 `LANG` 变量中相应的设置                                                                                                                                                               |
| `LANGUAGE` | 主要用于为 GNU gettext 等本地化库指定界面消息（例如命令行提示、错误信息、菜单文本等）的首选语言。GNU gettext 对 `LANGUAGE` 的优先级高于 `LC_ALL` 和 `LANG`。它一般不会影响日期、数字、货币等格式，这些格式类本地化仍由相应的 `LC_TIME`、`LC_NUMERIC`、`LC_MONETARY` 等 `LC_*` 变量或 `LANG` 控制。如果未设置 `LANGUAGE`，程序通常会回退到 `LC_MESSAGES` 或其他区域设置变量来确定界面消息语言 |

#### 参考文献

* GNU gettext Manual. The LANGUAGE variable\[EB/OL]. \[2026-06-08]. <https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html>.

### 常见配置方案

可通过多种方式实现中文环境：

1. 仅设置 `LC_MESSAGES` 为 `zh_CN.UTF-8` 即可实现中文界面（已在 SDDM/Xfce 环境下验证）
2. 常见做法是将 `LANG`、`LC_ALL`、`LANGUAGE` 三个环境变量均设置为 `zh_CN.UTF-8`
3. 在系统界面保持英文的同时使用中文输入法，仅设置输入法相关变量，其余环境变量保持默认英文设置

不同软件读取本地化变量时的优先级存在差异，因此建议将三个环境变量均设置为 `zh_CN.UTF-8`，以确保语言设置的一致性。

### 不同配置的效果不同

仅设置 `LC_MESSAGES` 时，该设置仅影响界面和提示信息，不影响其他格式的输出。以 sh 为例：

```sh
$ locale	# 显示当前系统的本地化设置
LANG=C.UTF-8
LC_CTYPE="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_TIME="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES=zh_CN.UTF-8
LC_ALL=
$ date	# 显示时间和日期
Fri Apr 21 21:14:43 UTC 2023
$ export LC_TIME=zh_CN.UTF-8
$ date
2023年 4月21日 星期五 21时15分07秒 UTC
```

默认：

* `LC_TIME` 环境变量值为 `C.UTF-8`
* `date` 命令输出 `Fri Apr 21 21:14:43 UTC 2023`
* `LC_TIME` 环境变量的值设置为 `zh_CN.UTF-8`
* `date` 命令输出为 `2023年 4月21日 星期五 21时15分07秒 UTC`

> **注意**
>
> 保持 `date` 命令的英文输出在某些脚本中可能非常重要。其他由 `LC_*` 变量控制的信息也存在类似情况。

## 课后习题

1. 在 FreeBSD 系统中配置不同 Shell（sh、bash、zsh、csh）的本地化环境变量，分别验证 `date` 命令在英文和中文环境下的输出。
2. 构建一个仅设置 `LC_MESSAGES=zh_CN.UTF-8` 的环境，测试常用命令（如 ls、pkg、man）的中文提示可用性。
3. 分析 `LANG`、`LC_ALL` 和各 `LC_*` 变量之间的优先级关系，举例说明在不同设置组合下的实际行为。


# 15.2 特定语言的区域配置

本节阐述在 FreeBSD 系统中配置区域设置的多种方法。

## 使用本地化

本地化设置基于三个组件：语言代码、区域代码和编码。区域设置名称由这些部分构成，如下所示：

```sh
语言代码（小写）_区域代码（大写）.编码
```

**语言代码** 和 **区域代码** 用于确定区域和特定的语言变体。以下是一些 **语言代码\_区域代码** 的示例：

**常见语言和区域代码**

| 语言代码\_区域代码\_编码 | 说明         |
| -------------- | ---------- |
| en\_US.UTF-8   | 美国（英语）     |
| zh\_CN.UTF-8   | 中国（简体中文）   |
| zh\_TW\.UTF-8  | 中国台湾（繁体中文） |
| zh\_HK.UTF-8   | 中国香港（繁体中文） |

键入以下命令可查看完整的可用区域设置列表：

```sh
$ locale -a | more
C
C.UTF-8
POSIX
af_ZA.ISO8859-1
af_ZA.ISO8859-15
af_ZA.UTF-8
am_ET.UTF-8
ar_AE.UTF-8
ar_EG.UTF-8
ar_JO.UTF-8
ar_MA.UTF-8
ar_QA.UTF-8
ar_SA.UTF-8
be_BY.CP1131
be_BY.CP1251
be_BY.ISO8859-5
be_BY.UTF-8
bg_BG.CP1251
bg_BG.UTF-8
ca_AD.ISO8859-1
ca_AD.ISO8859-15
ca_AD.UTF-8
ca_ES.ISO8859-1
ca_ES.ISO8859-15
ca_ES.UTF-8
--More--(byte 314) # 此处按回车键可继续浏览，按 q 键可退出
```

使用 `locale` 命令查看当前系统的本地化设置：

```sh
$ locale
LANG=C.UTF-8
LC_CTYPE="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_TIME="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_ALL=
```

中文或日语等语言无法用 ASCII 字符表示，需要使用宽字符或多字节字符的扩展语言编码，建议使用 **UTF-8**。

> **注意**
>
> FreeBSD 使用的区域编码与 Xorg 兼容。

## 设置登录 shell 的区域设置

区域设置可以在用户的 **\~/.login\_conf** 文件中或用户 shell 的启动文件中配置：**\~/.profile**、**\~/.bashrc** 或 **\~/.cshrc**。

需要设置两个环境变量：

* `LANG`：设置区域设置
* `MM_CHARSET`：设置应用程序使用的 MIME 字符集

除了用户的 shell 配置外，这些变量还需在特定应用程序和 Xorg 的配置中设置。

有两种方法可以设置所需的变量：推荐的方法是通过登录分级，另一种是通过启动文件。

### 登录分级方法

这是推荐的方法，它为每种 shell 设置所需的区域设置和 MIME 字符集环境变量。此设置可由每位用户单独完成，也可由超级用户为所有用户统一配置。

以下是一个最简单的示例，在个人用户的 **\~/.login\_conf** 中为简体中文（UTF-8 编码）设置两个变量：

```ini
me:\
	:charset=UTF-8:\
	:lang=zh_CN.UTF-8:
```

以下是一个用户的 **\~/.login\_conf** 示例，为简体中文 UTF-8 编码设置变量。一些应用程序未能正确处理中文、日文和韩文的区域设置变量，因此需要更多变量以确保其正常运行：

```ini
# 如不使用中国大陆的货币与时间格式，可手动调整对应变量
me:\
	:lang=zh_CN.UTF-8:\
	:setenv=LC_ALL=zh_CN.UTF-8:\
	:charset=UTF-8:
```

> **注意**
>
> 此 `setenv` 与 csh 无关。

另外，超级用户可以为系统上的所有用户配置本地化设置。以下变量可在 **/etc/login.conf** 中配置，用于设置区域和 MIME 字符集：

```ini
语言|账户说明:\
	:charset=MIME 字符集:\
	:lang=区域:\
	:tc=default: # 继承其他默认选项
```

例如，之前提到的简体中文示例在 **/etc/login.conf** 中可配置如下：

```sh
chinese|chinese Users Accounts:\
	:charset=UTF-8:\
	:lang=zh_CN.UTF-8:\
	:tc=default:
```

> **技巧**
>
> 该文件包含了预定义的 *russian* 分级文件。

每次编辑 **/etc/login.conf** 后，需要执行以下命令以重新生成登录能力数据库：

```sh
# cap_mkdb /etc/login.conf
```

> **注意**
>
> 最终用户需要在 **\~/.login\_conf** 上运行 `cap_mkdb` 命令才能使更改生效。

#### 更改登录分级的工具

除了手动编辑 **/etc/login.conf** 外，还可以使用一些工具为新创建的用户设置区域设置。

使用 `vipw` 添加新用户时，可以指定 **chinese** 分级将区域设置为简体中文（UTF-8 编码）：

```ini
用户名:密码:1111:11:chinese:0:0:User Name:/home/user:/bin/sh
```

例如要为用户 ykla 分配 **chinese** 分级，目前未分配任何自定义用户分级：

```ini
ykla:$6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa.g9P
0eZ32UwfByzRKdVnTaO7W.:1001:1001::0:0:User &:/home/ykla:/bin/sh
```

分配后，则为：

```ini
ykla:$6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa.g9P
0eZ32UwfByzRKdVnTaO7W.:1001:1001:chinese:0:0:User &:/home/ykla:/bin/sh
```

使用 `adduser` 添加新用户时，可以为所有新用户预配置默认语言，或为单个用户指定语言。

若所有新用户使用相同的语言（假设为简体中文），可以在 **/etc/adduser.conf** 中设置 `defaultclass=chinese`。

创建用户时如需覆盖此设置，可在以下提示符处输入所需的登录类别：

```sh
Login class [default]:
```

或者在调用 `adduser` 时指定区域设置：

```sh
# adduser -class chinese
Username:
```

如果使用 `pw` 添加新用户 test，则按以下方式指定区域设置：

```sh
# pw useradd test -L chinese
```

要更改既有用户的登录分级，可以使用 `chpass` 或者 `pw usermod`。以 root 调用并提供要编辑的用户名作为参数：

```sh
# chpass ykla
```

```sh
# pw usermod ykla -L chinese
```

验证修改结果：

```sh
# pw usershow ykla
ykla:$6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa.g9P0eZ32UwfByzRKdVnTaO7W.:1001:1001:chinese:0:0:User &:/home/ykla:/bin/sh
```

### Shell 启动文件方法

这种方法不推荐使用，因为每种 shell 都需要手动配置，每个 shell 配置文件和语法各异。例如，要为 `sh` shell 设置简体中文，可以将以下行添加到 **\~/.profile** 文件中，仅为该用户设置 shell。也可以将这些行添加到 **/etc/profile** 或 **/usr/share/skel/dot.profile** 中，为所有用户设置该 shell：

```sh
LANG=zh_CN.UTF-8; export LANG
MM_CHARSET=UTF-8; export MM_CHARSET
```

但 `csh` shell 的配置文件名称和语法不同。以下是在 **\~/.login**、**/etc/csh.login** 或 **/usr/share/skel/dot.login** 中的等效设置：

```sh
setenv LANG zh_CN.UTF-8
setenv MM_CHARSET UTF-8
```

配置 Xorg 的语法也取决于所使用的 shell，情况更为复杂。在 **\~/.xinitrc** 中，`sh` shell 和 `csh` shell 的配置示例如下：

```sh
LANG=zh_CN.UTF-8; export LANG
```

```sh
setenv LANG zh_CN.UTF-8
```

## 控制台设置

VT 控制台默认使用 `xterm` 作为终端类型。

### 字体

FreeBSD VT 控制台原生支持 CJK 字符集（中日韩统一表意文字），加载字体即可显示中文。所需字体格式为 `.fnt`：这是一种二进制字体文件，而非码表加 PNG 图片的集合。

使用命令切换控制台字体为 **test.fnt**（仅当前会话生效，重启后恢复默认字体）：

```sh
$ vidcontrol -f test.fnt
```

FreeBSD 基本系统提供了一款工具，可将 bdf 或 hex 格式转换为 fnt 文件，其中 `-o` 为必选参数：

```sh
$ vtfontcvt [ -h 高度 ] [ -v ] [ -w 宽度 ] -o 输出文件.fnt 字体路径
```

中文字体示例：

![未加入字体的 tty](/files/k7lXAgh6HmulfWQXgItC)

```sh
# 下载 b16 字体文件
fetch https://people.freebsd.org/~emaste/newcons/b16.fnt

# 切换控制台字体为 b16
vidcontrol -f b16.fnt
```

> **技巧**
>
> 如果上述链接失效，请访问 <https://github.com/FreeBSD-Ask/fnt-fonts> 下载字体。

![设置完成后的 tty](/files/cWGatiJF15xPsZwPJehC)

上述命令仅临时生效，如需永久生效，应加入 **/etc/rc.conf** 文件：

```ini
# 设置控制台所有屏幕使用 b16 字体
allscreens_flags="-f /root/b16.fnt"
```

## 键盘布局

键盘布局文件位于 **/usr/share/vt/keymaps/**：

```sh
INDEX.keymaps			il.kbd
am.kbd				is.acc.kbd
be.acc.kbd			is.kbd
be.kbd				it.kbd

……省略一部分输出……

gr.101.acc.kbd			us.emacs.kbd
gr.elot.acc.kbd			us.intl.acc.kbd
gr.kbd				us.kbd
hr.kbd				us.macbook.kbd
hu.101.kbd			us.unix.kbd
hu.102.kbd
```

例如要将当前的布局改为国际美式键盘，在 **/etc/rc.conf** 文件中加入：

```ini
keymap="us.intl.acc"
```

> **技巧**
>
> 在指定 **键盘布局** 时，请勿包含后缀名 **.kbd**。

重启后生效。

要在不重启的情况下测试键盘布局，可以使用 `kbdmap` 命令交互式选择键盘布局：

![使用 kbdmap 选择键盘布局](/files/DnC3AC4NO8Lr6yoD11PN)

## 输入法

**可用输入法** 总结了 FreeBSD Ports 中可用的输入法应用程序。

**Fcitx 5 可用输入法表**

| 语言        | 输入法                                                                                        |
| --------- | ------------------------------------------------------------------------------------------ |
| 简体中文（拼音）  | [chinese/fcitx5-chinese-addons](https://www.freshports.org/chinese/fcitx5-chinese-addons/) |
| 繁体中文（注音）  | [chinese/fcitx5-chewing](https://www.freshports.org/chinese/fcitx5-chewing/)               |
| 繁体中文（注音）  | [chinese/fcitx5-mcbopomofo](https://www.freshports.org/chinese/fcitx5-mcbopomofo/)         |
| 中文（RIME）  | [chinese/fcitx5-rime](https://www.freshports.org/chinese/fcitx5-rime/)                     |
| 中文（形码输入法） | [chinese/fcitx5-table-extra](https://www.freshports.org/chinese/fcitx5-table-extra/)       |
| 日语（Anthy） | [japanese/fcitx5-anthy](https://www.freshports.org/japanese/fcitx5-anthy/)                 |
| 日语（SKK）   | [japanese/fcitx5-skk](https://www.freshports.org/japanese/fcitx5-skk/)                     |
| 日语（SKK）   | [japanese/fcitx5-cskk](https://www.freshports.org/japanese/fcitx5-cskk/)                   |
| 朝鲜语       | [korean/fcitx5-hangul](https://www.freshports.org/korean/fcitx5-hangul/)                   |
| 非中文输入法码表  | [chinese/fcitx5-table-other](https://www.freshports.org/chinese/fcitx5-table-other/)       |

**IBus 可用输入法表**

| 语言        | 输入法                                                                          |
| --------- | ---------------------------------------------------------------------------- |
| 简体中文（拼音）  | [chinese/ibus-libpinyin](https://www.freshports.org/chinese/ibus-libpinyin/) |
| 繁体中文（注音）  | [chinese/ibus-chewing](https://www.freshports.org/chinese/ibus-chewing/)     |
| 中文（RIME）  | [chinese/ibus-rime](https://www.freshports.org/chinese/ibus-rime/)           |
| 日语（Anthy） | [japanese/ibus-anthy](https://www.freshports.org/japanese/ibus-anthy/)       |
| 日语（Mozc）  | [japanese/ibus-mozc](https://www.freshports.org/japanese/ibus-mozc/)         |
| 日语（SKK）   | [japanese/ibus-skk](https://www.freshports.org/japanese/ibus-skk/)           |
| 朝鲜语       | [korean/ibus-hangul](https://www.freshports.org/korean/ibus-hangul/)         |

## 故障排除与未竟事宜

### 如何手动生成中文字体的 fnt 文件

<https://github.com/usonianhorizon/vt-fnt> 提供的方法较为复杂，可生成 bdf 文件，但会出现与文中相同的错误提示。该项目探索了 FreeBSD 控制台字体的生成方法。文中提及的 FontForge 软件提供 Windows 版本，下载地址为 <https://fontforge.org/en-US/downloads/windows-dl/>。

## 参考文献

* FreeBSD Project. rc.conf\[EB/OL]. \[2026-03-25]. <https://man.freebsd.org/cgi/man.cgi?query=rc.conf&sektion=5>. 该手册页详细说明了 rc.conf 系统配置文件的语法与选项。
* Mariusz. vidcontrol font and color via /etc/rc.conf problem\[EB/OL]. \[2026-03-25]. <https://forums.freebsd.org/threads/vidcontrol-font-and-color-via-etc-rc-conf-problem.81696/>. 该讨论帖探讨了控制台字体与颜色配置的相关问题。


# 15.3 Fcitx 输入法框架

输入法框架与具体输入法是两个不同的技术层次，输入法运行依赖框架的支持。

Fcitx 即“小企鹅输入法”，原始英文全称为“Free Chinese Input Toy of X”（X 窗口系统的自由中文输入玩具）。自 Fcitx 4 起，该缩写不再对应单一全称，官方提供了多种释义（如“Flexible Context-aware Input Tool with eXtension”等），以体现 Fcitx 的发展已超越中文输入范畴。

> **技巧**
>
> 视频教程见 FreeBSD 中文社区. 006-FreeBSD 14.2 安装 fcitx5 及其输入法\[EB/OL]. \[2026-04-04]. <https://www.bilibili.com/video/BV13ji2YLE3m>.

> **注意**
>
> 在 FreeBSD-CURRENT 中可能会出现不可预见的问题：Fcitx 5 诊断信息英文乱码，输入法出现汉字显示异常，Qt 环境下无法正常加载输入法。

## 安装 Fcitx5

* 使用 pkg 安装：

```sh
# pkg install fcitx5 fcitx5-qt5 fcitx5-qt6 fcitx5-gtk2 fcitx5-gtk3 fcitx5-gtk4 fcitx5-configtool zh-fcitx5-chinese-addons
```

* 或者使用 Ports 安装（`fcitx5-qt` 与 `fcitx5-gtk` 为带 FLAVOR 的 Ports，每次仅构建对应 Qt 或 GTK 主版本，必要时需分别指定 FLAVOR 构建）：

```sh
# cd /usr/ports/textproc/fcitx5/ && make install clean # 主程序
# cd /usr/ports/textproc/fcitx5-qt/ && make FLAVOR=qt5 install clean  # Qt 5 支持
# cd /usr/ports/textproc/fcitx5-qt/ && make FLAVOR=qt6 install clean  # Qt 6 支持
# cd /usr/ports/textproc/fcitx5-gtk/ && make FLAVOR=gtk2 install clean # GTK 2 支持
# cd /usr/ports/textproc/fcitx5-gtk/ && make FLAVOR=gtk3 install clean # GTK 3 支持
# cd /usr/ports/textproc/fcitx5-gtk/ && make FLAVOR=gtk4 install clean # GTK 4 支持
# cd /usr/ports/textproc/fcitx5-configtool/ && make install clean # fcitx5 的图形配置工具（基于 Qt 6/KF 6）
# cd /usr/ports/chinese/fcitx5-chinese-addons/ && make install clean # 输入法
```

使用 SLiM 显示管理器时，系统会提示无法找到 IBus。

### Fcitx 5 开机启动

安装完成后，设置 Fcitx 5 随系统自动启动。

创建自启动路径。若为其他用户配置，应在该用户的命令行下执行：

```sh
$ mkdir -p ~/.config/autostart/
```

设置 Fcitx 5 开机启动：

```sh
$ cp /usr/local/share/applications/org.fcitx.Fcitx5.desktop ~/.config/autostart/
```

> **注意**
>
> 若使用 KDE Plasma (Wayland) 桌面，参见 KDE 相关章节。

## 配置环境变量

完成自启动设置后，还需配置相应环境变量，确保输入法框架在各应用程序中正常工作。有两种方法可以实现。

### X11

为简体中文 UTF-8 编码设置变量，编辑 **\~/.login\_conf** 文件，加入以下内容：

```ini
me:\
	:lang=zh_CN.UTF-8:\
	:setenv=LC_ALL=zh_CN.UTF-8,GTK_IM_MODULE=fcitx,QT_IM_MODULE=fcitx,XMODIFIERS="@im=fcitx":\
	:charset=UTF-8:
```

编辑后，需要执行以下命令来更新登录能力数据库：

```sh
$ cap_mkdb ~/.login_conf
```

### Wayland

在 Wayland 桌面环境中，推荐同时设置 `QT_IM_MODULES="wayland;fcitx"` 和 `QT_IM_MODULE=fcitx`，这一配置在 X11 桌面上也不会导致问题；`GTK_IM_MODULE` 的设置需视情况而定。

Wayland 提供了输入法相关的协议（`text-input` 和 `input-method`），GTK 3/4 在 Wayland 下可使用 `text-input-v3` 协议与 Fcitx 5 通信，无需依赖 GTK 输入法模块。若设置了 `GTK_IM_MODULE=fcitx`，GTK 3/4 应用会回退到 X11 输入法模块，可能导致候选框与光标位置间距离异常。

因此，不建议设置环境变量 `GTK_IM_MODULE`，建议通过 GTK 配置文件指定输入法模块：

* 在 **\~/.gtkrc-2.0** 中添加 `gtk-im-module="fcitx"`
* 在 **\~/.config/gtk-3.0/settings.ini** 的 `[Settings]` 段中添加 `gtk-im-module=fcitx`
* 在 **\~/.config/gtk-4.0/settings.ini** 的 `[Settings]` 段中添加 `gtk-im-module=fcitx`。

运行在 XWayland 下的程序，输入法由环境变量 `XMODIFIERS='@im=fcitx'` 配置。示例 **\~/.login\_conf** 配置文件如下：

```ini
me:\
	:lang=zh_CN.UTF-8:\
	:setenv=LC_ALL=zh_CN.UTF-8,QT_IM_MODULES="wayland;fcitx",QT_IM_MODULE=fcitx,XMODIFIERS="@im=fcitx":\
	:charset=UTF-8:
```

编辑后，请更新登录能力数据库。

## 安装 RIME 中州韵输入法

除了 Fcitx 自带的中文输入法插件外，还可以安装 RIME 中州韵输入法，这是一个高度可定制的输入法引擎。

* 使用 pkg 安装：

```sh
# pkg install zh-fcitx5-rime zh-rime-essay
```

* 或者使用 Ports 安装：

```sh
# cd /usr/ports/chinese/fcitx5-rime/ && make install clean
# cd /usr/ports/chinese/rime-essay/ && make install clean
```

> **注意**
>
> `chinese/rime-essay` 是必要的，它是 RIME 的共享词汇与语言模型，没有此 Port，RIME 输入法只会显示乱码。

如果 RIME 未自动添加到输入法列表，请手动添加以完成初始化。

普通用户如果配置未生效，请检查 Shell 是否已按教程配置。

## 参考文献

* Microsoft. TSF 管理器\[EB/OL]. \[2026-04-04]. <https://learn.microsoft.com/zh-cn/windows/win32/tsf/text-services-framework>。这种输入法架构关系在 Windows 系统中同样存在，该文档介绍了 Windows 文本服务框架的架构与接口规范。
* 小企鹅输入法 5. 历史\[EB/OL]. \[2026-04-16]. <https://fcitx-im.org/wiki/History/zh-cn>。该页面记录了 Fcitx 从创始至今的发展历程及名称演变。
* Fcitx. Using Fcitx 5 on Wayland\[EB/OL]. \[2026-06-05]. <https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland>。该页面详细说明了 Fcitx 5 在 Wayland 环境下的环境变量配置策略。

## 故障排除与未竟事宜

如果使用 Qt 相关桌面，请先更新基本系统及第三方软件包，再排查故障。

遇到问题，请先运行 Fcitx5 输入法诊断工具，检查配置和环境问题：

```sh
$ fcitx5-diagnose
```

如果出现与 `bash` 相关的提示且无法输出诊断结果，请安装 Bash。

Fcitx 5.x 中未检测到 Fcitx Qt 4 支持模块属于正常现象。


# 15.4 IBus 输入法框架

IBus 即“Intelligent Input Bus”（智能输入总线），是在 Linux 及类 UNIX 系统中广泛应用的输入法框架。

## 安装 IBus 输入法框架

* 使用 pkg 安装：

```sh
# pkg install ibus zh-ibus-libpinyin
```

其中 `zh-ibus-libpinyin` 是智能拼音输入法。

* 或者使用 Ports 安装：

```sh
# cd /usr/ports/textproc/ibus/ && make install clean
# cd /usr/ports/chinese/ibus-libpinyin/ && make install clean
```

可选的输入法包括：

| Port                         | 说明            |
| ---------------------------- | ------------- |
| `chinese/ibus-cangjie`       | 仓颉输入法         |
| `chinese/ibus-chewing`       | 新酷音输入法        |
| `chinese/ibus-rime`          | Rime 输入法引擎    |
| `chinese/ibus-table-chinese` | 包含五笔、仓颉等多种输入法 |

## 配置环境变量

为简体中文 UTF-8 编码设置变量，编辑 **\~/.login\_conf** 文件，加入以下内容：

```ini
me:\
	:lang=zh_CN.UTF-8:\
	:setenv=LC_ALL=zh_CN.UTF-8,LC_COLLATE=zh_CN.UTF-8,LC_CTYPE=zh_CN.UTF-8,LC_MESSAGES=zh_CN.UTF-8,LC_MONETARY=zh_CN.UTF-8,LC_NUMERIC=zh_CN.UTF-8,LC_TIME=zh_CN.UTF-8,XIM=ibus,GTK_IM_MODULE=ibus,QT_IM_MODULE=ibus,XMODIFIERS="@im=ibus",XIM_PROGRAM="ibus-daemon",XIM_ARGS="--daemonize --xim":\
	:charset=UTF-8:
```

其中输入法相关环境变量的含义如下：

| 变量                             | 说明                                                                   |
| ------------------------------ | -------------------------------------------------------------------- |
| `XIM=ibus`                     | 指定 X 输入法（XIM）框架为 IBus                                                |
| `GTK_IM_MODULE=ibus`           | 指定 GTK 应用程序使用 IBus 输入法模块                                             |
| `QT_IM_MODULE=ibus`            | 指定 Qt 应用程序使用 IBus 输入法模块                                              |
| `XMODIFIERS="@im=ibus"`        | 指定 X 应用程序通过 XIM 协议连接 IBus                                            |
| `XIM_PROGRAM="ibus-daemon"`    | 指定 XIM 守护进程的路径                                                       |
| `XIM_ARGS="--daemonize --xim"` | 指定 ibus-daemon 的启动参数，`--daemonize` 表示以后台守护进程模式运行，`--xim` 表示启用 XIM 支持 |

编辑后，需要执行以下命令来更新登录能力数据库：

```sh
$ cap_mkdb ~/.login_conf
```

### Wayland

在 Wayland 下，IBus 的环境变量配置与 X11 有所不同。GNOME 自 3.6 起已集成 IBus，在 GNOME Wayland 下无需手动设置 `GTK_IM_MODULE` 和 `QT_IM_MODULE`。对于其他桌面环境，`GTK_IM_MODULE` 和 `QT_IM_MODULE` 的设置策略与 Fcitx 5 类似（参见 15.3 节 Wayland 部分）。`XIM_PROGRAM` 和 `XIM_ARGS` 仅用于 X11/XWayland 环境，在纯 Wayland 会话中不需要。

## 配置 IBus

完成环境变量配置后，通过以下方式设置 IBus。

IBus 设置工具：

```sh
$ ibus-setup
```

![IBus](/files/jyS9ApffxgzMY4jJbyG7)

## UTF-8 编码

IBus 要求使用 UTF-8 编码，但对区域设置的具体取值（如 `C.UTF-8` 或 `zh_CN.UTF-8`）并无限制。

![IBus](/files/kxesC1Wllumce7Qw4b3g)


# 15.5 五笔输入法

五笔输入法是中文输入领域中一种常用的形码输入方法。FreeBSD 可通过 IBus + Rime 或 Fcitx 5 + 五笔拼音两种组合实现五笔支持。

## IBus 输入法框架

需要先安装并配置 IBus，本节不做详细说明。

### 安装 Rime 输入法

在 IBus 框架下，通过安装 Rime 输入法来使用五笔输入法。

* 使用 pkg 安装：

```sh
# pkg install zh-ibus-rime
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/chinese/ibus-rime/
# make install clean
```

在终端运行初始化命令 `ibus-setup` 添加 `rime` 输入法：

![添加 Rime 输入法](/files/QsKgolEKUIDTwk26iExf)

### 配置 Rime 输入法

安装完成后，配置 Rime 输入法以使用五笔输入法。

将 98 五笔码表（`free-bsd-98wubi-tables-master/wubi98.dict.yaml` 和 `free-bsd-98wubi-tables-master/wubi98.schema.yaml`）复制到 **/usr/local/share/rime-data** 目录。98 五笔码表下载地址：[FreeBSD-98wubi-tables](https://github.com/FreeBSD-Ask/98-input)。该仓库提供了适用于 FreeBSD 的 98 五笔输入法码表文件。

配置文件结构：

```sh
/usr/local/share/
└── rime-data/
    └── default.yaml # Rime 默认配置文件（系统级）
```

编辑用户级配置文件 **\~/.config/ibus/rime/default.custom.yaml**（IBus）或 **\~/.local/share/fcitx5/rime/default.custom.yaml**（Fcitx 5）。写入以下内容：

```yaml
patch:
  schema_list:
    - schema: wubi98
```

> **说明**
>
> `default.custom.yaml` 是 Rime 的用户级补丁文件，通过 `patch` 机制覆盖系统级 `default.yaml` 中的对应配置项，无需直接修改系统文件。重新部署 Rime 输入法即可生效。

保存后退出。重新部署 Rime 输入法即可。

![配置 Rime 输入法](/files/MbVEnQ0mdo4W5t1y9vjS)

![Rime 配置界面](/files/W6QFP7iAsDPJi7bqTIS9)

## Fcitx 5

除了 IBus 外，也可在 Fcitx 5 输入法框架下使用五笔输入法。

### 安装 Fcitx 5

```sh
# pkg install fcitx5 fcitx5-qt5 fcitx5-qt6 fcitx5-gtk2 fcitx5-gtk3 fcitx5-gtk4 fcitx5-configtool zh-fcitx5-chinese-addons
```

Fcitx 5 的具体配置步骤本节不做详细说明。

### Fcitx 5 配置 98 五笔

在 Fcitx 5 框架下配置 98 五笔输入法，步骤如下：

下载所需文件，地址为 <https://github.com/FreeBSD-Ask/98-input>。

* 将 `98五笔/98wbx.conf` 文件复制到 **/usr/local/share/fcitx5/inputmethod/** 目录下；
* 将 `98五笔/fcitx-98wubi.png` 和 `org.fcitx.Fcitx5.fcitx-98wubi.png` 图标复制到 **/usr/local/share/icons/hicolor/48x48/apps/** 目录下；
* 将 `98五笔/98wbx.main.dict` 词库放置到 **/usr/local/share/libime/** 目录下。
* 重启 fcitx5，在设置中启用 98 五笔即可。

相关文件结构：

```sh
/usr/local/share/
├── fcitx5/
│   └── inputmethod/
│       └── 98wbx.conf # Fcitx5 98 五笔配置文件
├── icons/
│   └── hicolor/
│       └── 48x48/
│           └── apps/
│               ├── fcitx-98wubi.png # 98 五笔图标
│               └── org.fcitx.Fcitx5.fcitx-98wubi.png # 98 五笔图标
└── libime/
    └── 98wbx.main.dict # 98 五笔词库
```

![Fcitx 5 配置界面](/files/LGlp2vjJZFlAoSka557F)

![Fcitx 5 输入法设置](/files/tPgqBWU67n6XextZS25N)

#### 附录：王码 98 五笔生成 `.dict` 库方法

使用 libime 工具将 `98wbx.txt` 转换为 `98wbx.main.dict` 字典文件：

```sh
$ libime_tabledict 98wbx.txt 98wbx.main.dict
```

## 配置 Rime 使用 86 五笔

安装并配置 Fcitx 5，配置步骤从略。

使用 pkg 安装：

```sh
# pkg install zh-fcitx5-rime zh-rime-essay zh-rime-wubi
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/chinese/rime-wubi/ && make install clean
# cd /usr/ports/chinese/fcitx5-rime/ && make install clean
# cd /usr/ports/chinese/rime-essay/ && make install clean
```

添加 Rime 输入法的方法同上。

编辑用户级配置文件 **default.custom.yaml**（若不存在则新建），写入以下内容：

```yaml
patch:
  schema_list:
    - schema: wubi86
```

## 配置文件

五笔输入法安装完成后，Rime 的配置文件位置如下：

* IBus 下 Rime 配置文件路径

```sh
$ cd ~/.config/ibus/rime
```

* Fcitx 5 下 Rime 配置文件路径

```sh
$ cd ~/.local/share/fcitx5/rime
```

相关文件结构：

```sh
~/
├── .config/
│   └── ibus/
│       └── rime/ # IBus 下 Rime 配置文件目录
│           └── build/
│               └── ibus_rime.yaml # IBus Rime 配置文件
└── .local/
    └── share/
        └── fcitx5/
            └── rime/ # Fcitx 5 下 Rime 配置文件目录
```

### 修改候选字每页显示 9 列

先切换到上述配置文件目录，再执行下列操作。

#### 方法 ①

使用 `rime_patch` 工具为默认 Rime 输入法生成菜单：

```sh
$ rime_patch default menu
page_size: 9 # 输入后回车
^D # 按 ctrl+D
patch applied.
```

其中：

* `default` 对应 `default.custom.yaml` 文件
* `menu` 对应一级选项，`page_size` 对应二级选项

重启。

#### 方法 ②

使用 `rime_patch` 工具为默认 Rime 输入法生成带分页大小设置的菜单：

```sh
$ rime_patch default menu/page_size
9 # 输入后回车
^D # 按 ctrl+D
patch applied.
```

重启。

推荐使用方法二设置；方法一在复杂场景下需对配置文件格式有一定了解。

### 默认英文输出

使用 `rime_patch` 工具重置 wubi86 输入法的第一个开关（ascii\_mode）配置：

```sh
$ rime_patch wubi86 'switches/@0/reset'
1
^D
patch applied.
```

此处将 patch 应用于 wubi86 输入法（写入 `wubi86.custom.yaml` 文件），大部分选项与输入法相关，少部分选项为全局设置（写入 `default.custom.yaml` 文件）。

重启。

### IBus 横排输出

编辑 **\~/.config/ibus/rime/ibus\_rime.custom.yaml** 文件，写入以下内容，重新部署输入法或重启：

```yaml
patch:
  style/horizontal: true
```

![IBus 横排设置](/files/tIYjhTicwZlXMEUAhDik)

## 故障排除

直接修改系统级文件（如 **/usr/local/share/rime-data/default.yaml**）会影响全局设置且系统更新时容易被覆盖，建议始终通过用户级配置文件（`default.custom.yaml`）进行定制。

## 参考文献

* Rime Project. CustomizationGuide\[EB/OL]. \[2026-03-25]. <https://github.com/rime/home/wiki/CustomizationGuide>. 该指南阐述了 Rime 输入法的定制方法与技巧。
* catfishjones. 请问 ibus-rime 如何设置输入框横排显示\[EB/OL]. \[2026-03-25]. <https://github.com/rime/ibus-rime/issues/52>. 该 Issue 提供了 ibus-rime 横排显示的配置方案。
* LEOYoon-Tsaw. Rime\_collections/Rime\_description.md\[EB/OL]. \[2026-03-25]. <https://github.com/LEOYoon-Tsaw/Rime_collections/blob/master/Rime_description.md>. 该文档详细介绍了 Rime 输入法的配置格式与选项。


# 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**。

3. **引导加载程序阶段（Boot Loader）**：FreeBSD 的引导加载程序分为四个阶段（在 BIOS 模式下为 `boot0`/`boot1`/`boot2`/`loader`，在 UEFI 模式下为 `loader.efi`）。其中 `boot0` 为阶段 0（引导管理器），`boot1` 和 `boot2` 为阶段 1 和阶段 2，`loader` 为阶段 3。最终阶段的 loader(8) 是一个交互式引导加载程序，它读取 **/boot/loader.conf** 配置文件，加载内核和模块，随后将控制权转移给内核。
4. **内核初始化阶段**：内核加载后，首先探测硬件并初始化设备，此后挂载根文件系统，启动 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 独立设置，不影响宿主系统。

5. **用户空间初始化阶段**：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 和多个操作系统，启动时将显示类似以下消息：

```sh
F1 Win
F2 FreeBSD

Default: F2
```

#### 参考文献

* FreeBSD Project. boot0 MBR 引导代码\[EB/OL]. \[2026-04-28]. <https://github.com/freebsd/freebsd-src/blob/main/stand/i386/boot0/boot0.S>. 该文件包含 MBR 引导扇区的实现，末两字节为 0x55AA 签名。

### 阶段 1 和阶段 2

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

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

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

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

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

```sh
>> FreeBSD/i386 BOOT
Default: 0:ada(0,a)/boot/loader
boot:
```

### 阶段 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 variable`、`set variable=value` | 设置指定的环境变量。                                                  |
| `unload`                            | 移除所有已加载的模块。                                                 |

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

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

```sh
boot -s
```

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

```sh
unload
load /路径1/路径2/内核文件
```

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

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

```sh
unload
set kernel="内核名称"
boot-conf
```

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

```sh
load -t 脚本 /boot/kernel.conf
```

### 最后阶段

内核经 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` 进入单用户模式。进入单用户模式后将显示以下内容：

```sh
Enter full pathname of shell or RETURN for /bin/sh:
```

如果用户按回车键，系统将进入默认的 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) 相关的文件结构如下：

```sh
/
└── boot/ 操作系统引导过程中使用的程序和配置文件
     ├── loader.conf 用户定义设置
     ├── loader.conf.lua 使用 Lua 编写的用户定义设置（默认不存在）
     ├── loader.conf.d/ 用户定义设置的子目录（默认为空）
     │    ├── *.conf 拆分成多个文件的用户定义设置（默认不存在）
     │    └── *.lua 使用 Lua 编写并拆分成多个文件的用户定义设置（默认不存在）
     ├── loader.conf.local 机器特定设置，可覆盖其他配置文件中的设置（默认不存在）
     └── defaults/ 存放默认引导配置文件
          └── loader.conf 默认设置文件（请勿直接修改），参见 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 为例）：

```ini
kern.geom.label.disk_ident.enable="0"     # 禁用 disk_ident 标签，形如 /dev/diskid/DISK-S3Z4NB0K123456（硬件序列号）
kern.geom.label.gptid.enable="0"     # 禁用基于 GPT UUID 生成的设备名，形如 /dev/gptid/3f6c3a3e-4bcb-11ee-8e6d-001b217e6c8a
zfs_enable="YES"     # 默认加载 zfs 模块
```

该文件由 bsdinstall(8) 安装程序在系统安装过程中自动写入。具体而言，[usr.sbin/bsdinstall/scripts/zfsboot](https://github.com/freebsd/freebsd-src/blob/e6d579be42550f366cc85188b15c6eb0cad27367/usr.sbin/bsdinstall/scripts/zfsboot#L1385) 脚本会分别写入 `kern.geom.label.disk_ident.enable="0"`、`kern.geom.label.gptid.enable="0"` 和 `zfs_enable="YES"` 这三行配置。因此在使用 ZFS 标准安装方案的系统中，这三行即是 **/boot/loader.conf** 文件的全部初始内容。

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

默认配置文件位于源代码中的 [stand/defaults/loader.conf](https://github.com/freebsd/freebsd-src/blob/main/stand/defaults/loader.conf)。以下内容基于版本 [loader.conf.5: “console” setting does not document multi-value possibility](https://github.com/freebsd/freebsd-src/commit/240c614d48cb0484bfe7876decdf6bbdcc99ba73)：

```ini
# 这是 loader.conf —— 一个包含许多实用变量的文件
# 可通过设置这些变量来改变系统的默认加载行为。
# 不应直接编辑此文件！
# 请把任何要覆盖的设置放入 loader_conf_files 中的某个文件里
# 这样以后更新这些默认值时，就不会影响原生配置信息。

#
# 所有参数都必须使用双引号。
#

###  基础配置选项  ############################
# 执行命令，在屏幕上打印“Loading /boot/defaults/loader.conf”这句话
exec="echo Loading /boot/defaults/loader.conf"     # （正在加载 /boot/defaults/loader.conf）

# 内核设置
kernel="kernel"		# /boot 子目录，包含内核和模块。
bootfile="kernel"	# 内核名称（可以是绝对路径）
kernel_options=""	# 传递给内核的标志

# 引导启动器配置文件配置
loader_conf_files="/boot/device.hints /boot/loader.conf"   # loader 默认读取的配置文件列表
loader_conf_dirs="/boot/loader.conf.d"                     # loader 读取的配置目录，将加载该目录中的 *.conf 和 *.lua 文件
local_loader_conf_files="/boot/loader.conf.local"          # 本机专用配置文件，可覆盖其他配置文件中的设置
nextboot_conf="/boot/nextboot.conf"                        # 下一次启动使用的临时配置文件
verbose_loading="NO"		# 设置为 YES 将启用详细的引导输出

###  启动画面配置  ############################
# 启动 Logo 设置
splash_bmp_load="NO"		# 设置为 YES 将启用 bmp 启动画面
splash_pcx_load="NO"		# 设置为 YES 将启用 pcx 启动画面
splash_txt_load="NO"		# 设置为 YES 将启用 TheDraw 启动画面
vesa_load="NO"			# 设置为 YES 将加载 vesa 模块
bitmap_load="NO"		# 如需使用启动画面，请设置为 YES
bitmap_name="splash.bmp"	# 设置为文件名
bitmap_type="splash_image_data" # 并将其放在 module_path 中
splash="/boot/images/freebsd-logo-rev.png"  # 再设置 boot_mute=YES 将加载它

###  屏幕保护模块  ###################################
# 建议在 rc.conf 中设置这些屏保
screensave_load="NO"		# 设置为 YES 将加载屏幕保护程序模块
screensave_name="green_saver"	# 设置要使用的屏幕保护程序模块名称

###  早期 hostid 配置 ############################
# 这台机器的唯一标识
hostuuid_load="YES"        # 设置为 YES 以加载 hostuuid 模块
hostuuid_name="/etc/hostid" # 指定 hostid 文件路径
hostuuid_type="hostuuid"   # 指定模块类型为 hostuuid

###  随机数生成配置  ##################
# 适用于密码模块，随机数生成
# 参见 rc.conf(5)。rc.conf 中 entropy_boot_file 配置变量必须与下面的设置相同
# rc.conf 中的 entropy_boot_file 和 loader.conf 中的 entropy_cache_name 必须指定同一个文件
entropy_cache_load="YES"		# 设置为 NO 将禁用在启动时加载缓存的熵
entropy_cache_name="/boot/entropy"	# 设置为该文件的名称
entropy_cache_type="boot_entropy_cache"	# 内核查找启动时熵缓存所必需的类型。即使上面的 _name 发生变化，这个值也绝不能改变！
entropy_efi_seed="YES"			# 设置为 NO 将禁用从 UEFI 硬件随机数生成器 API 加载熵
entropy_efi_seed_size="2048"		# 设置为其他值以改变从 EFI 请求的熵数量


###  内存黑名单配置  ############################
# 屏蔽坏内存地址用，适用于服务器
ram_blacklist_load="NO"			# 设置为 YES 可加载一个文件，该文件包含需要从运行系统中排除的地址列表
ram_blacklist_name="/boot/blacklist.txt" # 设置为该文件的名称
ram_blacklist_type="ram_blacklist"	# 内核查找黑名单模块所必需的类型

###  微码加载配置  ########################
# 处理器微码配置
cpu_microcode_load="NO"			# 设置为 YES 以在启动时加载并应用微码更新文件
cpu_microcode_name="/boot/firmware/ucode.bin" # 设置为微码更新文件路径
cpu_microcode_type="cpu_microcode"	# 内核查找微码更新文件所必需的类型

###  ACPI 设置  ##########################################
acpi_dsdt_load="NO"		# DSDT 覆盖
acpi_dsdt_type="acpi_dsdt"	# 请勿修改此项
acpi_dsdt_name="/boot/acpi_dsdt.aml"     # 使用此文件覆盖 BIOS 中的 DSDT
acpi_video_load="NO"		# ACPI 视频扩展驱动

###  审计设置  #########################################
# 安全审计系统的事件定义预加载配置
audit_event_load="NO"		# 设置为 YES 将在启动早期预加载 audit_event 配置文件
audit_event_name="/etc/security/audit_event" # 指定 audit_event 配置文件路径
audit_event_type="etc_security_audit_event"  # 内核查找并识别该配置文件所需的类型

### 初始内存磁盘设置 ###########################
# 内存盘设置
#mdroot_load="YES"		# “mdroot”前缀可任意修改
#mdroot_type="md_image"		# 在启动时创建 md(4) 内存磁盘
#mdroot_name="/boot/root.img"	# 指向包含磁盘镜像的文件路径
#rootdev="ufs:/dev/md0"		# 将根文件系统设置为 md(4) 设备

###  引导设置  ########################################
#loader_delay="3"		# 在加载任何内容前延迟的秒数。默认未设置且禁用（无延迟）
#autoboot_delay="10"		# 自动启动前延迟的秒数，-1 表示禁止用户中断，NO 表示禁用
#print_delay="1000000"		# loader 消息的慢速打印，便于调试。单位为微秒（1000000 微秒 = 1 秒）
#password=""			# 修改启动选项的密码，避免修改启动选项
#bootlock_password=""		# 设置启动锁定密码，避免未授权启动（参见 loader.conf(5)）
#geom_eli_passphrase_prompt="NO" # 是否提示：输入 geli(8) 密码来挂载根文件系统
bootenv_autolist="YES"		# 自动填充 ZFS 启动环境列表
#beastie_disable="NO"		# 是否启用 Beastie（小恶魔）启动菜单
efi_max_resolution="1x1"	# 设置 EFI 引导下使用的最大分辨率：可选 480p、720p、1080p、1440p、2160p/4k、5k；自定义宽 x 高（例如 1920x1080）
#kernels="kernel kernel.old"	        # 在启动菜单中显示的内核列表
kernels_autodetect="YES"	        # 自动检测 /boot 中的内核目录
#loader_gfx="YES"		        # 当图形可用时使用图形界面
#loader_logo="orbbw"		        # 可选启动 Logo 有：orbbw、orb、fbsdbw、beastiebw、beastie、none
#comconsole_speed="115200"	        # 设置当前串口控制台速率
#console="vidconsole"		        # 以逗号（,）或空格（ ）分隔的控制台列表
#currdev="disk1s1a"		        # 设置当前设备
module_path="/boot/modules;/boot/firmware;/boot/dtb;/boot/dtb/overlays"  # 设置模块搜索路径
module_blacklist="drm drm2 radeonkms i915kms amdgpu if_iwlwifi if_rtw88 if_rtw89"  # 引导器模块黑名单
module_blacklist="${module_blacklist} nvidia nvidia-drm nvidia-modeset"        # 追加黑名单模块
#prompt="\\${interpret}"		        # 设置 loader 命令提示符
#root_disk_unit="0"		        # 强制设置根磁盘单元号
#rootdev="disk1s1a"		        # 设置根文件系统
#dumpdev="disk1s1b"		        # 在启动早期设置 dump 设备
#tftp.blksize="1428"		        # 设置 RFC 2348 TFTP 块大小。若 TFTP 服务器不支持 RFC 2348，则块大小为 512 有效值范围：(8,9007)
#twiddle_divisor="16"		        # 减慢进度指示器 < 16 < 加快进度指示器

###  内核设置  ########################################
# 以下 boot_ 变量通过赋值来启用
# 它们在内核环境中存在（参见 kenv(1)）时，效果与设置对应的启动标志相同（参见 boot(8)）。
#boot_askname=""	# -a：提示用户输入根设备名称
#boot_cdrom=""		# -C：尝试从 CD-ROM 光学介质挂载根文件系统
#boot_ddb=""		# -d：指示内核通过 DDB 调试器模式启动
#boot_dfltroot=""	# -r：使用静态配置的根文件系统
#boot_gdb=""		# -g：为内核调试器选择 gdb-remote 模式
#boot_multicons=""	# -D：使用多个控制台
#boot_mute=""		# -m：静默控制台
#boot_pause=""		# -p：在设备探测时每行暂停
#boot_serial=""		# -h：使用串口控制台
#boot_single=""		# -s：以单用户模式启动系统
#boot_verbose=""	# -v：打印额外调试信息
#init_path="/sbin/init:/sbin/oinit:/sbin/init.bak:/rescue/init"     # 设置 init 的候选路径列表
#init_shell="/bin/sh"	# init(8) 使用的 shell 二进制文件
#init_script=""		# init(8) 在 chroot 前运行的初始脚本
#init_chroot=""		# init(8) 要 chroot 的目录

###  内核可调参数  ########################################
#hw.physmem="1G"		# 限制物理内存大小（loader(8)）
#kern.dfldsiz=""		# 设置初始数据段大小限制
#kern.dflssiz=""		# 设置初始栈大小限制
#kern.hz="100"			# 设置内核时间间隔定时器频率
#kern.maxbcache=""		# 设置最大缓冲区缓存 KVA 存储
#kern.maxdsiz=""		# 设置最大数据段大小
#kern.maxfiles=""		# 设置系统全局最大打开文件数
#kern.maxproc=""		# 设置最大进程数
#kern.maxssiz=""		# 设置最大栈大小
#kern.maxswzone=""		# 设置最大交换元 KVA 存储
#kern.maxtsiz=""		# 设置最大文本段大小
#kern.maxusers="32"		# 设置各种静态表的大小
#kern.msgbufsize="65536"	# 设置内核消息缓冲区大小
#kern.nbuf=""			# 设置缓冲区头数量
#kern.ncallout=""		# 设置最大定时器事件数量
#kern.ngroups="1023"		# 设置最大附加组数
#kern.sgrowsiz=""		# 设置栈增长量
#kern.cam.boot_delay="10000"	# 根挂载时 CAM 总线注册延迟（毫秒），当 USB 设备作为根分区时有用
#kern.cam.scsi_delay="2000"	# 扫描 SCSI 前的延迟（毫秒）
#kern.ipc.maxsockets=""		# 设置最大可用套接字数量
#kern.ipc.nmbclusters=""	# 设置 mbuf 集群数量
#kern.ipc.nsfbufs=""		# 设置 sendfile(2) 缓冲区数量
#net.inet.tcp.tcbhashsize=""	# 设置 TCBHASHSIZE 值（TCP 控制块哈希表的大小）
#vfs.root.mountfrom=""		# 指定根分区
#vm.kmem_size=""		# 设置内核内存大小（字节）
#debug.kdb.break_to_debugger="0" # 允许控制台进入调试器
#debug.ktr.cpumask="0xf"	# 启用 KTR 的 CPU 位掩码
#debug.ktr.mask="0x1200"	# 启用的 KTR 事件位掩码
#debug.ktr.verbose="1"		# 启用 KTR 事件的控制台输出

### 模块加载语法示例  ##########################
#module_load="YES"		# 加载模块 "module"
#module_name="realname"		# 使用 "realname" 替代 "module"
#module_type="type"		# 加载时传递 "-t type"
#module_flags="flags"		# 传递 "flags" 给模块
#module_before="cmd"		# 在加载模块前执行 "cmd" 命令
#module_after="cmd"		# 在加载模块后执行 "cmd"
#module_error="cmd"		# 模块加载失败时执行 "cmd"

### 固件名称映射列表
# 在加载网卡驱动时内核会寻找对应的固件文件
iwm3160fw_type="firmware"   # iwm3160 固件类型
iwm7260fw_type="firmware"   # iwm7260 固件类型
iwm7265fw_type="firmware"   # iwm7265 固件类型
iwm8265fw_type="firmware"   # iwm8265 固件类型
iwm9260fw_type="firmware"   # iwm9260 固件类型
iwm3168fw_type="firmware"   # iwm3168 固件类型
iwm7265Dfw_type="firmware"  # iwm7265D 固件类型
iwm8000Cfw_type="firmware"  # iwm8000C 固件类型
iwm9000fw_type="firmware"   # iwm9000 固件类型
```

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

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

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

```ini
autoboot_delay="2"
```

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

## 精简启动输出信息

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

```sh
# echo boot_mute="YES"  >> /boot/loader.conf # 静默启动并显示 Logo
# echo debug.acpi.disabled="thermal" >> /boot/loader.conf # 屏蔽可能存在的 ACPI 报错
# sysrc rc_startmsgs="NO" # 关闭进程启动信息
# sysrc dhclient_flags="-q" # 安静输出
# sysrc background_dhclient="YES" # 后台 DHCP
# sysrc synchronous_dhclient="YES" # 启动时同步 DHCP
# sysrc defaultroute_delay="0" # 立即添加默认路由
# sysrc defaultroute_carrier_delay="1" # 等待载波的时间为 1 秒
```

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

![FreeBSD 启动 Logo](/files/o8iO5VVZ2w6WwVXcxLbr)

### 参考文献

* vermaden. FreeBSD Desktop – Part 1 – Simplified Boot\[EB/OL]. (2018-03-29)\[2026-03-26]. <https://vermaden.wordpress.com/2018/03/29/freebsd-desktop-part-1-simplified-boot/>. 介绍 FreeBSD 引导加载程序的精简配置方法与启动优化实践。
* FreeBSD Project. loader(8)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=loader&sektion=8>. 系统引导加载程序手册页。
* FreeBSD Project. bsdinstall(8)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=bsdinstall&sektion=8>. FreeBSD 安装程序手册页。

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

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

## 使用 bsdconfig 配置屏幕保护程序

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

```sh
# bsdconfig
```

执行命令后，将显示如下界面：

```sh
┌---------------------┤System Console Screen Saver├---------------------┐
│ By default, the console driver will not attempt to do anything        │
│ special with your screen when it's idle.  If you expect to leave your │
│ monitor switched on and idle for long periods of time then you should │
│ probably enable one of these screen savers to prevent burn-in.        │
│ ┌-------------------------------------------------------------------┐ │
│ │   1 None    Disable the screensaver                               │ │
│ │   2 Blank   Blank screen                                          │ │
│ │   3 Beastie "BSD Daemon" animated screen saver (graphics)         │ │
│ │   4 Daemon  "BSD Daemon" animated screen saver (text)             │ │
│ │   5 Dragon  Dragon screensaver (graphics)                         │ │
│ │   6 Fade    Fade out effect screen saver                          │ │
│ │   7 Fire    Flames effect screen saver                            │ │
│ │   8 Green   "Green" power saving mode (if supported by monitor)   │ │
│ │   9 Logo    FreeBSD "logo" animated screen saver (graphics)       │ │
│ │   a Rain    Rain drops screen saver                               │ │
│ │   b Snake   Draw a FreeBSD "snake" on your screen                 │ │
│ │   c Star    A "twinkling stars" effect                            │ │
│ │   d Warp    A "stars warping" effect                              │ │
│ │   Timeout   Set the screen saver timeout interval                 │ │
│ ┌-------------------------------------------------------------------┐ │
├-----------------------------------------------------------------------┤
│                         [  OK  ]     [Cancel]                         │
└----------------- Choose a nifty-looking screen saver -----------------┘
```

| 菜单                                                          | 说明                                 |
| ----------------------------------------------------------- | ---------------------------------- |
| 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** 文件，添加以下配置：

```ini
saver="beastie" # 选择屏保样式
blanktime="300" # 屏幕超时时间
```

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

```sh
# ls /boot/kernel/*saver*
/boot/kernel/beastie_saver.ko	/boot/kernel/fire_saver.ko	/boot/kernel/snake_saver.ko
/boot/kernel/blank_saver.ko	/boot/kernel/green_saver.ko	/boot/kernel/star_saver.ko
/boot/kernel/daemon_saver.ko	/boot/kernel/logo_saver.ko	/boot/kernel/warp_saver.ko
/boot/kernel/dragon_saver.ko	/boot/kernel/plasma_saver.ko
/boot/kernel/fade_saver.ko	/boot/kernel/rain_saver.ko
```

## 自定义引导加载程序 Logo

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

| Logo 名称     | 说明                |
| ----------- | ----------------- |
| `fbsdbw`    | FreeBSD 黑白 Logo   |
| `beastie`   | 小恶魔彩色 Logo        |
| `beastiebw` | 小恶魔黑白 Logo        |
| `orb`       | UEFI 下彩色 Orb Logo |
| `orbbw`     | 默认黑白 Orb Logo     |
| `none`      | 无 Logo            |

以 `fbsdbw` 为例，在 **/boot/loader.conf** 文件中写入：

```ini
# 设置引导加载程序 Logo 为 fbsdbw
loader_logo="fbsdbw"
```

重启后效果如下：

![fbsdbw](/files/R9YCEtn3K48RA31m3WOx)

![beastie](/files/5Q7jZGUeTWQcVPeF0u1C)

![beastiebw](/files/EpwWuXkCeImH3QBuxW7t)

![orb](/files/Mx6HUE3jlVS23A0QHgcN)

![orbbw](/files/8fWYus8E3ts68El9S2bx)

![none](/files/rWtTF8eYQG4uCtkDBq9Q)

### 参考文献

* FreeBSD Forums. customize boot loader logo\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/customize-boot-loader-logo.72903/>. 讨论如何更换引导加载程序默认 Logo 的方法。
* FreeBSD Forums. How to change the FreeBSD logo which appears as soon it boots with that of the little devil\[EB/OL]. \[2026-03-26]. <https://forums.freebsd.org/threads/how-to-change-the-freebsd-logo-which-appears-as-soon-it-boots-with-that-of-the-little-devil.85934/>. 询问将启动 Logo 替换为小恶魔图标的具体操作。
* FreeBSD Project. loader: Load a splash screen if “splash” variable is defined\[EB/OL]. \[2026-03-26]. <https://reviews.freebsd.org/D45932>. 为引导加载程序添加 splash 画面加载功能的代码审查。

## 课后习题

1. 修改 `autoboot_delay` 为 0 并启用 `boot_mute`，对比两次系统启动的输出差异，分析引导器在用户体验与调试需求之间的设计权衡。
2. 查阅 **/boot/loader.conf.d/** 目录的加载机制源代码，创建一个自定义配置文件并验证其与主配置文件的优先级关系，分析分散配置设计对系统管理的影响。
3. 自定义一张 BMP 格式的启动 Logo，替代默认 Logo 并记录加载过程与格式要求。


# 16.2 启动消息（dmesg）

FreeBSD 启动时，大多数启动消息都与正在检测的设备有关。启动消息的副本保存在 **/var/run/dmesg.boot** 中。

以下示例是 Radxa X4 16G 128G eMMC 款在 15.0-CURRENT 下完整的启动消息内容。

```sh
# ----- 内核启动标记 -----
---<<BOOT>>---
# 此行标记内核开始输出启动消息。此前的引导加载程序（loader）输出不会出现在 dmesg 缓冲区中，
# 因为 dmesg 缓冲区由内核在初始化时创建。引导加载程序消息（启动菜单）只能通过串口控制台或屏幕查看。

# ----- 版权声明 -----
Copyright (c) 1992-2025 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
	The Regents of the University of California. All rights reserved.
FreeBSD is a registered trademark of The FreeBSD Foundation.
# 第一行声明 FreeBSD 项目的版权（FreeBSD 独有的代码，始于 1992 年）。
# 第二行声明加州大学董事会（The Regents）的版权——这是 4.4BSD-Lite 及之前 BSD 版本的版权持有者。
# 年份跨度 1979-1994 代表了 BSD 从 3BSD 到 4.4BSD-Lite 的完整历史（4.4BSD-Lite2 于 1995 年 6 月发布，在其后）。
# 第三行声明 FreeBSD Foundation 持有“FreeBSD”注册商标。

# ----- 内核版本标识 -----
FreeBSD 15.0-CURRENT #0 main-n275588-045a4c108fcf: Fri Feb 21 02:25:56 UTC 2025
    root@releng3.nyi.freebsd.org:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
# 格式：<系统名称> <版本>-<分支> #<构建号> <Git 提交哈希>: <构建日期时间>
# 15.0-CURRENT：开发分支（非正式发行版）。
# #0：该内核配置的第 0 次构建（config(8) 构建计数）。
# main-n275588-045a4c108fcf：Git main 分支的快照标识。
# 第二行：构建主机（root@releng3.nyi.freebsd.org）、构建目录路径、内核配置文件（GENERIC）、目标架构（amd64）。

# ----- 编译程序信息 -----
FreeBSD clang version 19.1.7 (https://github.com/llvm/llvm-project.git llvmorg-19.1.7-0-gcd708029e0b2)
# FreeBSD 基本系统编译程序版本。FreeBSD 当前版本的内核由 Clang 19.1.7 编译。
# FreeBSD 从 10.0 起将 Clang 作为默认系统编译程序，替代了 GCC。

# ----- 调试选项警告 -----
WARNING: WITNESS option enabled, expect reduced performance.
# WITNESS 是内核死锁检测和锁顺序验证机制。启用后会令每次锁获取都进行验证，
# 带来显著的性能开销。CURRENT 分支内核默认启用，
# 用于在开发过程中捕获锁顺序错误（lock order reversal）。RELEASE 版本禁用此选项。

# ----- 控制台与显示设备 -----
VT(efifb): resolution 800x600
# VT（Virtual Terminal，Newcons）：FreeBSD 新一代系统控制台驱动（替代了 syscons）。
# efifb：通过 EFI 固件提供的帧缓冲区（framebuffer）驱动来显示。
# UEFI 固件默认将显示分辨率设为 800x600。如果 drm（Direct Rendering Manager）驱动加载后，
# 分辨率可升至显示器原生分辨率。

# ===== CPU 检测与特性枚举 =====
CPU: Intel(R) N100 (806.40-MHz K8-class CPU)
# CPU 型号名称。Intel N100 是 Alder Lake-N 架构的低功耗处理器。
# 806.40 MHz 是内核启动时检测到的 CPU 初始频率（等于不变 TSC 频率），
# 并非 Intel 官方标注的 Processor Base Frequency（N100 官方基础频率为 800 MHz）。
# 加载 hwpstate_intel(4) 后内核会通过 Intel Speed Shift 动态调整频率（N100 最高睿频可达 ~3.4 GHz）。
# "K8-class" 表示该 CPU 支持 AMD64 指令集（AMD K8 是首个 x86-64 处理器）；
# 内核代码以 AMD K8 为 AMD64 功能基线进行分类。

  Origin="GenuineIntel"  Id=0xb06e0  Family=0x6  Model=0xbe  Stepping=0
# Origin：CPU 厂商字符串，GenuineIntel = Intel。Family/Model/Stepping 用于微码更新匹配。

  Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
# 基础 x86 特性（CPUID 叶子 1 的 EDX 寄存器）。涵盖 32 位时代的全部标准特性：
# FPU（x87 浮点）、VME（虚拟 8086 模式增强）、TSC（时间戳计数器）、APIC 等。
# SSE/SSE2：Streaming SIMD Extensions，Intel P4 时代引入的 128 位 SIMD。

  Features2=0x7ffafbbf<SSE3,PCLMULQDQ,DTES64,MON,DS_CPL,VMX,EST,TM2,SSSE3,SDBG,FMA,CX16,xTPR,PDCM,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,TSCDLT,AESNI,XSAVE,OSXSAVE,AVX,F16C,RDRAND>
# ECX 扩展特性（CPUID 叶子 1 的 ECX 寄存器）：
# VMX：Intel 虚拟化技术（VT-x），bhyve(8) 依赖此特性。
# AESNI：AES 指令集，加速加密操作（OpenSSL/ZFS 加密均可受益）。
# AVX：256 位 SIMD，浮点运算密集场景的加速指令。
# RDRAND：硬件随机数生成器，为 random(4) 提供熵源。

  AMD Features=0x2c100800<SYSCALL,NX,Page1GB,RDTSCP,LM>
  AMD Features2=0x121<LAHF,ABM,Prefetch>
# AMD 扩展特性（Intel 实现 AMD64 后也报告这些位）：
# SYSCALL：快速系统调用指令（AMD64 ABI 的核心）。NX：不可执行页位（W^X 安全机制）。
# LM（Long Mode）：64 位支持。Page1GB：1GB 大页支持。

  Structured Extended Features=0x239ca7eb<FSGSBASE,TSCADJ,BMI1,AVX2,FDPEXC,SMEP,BMI2,ERMS,INVPCID,NFPUSG,PQE,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,PROCTRACE,SHA>
# 结构化扩展特性（CPUID 叶子 7、子叶 0 的 EBX）：
# SMEP（Supervisor Mode Execution Protection）：内核态阻止执行用户态代码——关键安全特性。
# SMAP（Supervisor Mode Access Prevention）：内核态阻止访问用户态内存。
# AVX2：256 位整数 SIMD 扩展，提升媒体处理/加解密性能。
# RDSEED：与 RDRAND 互补的更强随机数指令（通过熵源直接生成而非增强后输出）。

  Structured Extended Features2=0x98c007bc<UMIP,PKU,OSPKE,WAITPKG,GFNI,VAES,VPCLMULQDQ,RDPID,MOVDIRI,MOVDIR64B>
# 结构化扩展特性 2（叶子 7、子叶 0 的 ECX）：
# UMIP/OSPKE：内存保护增强。WAITPKG：Intel 用户态等待指令包，用于自旋等待优化。
# GFNI/VAES/VPCLMULQDQ：Intel 10nm+ 引入的 Galois Field/AES 加速指令，显著加速加密操作。

  Structured Extended Features3=0xfc184410<FSRM,MD_CLEAR,IBT,IBPB,STIBP,L1DFL,ARCH_CAP,CORE_CAP,SSBD>
# 结构化扩展特性 3（叶子 7、子叶 0 的 EDX）：
# MD_CLEAR：支持 VERW 指令清除微架构缓冲区（MDS 缓解）。
# IBPB/STIBP/SSBD：Spectre/Meltdown 系列侧信道漏洞的硬件缓解控制位。
# FSRM：快速短 REP MOVSB（memcpy 加速），配合 ERMS 使用。

  XSAVE Features=0xf<XSAVEOPT,XSAVEC,XINUSE,XSAVES>
# XSAVE：x86 上下文保存/恢复扩展（CPUID 叶子 D、子叶 1 的 EAX）。
# XSAVEOPT/XSAVES：优化的状态保存，减少上下文切换开销。

  IA32_ARCH_CAPS=0x180fd6b<RDCL_NO,IBRS_ALL,SKIP_L1DFL_VME,MDS_NO,TAA_NO>
# IA32_ARCH_CAPABILITIES（MSR 0x10A）：Intel 架构能力 MSR，硬件报告自身安全特性。
# RDCL_NO：不受 RIDL / MDS 漏洞影响。MDS_NO/TAA_NO：不受微架构数据采样攻击影响。
# 这些标志位影响系统安全评估——它们表示该 CPU 不需要对应安全缓解措施。

  VT-x: PAT,HLT,MTF,PAUSE,EPT,UG,VPID,VID,PostIntr
# VT-x（Intel 虚拟化技术）子特性集：
# EPT（Extended Page Tables）：二级地址转换（SLAT），bhyve 的核心依赖，大幅提升虚拟机内存性能。
# VPID（Virtual Processor Identifier）：TLB 标记，避免 VM 切换时刷新 TLB。
# VID（Virtual Interrupt Delivery）：硬件直通中断分发。PostIntr：Posted Interrupt 支持。

  TSC: P-state invariant, performance statistics
# TSC（时间戳计数器）特性：Invariant TSC 意味着不受 P-state（频率调节）和 C-state（休眠）影响，
# 内核可将其用作高精度单调时钟源（timecounter）。

# ===== 物理内存检测 =====
real memory  = 17179869184 (16384 MB)
# 硬件实际提供的物理内存总量（16 GB）。

avail memory = 16318308352 (15562 MB)
# 内核可用的物理内存。差值（约 822 MB）包括：
# 1) 内核代码与静态数据段占用的内存。2) 内核内存分配器（kmem）预保留的内存。
# 3) BIOS/UEFI 固件内存映射中标记为保留（reserved）的内存区域。
# 4) 某些 PCI 设备 MMIO 区域映射所占用的地址空间。

# ===== 事件计时器 =====
Event timer "LAPIC" quality 600
# LAPIC（Local APIC）计时器质量评分。内核维护多个计时器源，quality 值越高优先级越大。
# 600 分相对较高（HPET 为 550（Event）/950（Timecounter），TSC 为 1000（最高优先级））。
# 内核启动时会遍历所有计时器并按 quality 降序选择最佳可用源。

# ===== ACPI 子系统 =====
ACPI APIC Table: <ALASKA A M I >
# ACPI APIC（MADT）表供应商信息。“ALASKA A M I”是 AMI（American Megatrends Inc.）
# BIOS 的通用默认 ACPI OEM ID，被众多主板厂商使用，并非特定厂商的产品线代号。

WARNING: L3 data cache covers more APIC IDs than a package (7 > 3)
# L3 缓存共享 APIC ID 范围与 BSP（Bootstrap Processor）报告值不一致，
# 可能是 BIOS/Firmware ACPI 表存在小问题，不影响正常运行。此问题常见于低功耗平台。

# ===== SMP（对称多处理）初始化 =====
FreeBSD/SMP: Multiprocessor System Detected: 4 CPUs
FreeBSD/SMP: 1 package(s) x 4 core(s)
# SMP 检测结果。1 个物理插槽（package）× 4 颗核心（core）。
# Intel N100 为 4 核 4 线程（不支持超线程），因此逻辑 CPU 数 = 物理核心数。

# ===== 随机数子系统初始化 =====
random: registering fast source Intel Secure Key RNG
random: fast provider: "Intel Secure Key RNG"
random: unblocking device.
# FreeBSD 随机数子系统（random(4)）初始化流程：
# 1) 注册快速的 Intel Secure Key RNG（RDRAND 指令）作为硬件熵源。
# 2) 标记 fast provider（快速提供者）为 “Intel Secure Key RNG”。
# 3) unblocking device：当内核收集到足够早期熵后，/dev/random 解除阻塞，
#    用户态程序从此可正常读取随机数。CURRENT 版本使用 FenestrasX 算法。

# ===== I/O APIC 与 AP 启动 =====
ioapic0 <Version 2.0> irqs 0-119
# I/O APIC（高级可编程中断控制器）版本 2.0，支持 120 条 IRQ 线（0-119），
# 负责将 PCI 设备中断请求分发至对应 CPU 核心（LAPIC）。

Launching APs: 2 1 3
# AP（Application Processor，应用处理器）启动顺序。BSP（Bootstrap Processor）为 CPU 0，
# 在 AP 启动前已经运行，后续逐核启动：CPU 2 → CPU 1 → CPU 3。
# 启动顺序由 APIC ID 和拓扑算法决定，通常先启动与 BSP 不在同一物理核心的 AP。

random: entropy device external interface
# random(4) 外部熵接口注册完毕。用户态程序可以开始读取 /dev/random。

# ===== 键盘多路复用器 =====
kbd0 at kbdmux0
# kbd0 连接到键盘多路复用器 kbdmux0(4)。kbdmux 允许多个键盘同时作为单一键盘设备工作
#（AT 键盘 + USB 键盘同时可用），输入被透明合并。

# ===== EFI 实时时钟 =====
efirtc0: <EFI Realtime Clock>
efirtc0: registered as a time-of-day clock, resolution 1.000000s
# efiRTC：通过 EFI 运行时服务（Runtime Services）获取/设置时间的时钟驱动。
# “time-of-day clock”：系统时间的硬件时钟源注册。1s 粒度说明 EFI RTC 只能精确到秒级，
# 在启动早期为内核提供初始时间基准。后续会使用更高精度的 TSC/HPET 作为 timecounter。

# ===== SMBIOS =====
smbios0: <System Management BIOS> at iomem 0x75ca6000-0x75ca6017
smbios0: Version: 3.6
# SMBIOS（DMI）提供主板、BIOS、系统序列号等硬件描述信息，驱动映射到内存地址处。

# ===== AES-NI 加速引擎 =====
aesni0: <AES-CBC,AES-CCM,AES-GCM,AES-ICM,AES-XTS,SHA1,SHA256>
# aesni(4) 驱动加载，提供 AES 各模式（CBC/CCM/GCM 等）以及 SHA-1/SHA-256 硬件加速。
# GELI 全盘加密、ZFS 原生加密、IPsec、OpenSSL 等都可利用此驱动实现线速加密。

# ===== ACPI 根设备 -----
acpi0: <ALASKA A M I>
# ACPI 根设备（插槽/主板的 ACPI 命名空间），OEM ID = ALASKA（AMI BIOS 通用默认 OEM ID）。

# ----- ACPI 固件错误（非致命）-----
Firmware Error (ACPI): Could not resolve symbol [\134_SB.PC00.TXHC.RHUB.SS01], AE_NOT_FOUND (20241212/dswload2-315)
ACPI Error: AE_NOT_FOUND, During name lookup/catalog (20241212/psobject-372)
Firmware Error (ACPI): Could not resolve symbol [\134_SB.PC00.TXHC.RHUB.SS02], AE_NOT_FOUND (20241212/dswload2-315)
ACPI Error: AE_NOT_FOUND, During name lookup/catalog (20241212/psobject-372)
# BIOS/UEFI 固件 ACPI DSDT/SSDT 表中引用了不存在的 USB SuperSpeed（SS）端口符号：
# \134 是反斜杠 ACPI 名称路径转义（ACPI namespace root \），RHUB.SS01/SS02
# 是 xHCI 的 Root Hub 下的 SuperSpeed 端口对象。AE_NOT_FOUND 表明找不到。
# 这通常是固件（BIOS/UEFI）编写的 Bug：定义了 USB 3.0 控制器的 SS 端口引用，
# 但实际的 DSDT/SSDT 表中并未声明对应设备节点。
# 影响：这两个 USB SS 端口无法使用（该平台物理上可能仅支持 USB 2.0 或无对应 USB 3.0 插槽）。

acpi0: Power Button (fixed)
# ACPI 的固定硬件电源按钮，由 acpi_button(4) 管理。

# ===== 高精度事件计时器（HPET）=====
hpet0: <High Precision Event Timer> iomem 0xfed00000-0xfed003ff on acpi0
# HPET 内存映射 I/O 地址范围。HPET 是 x86 平台替代传统 PIT/RTC 的高精度计时器。

Timecounter "HPET" frequency 19200000 Hz quality 950
# HPET 的 timecounter（时间计数器）频率 19.2 MHz，quality 950（仅次于 TSC 的 1000）。
# timecounter 用于 gettimeofday(2)/clock_gettime(2) 等精确时间获取。

Event timer "HPET" frequency 19200000 Hz quality 550
Event timer "HPET1" frequency 19200000 Hz quality 440
Event timer "HPET2" frequency 19200000 Hz quality 440
Event timer "HPET3" frequency 19200000 Hz quality 440
Event timer "HPET4" frequency 19200000 Hz quality 440
# HPET 的内部比较器（Comparator）作为 event timer（事件计时器/定时器）：
# 1 个主计时器（quality 550）+ 4 个从计时器（quality 440）。
# event timer 用于内核的 hardclock/statclock 等周期性和一次性定时中断。
# HPET1-4 的 quality 440 低于主计时器的 550，内核会优先使用主计时器，
# 仅在多 CPU 绑核（CPU binding）场景下才后续启用备用计时器。

# ===== AT 实时时钟（传统 RTC）=====
atrtc1: <AT realtime clock> on acpi0
atrtc1: Warning: Couldn't map I/O.
atrtc1: registered as a time-of-day clock, resolution 1.000000s
# 传统的 AT RTC（Motorola MC146818A 兼容），提供 date/time 设置/获取。
# Warning 表明无法映射 I/O 端口（可能 UEFI 模式下固件未分配 I/O 空间），但无实际影响。
# 现代 UEFI 平台更推荐使用 efiRTC；非 PNP ISA 的 AT RTC 已推迟至 FreeBSD 16.0 从 GENERIC 移除。

Event timer "RTC" frequency 32768 Hz quality 0
# RTC 的周期性中断频率 32768 Hz（2^15 Hz），quality 0（最低优先级，仅做最后备选）。

# ===== 传统 AT 定时器（i8254 PIT）=====
attimer0: <AT timer> port 0x40-0x43,0x50-0x53 irq 0 on acpi0
# i8254 可编程间隔定时器（Programmable Interval Timer, PIT）。端口 0x40-0x43
# 为 PIT 数据/命令端口，irq 0 为 PIT 中断。

Timecounter "i8254" frequency 1193182 Hz quality 0
# i8254 频率 = 1.193182 MHz（NTSC 彩色副载波频率 / 3，历史遗留值）。
# quality 0 = 最低优先级，仅在没有任何更高 priority timecounter 可用时使用。

Event timer "i8254" frequency 1193182 Hz quality 100
# 作为 event timer 时 quality 100，高于 RTC（0），但在现代平台上仍不如 LAPIC/HPET。

# ===== ACPI 快速计时器（ACPI PM Timer）=====
Timecounter "ACPI-fast" frequency 3579545 Hz quality 900
acpi_timer0: <24-bit timer at 3.579545MHz> port 0x1808-0x180b on acpi0
# ACPI Power Management Timer（PM Timer），频率 3.579545 MHz。24 位计数器意味着
# 约 4.7 秒计数器溢出回绕一次（2^24 / 3579545 ≈ 4.69 s），内核需在溢出前读值并累积，
# 方可作为高精度 timecounter 使用。quality 900，为中等偏高的时间计数器选择。

# ===== PCI 总线枚举 =====
pcib0: <ACPI Host-PCI bridge> port 0xcf8-0xcff on acpi0
# ACPI Host-PCI 桥（PCI 配置空间的端口映射方式，0xCF8=地址寄存器，0xCFC=数据寄存器）。

pci0: <ACPI PCI bus> on pcib0
# PCI 总线 0 绑定在 Host-PCI 桥上。内核随后枚举所有 PCI 设备并尝试匹配驱动。

# ----- 显卡 -----
vgapci0: <VGA-compatible display> port 0x4000-0x403f mem 0x6000000000-0x6000ffffff,0x4000000000-0x400fffffff at device 2.0 on pci0
# Intel N100 的集成 UHD 显卡（Alder Lake-N 内建 GPU）。device 2.0 = PCI BDF（Bus 0, Device 2, Function 0）。

vgapci0: Boot video device
# 此设备被标记为引导视频设备。UEFI GOP（Graphics Output Protocol）在此之前已将帧缓冲区
# 设置为 800x600（参见上面 VT(efifb) 行），此标记传递到内核 drm-kmod 驱动后可用作主显示输出。

# ----- USB 3.0 xHCI 控制器 0 -----
xhci0: <XHCI (generic) USB 3.0 controller> mem 0x6001120000-0x600112ffff at device 13.0 on pci0
xhci0: 32 bytes context size, 64-bit DMA
# xHCI（USB 3.0 主控制器，PCI Function 13.0）。context size=32 B 为 xHCI 数据结构大小，
# 64-bit DMA 表示支持 64 位总线地址——兼容 4 GB 以上的物理内存。

usbus0 on xhci0
# usbus0（USB 总线实例）绑定在 xhci0 上。USB 核心通过此总线管理连接的 USB 设备。

usbus0: 5.0Gbps Super Speed USB v3.0
# 速率 5.0 Gbps = SuperSpeed USB 3.0 Gen1。

# ----- 未匹配驱动的设备 -----
pci0: <simple comms, UART> at device 18.0 (no driver attached)
# PCI Serial/UART 控制器未绑定驱动。可能为 Intel Trace Hub 或串口。
# "(no driver attached)" 指内核没有为此 PCI 设备 ID 匹配的驱动程序（支持表中无此 VID/DID）。

# ----- USB 3.0 xHCI 控制器 1 -----
xhci1: <XHCI (generic) USB 3.0 controller> mem 0x6001100000-0x600110ffff at device 20.0 on pci0
xhci1: 32 bytes context size, 64-bit DMA
usbus1 on xhci1
usbus1: 5.0Gbps Super Speed USB v3.0
# 第二个 xHCI 控制器（Alder Lake-N 支持多个 USB 控制器）。usbus1 独立于 usbus0。

# ----- 未匹配驱动的其他 PCI 设备 -----
pci0: <memory, RAM> at device 20.2 (no driver attached)
# 可能为 Intel 电源管理/热监控所用的 MMIO RAM 区域，不需要专用驱动。

pci0: <simple comms> at device 22.0 (no driver attached)
# 可能为 Intel Management Engine Interface（MEI/HECI）。FreeBSD 无 MEI 驱动（大部分 MEI 功能
# 是管理引擎交互（多见于服务器/工作站）。

# ----- SD/MMC 控制器 -----
sdhci_pci0: <Generic SD HCI> mem 0x6001149000-0x6001149fff at device 26.0 on pci0
sdhci_pci0: 1 slot(s) allocated
# SD/MMC 主控制器驱动（sdhci(4)），检测到 1 个 SD 卡槽。

# ----- WITNESS 调试报告（非致命）-----
uma_zalloc_debug: zone "malloc-16" with the following non-sleepable locks held:
exclusive sleep mutex SD slot mtx (sdhci) r = 0 (0xfffff80001ad9020) locked @ /usr/src/sys/dev/sdhci/sdhci.c:688
# WITNESS 检测到在持有非可睡眠锁（sleep mutex）“SD slot mtx”的情况下，
# 内核内存分配器 UMA 试图从 zone "malloc-16" 分配内存且可能挂起（sleepable）——
# 这是一个潜在的锁顺序问题（lock order reversal, LOR）。
# r = 0 = 递归计数为 0，表示非递归锁的单次获取。

stack backtrace:
#0 0xffffffff80bcc76c at witness_debugger+0x6c
#1 0xffffffff80bcd980 at witness_warn+0x430
#2 0xffffffff80f05784 at uma_zalloc_debug+0x34
#3 0xffffffff80f052d7 at uma_zalloc_arg+0x27
#4 0xffffffff80b27bdd at malloc+0x7d
#5 0xffffffff80b28592 at reallocf+0x12
#6 0xffffffff80b9367d at devclass_add_device+0x1cd
#7 0xffffffff80b91c2b at make_device+0x10b
#8 0xffffffff80b91a6d at device_add_child_ordered+0x2d
#9 0xffffffff8086f42c at sdhci_card_task+0x1fc
#10 0xffffffff80875021 at sdhci_pci_attach+0x491
#11 0xffffffff80b93e8b at device_attach+0x45b
#12 0xffffffff80b951fa at bus_attach_children+0x4a
#13 0xffffffff8082ba77 at pci_attach+0xd7
#14 0xffffffff80f52775 at acpi_pci_attach+0x15
#15 0xffffffff80b93e8b at device_attach+0x45b
#16 0xffffffff80b951fa at bus_attach_children+0x4a
#17 0xffffffff80f55ad8 at acpi_pcib_acpi_attach+0x428
# 调用栈 (stack backtrace) 从上到下依次为调用顺序：
# witness_debugger：WITNESS 进入调试输出。
# witness_warn：WARN 级别——非严重的锁顺序警告（非死锁）。
# uma_zalloc_debug → uma_zalloc_arg → malloc → reallocf：内存分配器检测路径。
# devclass_add_device → make_device：设备类中添加新设备实例。
# sdhci_card_task：SD 卡检测任务（在 sdhci(4) attach 上下文内执行）。
# sdhci_pci_attach → device_attach：设备驱动 attach 入口。
# bus_attach_children → ... → acpi_pcib_acpi_attach：遍历总线子设备的递归 attach 调用链，层层向上经 ACPI 层回到 PCI 桥顶的 ACPI attach 入口。
# 此 LOR 不影响 SD 卡正常读写，仅为 CURRENT 调试用途。

mmc0: <MMC/SD bus> on sdhci_pci0
# mmc0 总线绑定在 sd/mmc 主控制器上，后续可识别 eMMC 或 SD 卡设备。

# ===== PCI-PCI 桥与子总线 =====
# ----- PCIe 根端口 1 -----
pcib1: <ACPI PCI-PCI bridge> at device 28.0 on pci0
pci1: <ACPI PCI bus> on pcib1
pci1: <network> at device 0.0 (no driver attached)
# PCIe 桥 28.0（PCIe Root Port #1）后方连接网络设备（无线网卡），
# 此时驱动尚未加载（驱动在启动后期通过 kldload 或 devmatch 才会加载）。

# ----- PCIe 根端口 6 -----
pcib2: <ACPI PCI-PCI bridge> at device 28.6 on pci0
pci2: <ACPI PCI bus> on pcib2

# ----- Intel I226-V 有线网卡 -----
igc0: <Intel(R) Ethernet Controller I226-V> mem 0x80500000-0x805fffff,0x80600000-0x80603fff at device 0.0 on pci2
# igc(4) 驱动为 Intel I225/I226 系列 2.5 Gbps 以太网控制器。

igc0: EEPROM V2.17-0 eTrack 0x80000303
# 网卡 EEPROM 版本及 Intel 内部版本追踪号。EEPROM 存储 MAC 地址和 PHY 校准数据。

igc0: Using 1024 TX descriptors and 1024 RX descriptors
# TX/RX 描述符环形缓冲区（ring descriptor）大小。描述符是硬件 DMA 传输的元数据结构，
# 每个描述符对应一个待发送/接收的数据包缓冲区。1024 个描述符 → 最多 1024 个未处理的数据包。

igc0: Using 4 RX queues 4 TX queues
# 多队列（multi-queue）RSS 配置：4 个 CPU 对应 4 个队列，每个 CPU 独立处理自己的数据包流。

igc0: Using MSI-X interrupts with 5 vectors
# MSI-X（Message Signaled Interrupts Extended）：每队列 1 个中断向量 + 1 个管理向量 = 5。
# 相比传统 pin-based INTx 中断，MSI-X 无中断共享、无优先级冲突、可绑定至特定 CPU。

igc0: Ethernet address: 10:02:b5:86:0e:f9
# MAC 地址。永久存储在 EEPROM 中，系统启动时由 igc(4) 读出。

igc0: netmap queues/slots: TX 4/1024, RX 4/1024
# netmap(4) 高性能零拷贝网络框架兼容信息：支持 4 个硬件队列，每队列 1024 个缓冲区槽位。

# ----- PCIe 根端口 7 -----
pcib3: <ACPI PCI-PCI bridge> at device 29.0 on pci0
pci3: <ACPI PCI bus> on pcib3

# ----- NVMe SSD -----
nvme0: <Generic NVMe Device> mem 0x80700000-0x80703fff at device 0.0 on pci3
# NVMe 控制器（PCIe 设备 0.0），通过 nda(4) CAM 层驱动或 nvd(4) 直接映射驱动管理。

# ===== PCI-ISA 桥与 ISA 总线 =====
isab0: <PCI-ISA bridge> at device 31.0 on pci0
isa0: <ISA bus> on isab0
# LPC（Low Pin Count）桥在软件上表现为 PCI-ISA 桥。ISA 总线是传统 x86 接口，
# 供 atrtc(4)、atkbd(4)、uart(4) 等以 ISA 方式访问的遗留设备使用。

# ===== Intel 高保真音频控制器 =====
hdac0: <Intel Alder Lake-N HDA Controller> mem 0x6001140000-0x6001143fff,0x6001000000-0x60010fffff at device 31.3 on pci0
# Intel HDA (High Definition Audio) 控制器，挂载在 PCI Function 31.3。

pci0: <serial bus> at device 31.5 (no driver attached)
# 可能是 I2C 串行总线控制器，当前无驱动匹配。

# ===== ACPI 固定特性 =====
acpi_button0: <Sleep Button> on acpi0
# ACPI 睡眠按钮（通常在笔记本上）。

cpu0: <ACPI CPU> on acpi0
# CPU 0 的 ACPI 处理器对象（用于 _PSS/_PCT/_CST 等电源管理对象）。

acpi_button1: <Power Button> on acpi0
# ACPI 电源按钮——与前面的 fixed Power Button 的区别在于：
# “fixed” = ACPI FADT 固定硬件事件，“acpi_button1” = ACPI 命名空间中的控制方法（Control Method）电源设备。

acpi_tz0: <Thermal Zone> on acpi0
# ACPI 温控区域（temperature sensor），用于 CPU/主板的温度监测与风扇调速。

acpi_syscontainer0: <System Container> on acpi0
acpi_syscontainer1: <System Container> on acpi0
# ACPI 系统容器设备，是 NUMA/多节点系统的拓扑容器。

# ===== AT RTC (ISA 侧) =====
atrtc0: <AT realtime clock> at port 0x70 irq 8 on isa0
atrtc0: Warning: Couldn't map I/O.
atrtc0: registered as a time-of-day clock, resolution 1.000000s
atrtc0: Can't map interrupt.
atrtc0: non-PNP ISA device will be removed from GENERIC in FreeBSD 15.
# atrtc(4) 在 ISA 总线侧的探测。两个 Warning 不影响系统运行——ISA I/O 和中断在 UEFI 平台上通常不可映射。
# 非 PNP ISA 的 atrtc 已推迟至 FreeBSD 16.0 从 GENERIC 内核配置中移除（ACPI 枚举的 atrtc 仍然存在，以 efirtc 和 ACPI 时钟替代）。

# ===== Intel Speed Shift (HWP) =====
hwpstate_intel0: <Intel Speed Shift> on cpu0
cpufreq0: <CPU frequency control> on cpu0
hwpstate_intel1: <Intel Speed Shift> on cpu1
cpufreq1: <CPU frequency control> on cpu1
hwpstate_intel2: <Intel Speed Shift> on cpu2
cpufreq2: <CPU frequency control> on cpu2
hwpstate_intel3: <Intel Speed Shift> on cpu3
cpufreq3: <CPU frequency control> on cpu3
# Intel Speed Shift（HWP = Hardware P-state）——Intel 从 Skylake 起引入的
# CPU 自动频率调节机制：CPU 自身硬件根据负载实时调整核心频率，
# 无需操作系统干预。传统方式（cpufreq）需要 OS 通过 ACPI _PSS 表选择 P-state（被动调速）。
# HWP 的延迟和粒度优于传统 cpufreq，是 FreeBSD 供电管理和性能的重要组成。

# ===== 最终 Timecounter 选择 =====
Timecounter "TSC" frequency 806401362 Hz quality 1000
# Time Stamp Counter（TSC）频率 = 806.4 MHz，即不变 TSC（Invariant TSC）的递增速率。
# 注意：TSC 频率 ≠ Intel 官方 Processor Base Frequency（N100 官方基础频率为 800 MHz）。
# quality 1000 是最高优先级——内核最终选择 TSC 为系统主 timecounter。
# 不变 TSC 以固定速率递增，不受 P-state/C-state 频率变化影响，是最细粒度的可靠时间源。

Timecounters tick every 1.000 msec
# 内核 timecounter 子系统以 1ms（1000 Hz）的频率更新系统时间基准。

# ===== USB 根集线器发现 =====
ugen1.1: <Intel XHCI root HUB> at usbus1
ugen0.1: <Intel XHCI root HUB> at usbus0
# USB generic 设备节点。ugenX.Y 中 X=USB 总线号，Y=设备地址（根集线器固定为 1）。

uhub0 on usbus1
uhub0: <Intel XHCI root HUB, class 9/0, rev 3.00/1.00, addr 1> on usbus1
# uhub(4)——USB 集线器驱动。class 9 = Hub 类。rev 3.00 = USB 3.0。

uhub1 on usbus0
uhub1: <Intel XHCI root HUB, class 9/0, rev 3.00/1.00, addr 1> on usbus0

# ===== ZFS 版本信息 =====
ZFS filesystem version: 5
ZFS storage pool version: features support (5000)
# ZFS 版本信息：文件系统层版本 5，存储池版本 5000（OpenZFS 2.x/3.x 原生功能标志支持）。
# "features support" 意味着每个 pool 有一个功能标志（feature flags）集合，
# 而非固定的版本号——不同的 pool 可独立启用不同的功能（如压缩、去重等）。

# ===== eMMC 存储设备 =====
mmcsd0: 125GB <MMCHC Y2P128 0.0 SN F034273C MFG 04/2023 by 155 0x0000> at mmc0 200.0MHz/8bit/8192-block
# Radxa X4 板载 128 GB eMMC 存储。通信速率 200.0 MHz，8 bit 数据宽度（HS400 模式）。

mmcsd0boot0: 4MB partition 1 at mmcsd0
mmcsd0boot1: 4MB partition 2 at mmcsd0
# eMMC 内置的两个引导分区（boot partitions）—— 通常存放 BootROM/UEFI 固件。
# Linux 内核通常用它们存放 U-Boot SPL。

mmcsd0rpmb: 17MB partition 3 at mmcsd0
# eMMC RPMB（Replay Protected Memory Block）—— 受重放保护的安全存储分区，
# 用于防回滚密钥存储等安全用途。大小 17 MB。

uhub1: 2 ports with 2 removable, self powered
# uhub1 具有 2 个可移除（external-facing）端口，自供电（意味着不从上游端口取电）。

# ===== NVMe 控制器初始化 =====
nvme0: Allocated 16MB host memory buffer
# NVMe 规范的主机内存缓冲区（Host Memory Buffer, HMB）——SSD 可使用主机系统内存
# 作为映射表（FTL mapping table）的缓存，减少 SSD 本地 DRAM 需求或增加缓存容量。

# ===== HD Audio Codec 探测 =====
hdacc0: <Realtek ALC269 HDA CODEC> at cad 0 on hdac0
# HD Audio Codec（Realtek ALC269）位于 codec address 0。ALC269 常见于笔记本电脑与小主机。

hdaa0: <Realtek ALC269 Audio Function Group> at nid 1 on hdacc0
# AFG（Audio Function Group），HDA 规范术语——包含 DAC/ADC/混音/插孔等功能节点。

pcm0: <Realtek ALC269 (Right Analog)> at nid 21 and 24 on hdaa0
# pcm(4) 音频设备实例。nid 21（Pin Complex）/ nid 24（Pin Complex）代表
# 右声道模拟输出引脚——可能是 3.5mm 耳机/音箱输出。系统至此具备音频输出能力。

# ===== NVMe 磁盘设备（nda/CAM 路径）=====
nda0 at nvme0 bus 0 scbus0 target 0 lun 1
# nda(4)：通过 CAM(4) 框架连接的 NVMe 磁盘设备。
# nda0：500 GB 梵想 S530Q NVMe SSD。
# scbus0 target 0 lun 1：SCSI 中层总线的模拟寻址。
# （FreeBSD 的 CAM 层统一了 nvme(4)→nda(4) 和 ahci(4)→ada(4) 等不同传输协议）

nda0: <Fanxiang S530Q 500GB SN14243 FX240960178>
nda0: Serial Number FX240960178
nda0: nvme version 1.4
nda0: 476940MB (976773168 512 byte sectors)
# NVMe 规范版本 1.4。476940 MiB ÷ 1024 ≈ 465.76 GiB。
# 976773168 × 512 B = 500.107 GB（多出 107 MB 用于固件/bad block 映射）。

# ===== 挂载根文件系统 =====
Trying to mount root from zfs:zroot/ROOT/default []...
# 内核尝试从 ZFS 池 "zroot" 的数据集 "zroot/ROOT/default" 挂载根文件系统。
# [] 中是传递给 mountroot 的可选参数（通常有“rw”或“ro”），CURRENT 启动为空。
# 这是引导过程的最后一个内核阶段——根系统挂载成功后内核执行 init(8)。

WARNING: WITNESS option enabled, expect reduced performance.
# WITNESS 第二次提醒（重复告警）。这是在挂载 root 且即将进入多用户模式前的最终提醒。

uhub0: 16 ports with 16 removable, self powered
# uhub0 具有 16 个端口（全部可移除、自供电），对应 xHCI 1 号控制器。

Root mount waiting for: usbus1
# 根挂载挂起等待 usbus1（2 号 xHCI 控制器）的 USB 总线枚举完成。
# 因为键盘或驱动等可能在 USB 总线上，必须先让 USB 准备好才能继续启动。

ugen1.2: <Realtek Bluetooth Radio> at usbus1
# 蓝牙适配器（Realtek）。ugen 节点创建标志着蓝牙硬件可用，启动后可加载 ubt(4) 驱动。

# ===== SMBus 控制器（后期枚举）=====
ichsmb0: <Intel Alder Lake SMBus controller> port 0xefa0-0xefbf mem 0x6001148000-0x60011480ff at device 31.4 on pci0
smbus0: <System Management Bus> on ichsmb0
# Intel PCH SMBus（系统管理总线）控制器，用于与 SPD（内存条 EEPROM）、
# 温度传感器、电压监控器等低速设备通信，通过 smbus(4) 框架访问。

# ===== Realtek 8852BE WiFi 6 网卡 =====
rtw890: <rtw89_8852be> port 0x3000-0x30ff mem 0x80800000-0x808fffff at device 0.0 on pci1
# rtw89(4) 驱动为 Realtek 8852BE WiFi 6 无线网卡。驱动以 firmware 方式加载闭源固件。

rtw890: successfully loaded firmware image 'rtw89/rtw8852b_fw-1.bin'
rtw890: loaded firmware rtw89/rtw8852b_fw-1.bin
rtw890: Firmware version 0.29.29.5 (da87cccd), cmd version 0, type 5
rtw890: Firmware version 0.29.29.5 (da87cccd), cmd version 0, type 3
# 固件加载流程：首先加载固件映像文件 .bin，随后验证固件版本。
# 固件版本 0.29.29.5（GIT 提交 da87cccd），cmd version = 0（命令接口版本），
# type 5 和 type 3 分别是 WiFi MAC 层固件和 Bluetooth 共存/PHY 子固件。
# 大部分现代 WiFi 芯片都需要运行时加载闭源固件——卡本身是无固件的 ROM+ 通用 DSP。

rtw890: chip rfe_type is 5
# RFE（RF Front-End）类型 = 5。前端类型决定了驱动如何进行射频校准和天线选择。

# ===== ACPI WMI（Windows Management Instrumentation）=====
acpi_wmi0: <ACPI-WMI mapping> on acpi0
acpi_wmi0: Embedded MOF found
# acpi_wmi(4)：ACPI WMI 映射驱动。WMI 提供 ACPI 至 Windows 驱动的接口，
# FreeBSD 通过此驱动读取 ACPI WMI 中内嵌的 MOF（Managed Object Format）元数据。
# WMI 接口常被用于笔记本热键、RF kill 开关、风扇控制等——但 x86 小主机平台可能无实际功能。

acpi_wmi0: cannot find EC device
# 未发现 Embedded Controller（EC）——许多 WMI 事件需要 EC 传递键盘/ACPI 通知，
# 没有 EC 说明该平台 WMI 仅提供基础信息（如 BIOS 型号）而无实际控制功能。

ACPI: \134_SB.WFDE.WQCC: 1 arguments were passed to a non-method ACPI object (Buffer) (20241212/nsarguments-361)
# ACPI namespace 的 WMI 事件数据对象（_SB.WFDE.WQCC）被内核解析时发现传入了参数
# 给一个非方法对象（Buffer 数据类型）——BIOS Bug，无影响功能。

acpi_wmi1: <ACPI-WMI mapping> on acpi0
acpi_wmi1: cannot find EC device
acpi_wmi1: Embedded MOF found
ACPI: \134_SB.WFTE.WQCC: 1 arguments were passed to a non-method ACPI object (Buffer) (20241212/nsarguments-361)
# 第二个 ACPI WMI 映射实例。某些主板通过两个 WMI GUID 提供不同类别的功能。
# 此处类似，无 EC 设备导致无法处理 WMI 事件。

# ===== 网络接口就绪 =====
lo0: link state changed to UP
# lo0（loopback 127.0.0.1）接口链路状态变为 UP。loopback 永远在线。

igc0: link state changed to UP
# Intel I226-V 有线网卡链路状态 UP。物理电缆插入且链路协商正常。

# ===== 蓝牙设备最终挂载 =====
ubt0 on uhub0
ubt0: <Realtek Bluetooth Radio, class 224/1, rev 1.00/0.00, addr 1> on usbus1
# ubt(4) 蓝牙 USB 设备驱动已经绑定。蓝牙为 USB class 224（Wireless），
# subclass 1（RF Controller = Bluetooth），protocol 1（BR/EDR+LE）。

# ===== MAC 安全策略加载 =====
Security policy loaded: MAC/ntpd (mac_ntpd)
# mac_ntpd(4)：MAC（强制访问控制/TrustedBSD）框架的 ntpd 隔离策略。
# 授予 ntpd 用户（uid 123）调节系统时钟和绑定 NTP 端口（123）的权限，
# 使 ntpd 能够以非 root 用户身份运行。这是 FreeBSD 默认安全策略之一。
```


# 16.3 引导管理器与 UEFI 固件

统一可扩展固件接口（Unified Extensible Firmware Interface，UEFI）是现代计算机的固件接口标准，旨在取代传统的基本输入输出系统（BIOS）。

UEFI 规范定义了操作系统与平台固件之间的接口，提供了启动服务（Boot Services）和运行时服务（Runtime Services），以及用于存储启动变量的非易失性存储空间。

FreeBSD 同时支持传统的 MBR 标准和 GUID 分区表（GUID Partition Table，GPT）引导方式。GPT 分区通常出现在使用 UEFI 固件的计算机上，但 FreeBSD 也可以通过 gptboot(8) 在仅有传统 BIOS 的机器上从 GPT 分区引导。

UEFI 引导过程与传统 BIOS 引导过程在架构上有所不同。

在传统 BIOS 系统中，固件读取主引导记录（MBR）中的引导代码并执行。

在 UEFI 系统中，固件直接从 EFI 系统分区（ESP）上的 FAT32 文件系统中加载 EFI 应用程序。ESP 是一个专用分区，其分区类型 GUID 为 `C12A7328-F81F-11D2-BA4B-00A0C93EC93B`，通常挂载于 **/boot/efi**。UEFI 引导加载程序是 `loader.efi`。其加载方式有两种：通过 efibootmgr(8) 配置或作为默认引导程序放置时，由固件直接加载；当 `loader.efi` 位于 UFS 或 ZFS 文件系统内时，则由固件先加载 `boot1.efi`，再由 `boot1.efi` 加载 `loader.efi`。使用 bsdinstall(8) 安装的系统，`loader.efi` 由固件直接加载。

## UEFI 系统检测方法

efibootmgr 是 FreeBSD 基本系统中用于查看和管理 EFI 启动项的工具，与 UEFI 固件交互以操作启动项配置。

在非 UEFI 环境下运行 efibootmgr 将报错 `efi variables not supported on this system`。

```sh
# efibootmgr
efibootmgr: efi variables not supported on this system. root? kldload efirt?
```

如果当前系统是 UEFI，efibootmgr 会输出类似以下内容：

```sh
# efibootmgr
Boot to FW : false
BootCurrent: 0004
BootOrder  : 0004, 0000, 0001, 0002, 0003
+Boot0004* FreeBSD
Boot0000* EFI VMware Virtual SCSI Hard Drive (0.0)
Boot0001* EFI VMware Virtual IDE CDROM Drive (IDE 1:0)
Boot0002* EFI Network
Boot0003* EFI Internal Shell (Unsupported option)
```

## UEFI 与 efibootmgr

* 查看当前启动项：

```sh
# efibootmgr
Boot to FW : false
BootCurrent: 0001
Timeout    : 1 seconds
BootOrder  : 0002, 0003, 0000, 0001
 Boot0002* Windows Boot Manager
 Boot0003* UEFI OS
 Boot0000* refind
+Boot0001* freebsd # + 为默认启动项
```

> **技巧**
>
> 使用 `efibootmgr -v` 可查看详细信息。

设置 rEFInd 优先启动（这并非将其设为默认启动项，仅改变 BIOS/UEFI 中的启动顺序）：

设置 EFI 启动顺序为 0000, 0001, 0002, 0003：

```sh
# efibootmgr -o 0000,0001,0002,0003
Boot to FW : false
BootCurrent: 0001
Timeout    : 1 seconds
BootOrder  : 0000, 0001, 0002, 0003
 Boot0000* refind
+Boot0001* freebsd
 Boot0002* Windows Boot Manager
 Boot0003* UEFI OS
```

> **警告**
>
> 不应使用 `efibootmgr -o 0000` 直接指定启动顺序，这样会将 BootOrder 设置为仅包含 0000，导致其他启动项被排除在启动顺序之外（启动项本身仍然存在，但不会被固件尝试引导）。

## UEFI 操作实例

多硬盘系统中，有时需要将分散的 EFI 分区合并为单一分区管理，以简化启动配置。以下示例演示如何将两块硬盘上的 EFI 配置文件统一到一块硬盘的 EFI 分区中。

EFI 分区的目录结构如下：

```sh
/mnt/efi/                  # EFI 分区挂载点
└── EFI/
    ├── freebsd/            # FreeBSD 引导文件目录
    │   └── loader.efi      # FreeBSD UEFI 引导程序
    ├── Boot/                # 默认引导目录
    │   └── bootx64.efi     # UEFI 平台默认回退引导程序
    └── Microsoft/           # Windows 引导目录（双系统场景）
```

此示例删除 nda0 上由 FreeBSD 安装生成的 EFI 分区，并将 FreeBSD 的引导文件迁移到 `ada0` 硬盘的 EFI 分区中。

首先关闭 Windows 的快速启动，命令为 `powercfg /h off`（若能进入 BIOS 设置界面，则无需关闭）。

随后关机并重启进入 FreeBSD 系统，创建挂载点：

```sh
# mkdir /mnt/efi
```

检测 `ada0p1`（硬盘的第一个分区）是否为待挂载的 EFI 分区，输入命令：

```sh
# fstyp /dev/ada0p1 # 检测 /dev/ada0p1 分区的文件系统类型，但不修改
```

上述命令输出为 `ntfs`，说明该分区不是 EFI 分区；

再检查第二块分区：

```sh
# fstyp /dev/ada0p2 # 检测 /dev/ada0p2 分区的文件系统类型
```

输出 `msdosfs`，表明这是 Windows 磁盘上的 EFI 分区。

接下来挂载 ada0 磁盘上的 EFI 分区到 FreeBSD 的 **/mnt/efi**：

```sh
# mount -t msdosfs /dev/ada0p2 /mnt/efi
```

为 FreeBSD 引导项在 EFI 路径下创建目录：

```sh
# mkdir /mnt/efi/EFI/freebsd
```

将 FreeBSD 启动文件复制到该路径：

```sh
# cp /boot/loader.efi /mnt/efi/EFI/freebsd/loader.efi
```

创建 EFI 启动项“FreeBSD 15.0”，指向 FreeBSD 的引导程序：

```sh
# efibootmgr -a -c -l /mnt/efi/EFI/freebsd/loader.efi -L "FreeBSD 15.0"
```

重启进入 Windows，使用 EasyUEFI 激活 `FreeBSD 15.0` 启动项。

确认 FreeBSD 可正常启动后，才能使用 [DiskGenius](https://www.diskgenius.cn/) 或其他分区工具删除 nda0 磁盘的 EFI 分区及其文件。

## Grub

测试表明，UEFI + ZFS 环境中，GRUB 直接引导 FreeBSD 内核存在兼容性问题，通常推荐使用 chainload 机制（如配置 `chainloader +1`）间接引导。传统 BIOS 启动 + UFS 根文件系统环境中，GRUB 可通过 `kfreebsd` 命令直接引导 FreeBSD 内核。

```ini
menuentry "FreeBSD 14.2-RELEASE" { # 指定 GRUB 条目名称
set root='(hd0,gpt1)'  # 根据实际情况确认，此处为 EFI 系统分区
chainloader /EFI/freebsd/loader.efi # 指定 FreeBSD 的 EFI 引导文件
}
```

### 故障排除

目前配置的报错（`grub2-efi` FreeBSD 15.0）：

```sh
# grub-install --target=x86_64-efi --efi-directory=/boot/efi/efi/ --bootloader-id=grub --boot-directory=/boot/ --modules="part_gpt part_msdos bsd zfs"
grub-install: error: relocation 0x4 is not implemented yet.
# grub-install --target=x86_64-efi --efi-directory=/boot/efi/efi/ --bootloader-id=grub --boot-directory=/boot/ --modules="part_gpt part_msdos bsd zfs"
Installing for x86_64-efi platform.
grub-install: error: unknown filesystem.
```

添加参数 `-vvv` 可查看详细错误信息，输出内容较长，可在 <https://gist.github.com/ykla/9b6de6c8d4eee524840acb9981bf850a> 查看。

## rEFInd 引导管理器（多系统引导管理）

多系统环境下，频繁进入 BIOS 固件界面切换操作系统较为不便。可借助 [rEFInd](https://www.rodsbooks.com/refind/) 实现类似于 Clover 的可视化启动菜单效果，开机时直观地选择要进入的操作系统。

`rEFInd` 派生自 `rEFIt`，其名称可理解为“re-find”（意为“重新发现”）与“EFI”（Extensible Firmware Interface，可扩展固件接口）的组合，主要用于管理 UEFI 启动，提供图形化界面与灵活的配置选项。

首先需要下载 rEFInd 软件。打开下载页面 [Getting rEFInd from Sourceforge](https://www.rodsbooks.com/refind/getting.html)，点击 `A binary zip file` 链接开始下载。本节撰写时使用的版本为 `refind-bin-0.14.2.zip`。

下载的压缩包中，仅部分文件是必需的启动文件。仅需保留其中的 `refind` 文件夹，其余文件无需使用。

`refind` 文件夹中也仅包含部分必需的启动文件。所有文件名中包含 `aa64` 或 `ia32` 的文件均可删除（通常仅保留 `x64` 版本）。

最终需要保留的文件如下图所示。

![rEFInd 文件结构](/files/XMwAHLuv8AUEzUu2ju1d)

将 `refind.conf-sample` 文件复制一份，并重命名为 `refind.conf`。

通常无需手动配置。但若出现无法自动识别现有操作系统的情况，请按以下方法手动添加引导项：

打开 `refind.conf` 文件，在任意空白处添加如下配置：

```ini
menuentry "FreeBSD" {
	icon \EFI\refind\icons\os_freebsd.png
	volume "FreeBSD"
	loader \EFI\freebsd\loader.efi
}

menuentry "Windows 10" {
	icon \EFI\refind\icons\os_win.png
	volume "Windows 10"
	loader \EFI\Microsoft\Boot\bootmgfw.efi
}
```

目录结构：

```sh
EFI/
├── refind/
│   ├── refind.conf        # rEFInd 主配置文件
│   ├── refind.conf-sample # rEFInd 示例配置文件
│   ├── refind_x64.efi     # rEFInd 64 位启动文件
│   ├── icons/
│   │   ├── os_freebsd.png # FreeBSD 图标
│   │   └── os_win.png    # Windows 图标
│   └── themes/
│       └── Matrix-rEFInd/
│           └── theme.conf  # Matrix 主题配置
├── freebsd/
│   └── loader.efi        # FreeBSD 引导加载程序
└── Microsoft/
    └── Boot/
        └── bootmgfw.efi   # Windows 启动管理器
```

使用 [DiskGenius](https://www.diskgenius.com/) 将处理后的 `refind` 文件夹复制到 EFI 系统分区（ESP）的 `EFI` 目录下。

![复制 rEFInd 到 EFI 分区](/files/sCNxTAz45dtIaWJtErd5)

### 添加启动项

使用 [DiskGenius](https://www.diskgenius.com/) 添加 UEFI 引导项。

![添加 UEFI 引导项](/files/Jvq0OANcvctuFabsGSzb)

点击菜单栏的“工具”，选择“设置 UEFI BIOS 启动项”。

![设置 UEFI BIOS 启动项](/files/GFOqRgLzQmWnITcEfNaj)

在新窗口中点击“添加”，随后浏览并选中 `refind` 文件夹内的 `refind_x64.efi` 文件。

![选择 rEFInd 启动文件](/files/MRQg7wUIFSTn0VzenNLB)

将该启动项移动至列表顶部，设为第一启动项。保存设置并重启电脑以测试效果。

![移动启动项至顶部](/files/ZP4dpFXQ4I4Nq2HkRv4z)

![rEFInd 启动界面](/files/f3BuWsUmROIpANKN1qfJ)

重启后，在 rEFInd 界面中选择任一操作系统选项，即可进入相应系统。

### 附录：rEFInd 主题

rEFInd 支持多种图形化主题。

本例以 Matrix-rEFInd（灵感来源于电影《黑客帝国》）主题为例来说明。

项目地址为：[Matrix-rEFInd](https://github.com/Yannis4444/Matrix-rEFInd/)

下载项目压缩包 `Matrix-rEFInd-master.zip` 并解压。将解压得到的文件夹 `Matrix-rEFInd-master` 重命名为 `Matrix-rEFInd`。

在本地新建目录 `themes`，将重命名后的 `Matrix-rEFInd` 文件夹放入其中。

将此 `themes` 目录整体复制到 EFI 系统分区中的 \**EFI\refind\** 目录下。

编辑 `refind.conf` 文件（如果无法直接在 ESP 中编辑，可将其复制到桌面，修改后覆盖原文件），在文件末尾添加一行：

```ini
include themes/Matrix-rEFInd/theme.conf
```

即可调用主题 Matrix-rEFInd。

重启之后观察效果：

![rEFInd Matrix 主题](/files/Jo7NhZhQeGSQmPgL58vi)

> **技巧**
>
> 如果在虚拟机（如 VMware、VirtualBox）中操作，由于其 UEFI 固件的屏幕分辨率限制，rEFInd 界面可能无法同时显示所有操作系统选项，需通过方向键切换查看，这与上图所示的效果可能不同。

## 参考文献

* Microsoft. set id (Diskpart)\[EB/OL]. (2024-11-01)\[2026-04-28]. <https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/set-id>. EFI 系统分区的 GUID 是 c12a7328-f81f-11d2-ba4b-00a0c93ec93b。
* Smith R W. rEFInd Boot Manager\[EB/OL]. \[2026-04-17]. <https://www.rodsbooks.com/refind/>. rEFInd 官方网站，该引导管理器派生自 rEFIt 项目，用于管理 UEFI 环境下的多系统启动。
* archlinuxcn. efibootmgr 无法添加 UEFI 启动项\[EB/OL]. \[2026-03-26]. <https://bbs.archlinuxcn.org/viewtopic.php?id=12914>. 讨论 efibootmgr 在部分固件上无法写入启动项的原因与替代方案。
* FreeBSD Project. efibootmgr(8)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=efibootmgr&sektion=8>. UEFI 启动管理器手册页。
* emacs\_8861834. 深入掌握 efibootmgr 操作要领安全删除启动项方法解析\[EB/OL]. \[2026-03-26]. <https://my.oschina.net/emacs_8861834/blog/17450288>. 详解 efibootmgr 各子命令的用法及安全删除启动项的注意事项。
* Stack Exchange. Working GRUB configuration for UEFI booting FreeBSD\[EB/OL]. \[2026-03-26]. <https://unix.stackexchange.com/questions/354260/working-grub-configuration-for-uefi-booting-freebsd>. 提供 GRUB 引导 FreeBSD 的可用配置示例与排错经验。
* Reddit. Trying to boot FBSD13 via grub2\[EB/OL]. \[2026-03-26]. <https://www.reddit.com/r/freebsd/comments/q4qgq9/trying_to_boot_fbsd13_via_grub2/>. 讨论通过 GRUB2 引导 FreeBSD 13 时遇到的常见问题。

## 课后习题

1. 在 QEMU 中测试 UEFI 固件下 FreeBSD 引导的多阶段流程，验证 EFI loader、loader.efi 和内核加载的各个阶段。
2. 尝试在 FreeBSD 上编译 Clover 引导管理器，记录编译过程中的平台适配问题。
3. 安装 FreeBSD 时，创建独立的 EFI 分区与 freebsd-boot 分区，对比两种引导方式下系统启动日志的差异。


# 16.4 进程与守护进程

## 进程与守护进程概述

FreeBSD 是一个多任务操作系统。任何时刻运行的程序均称为进程。每个运行的命令至少启动一个新进程，此外还有许多由 FreeBSD 运行的系统进程。

每个进程都由一个称为进程 ID（PID）的数字唯一标识。与文件类似，每个进程都有一个属主和组，属主和组权限用于确定进程可以打开哪些文件和设备。大多数进程还有一个启动它们的父进程。例如，shell 是一个进程，在 shell 中启动的任何命令都是以 shell 为父进程的进程。例外是特殊进程 init(8)，其始终是系统启动时的首个进程，并且始终具有 PID 1。在 FreeBSD 中，所有进程都是以某个账户的名义启动的。

Port **sysutils/htop** 能够直观地呈现这一点（注意 `△USER` 这列）：

```sh
$ htop
  PID△USER       PRI  NI  VIRT   RES S   CPU% MEM%   TIME+  Command
    1 root        20   0 12724  1324 S    0.0  0.0  0:00.08 /sbin/init
  216 root        20   0 36172  7308 S    0.0  0.1  0:00.77 ├─ /usr/local/bin/vmtoolsd -c /usr/local/share/vmware-tools/to
  400 root        48   0 14188  2684 S    0.0  0.0  0:00.00 ├─ dhclient: system.syslog
  403 root         4   0 14188  2760 S    0.0  0.0  0:00.00 ├─ dhclient: em0 [priv]
  481 _dhcp       20   0 14192  2808 S    0.0  0.0  0:00.01 ├─ dhclient: em0
  596 root        20   0 15444  4204 S    0.0  0.1  0:00.05 ├─ /sbin/devd
  800 root        20   0 13904  2792 S    0.0  0.0  0:00.02 ├─ /usr/sbin/syslogd -s
  867 messagebus  20   0 15188  4492 S    0.0  0.1  0:00.29 ├─ /usr/local/bin/dbus-daemon --system
  870 root        20   0 14120  2456 S    0.0  0.0  0:00.06 ├─ /usr/sbin/moused -p /dev/psm0 -t auto
  898 ntpd        20   0 24564  5848 S    0.0  0.1  0:00.06 ├─ /usr/sbin/ntpd -p /var/db/ntp/ntpd.pid -c /etc/ntp.conf -f
  944 root        68   0 23508  9560 S    0.0  0.1  0:00.00 ├─ sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups
  947 root        20   0 13944  2576 S    0.0  0.0  0:00.02 ├─ /usr/sbin/cron -s
  952 root        20   0 56736 23700 S    0.0  0.3  0:00.04 ├─ /usr/local/bin/sddm
  980 root        20   0  257M  124M S    1.0  1.5  0:04.83 │  ├─ /usr/local/libexec/Xorg -nolisten tcp -background none -
  993 root        23   0 50208 27572 S    0.0  0.3  0:00.02 │  └─ /usr/local/libexec/sddm-helper --socket /tmp/sddm-auth-4
  994 ykla        68   0 19992  4620 S    0.0  0.1  0:00.01 │     └─ /usr/local/bin/ck-launch-session /usr/local/bin/start
 1005 ykla        68   0  128M 67736 S    0.0  0.8  0:00.13 │        └─ /usr/local/bin/startplasma-x11
 1010 ykla        68   0  128M 68184 S    0.0  0.8  0:00.25 │           └─ /usr/local/bin/plasma_session
 1017 ykla        20   0  773M  190M S    0.0  2.3  0:01.33 │              ├─ /usr/local/bin/kded6
 1018 ykla        20   0  676M  262M S    0.0  3.2  0:30.96 │              ├─ /usr/local/bin/kwin_x11
```

有些程序并非为持续接收用户输入而设计，而是在启动后即与终端断开连接。例如，Web 服务器响应 Web 请求而非用户输入，邮件服务器是此类应用程序的另一个例子。这类程序被称为守护进程（daemon）。术语“daemon”来自希腊神话，代表一种非善非恶的实体，它默默执行有用的任务。因此，BSD 的吉祥物设计为身着运动鞋、手持草叉的快乐守护进程形象。在 Windows 系统中，这类程序被称为“服务”，可在任务管理器中查看。

这些长期在后台运行的服务通常命名为 `xxxd`，例如 `sshd`、`ntpd`，其中的 `d` 表示守护进程（[daemon](https://www.freebsd.org/copyright/daemon/)），这是 UNIX 系统的通用命名约定。例如，BIND 是 Berkeley Internet Name Domain，但实际执行的程序名为 named。Apache Web 服务器程序是 httpd，数据同步 Rsync 进程是 rsyncd。但这仅是命名约定，并无规范，如 `cron` 和 `sendmail` 的进程都不带 `d`。

## 查看进程

用户只能向自己拥有的进程发送信号，root 用户可以向任何进程发送信号。SIGKILL 和 SIGSTOP 信号无法捕获或忽略。特殊 PID：`0` 发送到同组所有进程，`-1` 发送到所有进程（root）或自己的所有进程。

要查看系统上运行的进程，可以使用 ps(1) 或 top(1)。FreeBSD 的 `ps` 基于 4.4BSD，BSD 风格关键字允许省略 `-`，如 `ps auxww`。

要显示当前运行进程的静态列表（包括它们的 PID、内存使用量和启动命令），使用 ps(1)。要以交互方式显示所有运行进程并每隔几秒更新显示以查看系统运行状态，使用 top(1)。

默认情况下，ps(1) 仅显示由当前用户拥有、且具有控制终端的进程：

```sh
$ ps
 PID TT  STAT    TIME COMMAND
1971  0  Is   0:00.03 -sh (sh)
2183  1  Ss   0:00.05 -sh (sh)
2186  1  R+   0:00.00 ps
```

ps(1) 的输出由多列构成：

| 列名      | 说明                                                                  |
| ------- | ------------------------------------------------------------------- |
| PID     | 进程 ID。PID 从 1 开始分配，递增至 99999 后回绕至起始值。若某个 PID 已被占用，则不会再次分配。          |
| TT      | 程序运行所在的 tty。                                                        |
| STAT    | 程序的状态。                                                              |
| TIME    | 程序在 CPU 上运行的时间量，通常不是程序启动以来的经过时间，因为大多数程序在需要花费 CPU 时间之前会花费大量时间等待事件触发。 |
| COMMAND | 用于启动程序的命令。                                                          |

有许多不同的选项可用于更改显示的信息。最有用的选项集之一是 `auxww`，其中：

| 选项  | 说明                                                                                    |
| --- | ------------------------------------------------------------------------------------- |
| `a` | 显示所有用户的有控制终端的进程的信息。若系统设置 `security.bsd.see_other_uids=0`，则非 root 用户使用此选项将无法查看其他用户的进程。 |
| `u` | 显示进程属主的用户名和内存使用量。                                                                     |
| `x` | 显示守护进程的信息。                                                                            |

`ps -auxww` 示例：

```sh
$ ps -auxww
USER   PID   %CPU %MEM   VSZ   RSS TT  STAT STARTED      TIME COMMAND
root    11 1592.5  0.0     0   256  -  RNL  11:51   648:25.89 [idle]
root     0    0.0  0.1     0  4240  -  DLs  11:51     0:05.08 [kernel]

……省略部分输出……

_dhcp  792    0.0  0.1 14656  3532  -  ICs  11:51     0:00.04 dhclient: em0 (dhclient)
root  1211    0.0  0.1 14652  3156  -  Is   11:51     0:00.00 /usr/sbin/moused -p /dev/input/event5 -t evdev -I /var/run/moused.event5.pid

……省略部分输出……

root  1974    0.0  0.1 14816  3532  0  I    12:04     0:00.01 su
root  1975    0.0  0.1 14872  3728  0  I+   12:04     0:00.03 su (sh)
ykla  2183    0.0  0.1 14872  3728  1  Ss   12:28     0:00.05 -sh (sh)
ykla  2191    0.0  0.1 14956  3576  1  R+   12:31     0:00.00 ps -auxww
```

选项 `ww` 可以使 ps(1) 显示每个进程的完整命令行，而非在超出屏幕宽度时截断。但是，因为内核中存储的命令行长度有限制，在某些情况下，使用带有 `ww` 选项的 `ps` 时，输出可能仍然被截断。对于内核线程，命令字段可能显示为 `[ ]` 包裹的名称。

top(1) 的输出如下：

```sh
$ top
last pid:  2189;  load averages:    0.24,    0.13,    0.04        up 0+00:39:10  12:30:35
30 processes:  1 running, 29 sleeping
CPU:  0.0% user,  0.0% nice,  0.0% system,  0.0% interrupt,  100% idle
Mem: 26M Active, 21M Inact, 260M Wired, 2056K Buf, 3617M Free
ARC: 35M Total, 6321K MFU, 27M MRU, 128K Anon, 407K Header, 1467K Other
     19M Compressed, 52M Uncompressed, 2.76:1 Ratio
Swap: 8192M Total, 8192M Free

  PID USERNAME    THR PRI NICE   SIZE    RES STATE    C   TIME    WCPU COMMAND
 2183 ykla          1   0    0    15M  3728K wait     9   0:00   0.10% sh
 1623 ntpd          2   0    0    26M  7072K select  12   0:00   0.00% ntpd
 1783 root          1   0    0    15M  3708K ttyin    5   0:00   0.00% sh
 2179 root          1   3    0    25M    12M select  12   0:00   0.00% sshd-session
 1714 root          1   0    0    25M    11M select   5   0:00   0.00% sshd
 1756 root          1   1    0    14M  3076K nanslp  14   0:00   0.00% cron
 1496 root          1   0    0    14M  3456K kqread  15   0:00   0.00% syslogd
 1224 root          1   0    0    16M  4668K select   0   0:00   0.00% devd
 1967 root          1   1    0    25M    12M select  11   0:00   0.00% sshd-session
  792 _dhcp         1   0    0    14M  3532K select   1   0:00   0.00% dhclient
 2182 ykla          1   0    0    25M    12M select   4   0:00   0.00% sshd-session
 1970 ykla          1   0    0    25M    12M select   5   0:00   0.00% sshd-session
 1975 root          1   1    0    15M  3728K ttyin    1   0:00   0.00% sh
 1971 ykla          1   9    0    15M  3720K wait     9   0:00   0.00% sh
 1499 root          1   0    0    14M  3276K select  15   0:00   0.00% syslogd
 1638 root          1   0    0    14M  3160K kqread   8   0:00   0.00% moused
 1974 ykla          1   7    0    14M  3532K wait    15   0:00   0.00% su
```

输出分为两个部分。头部（示例命令为前 7 行）显示最后运行的进程的 PID、系统负载平均值（衡量系统繁忙程度的指标）、系统正常运行时间（自上次重启以来的时间）和当前时间。头部中的其他数字与运行中的进程数量、已使用的内存和交换空间数量，以及系统在不同 CPU 状态下花费的时间有关。如果加载了 ZFS 文件系统模块，ARC 行指示从内存缓存而非磁盘读取了多少数据。

头部下方是一系列列，包含与 ps(1) 输出类似的信息，如 PID、用户名、CPU 时间量和启动进程的命令。在默认情况下，top(1) 还显示进程占用的内存空间量，分为两列：一列用于总大小，一列用于驻留大小。总大小是应用程序需要的内存量，驻留大小是它当前实际使用的量。top(1) 默认每两秒自动更新显示，可以使用 `-s` 指定不同的间隔，如 `-s4` 将每隔 4 秒刷新一次。

在非常繁忙的系统上，top 可能显示略微滞后的信息，因为采样需要时间。

## 终止进程

与任何运行中的进程或守护进程通信的一种方式是使用 kill(1) 发送信号。有许多不同的信号；有些具有特定含义，而其他信号在应用程序的文档中描述。用户只能向自己拥有的进程发送信号，向其他人的进程发送信号会提示权限不足。例外是 root 用户，其可向任何进程发送信号。

操作系统也可以向进程发送信号。如果应用程序编写不当并试图访问不应访问的内存，FreeBSD 将向进程发送“段违规”信号（SIGSEGV）。如果应用程序编写为使用 alarm(3) 系统调用在一段时间后收到警报，它将收到“闹钟”信号（SIGALRM）。

两个信号可用于停止进程：SIGTERM 和 SIGKILL。因为进程可以读取信号、关闭可能打开的任何日志文件，并尝试在关闭前完成正在执行的操作，SIGTERM 是终止进程的较为温和的方式。在某些情况下，如果进程正在执行某些无法中断的任务，它可能会忽略 SIGTERM。

进程无法忽略 SIGKILL。向进程发送 SIGKILL 通常会立即停止该进程。

其他常用的信号是 SIGHUP、SIGUSR1 和 SIGUSR2。由于这些是通用信号，不同的应用程序会有不同的响应。例如，在更改 Web 服务器的配置文件后，需要告诉 Web 服务器重新读取其配置。重启 httpd 会导致 Web 服务器短暂停机。相反，应向守护进程发送 SIGHUP 信号来使其重新读取配置。请注意，不同的守护进程会有不同的行为，因此请参阅守护进程的文档以确定 SIGHUP 是否能达到预期的结果。

随意终止系统中的进程是危险行为。尤其 init(8)，PID 1 是最特殊的。

## 命令的前台与后台运行

**Ctrl**+**Z**：将当前进程挂起（暂停），随后可使用 `fg` 命令将其恢复到前台：

```sh
# ping 163.com  # 测试与 163.com 的网络连通性
PING 163.com (59.111.160.244): 56 data bytes
64 bytes from 59.111.160.244: icmp_seq=0 ttl=52 time=27.611 ms
64 bytes from 59.111.160.244: icmp_seq=1 ttl=52 time=27.691 ms
^Z[1] + Suspended               ping 163.com # 注意此处，按下了 Ctrl+Z
# fg # 返回前台
ping 163.com
64 bytes from 59.111.160.244: icmp_seq=3 ttl=52 time=27.465 ms
64 bytes from 59.111.160.244: icmp_seq=4 ttl=52 time=27.586 ms
64 bytes from 59.111.160.244: icmp_seq=5 ttl=52 time=27.522 ms
^C # 按 Ctrl+C 结束命令
--- 163.com ping statistics ---
6 packets transmitted, 6 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 27.465/27.596/27.701/0.085 ms
```

## 附录：系统监控工具 htop

### 安装与配置

**使用 pkg 二进制包管理器安装：**

```sh
# pkg install htop
```

**或使用 Port 从源代码构建安装：**

```sh
# cd /usr/ports/sysutils/htop/
# make install clean
```

### htop 配置持久化

可通过界面或配置文件持久化 htop 的配置。需注意：在设置菜单中按 F10 保存后，若使用 Ctrl + C 退出 htop，已保存的设置将被丢弃；必须使用 F10 或 q 正常退出才能确保配置写入 **\~/.config/htop/htoprc**。

也可以手动编辑用户目录下的 **\~/.config/htop/htoprc** 配置文件，添加以下内容以启用 CPU 频率和温度显示功能：

```ini
show_cpu_frequency=1     # 启用 CPU 当前频率显示
show_cpu_temperature=1   # 启用 CPU 温度显示
```

### 参考文献

* htop-dev. Settings are not saved\[EB/OL]. \[2026-03-25]. <https://github.com/htop-dev/htop/issues/949>. 讨论了 htop 配置保存的常见问题与解决方案。

## 课后习题

1. 使用 `ps aux` 和 `top` 查看系统运行的进程，按用户进程与系统守护进程进行分类，分析两类进程在父进程关系和会话组上的特征差异。
2. 使用 `nice` 和 `renice` 修改进程优先级，记录不同 nice 值对 CPU 密集型任务执行时间的影响，分析 FreeBSD 调度程序对优先级的处理机制。
3. 编写一个简单的守护进程脚本，配置为 rc.d 服务，使用 `service` 命令启动、停止和查询其状态，记录服务生命周期管理的完整流程。


# 16.5 管理 FreeBSD 中的服务

## 概述

FreeBSD 使用传统的 BSD init（初始化系统）管理系统服务。与 systemd 等现代初始化系统不同，BSD init 采用基于脚本的服务管理方式。所有其他进程均由 init 直接或间接启动。rc 启动脚本系统用于系统初始化及服务管理。

简单脚本示例如下：

```sh
#!/bin/sh
#
# PROVIDE: utility
# REQUIRE: DAEMON
# KEYWORD: shutdown

. /etc/rc.subr

name=utility
rcvar=utility_enable

command="/usr/local/sbin/utility"

load_rc_config $name

#
# 不应在此处修改默认值，请在 /etc/rc.conf 中设置
#
utility_enable=${utility_enable-"NO"}
pidfile=${utility_pidfile-"/var/run/utility.pid"}

run_rc_command "$1"
```

FreeBSD 提供了两个核心的服务管理命令：`service` 命令用于控制 rc.d 系统中的服务启动脚本，支持 `start`、`stop`、`restart`、`status` 等操作，并可列出可用服务。

`sysrc` 命令用于安全地修改 rc.conf(5) 中的系统配置值。它从 **/etc/defaults/rc.conf** 中读取 `rc_conf_files` 变量来确定要操作的文件列表，默认值为 `/etc/rc.conf /etc/rc.conf.local`，避免手动编辑导致语法错误。修改变量时，若变量已存在于这些文件中，则替换最后出现的那一个；若不存在，则追加到 `rc_conf_files` 列表中的第一个文件。

## 目录结构

```sh
/
├── etc/  # 参见 rc.conf(5)
│   ├── defaults/
│   │   ├── rc.conf         # 系统默认 rc 配置
│   │   └── vendor.conf     # 厂商默认配置（默认不存在）
│   ├── rc                  # 系统启动主脚本
│   ├── rc.conf             # 用户主配置文件
│   ├── rc.conf.local       # 本地自定义配置（默认不存在），用于开机时自定义配置
│   ├── rc.conf.d/          # 分散的用户自定义配置文件目录（默认为空）
│   ├── rc.d/               # 基本系统的服务脚本，参见 rc.d(8)
│   ├── rc.firewall         # 防火墙启动脚本
│   ├── rc.local            # 本地自定义启动脚本（默认不存在）
│   ├── rc.shutdown         # 系统关机执行脚本
│   ├── rc.suspend          # 系统挂起前执行的脚本
│   └── rc.subr             # rc 脚本公共函数库
├── var/
│   └── run/
│       └── dmesg.boot      # 启动时 dmesg(8) 输出
└── usr/
    └── local/
        └── etc/
            └── rc.d/       # 第三方应用的服务脚本
```

上述文件在 FreeBSD 源代码中主要位于 [libexec/rc](https://github.com/freebsd/freebsd-src/tree/main/libexec/rc) 路径下。

> **注意**
>
> 不应编辑 **/etc/defaults/rc.conf** 文件中包含的默认设置。所有系统特定的更改应写入 **/etc/rc.conf**。**/etc/rc.conf** 文件的优先级高于 **/etc/defaults/rc.conf** 文件。换言之，**/etc/rc.conf** 文件将覆盖 **/etc/defaults/rc.conf** 文件中的同名配置项。

> **技巧**
>
> **/etc/rc.conf** 和 **/etc/rc.conf.local** 都由 sh(1) 解析。这使得系统操作员能够创建复杂的配置场景。

## 管理系统特定的配置

系统配置的主要位置是 **/etc/rc.conf**。该文件包含广泛的配置信息，系统启动时读取，用于配置系统。它为 rc\* 文件提供配置信息。

**/etc/rc.conf** 中的条目将覆盖 **/etc/defaults/rc.conf** 中的默认设置。推荐将特定系统的配置放入 **/etc/rc.conf.local** 文件。

> **技巧**
>
> 系统更新不会覆盖 **/etc/rc.conf**，因此系统配置信息不会丢失。

集群应用程序中，可以采取多种策略，将全站配置与特定系统配置分开，以减少管理开销。

例如，**/etc/rc.conf** 文件中的这些条目适用于所有系统：

```ini
sshd_enable="YES"
defaultrouter="10.1.1.254"
```

而 **/etc/rc.conf.local** 中的这些条目仅适用于该系统：

```ini
hostname="node1.example.org"
ifconfig_fxp0="inet 10.1.1.1/8"
```

使用诸如 `rsync` 或 `puppet` 等应用程序将 **/etc/rc.conf** 分发到每个系统，而 **/etc/rc.conf.local** 保持唯一。

## 常用命令集

BSD init 系统提供了 `service` 命令作为服务管理的统一接口，配合 `sysrc` 命令实现服务的启动、停止和开机自启动配置。以下是常用命令集。

启动服务：

```sh
# service xxx start
```

停止服务：

```sh
# service xxx stop
```

临时启动服务（即使未在 rc.conf 文件中启用）：

```sh
# service XXX onestart
```

临时停止服务（即使未在 rc.conf 文件中启用）：

```sh
# service XXX onestop
```

重启服务：

```sh
# service xxx restart
```

添加服务并设置开机自启：

```sh
# service xxx enable
# sysrc xxx_enable="YES"
```

> **注意**
>
> `service xxx enable` 命令并非适用于所有服务，仍有局限，参见：FreeBSD Project. rc keywords: enable, disable, delete cannot manage certain built-in rc startup items.\[EB/OL]. \[2026-03-26]. <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=285543>. 下同。

禁用开机启动：

```sh
# service xxx disable
# sysrc xxx_enable="NO"
```

删除启动项：

```sh
# service xxx delete
```

> **注意**
>
> 关键字 `enable`、`disable`、`delete` 参见：FreeBSD Project. Add new rc keywords: enable, disable, delete\[EB/OL]. \[2026-03-26]. <https://reviews.freebsd.org/D17113>.

系统服务安装后默认未启用，上述命令无法直接执行，需先启用服务。

编辑 **/etc/rc.conf** 文件，在文件中添加一行：`XXX_enable="YES"`，其中 `XXX` 表示服务名称（例如 `nginx`、`samba` 等），这是固定格式。

```ini
# 启用 XXX 服务或功能（将 XXX 替换为具体服务名称），以下格式类似
XXX_enable="YES"
```

> **技巧**
>
> ```sh
> # sysrc XXX_enable="YES"
> ```
>
> 上述命令中 `"YES"` 的双引号可省略，系统会自动添加。`"NO"` 同理。

基本系统服务的脚本路径为 **/etc/rc.d/**，第三方应用服务的脚本路径为 **/usr/local/etc/rc.d/**。可直接调用这两个目录下的脚本。

重新加载服务配置：

```sh
# /usr/local/etc/rc.d/XXX reload
```

停止服务：

```sh
# /usr/local/etc/rc.d/XXX stop
```

## 默认 rc.conf 配置文件的内容与结构

默认 rc.conf 配置文件的源代码位于 [libexec/rc/rc.conf](https://github.com/freebsd/freebsd-src/blob/main/libexec/rc/rc.conf)，对应提交为 [Set virtual\_oss\_enable="NO" in **/etc/defaults/rc.conf**](https://github.com/freebsd/freebsd-src/commit/1b2d495a24c36d81b14178a2f898025946bff2d8)。

```sh
#!/bin/sh

# 这是 rc.conf 文件 —— 包含许多可用变量，可用于修改系统的默认启动行为。不应直接编辑此文件！
# 应将那些覆盖配置放入 ${rc_conf_files}（即 /etc/rc.conf、/etc/rc.conf.local）中，这样就可以在不污染原生配置信息的情况下，
# 以后更新系统默认值时仍然保留自定义设置。
#
# ${rc_conf_files} 文件中应仅包含那些覆盖本文件中设置的值。
# 这样默认值变动或新增功能时，升级路径会更简单。
#
# 所有参数必须用双引号或单引号括起来。
#
# 如需更详细的 rc.conf 变量说明，请参阅 rc.conf(5) 手册页。

##############################################################
###  重要的启动时初始选项                   ####################
##############################################################

# 如果之前未设置 _localbase，则设置默认值
# 尝试从 sysctl 获取 user.localbase 的值，参见 getlocalbase(3)
# 此处设置的是本地软件第三方目录的基础路径
: ${_localbase:="$(/sbin/sysctl -n user.localbase 2> /dev/null)"}
# 如果获取不到，则默认使用 /usr/local
: ${_localbase:="/usr/local"}


# 不能在此处设置 rc_debug，否则会干扰在设置 kenv 变量 rc.debug 时的 rc.subr 操作
#rc_debug="NO"        # 设置为 YES 可启用 rc.d 的调试输出
rc_info="NO"           # 启用启动时的信息消息显示
rc_startmsgs="YES"     # 启动时显示 "Starting foo:" 消息
rcshutdown_timeout="90" # 在终止 rc.shutdown 前等待的秒数
precious_machine="NO"  # 设置为 YES 可防止意外执行 shutdown(8) 命令
early_late_divider="FILESYSTEMS" # 分隔启动过程早期/晚期阶段的脚本，修改前请确保了解其影响，详见 rc.conf(5)
always_force_depends="NO"        # 设置为 YES 可在启动过程中检查依赖服务是否已启动（可能增加启动时间）


apm_enable="NO"        # 设置为 YES 可启用 BIOS 功能 APM（高级电源管理），否则禁用
apmd_enable="NO"       # 启动 apmd 来处理用户空间的 APM 事件
apmd_flags=""          # 在启用 apmd 时额外传递的标志
ddb_enable="NO"        # 设置为 YES 将在启动时加载 ddb 脚本
ddb_config="/etc/ddb.conf"  # ddb(8) 配置文件路径
devd_enable="YES"      # 启动 devd，用于在设备树变化时触发程序
devd_flags=""          # devd(8) 的额外标志
devmatch_enable="YES"   # 根据设备 ID 按需加载内核模块
devmatch_blocklist=""  # 排除 devmatch 加载的模块列表（不加后缀名 .ko）
#kld_list=""           # 本地磁盘挂载后要加载的内核模块
kldxref_enable="YES"   # 使用 kldxref(8) 构建 linker.hints 文件
kldxref_clobber="NO"   # 启动时是否覆盖旧的 linker.hints
kldxref_module_path="" # 覆盖 kern.module_path；以分号 ';' 分隔的列表
powerd_enable="NO"     # 启动 powerd(8) 降低功耗，系统电源控制管理
powerd_flags=""        # 启用 powerd(8) 时传递的标志
tmpmfs="AUTO"          # 设置为 YES 始终创建 mfs /tmp，NO 表示从不创建
tmpsize="20m"          # 创建 mfs /tmp 时的大小
tmpmfs_flags="-S"      # mfs /tmp 的额外 mdmfs 选项
utx_enable="YES"       # 启用用户账户管理
varmfs="AUTO"          # 设置为 YES 始终创建 mfs /var，NO 表示从不创建
varsize="32m"          # 创建 mfs /var 时的大小
varmfs_flags="-S"      # mfs /var 的额外挂载选项
mfs_type="auto"        # 可选 "md", "tmpfs", "auto"，优先 tmpfs，md 作为回退
populate_var="AUTO"    # 设置为 YES 始终（重新）填充 /var，NO 表示从不填充
cleanvar_enable="YES"  # 清理 /var 目录
var_run_enable="YES"   # 在关机/重启时保存/恢复 /var/run 结构
var_run_autosave="YES" # 仅在关机/重启时恢复 /var/run 结构，用户可通过 service var_run save 手动保存
var_run_mtree="/var/db/mtree/BSD.var-run.mtree"  # 保存 /var/run mtree 的路径
local_startup="${_localbase}/etc/rc.d"         # 启动脚本目录
script_name_sep=" "      # 如果启动脚本名包含空格，可修改此分隔符
rc_conf_files="/etc/rc.conf /etc/rc.conf.local" # 要加载的 rc.conf 文件列表

# ZFS 支持
zfs_enable="NO"             # 设置为 YES 将自动挂载 ZFS 文件系统
zfskeys_enable="NO"         # 设置为 YES 将自动加载 ZFS 加密密钥
zfs_bootonce_activate="NO"  # 设置为 YES，使成功的 bootonce ZFS 启动环境永久生效
zpool_reguid=""              # 指定首次启动时要替换 GUID 的 zpool
zpool_upgrade=""             # 指定首次启动时要升级版本的 zpool

# ZFSD 支持
zfsd_enable="NO"            # 设置为 YES 自动启动 ZFS 故障管理守护进程

gptboot_enable="YES"        # GPT 引导成功/失败报告

# GELI 磁盘加密配置
geli_devices=""             # 除 /etc/fstab 中的 GELI 设备外，自动附加的设备列表
geli_groups=""              # 自动附加同一组设备，使用相同密钥或口令
geli_tries=""               # 尝试附加 geli 设备的次数；为空时使用 kern.geom.eli.tries
geli_default_flags=""       # geli(8) 的默认标志
geli_autodetach="YES"       # 在最后一次关闭时自动分离。在所有文件系统挂载后，提供者将被标记为可自动分离

# 示例用法
#geli_devices="da1 mirror/home"                  # 指定要自动附加的 GELI 加密设备列表
#geli_da1_flags="-p -k /etc/geli/da1.keys"      # 为 da1 设备设置附加标志和密钥文件路径
#geli_da1_autodetach="NO"                        # 设置 da1 设备在最后关闭时是否自动分离（NO 表示不自动分离）
#geli_mirror_home_flags="-k /etc/geli/home.keys" # 为 mirror/home 设备设置密钥文件
#geli_groups="storage backup"                    # 定义设备组，用于按组自动附加
#geli_storage_flags="-k /etc/geli/storage.keys" # 为 storage 组的设备设置密钥文件
#geli_storage_devices="ada0 ada1"               # storage 组中包含的物理设备
#geli_backup_flags="-j /etc/geli/backup.passfile -k /etc/geli/backup.keys" # 为 backup 组的设备设置口令文件和密钥文件
#geli_backup_devices="ada2 ada3"                # backup 组中包含的物理设备

## 磁盘相关选项
root_rw_mount="YES"           # 设置为 YES 表示允许将根文件系统重新挂载为可读写；NO 表示禁止重新挂载为可读写
root_hold_delay="30"           # 在释放根文件系统挂载保持锁之前等待的时间（秒）
fsck_flags="-p"                # fsck 的默认标志，-p 表示自动修复可修复的错误；可改为 -f 或 -f -y 强制完全检查
fsck_y_enable="NO"             # 设置为 YES，如果初次预检（preen）失败，则自动执行 fsck -y
fsck_y_flags="-T ffs:-R -T ufs:-R"  # fsck -y 的额外标志
background_fsck="YES"          # 尝试在后台执行 fsck（如果可能）
background_fsck_delay="60"     # 启动后台 fsck 前等待的时间（秒）
growfs_enable="NO"             # 设置为 YES 在启动时尝试扩展根文件系统
growfs_swap_size=""             # 指定 growfs 扩展 swap 大小，0 表示禁用，"" 表示使用默认大小（单位为字节）
netfs_types="nfs:NFS smbfs:SMB"  # 网络文件系统类型映射
extra_netfs_types="NO"         # 启动时延迟挂载的额外网络文件系统类型列表，或 NO 表示不使用

##############################################################
###  网络配置小节                        ######################
##############################################################

### 基本网络与防火墙/安全选项： ###

hostname=""                          # 请设置主机名！
hostid_enable="YES"                  # 启用主机 UUID
hostid_file="/etc/hostid"            # 存放 hostuuid 的文件
hostid_uuidgen_flags="-r"            # uuidgen 命令的标志
machine_id_file="/etc/machine-id"    # 存放 machine-id 的文件
nisdomainname="NO"                   # 如果使用 NIS，设置 NIS 域名，否则 NO
dhclient_program="/sbin/dhclient"    # DHCP 客户端程序路径
dhclient_flags=""                     # 传递给 DHCP 客户端的额外参数
#dhclient_flags_em0=""                # 仅为 em0 接口传递额外 dhclient 参数
background_dhclient="NO"             # 在后台启动 DHCP 客户端
#background_dhclient_em0="YES"       # 在后台启动 em0 接口的 DHCP 客户端
dhclient_arpwait="YES"               # 等待 ARP 解析完成
synchronous_dhclient="NO"            # 在启动时直接在配置的接口上启动 dhclient
defaultroute_delay="30"              # 等待 DHCP 接口默认路由的时间（秒）
defaultroute_carrier_delay="5"       # 等待链路信号的时间（秒）
netif_enable="YES"                    # 启用网络接口初始化
netif_ipexpand_max="2048"             # IP 范围规格中允许的最大 IP 数量
wpa_supplicant_program="/usr/sbin/wpa_supplicant"  # WPA supplicant 程序路径
wpa_supplicant_flags="-s"             # 传递给 wpa_supplicant 的额外参数
wpa_supplicant_conf_file="/etc/wpa_supplicant.conf" # WPA supplicant 配置文件

# IPFW 防火墙
firewall_enable="NO"             # 设置为 YES 启用防火墙（IPFW）功能
firewall_script="/etc/rc.firewall"  # 设置启动防火墙时执行的脚本
firewall_type="UNKNOWN"           # 防火墙类型（参见 /etc/rc.firewall）
firewall_quiet="NO"               # 设置为 YES 可禁止显示防火墙规则
firewall_logging="NO"             # 设置为 YES 启用防火墙事件日志
firewall_flags=""                  # 当类型为文件时，传递给 ipfw 的标志
firewall_coscripts=""              # 防火墙启动/停止后要执行的可执行文件或脚本列表

firewall_client_net="192.0.2.0/24"       # "client" 防火墙的 IPv4 网络地址
#firewall_client_net_ipv6="2001:db8:2:1::/64" # "client" 防火墙的 IPv6 网络前缀

firewall_simple_iif="em1"          # "simple" 防火墙的内部网络接口
firewall_simple_inet="192.0.2.16/28" # "simple" 防火墙的内部网络地址
firewall_simple_oif="em0"          # "simple" 防火墙的外部网络接口
firewall_simple_onet="192.0.2.0/28" # "simple" 防火墙的外部网络地址
#firewall_simple_iif_ipv6="em1"       # "simple" 防火墙的内部 IPv6 网络接口
#firewall_simple_inet_ipv6="2001:db8:2:800::/56" # "simple" 防火墙的内部 IPv6 网络前缀
#firewall_simple_oif_ipv6="em0"       # "simple" 防火墙的外部 IPv6 网络接口
#firewall_simple_onet_ipv6="2001:db8:2:0::/56" # "simple" 防火墙的外部 IPv6 网络前缀

firewall_myservices=""             # 本机为"workstation"防火墙提供服务的端口/协议列表
firewall_allowservices=""          # 允许访问 $firewall_myservices 的 IP 列表
firewall_trusted=""                # 对本机具有完全访问权限的受信任 IP 列表
firewall_logdeny="NO"              # 设置为 YES 记录被拒绝的默认入站数据包
firewall_nologports="135-139,445 1026,1027 1433,1434" # 对这些端口的被拒绝数据包不记录日志
firewall_nat_enable="NO"       # 启用内核 NAT（前提是 firewall_enable 为 YES）
firewall_nat_interface=""       # 用于 NAT 的公共接口或 IP 地址
firewall_nat_flags=""           # 额外配置参数
firewall_nat64_enable="NO"     # 启用内核 NAT64 模块
firewall_nptv6_enable="NO"     # 启用内核 NPTv6 模块
firewall_pmod_enable="NO"      # 启用内核协议修改模块
dummynet_enable="NO"           # 加载 dummynet(4) 模块
ipfw_netflow_enable="NO"       # 通过 ng_netflow 启用 netflow 日志
ip_portrange_first="NO"        # 设置动态分配端口的起始端口
ip_portrange_last="NO"         # 设置动态分配端口的结束端口

ike_enable="NO"                # 启用 IKE 守护进程（通常是 racoon 或 isakmpd）
ike_program="${_localbase}/sbin/isakmpd" # IKE 守护进程路径
ike_flags=""                    # IKE 守护进程额外标志

ipsec_enable="NO"               # 设置为 YES 时，使用 setkey 加载 ipsec_file
ipsec_file="/etc/ipsec.conf"    # setkey 的配置文件名称

natd_program="/sbin/natd"       # natd 程序路径
natd_enable="NO"                # 启用 natd（前提是 firewall_enable 为 YES）
natd_interface=""               # 公共接口或 IP 地址
natd_flags=""                   # natd 额外标志

ipfilter_enable="NO"            # 设置为 YES 启用 ipfilter 功能
ipfilter_program="/sbin/ipf"    # ipfilter 程序路径
ipfilter_rules="/etc/ipf.rules" # ipfilter 规则文件（示例见 /usr/src/share/examples/ipfilter）
ipfilter_flags=""               # ipfilter 额外标志
ipfilter_optionlist=""          # ipf(8) 的 optionlist

ippool_enable="NO"              # 设置为 YES 启用 ip filter pool
ippool_program="/sbin/ippool"   # ippool 程序路径
ippool_rules="/etc/ippool.tables" # ippool 规则文件
ippool_flags=""                 # ippool 额外标志

ipnat_enable="NO"               # 设置为 YES 启用 ipnat 功能
ipnat_program="/sbin/ipnat"     # ipnat 程序路径
ipnat_rules="/etc/ipnat.rules"  # ipnat 规则文件
ipnat_flags=""                  # ipnat 额外标志

ipmon_enable="NO"               # 设置为 YES 启用 ipmon；需要 ipfilter 或 ipnat
ipmon_program="/sbin/ipmon"     # ipfilter 监控程序路径
ipmon_flags="-Ds"               # 通常为 "-Ds" 或 "-D /var/log/ipflog"

ipfs_enable="NO"                # 设置为 YES 启用在关机和启动时保存/恢复状态表
ipfs_program="/sbin/ipfs"       # ipfs 程序路径
ipfs_flags=""                   # ipfs 额外标志

pf_enable="NO"                  # 设置为 YES 启用 packet filter (pf)
pf_rules="/etc/pf.conf"         # pf 规则文件（默认不存在）
pf_program="/sbin/pfctl"        # pfctl 程序路径
pf_flags=""                     # pfctl 额外标志
pf_fallback_rules_enable="NO"   # 如果规则集加载失败则使用备用规则
pf_fallback_rules="block drop log all" # 规则集加载失败时使用的规则
#pf_fallback_rules="block drop log all
#pass quick on em4"             # 多规则示例
pf_fallback_rules_file="/etc/pf-fallback.conf" # 规则集失败时使用的文件

pflog_enable="NO"               # 设置为 YES 启用 pf 日志
pflog_logfile="/var/log/pflog"  # pflogd 日志存放路径
pflog_program="/sbin/pflogd"    # pflogd 程序路径
pflog_flags=""                  # pflogd 额外标志

dnctl_enable="NO"               # 启用 dnctl（pf 状态管理工具）
dnctl_program="/sbin/dnctl"     # dnctl 程序路径
dnctl_rules="/etc/dnctl.conf"   # dnctl 规则文件

ftpproxy_enable="NO"            # 设置为 YES 启用 pf 的 ftp-proxy(8)
ftpproxy_flags=""               # ftp-proxy 额外标志

pfsync_enable="NO"              # 向其他主机同步 pf 状态
pfsync_syncdev=""               # pfsync 使用的接口
pfsync_syncpeer=""              # pfsync 对端主机 IP
pfsync_ifconfig=""              # pfsync 的额外 ifconfig(8) 选项

tcp_extensions="YES"            # 设置为 NO 关闭 RFC1323 TCP 高性能扩展
log_in_vain="0"                 # >=1 时记录连接到无监听端口的日志
tcp_keepalive="YES"             # 启用 TCP 空闲连接超时检测（或 NO）
tcp_drop_synfin="NO"            # 设置为 YES 丢弃 SYN+FIN 的 TCP 包
                                # 注意：违反 TCP 协议规范
icmp_drop_redirect="auto"       # 设置为 YES 忽略 ICMP REDIRECT 包
icmp_log_redirect="NO"          # 设置为 YES 记录 ICMP REDIRECT 包

network_interfaces="auto"       # 网络接口列表，或使用 "auto" 自动检测
cloned_interfaces=""            # 要创建的克隆网络接口列表
#cloned_interfaces="gif0 gif1 gif2 gif3"	# 预先克隆 GENERIC 配置的虚拟接口
#ifconfig_lo0="inet 127.0.0.1/8" # 默认回环设备配置，用于本地通信
#ifconfig_lo0_alias0="inet 127.0.0.254/32"	# 回环设备别名示例，用于绑定额外 IPv4 地址
#ifconfig_em0_ipv6="inet6 2001:db8:1::1 prefixlen 64"	# 为 em0 配置主 IPv6 地址，前缀长度 64
#ifconfig_em0_alias0="inet6 2001:db8:2::1 prefixlen 64"	# em0 的 IPv6 别名，用于多地址配置
#ifconfig_em0_name="net0"	# 将物理接口 em0 重命名为 net0，便于管理
#vlans_em0="101 vlan0"	# 在 em0 上创建 VLAN 101，并命名为 vlan0
#create_args_vlan0="vlan 102"	# 为 vlan0 配置二级 VLAN tag 102
#wlans_ath0="wlan0"	# 将 ath0 无线接口配置为 wlan0
#wlandebug_wlan0="scan+auth+assoc"	# 使用 wlandebug(8) 设置 WLAN 调试标志，包括扫描、认证和关联过程
#ipv4_addrs_em0="192.168.0.1/24 192.168.1.1-5/28"	# 为 em0 配置多个 IPv4 地址：192.168.0.1/24 和 192.168.1.1 到 192.168.1.5/28 的连续范围
#
#autobridge_interfaces="bridge0"    # 要检查的桥接接口列表
#autobridge_bridge0="tap* vlan0"    # 自动添加到桥接的接口 glob

# 用户 PPP 配置
ppp_enable="NO"                     # 启动用户 PPP（或 NO）
ppp_program="/usr/sbin/ppp"         # 用户 PPP 程序路径
ppp_mode="auto"                      # 模式选择：auto、ddial、direct 或 dedicated，默认 auto
ppp_nat="YES"                        # 使用 PPP 内部 NAT（或 NO）
ppp_profile="papchap"                # 使用配置文件 /etc/ppp/ppp.conf
ppp_user="root"                      # PPP 运行用户

# 启动多个 PPP 实例
#ppp_profile="profile1 profile2 profile3" # 要使用的 PPP 配置文件
#ppp_profile1_mode="ddial"             # 覆盖 profile1 的 PPP 模式
#ppp_profile2_nat="NO"                 # 覆盖 profile2 的 NAT 模式
# profile3 使用默认 ppp_mode 和 ppp_nat

### 网络守护进程（杂项） ###
hostapd_program="/usr/sbin/hostapd"
hostapd_enable="NO"           # 启动 hostap 守护进程

syslogd_enable="YES"          # 启动 syslog 守护进程（或 NO）
syslogd_program="/usr/sbin/syslogd" # syslogd 程序路径（可替换）
syslogd_flags="-s"            # syslogd 启动参数
syslogd_oomprotect="YES"      # 当交换空间耗尽时，不杀死 syslogd

altlog_proglist=""            # /var 下 chroot 应用程序列表

inetd_enable="NO"             # 启动网络守护进程调度程序（YES/NO）
inetd_program="/usr/sbin/inetd"   # inetd 程序路径（可替换）
inetd_flags="-wW -C 60"       # inetd 可选启动参数

iscsid_enable="NO"            # iSCSI 发起端守护进程
iscsictl_enable="NO"          # iSCSI 发起端自动启动
iscsictl_flags="-Aa"          # iscsictl 可选参数

hastd_enable="NO"             # 启动 HAST 守护进程（YES/NO）
hastd_program="/sbin/hastd"   # hastd 程序路径（可替换）
hastd_flags=""                # hastd 可选参数

ggated_enable="NO"            # 启动 ggate 守护进程（YES/NO）
ggated_config="/etc/gg.exports"   # ggated(8) 导出文件
ggated_flags=""               # 额外参数，例如绑定端口

ctld_enable="NO"              # CAM Target Layer / iSCSI 目标守护进程

local_unbound_enable="NO"     # 本地缓存 DNS 解析器
local_unbound_oomprotect="YES" # 交换空间耗尽时不杀死 local_unbound
local_unbound_tls="NO"        # 使用 DNS over TLS

blacklistd_enable="NO"        # 已重命名为 blocklistd_enable
blacklistd_flags=""           # 已重命名为 blocklistd_flags
blocklistd_enable="NO"        # 启动 blocklistd 守护进程（YES/NO）
blocklistd_flags=""           # blocklistd(8) 可选参数

resolv_enable="YES"           # 启用 resolv / resolvconf

#
# Kerberos。请勿在从属服务器上运行管理守护进程
#
kdc_enable="NO"             # 启动 Kerberos 5 KDC（或 NO）
kdc_program=""              # Kerberos 5 KDC 程序路径
kdc_flags=""                # Kerberos 5 KDC 额外参数
kdc_restart="NO"            # KDC 异常终止时自动重启
kdc_restart_delay=""        # 自动重启延迟时间（秒）

kadmind_enable="NO"         # 启动 kadmind（或 NO）
kadmind_program="/usr/libexec/kadmind" # kadmind 程序路径

kpasswdd_enable="NO"        # 启动 kpasswdd（或 NO）
kpasswdd_program="/usr/libexec/kpasswdd" # kpasswdd 程序路径

kfd_enable="NO"             # 启动 kfd（或 NO）
kfd_program="/usr/libexec/kfd" # Kerberos 5 kfd 守护进程路径
kfd_flags=""                # kfd 额外参数

ipropd_master_enable="NO"   # 启动 Heimdal 增量同步守护进程（主节点）
ipropd_master_program="/usr/libexec/ipropd-master"
ipropd_master_flags=""      # ipropd-master 参数
ipropd_master_keytab="/etc/krb5.keytab"  # 主节点 keytab
ipropd_master_slaves=""     # /var/heimdal/slaves 中使用的从节点名列表

ipropd_slave_enable="NO"    # 启动 Heimdal 增量同步守护进程（从节点）
ipropd_slave_program="/usr/libexec/ipropd-slave"
ipropd_slave_flags=""       # ipropd-slave 参数
ipropd_slave_keytab="/etc/krb5.keytab"   # 从节点 keytab
ipropd_slave_master=""      # 主节点名

gssd_enable="NO"            # 启动 gssd 守护进程（或 NO）
gssd_program="/usr/sbin/gssd" # gssd 程序路径
gssd_flags=""               # gssd 参数
rwhod_enable="NO"           # 启动 rwho 守护进程（或 NO）
rwhod_flags=""               # rwhod 参数
rarpd_enable="NO"            # 启动 rarpd（或 NO）
rarpd_flags="-a"             # rarpd 参数
bootparamd_enable="NO"       # 启动 bootparamd（或 NO）
bootparamd_flags=""          # bootparamd 参数

pppoed_enable="NO"           # 启动 PPP over Ethernet 守护进程
pppoed_provider="*"          # PPPoE 提供者和 ppp(8) 配置文件条目
pppoed_flags="-P /var/run/pppoed.pid" # PPPoE 参数（如果启用）
pppoed_interface="em0"       # PPPoE 运行的接口

sshd_enable="NO"             # 启用 sshd
sshd_oomprotect="YES"        # 当交换空间耗尽时不杀死 sshd
sshd_program="/usr/sbin/sshd" # sshd 程序路径
sshd_flags=""                # sshd 额外参数

### 网络守护进程（NFS）：所有需 rpcbind_enable="YES" ###
autofs_enable="NO"           # 启动 autofs 守护进程
automount_flags=""           # automount(8) 参数（如果启用 autofs）
automountd_flags=""          # automountd(8) 参数（如果启用 autofs）
autounmountd_flags=""        # autounmountd(8) 参数（如果启用 autofs）

nfs_client_enable="NO"       # 本机作为 NFS 客户端（或 NO）
nfs_access_cache="60"        # 客户端缓存超时时间（秒）
nfs_server_enable="NO"       # 本机作为 NFS 服务器（或 NO）
nfs_server_flags="-u -t"     # nfsd 参数（如果启用）
nfs_server_managegids="NO"   # NFS 服务器是否映射 AUTH_SYS 的 gids（或 NO）
nfs_server_maxio="131072"    # nfsd 最大 I/O 大小
mountd_enable="NO"           # 启动 mountd（或 NO）
mountd_flags="-r -S"         # mountd 参数（如果启用 NFS 服务器）
weak_mountd_authentication="NO" # 允许非 root 挂载请求
nfs_reserved_port_only="YES" # 仅在安全端口提供 NFS（或 NO）
nfs_bufpackets=""            # 客户端 bufspace（以包计）

rpc_lockd_enable="NO"        # 启动 NFS rpc.lockd（客户端/服务器需要）
rpc_lockd_flags=""            # rpc.lockd 参数（如果启用）
rpc_statd_enable="NO"        # 启动 NFS rpc.statd（客户端/服务器需要）
rpc_statd_flags=""            # rpc.statd 参数（如果启用）
rpcbind_enable="NO"           # 启动端口映射服务（YES/NO）
rpcbind_program="/usr/sbin/rpcbind" # rpcbind 程序路径
rpcbind_flags=""             # rpcbind 参数（如果启用）

rpc_ypupdated_enable="NO"    # 如果是 NIS 主节点且启用 SecureRPC
nfsv4_server_enable="NO"     # 启用 NFSv4 支持
nfsv4_server_only="NO"       # 设置 NFS 服务器仅支持 NFSv4
nfscbd_enable="NO"           # NFSv4 客户端回调守护进程
nfscbd_flags=""               # nfscbd 参数
nfsuserd_enable="NO"         # NFSv4 用户/组名称映射守护进程
nfsuserd_flags=""             # nfsuserd 参数
tlsclntd_enable="NO"         # 启动 rpc.tlsclntd（NFS-over-TLS 挂载需要）
tlsclntd_flags=""             # rpc.tlsclntd 参数
tlsservd_enable="NO"         # 启动 rpc.tlsservd（NFS-over-TLS nfsd 需要）
tlsservd_flags=""             # rpc.tlsservd 参数

### 网络时间服务选项 ###
ntpdate_enable="NO"               # 启动 ntpdate 在开机时同步时间（或 NO）
ntpdate_program="/usr/sbin/ntpdate" # ntpdate 程序路径（可自定义）
ntpdate_flags="-b"                # ntpdate 参数（如果启用）
ntpdate_config="/etc/ntp.conf"    # ntpdate(8) 配置文件
ntpdate_hosts=""                   # ntpdate(8) 服务器列表，用空格分隔

ntpd_enable="NO"                   # 启动 ntpd 网络时间协议守护进程（或 NO）
ntpd_program="/usr/sbin/ntpd"      # ntpd 程序路径（可自定义）
ntpd_config="/etc/ntp.conf"        # ntpd(8) 配置文件
ntpd_sync_on_start="NO"            # 启动 ntpd 时是否立即同步时间（即使偏移大）
ntpd_flags=""                       # ntpd 额外参数

ntp_src_leapfile="/etc/ntp/leap-seconds"          # ntpd leapfile 的初始来源
ntp_db_leapfile="/var/db/ntpd.leap-seconds.list" # 获取闰秒的标准位置
ntp_leapfile_sources="https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list https://data.iana.org/time-zones/tzdb/leap-seconds.list"  #  leapfile 的获取来源
ntp_leapfile_fetch_opts="-mq"       # 获取 NTP leapfile 时使用的选项，例如 --no-verify-peer
ntp_leapfile_expiry_days=30         # 在到期前 30 天检查新的 leapfile
ntp_leapfile_fetch_verbose="NO"     # 获取 NTP leapfile 时是否输出详细信息

# 网络信息服务 (NIS) 选项：全部都依赖 rpcbind_enable="YES" ###
nis_client_enable="NO"        # 是 NIS 客户端（或 NO）
nis_client_flags=""            # ypbind 的参数（如果启用）
nis_ypset_enable="NO"         # 开机时运行 ypset（或 NO）
nis_ypset_flags=""             # ypset 参数（如果启用）
nis_server_enable="NO"        # 是 NIS 服务器（或 NO）
nis_server_flags=""            # ypserv 参数（如果启用）
nis_ypxfrd_enable="NO"        # 开机时运行 rpc.ypxfrd（或 NO）
nis_ypxfrd_flags=""            # rpc.ypxfrd 参数（如果启用）
nis_yppasswdd_enable="NO"     # 开机时运行 rpc.yppasswdd（或 NO）
nis_yppasswdd_flags=""         # rpc.yppasswdd 参数（如果启用）
nis_ypldap_enable="NO"         # 开机时运行 ypldap（或 NO）
nis_ypldap_flags=""             # ypldap 参数（如果启用）

### SNMP 守护进程 ###
# 确保理解在网络中运行 SNMP v1/v2 的安全隐患
bsnmpd_enable="NO"            # 启动 SNMP 守护进程（或 NO）
bsnmpd_flags=""                # bsnmpd 参数

### 网络路由选项： ###
defaultrouter="NO"            # 设置默认网关（或 NO）
#defaultrouter_fibN="192.0.2.1" # 使用此形式为 FIB N 设置网关
static_arp_pairs=""            # 设置静态 ARP 列表（或留空）
static_ndp_pairs=""            # 设置静态 NDP 列表（或留空）
static_routes=""               # 设置静态路由列表（或留空）
gateway_enable="NO"            # 如果此主机将作为网关，则设置为 YES
routed_enable="NO"             # 启用路由守护进程则设置为 YES
routed_program="/sbin/routed"  # 启用时使用的路由守护进程
routed_flags="-q"              # 路由守护进程参数
arpproxy_all="NO"              # 替代过时的内核选项 ARP_PROXYALL
forward_sourceroute="NO"       # 执行源路由（仅当 gateway_enable 设置为 YES 时）
accept_sourceroute="NO"        # 接受发往本机的源路由数据包

### 蓝牙 ###
hcsecd_enable="NO"               # 启用 hcsecd(8)（或 NO）
hcsecd_config="/etc/bluetooth/hcsecd.conf"  # hcsecd(8) 配置文件

sdpd_enable="NO"                 # 启用 sdpd(8)（或 NO）
sdpd_control="/var/run/sdp"      # sdpd(8) 控制套接字
sdpd_groupname="nobody"          # 初始化后设置 sdpd(8) 运行的用户组
sdpd_username="nobody"           # 初始化后设置 sdpd(8) 运行的用户名

bthidd_enable="NO"               # 启用 bthidd(8)（或 NO）
bthidd_config="/etc/bluetooth/bthidd.conf"  # bthidd(8) 配置文件
bthidd_hids="/var/db/bthidd.hids"          # bthidd(8) 已知 HID 设备文件
bthidd_evdev_support="AUTO"      # AUTO 取决于 EVDEV_SUPPORT 内核选项

rfcomm_pppd_server_enable="NO"   # 以服务器模式启用 rfcomm_pppd(8)（或 NO）
rfcomm_pppd_server_profile="one two"  # 使用 /etc/ppp/ppp.conf 中的配置文件

#rfcomm_pppd_server_one_bdaddr=""   # 为 'one' 覆盖本地 bdaddr
rfcomm_pppd_server_one_channel="1"  # 为 'one' 覆盖本地通道
#rfcomm_pppd_server_one_register_sp="NO"  # 为 'one' 覆盖 SP 和 DUN 注册
#rfcomm_pppd_server_one_register_dun="NO" # 为 'one'

#rfcomm_pppd_server_two_bdaddr=""   # 为 'two' 覆盖本地 bdaddr
rfcomm_pppd_server_two_channel="3"  # 为 'two' 覆盖本地通道
#rfcomm_pppd_server_two_register_sp="NO"  # 为 'two' 覆盖 SP 和 DUN 注册
#rfcomm_pppd_server_two_register_dun="NO" # 为 'two'

ubthidhci_enable="NO"            # 将存在的 USB 蓝牙控制器从 HID 模式切换到 HCI 模式
#ubthidhci_busnum="3"             # 总线号 3
#ubthidhci_addr="2"               # 地址 2，使用 usbconfig 列表检查系统的正确编号

### 网络连接/可用性验证选项 ###
netwait_enable="NO"           # 启用 rc.d/netwait（或 NO）
#netwait_ip=""                # 等待此列表中任意 IP 的 ping 响应
netwait_timeout="60"           # 执行 ping 的总秒数
#netwait_if=""                # 等待此列表中每个接口的活动链路
netwait_if_timeout="30"        # 监控链路状态的总秒数
netwait_dad="NO"               # 等待 DAD 完成
netwait_dad_timeout=""         # 等待 DAD 的总秒数，0 或未设置表示自动检测

### 杂项网络选项 ###
icmp_bmcastecho="NO"           # 响应广播 ping 数据包

### IPv6 选项 ###
ipv6_network_interfaces="auto"         # IPv6 网络接口列表（或 "auto" 或 "none"）
ipv6_activate_all_interfaces="NO"     # 如果 NO，没有对应 $ifconfig_IF_ipv6 的接口会被标记为 IFDISABLED（出于安全原因）
ipv6_defaultrouter="NO"               # 设置 IPv6 默认网关（或 NO）
#ipv6_defaultrouter="2002:c058:6301::"  # 用于 6to4（RFC 3068）
#ipv6_defaultrouter_fibN="2001:db8::"   # 设置 FIB N 的网关
ipv6_static_routes=""                  # 静态路由列表（或留空）
#ipv6_static_routes="xxx"              # 示例：设置 fec0:0000:0000:0006::/64 路由到回环接口
#ipv6_route_xxx="fec0:0000:0000:0006:: -prefixlen 64 ::1"
ipv6_gateway_enable="NO"               # 如果此主机作为网关则设置为 YES
ipv6_cpe_wanif="NO"                    # 如果此节点作为路由器转发 IPv6 包，设置上游接口名
ipv6_privacy="NO"                      # 在接收 RA 的接口上使用隐私地址（RFC 4941）

route6d_enable="NO"               # 设置为 YES 启用 IPv6 路由守护进程
route6d_program="/usr/sbin/route6d"  # IPv6 路由守护进程名称
route6d_flags=""                   # IPv6 路由守护进程参数
#route6d_flags="-l"               # 仅监听本地链路 IPv6 地址。（路由器示例）
#route6d_flags="-q"               # 静默模式，关闭路由通告。示例：终端节点运行路由守护进程时应停止通告
# 示例：为路由器或终端节点配置静态 IPv6
#ipv6_network_interfaces="em0 em1"  # 指定启用 IPv6 的网络接口 em0 和 em1（路由器示例）
#ipv6_prefix_em0="fec0:0000:0000:0001 fec0:0000:0000:0002"  # 为 em0 接口分配静态 IPv6 前缀/地址（路由器示例），此处分配了 2 个 IPv6 地址
#ipv6_prefix_em1="fec0:0000:0000:0003 fec0:0000:0000:0004"  # 为 em1 接口分配静态 IPv6 前缀/地址（路由器示例），此处分配了 2 个 IPv6 地址
ipv6_default_interface="NO"       # 默认输出接口（仅在 ipv6_gateway_enable="NO" 时生效）
rtsol_flags="-i"                  # IPv6 路由器请求标志
rtsold_enable="NO"                # 设置为 YES 启用 IPv6 路由器请求守护进程
rtsold_flags="-a -i"              # IPv6 路由器请求守护进程参数
rtadvd_enable="NO"                # 设置为 YES 启用 IPv6 路由器通告守护进程
rtadvd_flags=""                   # IPv6 路由器通告守护进程参数
rtadvd_interfaces=""              # rtadvd 发送 RA 数据包的接口
stf_interface_ipv4addr=""         # 6to4 IPv6 over IPv4 隧道接口的本地 IPv4 地址
stf_interface_ipv4plen="0"        # 6to4 IPv4 地址前缀长度，有效值 0-31
stf_interface_ipv6_ifid="0:0:0:1" # stf0 的 IPv6 接口 ID，可设置为 AUTO
stf_interface_ipv6_slaid="0000"   # stf0 的 IPv6 Site Level Aggregator
ipv6_ipv4mapping="NO"             # 设置为 YES 启用 IPv4 映射 IPv6 地址通信 (::ffff:a.b.c.d)
ip6addrctl_enable="YES"           # 启用默认 IPv6 地址选择
ip6addrctl_verbose="NO"           # 启用详细配置消息
ip6addrctl_policy="AUTO"          # 预定义地址选择策略（ipv4_prefer, ipv6_prefer, 或 AUTO）

##############################################################
###  系统控制台选项           #################################
##############################################################

keyboard=""                # 使用的键盘设备（默认 /dev/kbd0）
keymap="NO"                # /usr/share/{syscons,vt}/keymaps/* 中的键盘映射（或 NO）
keyrate="NO"               # 键盘速率：slow, normal, fast（或 NO）
keybell="NO"               # kbdcontrol(1) 中选项，使用 "off" 禁用
keychange="NO"             # 功能键默认值（或 NO）
cursor="NO"                # 光标类型 {normal 普通光标|blink 闪烁光标|destructive 反显光标}（或 NO）
scrnmap="NO"               # /usr/share/syscons/scrnmaps/* 中的屏幕映射（或 NO）
font8x16="NO"              # /usr/share/{syscons,vt}/fonts/* 中 8x16 字体（或 NO）
font8x14="NO"              # /usr/share/{syscons,vt}/fonts/* 中 8x14 字体（或 NO）
font8x8="NO"               # /usr/share/{syscons,vt}/fonts/* 中 8x8 字体（或 NO）
blanktime="300"            # 空屏时间（秒），或 "NO" 禁用
saver="NO"                 # 屏幕保护：使用 /boot/kernel/${saver}_saver.ko
moused_nondefault_enable="YES" # 除非在 rc.conf(5) 中明确覆盖，否则非默认鼠标视为启用
moused_enable="NO"          # 运行鼠标守护进程
moused_type="evdev"         # 可用设置见 rc.conf(5) 手册
moused_port="/dev/psm0"     # 鼠标端口设置
moused_flags=""             # moused 的附加参数
mousechar_start="NO"        # 如果 0xd0-0xd3 默认范围被占用，可指定其他起始范围，如 mousechar_start=3
msconvd_enable="NO"         # 运行鼠标协议转换守护进程
msconvd_type="auto"         # 可用 moused_type 类型见 rc.conf(5)
msconvd_ports=""            # msconvd 端口列表
msconvd_flags=""            # msconvd 的附加参数
allscreens_flags=""         # 为所有虚拟屏幕设置 vidcontrol 模式
allscreens_kbdflags=""      # 为所有虚拟屏幕设置 kbdcontrol 模式

##############################################################
###  邮件传输代理（MTA）选项              ######################
##############################################################

# /etc/rc.d/sendmail 设置：
sendmail_enable="NONE"              # 运行 sendmail 收件守护进程（YES/NO/NONE）
                                    # 如果为 NONE，则不启动任何 sendmail 进程
sendmail_pidfile="/var/run/sendmail.pid"  # sendmail PID 文件
sendmail_procname="/usr/sbin/sendmail"   # sendmail 进程名称
sendmail_flags="-L sm-mta -bd -q30m"     # 作为服务器运行 sendmail 的参数
sendmail_cert_create="YES"          # 如果没有证书则创建服务器证书（YES/NO）
#sendmail_cert_cn="CN"              # 生成证书的 CN（Common Name，共用名）
sendmail_submit_enable="YES"        # 启动仅本地主机的 MTA 用于邮件提交
sendmail_submit_flags="-L sm-mta -bd -q30m -ODaemonPortOptions=Addr=localhost"
                                    # 本地主机 MTA 的参数
sendmail_outbound_enable="YES"      # 出队滞留邮件（YES/NO）
sendmail_outbound_flags="-L sm-queue -q30m"  # 出站 sendmail 参数
sendmail_msp_queue_enable="YES"     # 出队滞留 clientmqueue 邮件（YES/NO）
sendmail_msp_queue_flags="-L sm-msp-queue -Ac -q30m"  # sendmail_msp_queue 守护进程参数
sendmail_rebuild_aliases="NO"       # 如有必要运行 newaliases（YES/NO）


##############################################################
###  杂项管理选项                           ###################
##############################################################

auditd_enable="NO"	# 运行审计守护进程
auditd_program="/usr/sbin/auditd"	# 审计守护进程路径
auditd_flags=""		# 传递给审计守护进程的选项
auditdistd_enable="NO"	# 运行分布式审计守护进程
auditdistd_program="/usr/sbin/auditdistd"	# auditdistd 守护进程路径
auditdistd_flags=""	# 传递给 auditdistd 守护进程的选项
cron_enable="YES"	# 运行定期任务守护进程
cron_program="/usr/sbin/cron"	# 启用时使用的 cron 可执行文件路径
cron_dst="YES"		# 智能处理夏令时转换（YES/NO）
cron_flags=""		# 传递给 cron 守护进程的选项
cfumass_enable="NO"	# 为 cfumass(4) 创建默认 LUN
cfumass_dir="/var/cfumass"	# LUN 内容文件所在目录
cfumass_image="/var/tmp/cfumass.img"	# LUN 支撑文件路径
lpd_enable="NO"		# 运行行打印守护进程
lpd_program="/usr/sbin/lpd"	# lpd 可执行文件路径
lpd_flags=""		# 传递给 lpd 的选项
nscd_enable="NO"	# 运行 NSS 缓存守护进程
chkprintcap_enable="NO"	# 在运行 lpd 之前运行 chkprintcap(8)
chkprintcap_flags="-d"	# 默认创建缺失的目录
dumpdev="AUTO"		# 崩溃转储设备（设备名、AUTO 或 NO）；稳定分支建议注释此项以遵循 kenv
dumpon_flags=""		# 传递给 dumpon(8) 的选项，紧随 dumpdev
dumpdir="/var/crash"	# 存放崩溃转储的目录
savecore_enable="YES"	# 如果存在转储设备，从中提取核心转储
savecore_flags="-m 10"	# 如果启用了 dumpdev 且存在，则使用。默认仅保存最近 10 个内核转储

service_delete_empty="NO"	# 让 'service delete' 删除空的 rc.conf.d 文件
crashinfo_enable="YES"		# 自动生成崩溃转储摘要
crashinfo_program="/usr/sbin/crashinfo"	# 生成崩溃转储摘要的脚本
quota_enable="NO"		# 启动时启用磁盘配额（或 NO）
check_quotas="YES"		# 启动时检查配额（或 NO）
quotaon_flags="-a"		# 启用所有文件系统的配额（如果启用）
quotaoff_flags="-a"		# 关机时关闭所有文件系统的配额。
quotacheck_flags="-a"		# 检查所有文件系统的配额（如果启用）
accounting_enable="NO"		# 启用进程记账（或 NO）
firstboot_sentinel="/firstboot"	# 如果此文件存在，运行带 "firstboot" 关键字的脚本。应位于可读写文件系统，以便启动完成后可删除
sysvipc_enable="NO"		# 启动时加载 System V IPC 原语（或 NO）
linux_enable="NO"		# 启动时加载 Linux 二进制兼容性（或 NO）
linux_mounts_enable="YES"	# 如果 linux_enable 为 YES，启动时挂载 Linux 特定文件系统
clear_tmp_enable="NO"		# 启动时清空 /tmp
clear_tmp_X="YES" 		# 清空并重新创建 /tmp 中的 X11 相关目录
ldconfig_insecure="NO"		# 设置为 YES 以禁用 ldconfig 安全检查
ldconfig_paths="/usr/lib/compat ${_localbase}/lib ${_localbase}/lib/compat/pkg"  # 共享库搜索路径
ldconfig32_paths="/usr/lib32/compat"  # 32 位兼容共享库搜索路径
ldconfig_local_dirs="${_localbase}/libdata/ldconfig"  # 带 ldconfig 配置文件的本地目录
ldconfig_local32_dirs="${_localbase}/libdata/ldconfig32"  # 带 32 位兼容 ldconfig 配置文件的本地目录
kern_securelevel_enable="NO"	# 内核安全级别（参见 security(7)）
kern_securelevel="-1"		# 范围：-1..3；-1 最不安全。注意：将 securelevel 设置为 0 会导致系统以安全等级 1 启动，因为 init(8) 会在 rc(8) 完成后提升级别
update_motd="YES"		# 更新 /var/run/motd 中的版本信息（或 NO）
entropy_boot_file="/boot/entropy"  # 设置为 NO 以禁用非常早期（启动早期）通过重启缓存熵
entropy_file="/entropy"  # 设置为 NO 以禁用晚期（多用户模式）通过重启缓存熵。如果 / 不可用，推荐使用 /var/db/entropy-file
entropy_dir="/var/db/entropy"  # 设置为 NO 以禁用通过 cron 缓存熵
entropy_save_sz="4096"		# 熵缓存文件大小
entropy_save_num="8"		# 要保存的熵缓存文件数量
harvest_mask="4607"		# 熵设备收集除最侵入性来源外的所有来源。（参见 'sysctl kern.random.harvest' 和 random(4)）
osrelease_enable="YES"		# 启动时更新 /var/run/os-release（或 NO）
osrelease_file="/var/run/os-release"	# 用于更新 os-release 的文件
osrelease_perms="444"		# os-release 文件的默认权限
osrelease_home_url="https://FreeBSD.org"	# /var/run/os-release 中的 HOME_URL
osrelease_documentation_url="https://docs.FreeBSD.org"	# /var/run/os-release 中的 DOCUMENTATION_URL
osrelease_support_url="https://www.FreeBSD.org/support"	# /var/run/os-release 中的 SUPPORT_URL
osrelease_bug_report_url="https://bugs.FreeBSD.org"	# /var/run/os-release 中的 BUG_REPORT_URL
dmesg_enable="YES"		# 将 dmesg(8) 保存到 /var/run/dmesg.boot
dmesg_umask="022"		# /var/run/dmesg.boot 文件的默认 umask
watchdogd_enable="NO"		# 启动软件看门狗守护进程
watchdogd_flags=""		# watchdogd 的参数（如果启用）
watchdogd_timeout=""		# watchdogd 超时，覆盖 watchdogd_flags 中的 -t
watchdogd_shutdown_timeout=""	# 停止 watchdogd 后使用的超时，仅对系统关机有效，覆盖 watchdogd_flags 中的 -x 选项
devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules"  # 包含 devfs(8) 规则的文件
devfs_system_ruleset=""		# 要应用于 /dev 的规则集名称（非编号）
devfs_set_rulesets=""		# 要应用的 /mount/dev=ruleset_name 列表（必须已挂载，即 fstab(5)）
devfs_load_rulesets="YES"	# 始终加载默认规则集
performance_cx_lowest="NONE"	# 在线 CPU 空闲状态
performance_cpu_freq="NONE"	# 在线 CPU 频率
economy_cx_lowest="Cmax"	# 离线 CPU 空闲状态
economy_cpu_freq="NONE"		# 离线 CPU 频率
virecover_enable="YES"		# 为 vi(1) 编辑器执行维护操作
ugidfw_enable="NO"		# 启动时加载 mac_bsdextended(4) 规则
bsdextended_script="/etc/rc.bsdextended"	# 默认 mac_bsdextended(4) 规则文件
newsyslog_enable="YES"		# 启动时运行 newsyslog
newsyslog_flags="-CN"		# newsyslog 参数，用于创建标记文件
mixer_enable="YES"		# 运行音量混合器
opensm_enable="NO"		# 启动 infiniband 设备的 Opensm，默认关闭
nuageinit_enable="NO"		# 启动时运行 nuageinit
virtual_oss_enable="NO"		# 启动时运行 virtual_oss
rctl_enable="YES"		# 启动时加载 rctl(8) 规则
rctl_rules="/etc/rctl.conf"	# rctl(8) 规则文件，参见 rctl.conf(5)
iovctl_files=""			# iovctl(8) 的配置文件

##############################################################
### Jail 配置（参见 rc.conf(5) 手册页）               ##########
##############################################################
jail_enable="NO"		# 设置为 NO 禁止启动任何 jail
jail_conf="/etc/jail.conf"	# jail(8) 的配置文件
jail_confwarn="YES"		# 防止关于过时的每个 jail 配置的警告
jail_parallel_start="NO"	# 后台启动 jail
jail_list=""			# 用空格分隔的 jail 名称列表
jail_reverse_stop="NO"		# 以逆序停止 jail

##############################################################
### 定义 source_rc_confs                                   ###
### 这是 /etc/rc.* 脚本用于安全引用 rc_conf_files 覆盖的机制  ###
##############################################################

# 如果 source_rc_confs 尚未定义，则定义之
if [ -z "${source_rc_confs_defined}" ]; then
	source_rc_confs_defined=yes

	# 定义 source_rc_confs 函数，用于安全地加载 rc_conf_files 中列出的配置文件
	source_rc_confs() {
		local i sourced_files

		# 遍历 rc_conf_files 列表
		for i in ${rc_conf_files}; do
			case ${sourced_files} in
			*:$i:*)  # 如果已加载过该文件，则跳过
				;;
			*)
				# 将当前文件标记为已加载
				sourced_files="${sourced_files}:$i:"
				# 如果文件可读，则加载它
				if [ -r $i ]; then
					. $i
				fi
				;;
			esac
		done

		# 再次遍历 rc_conf_files，处理可能在第一次加载中被重新定义的新文件
		for i in ${rc_conf_files}; do
			case ${sourced_files} in
			*:$i:*)  # 如果已加载过该文件，则跳过
				;;
			*)
				sourced_files="${sourced_files}:$i:"
				if [ -r $i ]; then
					. $i
				fi
				;;
			esac
		done
	}
fi

# 允许厂商在 /etc/default/rc.conf 中覆盖 FreeBSD 默认设置，
# 而无需手动管理 /etc/rc.conf。
if [ -r /etc/defaults/vendor.conf ]; then
	. /etc/defaults/vendor.conf
fi
```

## 关机与重启

`reboot` 与 `halt` 在 FreeBSD 中属于同一程序，根据调用名称的不同而表现出不同行为。而在 Linux 中，这些命令可能是 systemd 的符号链接，行为也不同。FreeBSD 的设计更接近传统 UNIX 的行为。

关机：

* 使用 `shutdown now` 不会关机，而是切换到“单用户模式”，将提示：`Enter full pathname of shell or RETURN for /bin/sh:` 回车后进入单用户模式；
* 使用 `shutdown -h now` 不会彻底断电，只会停止系统的运行，提示：`The operating system has halted. Please press any key to reboot.` 此处按任意键可重启系统；
* 关机并断电推荐使用 `shutdown -p now`，该命令通过向 init(8) 发送信号来运行 **/etc/rc.shutdown** 脚本（源代码位于 **libexec/rc/rc.shutdown**）有序关闭服务后断电。也可使用 `halt -p`，该命令直接刷新文件系统缓存并向所有进程发送 SIGTERM 及 SIGKILL 信号后断电，不执行 **/etc/rc.shutdown**。

重启：

* 重启命令与 Linux 相同，均为 `reboot`，但参数不通用。
* FreeBSD 下 `reboot` 直接刷新文件系统缓存，向所有进程发送 SIGTERM 及 SIGKILL 信号后重启系统，不执行 **/etc/rc.shutdown**。若需有序关闭服务后重启，应使用 `shutdown -r now`，该命令通过 init(8) 运行 **/etc/rc.shutdown**。若需快速重启（跳过向进程发送信号，可能导致数据丢失），可使用 `reboot -q` 命令，该选项仅刷新文件系统缓存后立即重启。`fastboot` 是 `reboot` 的别名，行为与 `reboot` 相同。

> **注意**
>
> FreeBSD 下，`shutdown` 命令允许 root 用户和 operator 组成员执行；`reboot` 与 `halt` 命令仅限 root 用户执行。

## 课后习题

1. 创建一个自定义服务脚本放入 **/usr/local/etc/rc.d/** 目录，分析 `rc.subr` 中依赖关系检查的实现逻辑，评估其与 systemd unit 依赖模型的差异。
2. 修改 `rc_debug` 为 YES，追踪一次服务启动的完整流程，对比正常启动与调试启动的输出差异，分析调试输出中各阶段的执行顺序。
3. 禁用 `rc_startmsgs` 并修改关键服务的启动顺序（通过 `REQUIRE` 和 `BEFORE` 关键字），记录系统启动行为的变化。


# 17.1 用户和基本账户管理

FreeBSD 系统的所有访问均通过账户实现，所有进程都由用户运行，因此用户与账户管理是系统安全的基础。

FreeBSD 提供了多种用户管理工具。`adduser` 命令以交互方式添加新用户，自动完成创建 passwd 条目、构建新用户主目录、从 **/usr/share/skel** 复制默认配置文件等操作。

adduser(8) 是一个 shell 脚本，内部调用 pw(8) 完成实际的用户数据库操作。adduser(8) 并非 FreeBSD 独有，OpenBSD 和 DragonFly BSD 也有各自的 adduser(8) 实现，但选项和行为有所不同。

`pw` 命令是更底层的用户和组管理工具，支持非交互式批量操作，可直接修改系统用户数据库文件。

用户账户信息存储在 master.passwd(5) 文件中，该文件包含用户名、加密密码、UID、GID、登录类、密码过期时间、账户过期时间、GECOS 信息、主目录和登录 shell 等字段。

## 账户类型

登录 FreeBSD 系统需具备有效的用户账户。

以下直接通过密码文件 **/etc/master.passwd** 观察用户：

```ini
root:$6$huh5iMfeueumGM3B$ycd9HsGOzKfFq6hbWMxceNBRCLibbSj5Ofjv/ed6Kq60M2F.syaGaxfdfYMqB79DZzqyhQlIiRZ4.D9ST90Gv/:0:0::0:0:Charlie &:/root:/bin/sh
toor:*:0:0::0:0:Bourne-again Superuser:/root:
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin

……省略一部分……

www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
ntpd:*:123:123::0:0:NTP Daemon:/var/db/ntp:/usr/sbin/nologin
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
ykla:$6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa.g9P0eZ32UwfByzRKdVnTaO7W.:1001:1001::0:0:User &:/home/ykla:/bin/sh
```

可以看到系统中存在若干用户账户。

FreeBSD 中主要有三类账户：系统账户、普通用户账户，以及超级用户账户。

### 系统账户

系统账户用于运行 DNS、邮件和 Web 服务器等服务。如果所有服务均以超级用户身份运行，其操作将不受限制，此即使用系统账户的安全性考量。

系统账户由源代码中的 [main/etc/master.passwd](https://github.com/freebsd/freebsd-src/blob/main/etc/master.passwd) 文件定义，截至写作时共计 27 个（26 个 UID < 1000 的账户加上 nobody(65534)，该数量随版本迭代可能变化），`_dhcp`、`ntpd` 便属于此类系统账户。系统账户是具有受限权限的专用账户，通常用于运行系统服务和守护进程。

`nobody` 是通用的非特权系统账户，但使用 `nobody` 的服务越多，该用户关联的文件和进程就越多，该用户特权越大，因此最佳实践是为每个服务分配独立的系统账户，而非共用 `nobody`。

系统默认的组定义于源代码 **/etc/group** 中。

### 普通用户账户

普通用户账户分配给实际使用者，用于登录和使用系统。为便于管理员追踪用户操作并防止用户互相干扰彼此的设置，每个访问系统的人都应拥有唯一的用户账户。

`ykla` 是在安装系统时创建的普通用户账户。如果希望通过 `su` 命令切换为 `root` 用户，必须将该用户加入 `wheel` 用户组。此外，部分用户账户是 Port 自动创建的系统用户。

每个用户账户在 FreeBSD 系统上都关联着若干属性信息：

| 属性             | 说明                                                                                          |
| -------------- | ------------------------------------------------------------------------------------------- |
| **用户名**        | 在 `login:` 提示符处输入的名称，每个用户必须拥有唯一的用户名。passwd(5) 中记载了创建有效用户名的规则。建议使用八个或更少的全部小写字符作为用户名，以保持向后兼容性 |
| **密码**         | 每个账户都有一个关联的密码                                                                               |
| **用户 ID（UID）** | 用于在 FreeBSD 系统中唯一标识用户的数字。由于较高的值可能导致某些软件的兼容性问题，建议使用小于 65535 的 UID                            |
| **组 ID（GID）**  | 用于唯一标识用户所属主组的数字。建议使用 65535 或更低的 GID                                                         |
| **登录类**        | 组机制的扩展，在为不同用户定制系统时提供额外的灵活性                                                                  |
| **密码更改时间**     | 在默认情况下密码不会过期，但可以按用户启用密码过期                                                                   |
| **账户过期时间**     | 在默认情况下 FreeBSD 不会使账户过期                                                                      |
| **用户全名**       | 用户名唯一标识 FreeBSD 的账户，但不一定反映用户的真实姓名                                                           |
| **主目录**        | 用户登录时的起始目录。常见约定是将所有用户主目录放在 **/home/username** 或 **/usr/home/username** 下                    |
| **用户 shell**   | shell 提供用户与系统交互的默认环境                                                                        |

需要注意，普通用户权限虽有限，但其运行的软件越多，系统暴露的攻击面也越大——可供攻击者利用的漏洞入口随之增多。攻击者仅在程序存在漏洞或配置不当的情况下，才能利用这些进程实现权限提升。

### 超级用户账户

超级用户账户，通常称为 root，用于无限制地管理系统。超级用户与普通用户账户不同，其操作不受限制，误用可能导致灾难性后果。普通用户账户无法因误操作而破坏操作系统，因此建议以普通用户账户登录，仅在命令需要额外特权时才切换为超级用户。

事实上，内核根据账户的 EUID（有效用户 ID）是否为 `0` 来判定某账户是否拥有 root 权限。参见：main/sys/kern/kern\_priv.c\[EB/OL]. \[2026-03-26]. <https://github.com/freebsd/freebsd-src/blob/main/sys/kern/kern_priv.c> 中的 `if (suser_enabled(cred))` 代码块部分。

获取超级用户特权有多种方式。虽然可以直接以 root 登录，但不推荐这种做法，建议使用 su(1) 命令切换为超级用户。

## 账户管理

FreeBSD 提供了多种不同的命令来管理用户账户。

**管理用户账户的工具**

| 命令           | 概要                  |
| ------------ | ------------------- |
| adduser(8)   | 推荐用于添加新用户的命令行应用程序。  |
| rmuser(8)    | 推荐用于删除用户的命令行应用程序。   |
| chpass(1)    | 用于更改用户数据库信息的灵活工具。   |
| passwd(1)    | 用于更改用户密码的命令行工具。     |
| pw(8)        | 可修改用户账户所有方面的强大灵活工具。 |
| bsdconfig(8) | 带有账户管理支持的系统配置工具。    |

### adduser 创建用户

推荐使用的添加新用户的程序是脚本文件 adduser(8)。添加新用户时，此程序会自动更新 **/etc/passwd** 和 **/etc/group**。

adduser 还会为新用户创建主目录，从 **/usr/share/skel** （源代码路径为 `share/skel`）复制默认配置文件。`adduser` 的源代码路径为 `usr.sbin/adduser/adduser.sh`。

adduser(8) 是交互式的，会逐步引导创建新用户账户。如下所示，输入所需信息或按 **回车键** 接受方括号中的默认值。

在此示例中，用户受邀加入 `wheel` 组，使其可以通过 su(1) 成为超级用户。

完成后，该工具会提示是创建另一名用户还是退出。

示例：创建普通用户 `ykla`，并添加到 `video` 组：

```sh
# adduser -G video -s sh -w yes
# Username: ykla
```

示例：创建用户 test，并添加到 wheel 组，设置其默认 shell 为 sh：

```sh
# adduser # 此工具必须由超级用户运行
Username: test # 用户名 ①
Full name:  # 全名，可留空
Uid (Leave empty for default): # UID 设置，可留空
Login group [test]: # 登录组
Login group is test. Invite test into other groups? []: wheel # 设置要加入的组，多个用空格隔开，可留空
Login class [default]: # 登录分类，可留空
Shell (sh csh tcsh nologin) [sh]: sh  # 除非手动设置默认 Shell，否则默认 Shell 为 sh
Home directory [/home/test]: # 指定家目录
Home directory permissions (Leave empty for default): # 指定家目录权限
Enable ZFS encryption? (yes/no) [no]: # 是否使用 ZFS 加密
Use password-based authentication? [yes]:  # 是否使用密码
Use an empty password? (yes/no) [no]:   # 是否空密码
Use a random password? (yes/no) [no]:   # 是否随机密码
Enter password: # 输入密码
Enter password again: # 重复输入密码
Lock out the account after creation? [no]: # 锁定账户？
Username   : test
Password   : *****
Full Name  :
Uid        : 1002
ZFS dataset : zroot/home/test
Class      :
Groups     : test wheel
Home       : /home/test
Home Mode  :
Shell      : /bin/sh
Locked     : no
OK? (yes/no): yes # 检查是否有错误
adduser: INFO: Successfully created ZFS dataset (zroot/home/test).
adduser: INFO: Successfully added (test) to the user database.
Add another user? (yes/no): no # 还需要创建另一个账户吗？
Goodbye!
```

> **注意**
>
> 由于输入密码时不会打印在屏幕上，也不会显示为掩码 `*`，请谨慎创建用户账户。

* ① 登录名命名有一些限制，参见 passwd(5)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=passwd&sektion=5>。但请注意，登录名不支持八位编码字符集，例如不支持中文（即仅支持特定 ASCII 字符）。

只有 root 才能使用此命令，否则将提示错误如下：

```sh
$ adduser test
adduser: ERROR: you must be the super-user (uid 0) to use this utility.
```

提示只有 UID 0 的用户（通常是 root）才能调用 adduser 命令。

### rmuser 删除用户

> **警告**
>
> `rmuser` 将永久删除用户账户及其主目录、邮件等所有相关信息，操作不可逆。使用 `-y` 参数将跳过确认步骤，请务必确认用户名正确无误。

`rmuser` 用于删除用户，与 `adduser` 命令一样，也是交互式的脚本。`rmuser` 源代码路径是 `usr.sbin/adduser/rmuser.sh`。

示例：删除用户 test1 test2。

```sh
# rmuser -y test1 test2 # 同时删除用户 test1 和 test2
Removing user (test1): mailspool home passwd.
Removing user (test2): home passwd.
```

参数 `-y` 用于跳过确认步骤。

### chpass 更改用户信息

所有用户都可以使用 chpass(1) 更改其默认 shell 和账户的个人信息。chpass 源代码位于 `usr.bin/chpass`。

示例：普通用户使用 nvi 文本编辑器打开当前用户信息并修改。

```sh
$ chpass ykla	# 修改 ykla 的账户信息数据库
#Changing user information for ykla.
Shell: /bin/sh	# 用户 shell
Full Name: User &	# 用户全名
Office Location:	# 办公地点
Office Phone:	# 办公电话
Home Phone:	# 家庭电话
Other information:	# 其他信息
~
~
~
/etc/pw.ogzb33: unmodified: line 1
```

root 可使用此工具更改任意用户的额外账户信息。

```sh
# chpass ykla	# 修改 ykla 的账户信息数据库
#Changing user information for ykla.
Login: ykla	# 指定 ykla
Password: $6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa
.g9P0eZ32UwfByzRKdVnTaO7W.	# 用户密码
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:	# 密码更改日期
Expire [month day year]:	# 账户过期日期
Class:	# 用户分级
Home directory: /home/ykla	# 用户家目录
Shell: /bin/sh
Full Name: User &
Office Location:
Office Phone:
Home Phone:
Other information:
~
~
~
/etc/pw.mDp9q3: unmodified: line 1
```

示例：修改用户 test1 的登录环境为 **/bin/sh**。

```sh
# chpass -s sh test1
chpass: user information updated
```

常用参数：`-s`，用于修改登录 shell。

> **技巧**
>
> chfn(1) 与 chsh(1) 是 chpass(1) 的链接命令，ypchpass(1)、ypchfn(1) 和 ypchsh(1) 也是。由于 NIS 支持是自动的，无需在命令前加 `yp`。这一点可以从源代码 `usr.bin/chpass/Makefile` 进行推断：
>
> ```makefile
> SYMLINKS=	chpass ${BINDIR}/chfn
> SYMLINKS+=	chpass ${BINDIR}/chsh
> .if ${MK_NIS} != "no"	# 如果系统启用了 NIS
> SYMLINKS+=	chpass ${BINDIR}/ypchfn
> SYMLINKS+=	chpass ${BINDIR}/ypchpass
> SYMLINKS+=	chpass ${BINDIR}/ypchsh
> .endif
>
> MLINKS=	chpass.1 chfn.1 chpass.1 chsh.1
> .if ${MK_NIS} != "no"
> MLINKS+= chpass.1 ypchpass.1 chpass.1 ypchfn.1 chpass.1 ypchsh.1
> .endif
> ```

### passwd 更改用户密码

修改用户密码，如不指定用户则默认为当前用户。普通用户只能修改自己的密码，否则将提示错误如下：

```sh
$ passwd test
passwd: permission denied
```

示例：使用 ykla 更改自己的密码。

```sh
$ passwd ykla
Changing local password for ykla
Old Password:	# 输入旧密码
New Password:	# 输入新密码
Retype New Password:	# 再次输入新密码
```

root 用户可以修改所有用户的密码，且无需旧密码。

示例：使用 root 更改用户 ykla 的密码。

```sh
# passwd ykla
Changing local password for ykla
New Password:	# 输入新密码
Retype New Password:	# 再次输入新密码
```

> **技巧**
>
> FreeBSD 的 `passwd` 选项与 Linux 不同，锁定/解锁账户请使用 `pw lock/unlock`。

## 组管理

组是用户的列表。组由其组名和 GID 标识。在 FreeBSD 中，内核使用进程的 UID 和其所属的组列表来确定进程可执行的操作范围。在大多数情况下，用户或进程的 GID 通常指列表中的第一个组。

组名到 GID 的映射列在 **/etc/group** 中。**/etc/group** 是纯文本文件，有四个以冒号分隔的字段。

```sh
# cat /etc/group
wheel:*:0:root,ykla	#
operator:*:5:root

……省略部分输出……

ykla:*:1001:
test:*:1002:
```

可以看到 **/etc/group** 的格式形如 `组名:加密后的密码:GID:成员列表`，通过英文冒号分隔。

超级用户可以使用文本编辑器修改 **/etc/group**，但因编辑错误可能导致严重后果，不建议这样做。建议使用 pw(8) 添加和编辑组。

> **警告**
>
> `operator` 组可能授予意外的类似超级用户的访问权限，包括但不限于关机（`shutdown`）和访问 **/dev** 中的部分设备（如磁盘设备），因此使用该组时请务必小心。注意 `reboot` 和 `halt` 仅限 root 用户，operator 组成员无法执行。

在 FreeBSD 中，可以使用 `pw` 命令管理用户和组：它是系统用户和组文件的前端。pw(8) 提供了非常强大的命令行选项，适合用于 shell 脚本，但对于新用户来说可能比本节中的其他命令更复杂。

### 添加组

使用 pw(8) 添加组：

```sh
# pw groupadd ykla2
# pw groupshow ykla2
ykla2:*:1002:
```

在此示例中，1002 是 ykla2 的 GID。此时，ykla2 没有成员。

### 向组中添加用户

使用 pw(8) 将用户添加到组中。

示例：设置组 test5 的成员为 test1。

```sh
# pw groupmod test5 -M test1 # 原有成员会被删除！
```

示例：将用户 `ykla` 同时添加到 `ykla2` 和 `wheel` 组：

```sh
# pw usermod ykla -G ykla2,wheel
```

`-G` 组列表，逗号分隔。

验证如下：

```sh
# id ykla
uid=1001(ykla) gid=1001(ykla) groups=1001(ykla),0(wheel),1002(ykla2)
```

示例：将用户 `test` 添加到 `wheel` 组（`wheel` 组为系统默认组，无需创建）：

```sh
# pw groupmod wheel -m test
```

在此示例中，传递给 `-m` 的参数是用户列表（逗号分隔），这些用户会追加到组中，并不会替换已有用户。

### 删除组

示例：删除 `admin` 组：

```sh
# pw groupdel admin
```

### 删除组中的用户

示例：从 `admin` 组里移除用户 `ykla`：

```sh
# pw groupmod admin -d ykla
```

### 添加用户

`pw useradd` 命令用于新建用户。

示例：创建用户 test1。

```sh
# pw useradd test1 # uid 系统默认，test1 组，登录环境 /bin/sh，未创建主目录
```

示例：创建用户 test2。

```sh
# pw useradd test2 -u 1200 -m -d /tmp/test -g test2 -G wheel -s sh -c test2 # 创建用户 test2：UID 1200，创建主目录 /tmp/test，主组 test2，附加 wheel 组，登录 shell 为 sh，全名 test2
```

### 修改用户信息

`pw usermod` 命令用于修改用户信息。

示例：

```sh
# pw usermod test1 -l test2 # 将用户 test1 重命名为 test2
```

选项 `-l` 修改用户名。

### 删除用户

`pw userdel` 命令用于删除用户。

> **警告**
>
> `pw userdel -r` 将永久删除用户及其主目录和所有相关信息，操作不可逆。如果主目录为 ZFS 数据集，pw(8) 仅删除其中的文件，不会销毁该数据集，需手动执行 `zfs destroy` 销毁数据集及其子数据集和快照。请确认用户名正确无误。

示例：删除用户 test2 及其主目录。

```sh
# pw userdel -r test2
```

常用参数：`-r` 删除用户，同时删除用户主目录及所有相关信息；如果不使用该参数则信息保留，仅删除用户。如果主目录为 ZFS 数据集，pw(8) 仅删除其中的文件，不会销毁该数据集，需手动执行 `zfs destroy` 销毁数据集及其子数据集和快照。

### 显示用户信息

`pw usershow` 命令用于显示用户信息。

示例：显示用户 test2 的详细信息。

```sh
# pw usershow test2
test2:$6$FkxPcs2y.Y8cxyuj$kVDoV1LC.IWKGlSitll3oLArF18aHQYID0JYE.TUuD0YFgba.c7MbGs3xLnmpCZyu1nVKHhNqW2X7a57qN0xg/:1201:1201::0:0:User &:/home/test2:/bin/sh
```

### 修改组信息

`pw groupmod` 命令用于修改组信息。

示例：修改 test 组的 gid 为 1300。

```sh
# pw groupmod test -g 1300
```

示例：将 test 组重命名为 test2。

```sh
# pw groupmod test -l test2
```

## 参考文献

* FreeBSD Project. pw(8)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=pw&sektion=8>. 手册页，介绍了用户和组管理命令。

## 课后习题

1. 修改 FreeBSD 源代码，使操作的用户名支持 UTF-8 编码。
2. 查看 FreeBSD 中 pw 命令的源代码实现，使其更加现代化。


# 17.2 权限

文件系统权限机制是类 UNIX 系统安全架构的基石。

在 FreeBSD 中，每个文件和目录都关联一组权限，有多种工具可用于查看和修改这些权限。

权限决定了用户能够访问哪些文件，以及能否修改或执行不属于自身的文件。

基本的 UNIX 权限使用三种访问类型分配：读、写和执行。这些访问类型用于确定文件属主、组和其他用户的文件访问权限。

本节讨论的是 FreeBSD 中使用的传统 UNIX® 权限，不涉及细粒度的权限。

## 自主访问控制（DAC）模型

FreeBSD 采用的传统 UNIX 权限模型属于自主访问控制（Discretionary Access Control，DAC）范畴。DAC 的核心特征是：客体的属主（owner）有权自主决定将访问权限授予其他主体，或撤销其他主体的访问权限。在 UNIX 系统中，文件的属主可以自行修改文件的权限位，决定其他用户对该文件的访问能力。由于访问控制决策由客体属主而非系统管理员集中做出，这种模型称作“自主的”（discretionary）。

DAC 模型的理论基础可追溯至 20 世纪 60—70 年代的多用户操作系统安全研究。美国国防部于 1985 年发布的《可信计算机系统评估准则》（Trusted Computer System Evaluation Criteria，TCSEC，又称“橘皮书”）将 DAC 定义为：一种基于主体身份和/或所属组来限制对客体访问的访问控制机制，客体的属主可以自行指定或修改访问权限（来源：Department of Defense. DoD 5200.28-STD: Trusted Computer System Evaluation Criteria\[S]. Washington, D.C.: Department of Defense, 1985.）。

传统 UNIX DAC 模型具有以下特征与局限：

* **粗粒度控制**：仅区分属主、所属组和其他用户三类主体，无法为单个用户或多个组授予细粒度权限。
* **权限传播**：文件属主可以将权限授予任意用户，包括将写权限授予非信任用户，这可能导致权限泄露。
* **超级用户绕过**：root 用户不受 DAC 约束，可以访问任何文件。这种设计在提供管理便利性的同时，也构成了潜在的安全风险，一旦 root 权限遭非法获取，整个系统的安全防线即告瓦解。

为弥补传统 DAC 模型的不足，FreeBSD 提供了以下增强机制：

* **访问控制列表（ACL）**：基于 POSIX.1e 草案标准的 ACL 机制，允许对单个用户或组设置细粒度的访问权限，突破了传统 DAC 仅支持三类主体的限制。
* **强制访问控制（MAC）**：TrustedBSD MAC 框架提供了基于安全策略的强制访问控制能力，包括 Biba 完整性模型、MLS 多级安全模型等。与 DAC 不同，MAC 的访问控制决策由系统安全策略强制执行，客体属主无法自行修改。
* **文件标志（File Flags）**：FreeBSD 支持通过 chflags(1) 设置文件标志，如 `schg`（系统不可变标志）和 `sappnd`（系统仅追加标志），即使 root 用户也无法修改带有这些标志的文件（除非先移除标志）。文件标志增加了额外的安全和控制层级，即使 root 也无法删除或修改这些文件。
* **Capsicum 沙盒框架**：通过能力（capability）机制限制进程可访问的系统资源范围，实现最小权限原则。

## 权限表达式

观察以下 `ls` 命令的输出示例，以理解权限表达式的构成：

```sh
# ls -al /home/ykla  # 显示 /home/ykla 目录下的详细文件列表
total 74
drwxr-xr-x  17 ykla ykla    27 Mar 19 17:57 .
drwxr-xr-x   3 root wheel    4 Mar 19 16:05 ..
drwx------   4 ykla ykla     4 Mar 10 16:21 .mozilla
-rw-r--r--   1 ykla ykla   966 Feb 24 12:18 .profile
-rw-------   1 ykla ykla   200 Mar 19 17:57 .sh_history
-rw-r--r--   1 ykla ykla  1003 Feb 24 12:18 .shrc
drwxr-xr-x   2 ykla ykla     2 Mar  9 23:48 .themes
drwxr-xr-x   2 ykla ykla     2 Mar  9 20:45 桌面
```

再观察：

```sh
----------   1 root wheel         0 Mar 19 22:26 test
```

FreeBSD 文件访问权限可使用 10 个标志位来表示（请读者核实第一列是否为 10 位），而这 10 个标志位由 4 个部分组成：

用斜杠分隔：`-/---/---/---`

```sh
- / --- / --- / ---
|   |     |     |
|   |     |     └─── 第四部分：其他用户权限（others）
|   |     └───────── 第三部分：同组用户权限（group）
|   └─────────────── 第二部分：属主权限（owner）
└─────────────────── 第一部分：文件类型 / 设备类型
```

第一部分是第 1 位，表示文件类型 / 设备类型：

| 字符  | 类型     |
| --- | ------ |
| `d` | 目录     |
| `-` | 普通文件   |
| `l` | 符号链接文件 |
| `b` | 块设备文件  |
| `p` | 管道文件   |
| `c` | 字符设备文件 |
| `s` | 套接字文件  |

第二部分是第 2、3、4 位，用于表示文件所属用户对文件的访问权限，用 `rwx` 表示读、写、执行权限（对于目录来说即访问权限，如 `ls`、`cd`），无权限则写成 `-`。

第三部分是第 5、6、7 位，用于标识文件所属组成员对文件的访问权限。

第四部分是第 8、9、10 位，用于标识其他用户对文件的访问权限。

读、写、执行权限除了用 `rwx` 表示外，也可分别对应数字 4、2、1，无权限即 0。每三位权限对应的数字相加后组合，即形成 3 位数字的表示方式（记忆口诀：“读 4 写 2 执行 1”）。

可能的数字与字母组合方式如下。

**UNIX® 权限**

| 值 | 权限说明        | 目录列表  |
| - | ----------- | ----- |
| 0 | 无读、无写、无执行权限 | `---` |
| 1 | 无读、无写、有执行权限 | `--x` |
| 2 | 无读、有写、无执行权限 | `-w-` |
| 3 | 无读、有写、有执行权限 | `-wx` |
| 4 | 有读、无写、无执行权限 | `r--` |
| 5 | 有读、无写、有执行权限 | `r-x` |
| 6 | 有读、有写、无执行权限 | `rw-` |
| 7 | 有读、有写、有执行权限 | `rwx` |

关于上面数字代表权限的代码可以在 [main/sys/sys/stat.h](https://github.com/freebsd/freebsd-src/blob/main/sys/sys/stat.h) 找到，由 IEEE Std 1003.1 规范定义：

```c
#define	S_IRWXU	0000700			/* 拥有者的读、写、执行（RWX）权限掩码 */
#define	S_IRUSR	0000400			/* 拥有者的读（Read）权限 */
#define	S_IWUSR	0000200			/* 拥有者的写（Write）权限 */
#define	S_IXUSR	0000100			/* 拥有者的执行（Execute）权限 */
```

系统控制设备权限的机制基于传统的 UNIX 哲学“一切皆文件”，即将大多数硬件设备视为文件，程序可以打开、读写这些设备。这些特殊的设备文件存储在 **/dev/** 目录中。

典型的 **/dev/** 目录：

```sh
$ ls /dev
acpi		efi		mixer0		pci		ttyv6
apm		fd		mlx5ctl		pfil		ttyv7
apmctl		fido		nda0		psm0		ttyv8
atkbd0		full		nda0p1		pts		ttyv9
audit		geom.ctl	nda0p2		random		ttyva
auditpipe	gpt		nda0p3		reroot		ttyvb
bpf		hpet0		netdump		sndstat		ufssuspend
bpf0		input		netmap		stderr		ugen0.1
bpsm0		io		null		stdin		ugen0.2
cd0		iso9660		nvd0		stdout		ugen0.3
console		kbd0		nvd0p1		sysmouse	ugen1.1
consolectl	kbd1		nvd0p2		tcp_log		uinput
ctty		kbdmux0		nvd0p3		ttyv0		urandom
devctl		klog		nvme0		ttyv1		usb
devctl2		kmem		nvme0n1		ttyv2		usbctl
devstat		log		nvme0ns1	ttyv3		xpt0
dsp0		mdctl		pass0		ttyv4		zero
dumpdev		mem		pass1		ttyv5		zfs
```

> **思考题**
>
> > `drw-------`，即 `600`，这是一个目录，只有所属用户可以读、写。
>
> 这种说法正确吗，有意义吗，为什么？读者如何理解这种设计上的逻辑悖论？

目录也视为文件，同样处理，同样具有读、写和执行权限。目录的可执行位与文件略有不同，目录设置为可执行时，表示可以使用 `cd` 命令切换进入该目录。

这也意味着要访问该目录中的文件，前提是文件本身的权限允许访问：

```sh
$ cd test/
cd: test/: Permission denied	# 提示权限不足
$ ls -ld test/	# 浏览目录权限
drw-------  2 ykla ykla 2 Apr 28 00:24 test/
```

如果要列出目录内容，该目录必须具有读权限。如果要删除已知名称的文件，则必须对该文件所在的目录同时具有写权限和执行权限。

还存在额外的权限位，主要用于特殊场景，例如 setuid 可执行文件和 sticky 目录。

## 符号权限

符号权限使用字符而非八进制值来为文件或目录分配权限，其语法为 `(对象)(操作)(权限)`，其中可用的值如下：

| 选项 | 字母 | 代表               |
| -- | -- | ---------------- |
| 对象 | u  | 用户（User）         |
| 对象 | g  | 组属主（Group owner） |
| 对象 | o  | 其他（Other）        |
| 对象 | a  | 所有（ALL）          |
| 操作 | +  | 添加权限             |
| 操作 | -  | 移除权限             |
| 操作 | =  | 显式设置权限           |
| 权限 | r  | 读（Read）          |
| 权限 | w  | 写（Write）         |
| 权限 | x  | 执行（Execute）      |
| 权限 | t  | 粘滞位（Sticky bit）  |
| 权限 | s  | 设置 UID 或 GID     |

> **注意**
>
> chmod(1) 符号模式中的 `t`（sticky bit, 粘滞位）在 POSIX 标准中标记为 XSI 扩展选项，非 POSIX 基本要求。对“其他”权限（`o`）单独操作 `s`（设置 UID 或 GID）或 `t` 标志（粘滞位）时会忽略。设置粘滞位应使用 `+t` 或 `a+t`，而非 `o+t`。

这些值与 chmod(1) 一起使用，但使用字母而非数字。例如，以下命令将阻止与 test 关联的组成员和所有其他用户访问 test：

```sh
% chmod go= test
```

~~这里的 go 并不是代表“前进”，而是“组属主”和“其他”。并且等于号后面的空格是必要的。~~

当需要多次更改文件权限时，可以提供逗号分隔的列表。例如，以下命令移除 test 的组和“world”写权限，并为所有用户添加执行权限：

```sh
% chmod go-w,a+x test
```

> **技巧**
>
> chmod(1) 符号模式中 `X` 权限仅在文件已是可执行或为目录时才设置执行位，常用于 `chmod =rw,+X` 保留已有执行权限。

### 操作符方式

赋予所有用户对 test.sh 脚本的执行权限：

```sh
$ chmod a+x test.sh
```

在 `a+x` 中：

* `a` 表示操作对象为所有用户。可选项还有：`u` 表示所属用户，`g` 表示所属组，`o` 表示其他用户，如果省略则依照系统默认对象操作；
* `+` 是操作符，意为增加权限；可选项 `-` 则为移除权限；
* `rwx` 是权限模式。`r` 表示读、`w` 表示写、`x` 表示执行。可选项 `s` 表示在文件执行时将进程的属主或属组设置为文件的属主或属组。

### 数字方式

设置 `test.sh` 的权限为属主可读写执行、组用户可读执行、其他用户无权限：

```sh
$ chmod 750 test.sh
```

其中：

* `7`：所属用户拥有读、写、执行的权限
* `5`：同组用户有读和执行的权限
* `0`：其他用户没有任何权限

此处，选项 `-R` 可递归修改权限。

示例：

```sh
# chmod -R 777 /tmp # 允许任何用户读、写、执行 /tmp 目录下所有文件
# chmod -R a+rwx /tmp # 允许任何用户读、写、执行 /tmp 目录下所有文件
```

## umask：文件创建掩码

在 UNIX 系统中，当进程调用 open(2)、mkdir(2) 等系统调用创建文件或目录时，内核使用文件创建掩码（umask）来确定最终权限。umask 是一个进程级属性，指定在文件创建时应屏蔽（移除）的权限位。umask 机制确保新创建的文件不会意外地拥有过于宽松的权限。

事实上，权限数值是八进制，而非十进制。将八进制 755 转为二进制则为：111 101 101。具体计算过程：

```sh
7
= 4 + 2 + 1
= 1×2² + 1×2¹ + 1×2⁰
= 111₂

5
= 4 + 0 + 1
= 1×2² + 0×2¹ + 1×2⁰
= 101₂

5
= 4 + 0 + 1
= 1×2² + 0×2¹ + 1×2⁰
= 101₂

合并（最后数字 = Σ (数字 × 进制数^位置)，位置从 0 开始，从右到左，Σ 代表总和）：

111 101 101₂
```

> **技巧**
>
> 一般来说，任何非零数的 0 次方都等于 1。

具体而言，新文件的初始权限由创建请求中的模式参数与 umask 取反后进行按位与运算得出：

```sh
最终权限 = 请求模式 & ~umask
```

> **技巧**
>
> 按位与 `&`：
>
> 按位取反：
>
> ```sh
> umask:   000 010 010   （022）
> ~umask:  111 101 101   （755）
> ```

| 位 1 | 位 2 | 结果 |
| --- | --- | -- |
| 1   | 1   | 1  |
| 1   | 0   | 0  |
| 0   | 1   | 0  |
| 0   | 0   | 0  |

例如，进程请求以模式 `0666`（所有用户读写）创建文件，而当前 umask 为 `0022` 时：

```sh
  110 110 110   (0666)
& 111 101 101   (~0022)
--------------
  110 100 100
```

则最终权限为 `0666 & ~0022 = 0644`（属主读写、组和其他用户只读）。

```sh
  111 111 111   (0777)
& 111 101 101   (~0022)
--------------
  111 101 101
```

对于目录，通常的请求模式为 `0777`，在 umask 为 `0022` 时结果为 `0755`。

FreeBSD 的默认 umask 为 `0022`，可通过 umask(2) 系统调用或 shell 内建的 `umask` 命令查看和设置：

```sh
% umask      # 显示当前 umask（八进制）
0022
% umask -S   # 以符号方式显示
u=rwx,g=rx,o=rx
% umask 027  # 设置 umask 为 027（请勿在生产环境执行）
```

| umask 值 | 新文件权限（请求 0666）    | 新目录权限（请求 0777）    | 备注           |
| ------- | ----------------- | ----------------- | ------------ |
| `0022`  | `0644`（rw-r--r--） | `0755`（rwxr-xr-x） | 默认值          |
| `0027`  | `0640`（rw-r-----） | `0750`（rwxr-x---） | 更严格，禁止其他用户访问 |
| `0077`  | `0600`（rw-------） | `0700`（rwx------） | 最严格，仅属主可访问   |

umask 在 shell 启动文件（如 **\~/.profile** 或 **\~/.cshrc**）中设置。在 csh/tcsh 中使用 `umask 022`，在 sh/bash 中同样使用 `umask 022`。

> **注意**
>
> * umask 仅影响文件创建时的初始权限，不会修改已存在文件的权限。
> * 在 Jail 容器中，umask 继承自主机系统的进程环境，不受 Jail 配置的直接影响。

## `chown` 命令

chown(8) 命令用于修改文件的属主，包括所属用户和所属组。只有 root 才能修改文件的属主。

> **注意**
>
> 符号表示法：`用户:组` 同时修改属主和属组；`:组` 仅修改属组；`用户:` 修改属主并将属组设为指定用户的登录组。

示例：修改 `t.sh` 的属主为 `test1`。

```sh
# chown test1 t.sh
```

示例：修改 `t.sh` 的属主为用户 `test1`、组 `test`。

```sh
# chown test1:test t.sh
```

示例：修改 **/tmp** 目录下所有文件的属主为用户 `test1`、组 `test`。

```sh
# chown -R test1:test /tmp
```

此处，选项 `-R` 可递归修改属主。

## 特殊权限位：setuid、setgid 与 sticky bit

除基本的读、写、执行权限外，UNIX 系统还定义了三种特殊权限位，这些设置提供了通常不授予普通用户的功能。要理解这些权限位，必须注意实际用户 ID（real user ID）与有效用户 ID（effective user ID）之间的区别：实际用户 ID 是拥有或启动进程的 UID，而有效 UID 是进程运行时所采用的 UID。

### setuid（设置用户 ID）

可执行文件设置了 setuid 位后，无论哪个用户执行该文件，进程的有效用户 ID（EUID）都会设置为文件属主的 UID，而非执行者的 UID。这一机制令普通用户可以临时获得文件属主的权限来执行特定操作。

setuid 位在权限表达式中以属主执行位上的 `s` 表示（如 `-r-sr-xr-x`）。

setuid 最典型的应用场景是 passwd(1) 命令。

```sh
# ls -al /usr/bin/passwd
-r-sr-xr-x  1 root wheel 8368 Apr 13 12:38 /usr/bin/passwd
```

普通用户修改密码时需要更新 **/etc/master.passwd** 文件，而该文件只有 root 才有写权限。通过 setuid 机制，`passwd` 命令以 root 的 EUID 运行，从而获得修改密码文件的权限。passwd(1) 以普通用户的实际用户 ID 运行，但为了更新密码数据库，该命令以 root 用户的有效 ID 运行，使用户能够更改密码而不会遇到“Permission Denied”错误。

setuid 位数字表示法中在三位权限码前加 `4`（如 `4555`），使用命令显示完整权限（含类型和特殊位，八进制）：

```sh
# stat -f "%p" /usr/bin/passwd
104555
```

> **警告**
>
> setuid 机制是一把双刃剑：如果 setuid 程序存在安全漏洞，攻击者便可能利用该程序以文件属主（通常是 root）的权限执行任意代码，因此，系统管理员应尽量减少 setuid 程序的数量，并定期审计系统中的 setuid 文件。`nosuid` 挂载选项会使内核忽略文件系统上可执行文件的 setuid/setgid 位，程序仍可运行但不会获得提权。

### setgid（设置组 ID）

setgid 的作用与 setuid 类似，但作用于组而非用户。可执行文件设置了 setgid 位后，进程的有效组 ID（EGID）会设置为文件所属组的 GID。目录设置了 setgid 位后，在该目录中创建的新文件将继承目录的所属组，而非创建者的主组。

setgid 位在权限表达式中以所属组执行位上的 `s` 表示（如 `-r-xr-sr-x`）：

```sh
# stat -f "%Sp" /usr/libexec/dma
-r-xr-sr-x
```

数字表示法中在三位权限码前加 `2`（如 `2555`）:

```sh
# stat -f "%p" /usr/libexec/dma
102555
```

### sticky bit（粘滞位）

sticky bit 最初用于将可执行文件的代码段“粘滞”在交换空间中以提高重复启动速度，但这一用途在现代系统中已不再适用。当前，sticky bit 主要用于目录：目录设置了 sticky bit 后，只有文件的属主（或 root）才能删除或重命名该目录下的文件，即使其他用户对该目录拥有写权限。

sticky bit 最常见的应用场景是 **/tmp** 目录。该目录对所有用户开放写权限，但通过 sticky bit 防止用户删除他人的临时文件。目录设置了 sticky bit 时，仅文件属主可以删除该目录下的文件，这对于防止公共目录中非文件属主删除文件非常有用。

sticky bit 在权限表达式中以其他用户执行位上的 `t` 表示（如 `drwxrwxrwt`）：

```sh
# ls -ald /tmp
drwxrwxrwt  6 root wheel 6 Apr 27 21:55 /tmp
```

数字表示法中在三位权限码前加 `1`（如 `1777`）:

```sh
# stat -f "%p" /tmp
41777
```

## FreeBSD 文件标志

除了文件权限外，FreeBSD 还支持使用“文件标志”。这些标志增加了额外的安全和控制层级，适用于文件和目录，通过文件标志甚至可以阻止 root 删除或修改文件。

常用标志如下：

| 标志                                | 说明       | 备注                                    |
| --------------------------------- | -------- | ------------------------------------- |
| `schg` / `schange` / `simmutable` | 系统不可变标志  | 仅超级用户可设置；在安全级别（securelevel）大于 0 时无法清除 |
| `sappnd` / `sappend`              | 系统仅追加标志  | 仅超级用户可设置；同受安全级别限制                     |
| `uchg` / `uchange` / `uimmutable` | 用户不可变标志  | 文件属主或超级用户可设置；不受安全级别限制                 |
| `uappnd` / `uappend`              | 用户仅追加标志  | 文件属主或超级用户可设置                          |
| `nodump`                          | 不转储标志    | 文件属主或超级用户可设置；dump(8) 将跳过此类文件          |
| `sunlnk` / `sunlink`              | 系统不可删除标志 | 仅超级用户可设置                              |
| `uunlnk` / `uunlink`              | 用户不可删除标志 | 文件属主或超级用户可设置                          |

> **注意**
>
> * 标志前加 `no` 可清除该标志，如 `nouchg` 清除用户不可变标志。
> * 某些标志的修改能力取决于当前内核安全级别（securelevel），参见 security(7)。
> * 仅有限数量的工具支持 chflags 标志，包括 ls(1)、cp(1)、find(1)、install(1)、dump(8)、restore(8)；目前 pax(1) 不支持 chflags。

使用 chflags(1) 可修改文件标志。chflags(1) 首次出现于 4.4BSD，是 BSD 系统特有的功能，Linux 不原生支持（需通过 `chattr` 命令和 `lsattr` 命令实现类似功能）。查看文件的标志可使用 ls(1) 的 `-lo` 选项：

```sh
# ls -lo test
-rwx--x--x  1 ykla ykla uarch 0 Apr 16 12:44 test
```

> **注意**
>
> 如果使用 ZFS 文件系统，所有文件都可能拥有归档标志 `uarch`，这是符合预期的。

例如，要在文件 `test` 上启用系统不可删除标志，执行以下命令：

```sh
# chflags sunlink test
```

执行后，查看文件：

```sh
# ls -lo test
-rwx--x--x  1 ykla ykla sunlnk,uarch 0 Apr 16 12:44 test
```

要禁用系统不可删除标志，在 sunlink 前面加上“no”：

```sh
# chflags nosunlink test
```

文件标志通常只能由 root 用户添加或移除：

```sh
$ ls -lo
-rwx--x--x  1 ykla ykla     0 Apr 16 12:44 test
$ chflags sunlink test
chflags: test: Operation not permitted
```

否则系统将返回操作不允许错误。

### 参考文献

* FreeBSD Forums. File flag defaults on ZFS\[EB/OL]. (2020-09-22)\[2026-04-27]. <https://forums.freebsd.org/threads/file-flag-defaults-on-zfs.77088/>.

## 课后习题

1. 查看 FreeBSD 内核中权限检查的核心源代码，尝试使其更加细粒度。
2. 修改一个系统目录（如 **/var/tmp**）的默认权限配置，记录修改后对该目录下文件创建和进程访问行为的影响。
3. Unix 的 rwx 三级权限模型自 1970 年代沿用至今。比较此模型与 SELinux 的类型强制（Type Enforcement）和 AppArmor 的路径名限制在表达力上的差异，分析在单一系统上混合使用三种机制是否会引入策略冲突。


# 17.3 用户分级

**/etc/login.conf** 是登录类能力数据库（最早引入自 FreeBSD 2.1.5），用于控制资源配额、计量配额及默认用户环境设置。本节介绍其文件结构、class 定义语法与用户本地覆盖方法。

## login.conf 的概念与文件结构

系统中的多种程序利用该数据库建立用户的登录环境，并执行策略、计数和管理限制。它还提供了用户认证以及可用认证类型的配置方式。

```sh
/
├── etc/
│   └── login.conf           # 系统级用户分级配置文件，定义各种 class 的资源限制、环境变量等
└── 用户家目录 (~)/
    └── .login_conf          # 用户本地覆盖文件，可覆盖 /etc/login.conf 的设置
```

普通用户可通过主目录下的 **\~/.login\_conf** 文件覆盖系统级配置，该文件仅包含一条记录 ID 为“me”的条目。但仅部分登录能力可覆盖，通常仅限于不涉及认证、资源限制和计费的环境设置；系统级配置文件 **/etc/login.conf** 的优先级低于用户本地配置。

`login.conf` 文件在 FreeBSD 源代码中的位置为 [usr.bin/login/login.conf](https://github.com/freebsd/freebsd-src/blob/main/usr.bin/login/login.conf)，该文件即为默认配置，默认设置禁用了资源配额。

> **注意**
>
> 每次修改该文件后，必须手动运行 `cap_mkdb /etc/login.conf` 以刷新数据库。`cap_mkdb` 将文本格式的 login.conf 编译为哈希数据库格式，以提高查询性能。只有将文件编译为数据库后，修改才会生效。该数据库文件的扩展名为 `.db`，可通过 cgetent(3) 等函数调用。用户级 `~/.login_conf` 同样需要 `cap_mkdb ~/.login_conf` 编译才能生效。

## 默认配置文件解读

```ini
# 请注意，像“cputime”这样的条目会同时设置“cputime-cur”和“cputime-max”。
# “default”登录类会自动（由 login(1) 实现）应用于所有在 /etc/master.passwd 中未设置有效登录类的非 root 用户。
# 请注意，由于冒号 ':' 用于分隔能力条目，因此在能力的值或名称中嵌入字面冒号时必须使用 \c 转义序列（有关更多转义序列，请参见 getcap(3) 的“CGETNUM AND CGETSTR SYNTAX AND SEMANTICS”部分）。
# UID 为 0 的用户（root）如果没有有效登录类，则使用 root 记录（如果有），否则使用 default。
# default 登录类

default:\
	:passwd_format=sha512:\ # 新建或更改密码将使用的加密格式。类型为字符串。有效值为 "des"、"md5"、"blf"、"sha256" 和 "sha512"；详细信息请参见 crypt(3)。使用非 FreeBSD NIS 服务器的 NIS 客户端通常应使用 "des"。
	:welcome=/var/run/motd:\  # 登录后会看到的信息
	:setenv=BLOCKSIZE=K:\  # 由逗号分隔的环境变量及其对应值的列表。包含逗号的值必须加引号。BLOCKSIZE=K 即让命令以 KB 大小格式显示
	:mail=/var/mail/$:\  # 将环境变量 $MAIL 设置为指定的值。
	:path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin ~/bin:\  # 默认的 PATH 环境变量路径，会在其中查找可执行文件
	:nologin=/var/run/nologin:\  # 如果该文件存在，将打印该文件到屏幕上，并且对应用户的登录会话将被终止。
	:cputime=unlimited:\  # 限制进程可使用的 CPU 时间量。类型为时间，默认单位为秒。时间值可以使用不同单位表示：y 表示年（365 天）、w 表示周、d 表示天、h 表示小时、m 表示分钟、s 表示秒。单位可以连写，其值会累加。例如，2 小时 40 分钟可以写作 9600s、160m 或 2h40m。
	:datasize=unlimited:\  # 限制数据段（属于静态内存分配）的最大大小。类型为数值，默认单位为字节。常用单位包括 b、k、m、g、t，分别表示 512 字节、KB、MB、GB 和 TB，大小写不敏感。多个值可以连写，其数值会累加。例如 2g512M 表示总大小为 2.5 GB。
	:stacksize=unlimited:\  # 最大栈大小限制。类型为数值。
	:memorylocked=64K:\  # 最大核心锁定内存大小限制。类型为数值。
	:memoryuse=unlimited:\  # 最大核心内存使用量限制。类型为数值。
	:filesize=unlimited:\  # 限制进程可以创建的文件的最大大小。类型为数值。
	:coredumpsize=unlimited:\ # 最大 coredump 大小限制。类型为数值。
	:openfiles=unlimited:\  # 限制每个进程允许打开的最大文件数。类型为数字。数字类型可以是十六进制（0x 开头）或八进制（0 开头），每次只能指定一个值，也可以用字符串格式。数据库中所有记录必须统一使用同一表示方法。
	:maxproc=unlimited:\  # 限制最大进程数。类型为数字。
	:sbsize=unlimited:\  # 最大的套接字缓冲区大小。类型为数值。
	:vmemoryuse=unlimited:\  # 每个进程允许的最大虚拟存储器使用量。类型为数值。
	:swapuse=unlimited:\  # 最大交换空间大小限制。类型为数值。
	:pseudoterminals=unlimited:\  # 最大伪终端数量。类型为数字。
	:kqueues=unlimited:\  # 每个进程可创建的 kqueue 数量。类型为数字。
	:umtxp=unlimited:\  # 最大进程间共享的 pthread 锁数量。类型为数字。
	:pipebuf=unlimited:\  # 管道缓冲区的最大大小。类型为数字。
	:priority=0:\  # 初始进程优先级等级。类型为数字。用于设置进程的初始优先级：既可使用普通 nice 范围（-20 到 20），也可映射到实时或空闲优先级；如果设置特殊值“inherit”表示继承原有优先级，不进行重置。0 代表正常优先级。
	:umask=022:\  # 设置初始 umask。类型为数字，应以 0 开头以确保按八进制识别。特殊值 "inherit" 表示保持原有 umask 不变。022 表示文件默认权限为 644，目录默认权限为 755。
	:charset=UTF-8:\  # 指定环境变量 $MM_CHARSET（邮件相关程序会使用）的值。类型为字符串。
	:lang=C.UTF-8:  # 指定环境变量 $LANG 的值。类型为字符串。修改此处即可实现整个操作系统的全局 i18n 配置。

#
# 一组常见的类别名称，将它们全部转发到 'default'（login 通常也会这么做，但在这里有类别名称会抑制诊断信息）。
#
standard:\
	:tc=default:
xuser:\
	:tc=default:
staff:\
	:tc=default:

# 该 PATH 可能会被各个应用程序覆盖。特别是在默认情况下，rc(8)、service(8) 和 cron(8) 在启动服务或任务时会使用默认 PATH，而该 PATH 可能不包含 /usr/local/sbin 和 /usr/local/bin。
daemon:\
	:path=/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin:\
	:mail@:\
	:memorylocked=128M:\
	:tc=default:
news:\
	:tc=default:
dialer:\
	:tc=default:

#
# 让 Root 始终可以登录。
#
# 注意，对于 root 账户，login_getpwclass(3)（仅限该软件，不是全局设置）会应用此条目，而不是 'default' 中的参数。
root:\
	:ignorenologin:\  # 防止 nologin 设置阻止 root 登录
	:memorylocked=unlimited:\  # 防止内存配额限制导致 root 无法分配内存
	:tc=default:  # 继承父类（default）的属性和能力，子类同名条目可覆盖父类值

#
# 为俄罗斯用户账户配置正确的环境变量
#
# russian 登录类。可使用命令 pw usermod XXX -L russian 指定用户 XXX 使用该登录类。
#
russian|Russian Users Accounts:\
	:charset=UTF-8:\
	:lang=ru_RU.UTF-8:\
	:tc=default: # 继承父类（default）的属性和能力，子类同名条目可覆盖父类值


######################################################################
######################################################################
##
## 示例条目
##
######################################################################
######################################################################

## 示例默认值
## 这些设置默认由 login(1) 分配给无类别用户。请注意，像“cputime”这样的条目会同时设置“cputime-cur”和“cputime-max”。
#
#default:\
#	:cputime=infinity:\
#	:datasize-cur=22M:\
#	:stacksize-cur=8M:\
#	:memorylocked-cur=10M:\
#	:memoryuse-cur=30M:\
#	:filesize=infinity:\
#	:coredumpsize=infinity:\
#	:maxproc-cur=64:\
#	:openfiles-cur=64:\
#	:priority=0:\
#	:requirehome@:\
#	:umask=022:\
#	:tc=auth-defaults:
#
#
##
## standard - 标准用户默认值
##
#standard:\
#	:welcome=/var/run/motd:\
#	:setenv=BLOCKSIZE=K:\
#	:mail=/var/mail/$:\
#	:path=~/bin /bin /usr/bin /usr/local/bin:\
#	:manpath=/usr/share/man /usr/local/man:\
#	:nologin=/var/run/nologin:\
#	:cputime=1h30m:\
#	:datasize=8M:\
#	:vmemoryuse=100M:\
#	:stacksize=2M:\
#	:memorylocked=4M:\
#	:memoryuse=8M:\
#	:filesize=8M:\
#	:coredumpsize=8M:\
#	:openfiles=24:\
#	:maxproc=32:\
#	:priority=0:\
#	:requirehome:\
#	:passwordtime=90d:\
#	:umask=002:\
#	:tc=default:
#
#
##
## X 用户（需要更多资源！）
##
#xuser:\
#	:manpath=/usr/share/man /usr/local/man:\
#	:cputime=4h:\
#	:datasize=12M:\
#	:vmemoryuse=infinity:\
#	:stacksize=4M:\
#	:filesize=8M:\
#	:memoryuse=16M:\
#	:openfiles=32:\
#	:maxproc=48:\
#	:tc=standard:
#
#
##
## Staff（工作人员）用户，限制少，可随时登录
##
#staff:\
#	:ignorenologin:\
#	:requirehome@:\
#	:accounted@:\
#	:path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
#	:umask=022:\
#	:tc=standard:
#
#
##
## root - root 登录的备选方案
##
#root:\
#	:path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
#	:cputime=infinity:\
#	:datasize=infinity:\
#	:stacksize=infinity:\
#	:memorylocked=infinity:\
#	:memoryuse=infinity:\
#	:filesize=infinity:\
#	:coredumpsize=infinity:\
#	:openfiles=infinity:\
#	:maxproc=infinity:\
#	:memoryuse-cur=32M:\
#	:maxproc-cur=64:\
#	:openfiles-cur=1024:\
#	:priority=0:\
#	:requirehome@:\
#	:umask=022:\
#	:tc=auth-root-defaults:
#
#
##
## /etc/rc 使用的设置
##
#daemon:\
#	:coredumpsize@:\
#	:coredumpsize-cur=0:\
#	:datasize=infinity:\
#	:datasize-cur@:\
#	:maxproc=512:\
#	:maxproc-cur@:\
#	:memoryuse-cur=64M:\
#	:memorylocked-cur=64M:\
#	:openfiles=1024:\
#	:openfiles-cur@:\
#	:stacksize=16M:\
#	:stacksize-cur@:\
#	:tc=default:
#
#
##
## news 子系统使用的设置
##
#news:\
#	:path=/usr/local/news/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
#	:cputime=infinity:\
#	:filesize=128M:\
#	:datasize-cur=64M:\
#	:stacksize-cur=32M:\
#	:coredumpsize-cur=0:\
#	:maxmemorysize-cur=128M:\
#	:memorylocked=32M:\
#	:maxproc=128:\
#	:openfiles=256:\
#	:tc=default:
#
#
##
## dialer 类应当用于拨号 PPP 账号
## 欢迎信息/新闻已被屏蔽
##
#dialer:\
#	:hushlogin:\
#	:requirehome@:\
#	:cputime=unlimited:\
#	:filesize=2M:\
#	:datasize=2M:\
#	:stacksize=4M:\
#	:coredumpsize=0:\
#	:memoryuse=4M:\
#	:memorylocked=1M:\
#	:maxproc=16:\
#	:openfiles=32:\
#	:tc=standard:
#
#
##
## dialer 类，应当用于拨号 PPP 账号
## 欢迎信息/新闻已被屏蔽
##
#site:\
#	:passwordtime@:\
#	:refreshtime@:\
#	:refreshperiod@:\
#	:sessionlimit@:\
#	:autodelete@:\
#	:expireperiod@:\
#	:graceexpire@:\
#	:gracetime@:\
#	:warnexpire@:\
#	:warnpassword@:\
#	:idletime@:\
#	:sessiontime@:\
#	:daytime@:\
#	:weektime@:\
#	:monthtime@:\
#	:warntime@:\
#	:accounted@:\
#	:tc=dialer:\
#	:tc=staff:
#
#
##
## 订阅等级的标准会计分录示例
##
#
#subscriber|Subscribers:\
#	:accounted:\
#	:refreshtime=180d:\
#	:refreshperiod@:\
#	:sessionlimit@:\
#	:autodelete=30d:\
#	:expireperiod=180d:\
#	:graceexpire=7d:\
#	:gracetime=10m:\
#	:warnexpire=7d:\
#	:warnpassword=7d:\
#	:idletime=30m:\
#	:sessiontime=4h:\
#	:daytime=6h:\
#	:weektime=40h:\
#	:monthtime=120h:\
#	:warntime=4h:\
#	:tc=standard:
#
#
##
## 订阅账号。这些账号的登录时间会被记录，并施加访问限制。
##
#subppp|PPP Subscriber Accounts:\
#	:tc=dialer:\
#	:tc=subscriber:
#
#
#subshell|Shell Subscriber Accounts:\
#	:tc=subscriber:
#
##
## 如果希望部分账号使用传统的 UNIX DES 加密密码哈希。
##
#des_users:\
#	:passwd_format=des:\
#	:tc=default:
```

## 参考文献

* FreeBSD Project. login.conf(5)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=login.conf&sektion=5>. 登录类别功能数据库手册页。
* FreeBSD Project. cgetent -- capability database access routines\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=cgetent&sektion=3>. 能力数据库访问例程手册页。

## 课后习题

1. 修改用户的 **\~/.login\_conf** 文件覆盖系统级 `login.conf` 的部分设置，记录两种配置的优先级关系，分析 `cgetent()` 函数的数据库检索顺序。
2. 修改 default 类的 `umask` 和 `passwd_format` 设置，对比修改前后新建文件权限和密码加密方式的变化。
3. 创建一个自定义登录类，设置特定的资源限制（如 `cputime` 和 `maxproc`），分配给测试用户并验证限制是否生效，分析资源限制在内核层面的实现机制。


# 17.4 权限提升工具

sudo 和 doas 通过配置文件定义权限规则，使特定用户无需 root 密码即可执行特权操作，并提供操作日志。

> **思考题**
>
> > 即使是管理员，在无需特权操作时也应当限制自己的权限。
>
> 你认为这种权限限制设计的缺点是什么？

![权限示意图](/files/dYhIQ9CMGOkFHkCJYEI3)

## 权限提升工具配置文件结构

以下是本节介绍的权限提升工具配置文件路径总结：

```sh
/usr/local/etc/
├── doas.conf  # doas 配置文件
├── doas.conf.sample  # doas 示例配置文件
├── sudoers  # sudo/sudo-rs 主配置文件
└── sudoers.d/  # sudo 附加配置目录
    ├── username  # 用户名配置文件
    └── wheel  # wheel 组配置文件
```

## doas

doas 是从 OpenBSD 移植的命令行工具，可作为类 Unix 系统中 sudo 的替代方案。

doas 的作者是 Ted Unangst，首次随 OpenBSD 5.8 引入。用户可通过 doas 以提升的权限执行命令（通常以 root 身份）。与 sudo 不同，doas 强调配置简洁与安全性，专注于精简的权限委派，避免庞杂的配置选项。

使用时可将 `sudo` 直接替换为 `doas`，二者在基本使用场景下功能等价。doas 支持以下选项：

| 选项                   | 说明                                    |
| -------------------- | ------------------------------------- |
| `nopass`             | 免密码执行                                 |
| `keepenv` / `setenv` | 环境变量控制（继承或设置）                         |
| `args`               | 命令参数限制                                |
| `nolog`              | 不记录日志                                 |
| `persist`            | 密码缓存（仅 Port **security/opendoas** 支持） |

doas 不具备 sudo 的插件架构和 LDAP 集成等高级特性。

### 安装 doas

* 使用 pkg 安装：

```sh
# pkg install doas
```

* 或者使用 Ports 安装：

```sh
# cd /usr/ports/security/doas/
# make install clean
```

### 使用 doas 管理共享权限

用户 `user2` 只需创建文件 **/usr/local/etc/doas.conf** 并写入：

```ini
permit nopass user2 as root
```

即可允许用户 `user2` 在执行 doas 时无需输入密码即可获取 `root` 权限。如果不需要 doas 免密码，移除 `nopass` 即可。

> **警告**
>
> `nopass` 选项虽然便捷，但存在安全风险：如果该用户账户被攻破，攻击者无需任何额外凭证即可获得 root 权限。建议仅在受信任的单用户桌面环境使用 `nopass`，多用户或服务器环境应要求密码认证。

对于 wheel 组用户，则写入以下行即可：

```ini
permit nopass :wheel
```

安装并配置好 `doas` 之后，即可执行特权命令：

```sh
$ doas ee /etc/rc.conf
```

### doas 示例配置文件

示例配置文件位于 **/usr/local/etc/doas.conf.sample**。

简要注释如下：

```ini
# Sample file for doas
# Please see doas.conf manual page for information on setting
# up a doas.conf file.

# Permit members of the wheel group to perform actions as root.
permit :wheel # 允许 wheel 组成员 doas

# Same without having to enter the password
permit nopass :wheel # 允许 wheel 组成员 doas，但免密码

# Permit user alice to run commands as a root user.
permit alice as root # 允许用户 alice doas

# Permit user bob to run programs as root, maintaining
# environment variables. Useful for GUI applications.
permit keepenv bob as root  # 允许用户 bob doas，并继承用户 bob 的环境变量，图形用户界面程序需要，但会降低安全性（参见查看安装后信息）

# Permit user cindy to run only the pkg package manager as root
# to perform package updates and upgrades.
permit cindy as root cmd pkg args update  # 仅允许用户 cindy 执行 pkg update
permit cindy as root cmd pkg args upgrade # 仅允许用户 cindy 执行 pkg upgrade

# Allow david to run id command as root without logging it
permit nolog david as root cmd id # 允许 david 以 root 身份运行 id 命令且不记录日志
```

## sudo

sudo 的初始作者是 Bob Coggeshall 和 Cliff Spencer（原始版本，约 1980 年），面向 4.1BSD。sudo 的主要重写和维护者是 Todd C. Miller。

sudo 的 `sudoers` 配置语法复杂度较高，手册页逾 1000 行，容易配置错误导致安全漏洞；时间戳文件位于 **/var/run/sudo/ts/**，若文件系统已满可能无法正常工作；`sudo -i` 在某些 shell 环境下可能不会完整加载环境变量。

`sudo` 允许管理员配置更严格的系统命令访问，并提供日志记录功能。

### 安装 sudo

* 使用 pkg 安装：

```sh
# pkg install sudo
```

* 或者使用 Ports 安装：

```sh
# cd /usr/ports/security/sudo/
# make install clean
```

### 使用 sudo 进行共享管理

sudo 配置文件由若干小节组成，支持深度自定义。

#### 配置普通用户使用 sudo

未配置的普通用户执行 sudo 将提示错误 `xxx Is Not in the Sudoers File. This Incident Will Be Reported`。

需要在 sudoers 配置文件中加入一行以解决该问题。编辑 **/usr/local/etc/sudoers** 文件，找到 `root ALL=(ALL:ALL) ALL` 这一行，在其下方添加一行：

```ini
实际普通用户 ALL=(ALL:ALL) ALL
```

随后保存并退出。用户“实际普通用户”将能够使用 sudo，提示输入密码时输入该用户密码即可，无需 root 用户密码。

#### 授予特定用户执行特定命令的权限

在下面的示例中，Web 应用运维人员 user1 需要启动、停止和重启 Web 应用程序 *webservice*。要授予该用户相关权限，请在 **/usr/local/etc/sudoers** 文件末尾新增一行：

```ini
user1   ALL=(ALL)       /usr/sbin/service webservice *
```

随后用户 user1 即可通过以下命令启动 *webservice*：

```sh
$ sudo /usr/sbin/service webservice start
```

上述配置仅对单个用户（user1）授权了 webservice 服务，但大多数组织会有 Web 团队负责相关管理。仅需一行配置，即可将权限赋予整个组。以下步骤将先创建 web 组，再向其中添加用户，最终使组内所有成员都具备管理该服务的能力：

```sh
# pw groupadd -g 6001 -n webteam
```

再使用 pw 命令将所需用户 user1 添加至 webteam 组：

```sh
# pw groupmod -m user1 -n webteam
```

最后，在 **/usr/local/etc/sudoers** 文件中写入以下行，即可让 webteam 组的所有成员都有权限管理 *webservice*：

```ini
%webteam   ALL=(ALL)       /usr/sbin/service webservice *
```

#### sudo 普通用户和组免密码

授权使用 sudo 的用户只需输入自身密码即可完成认证。相比 `su`，sudo 的优点在于：`su` 需要输入 `root` 密码并授予完整的 `root` 权限，而 sudo 可按用户或组进行细粒度权限控制。要允许 webteam 组成员免密码管理该服务，可改为：

```ini
%webteam   ALL=(ALL)       NOPASSWD: /usr/sbin/service webservice *
```

类似地，如果希望用户 user1 免密码，则改为：

```sh
user1   ALL=(ALL)       NOPASSWD:ALL
```

如果希望 `wheel` 组中的用户也免密码，则如下：

```sh
%wheel   ALL=(ALL)       NOPASSWD:ALL
```

百分号 `%` 表示组，不加 `%` 表示普通用户。

### 参考文献

* Sudo. A Brief History of Sudo\[EB/OL]. \[2026-03-26]. <https://www.sudo.ws/about/history>. sudo 官方简史。

## sudo-rs

sudo-rs 是 Rust 编写的 sudo 与 su 实现，以安全为导向，具备内存安全性。

### 与 sudo 不共存的安装方案

安装 sudo-rs 前必须先卸载 sudo，该方式下两者不能共存。

* 使用 pkg 安装：

```sh
# pkg install sudo-rs
```

* 或者使用 Ports 安装：

```sh
# cd /usr/ports/security/sudo-rs/
# make install clean
```

提供了 `sudo`、`visudo` 和 `sudoedit` 命令。

`visudo` 以安全方式编辑 sudoers 文件，类似于 vipw(8)。它锁定 sudoers 文件防止同时编辑，执行基本有效性检查，并在安装前检查语法错误。若发现语法错误，会显示行号并提示“What now?”，用户可选择 `e`（重新编辑）、`x`（退出不保存）或 `Q`（强制保存，有风险）。编辑器选择由 `SUDO_EDITOR`、`VISUAL`、`EDITOR` 环境变量决定，默认为 **/usr/bin/vi**。

FreeBSD 的 `visudo` 来自 sudo 软件包（非基本系统），与 Linux 版本来自同一上游源代码，基本兼容。

### 与 sudo 共存的安装方案

系统中同时存在 sudo 与 sudo-rs。

* 使用 pkg 安装：

```sh
# pkg install sudo-rs-coexist
```

* 还可以通过 Ports 来安装：

```sh
# cd /usr/ports/security/sudo-rs/
# make -V FLAVORS # 查看有哪些 FLAVORS
default coexist
# make FLAVOR=coexist install clean # 指定安装共存版本的 sudo-rs
```

提供了 `sudo-rs`、`visudo-rs` 和 `sudoedit-rs` 命令。

### sudo-rs 示例配置文件

配置文件位于：**/usr/local/etc/sudoers**。

```ini
## sudoers file.
## sudoers 文件。

##
## This file MUST be edited with the 'visudo' command as root.
## 此文件必须通过 root 身份使用 visudo 命令编辑。

## Failure to use 'visudo' may result in syntax or file permission errors
## that prevent sudo from running.
## 不使用 visudo 可能导致语法或权限错误，从而使 sudo 无法运行。

##
## See the sudoers man page for the details on how to write a sudoers file.
## 如何编写 sudoers 文件的详细说明请参阅 sudoers 的手册页（man sudoers）。

## Defaults specification
## 默认设置规范

##
## Preserve editor environment variables for visudo.
## 为 visudo 保留编辑器相关的环境变量。

## To preserve these for all commands, remove the "!visudo" qualifier.
## 若希望对所有命令都保留这些变量，请移除“!visudo”限定。

Defaults!/usr/local/sbin/visudo env_keep += "SUDO_EDITOR EDITOR VISUAL"
## 仅对 /usr/local/sbin/visudo 命令保留环境变量 SUDO_EDITOR、EDITOR、VISUAL。

##
## Use a hard-coded PATH instead of the user's to find commands.
## 使用硬编码的 PATH 查找命令，而不是使用用户的 PATH。

## This also helps prevent poorly written scripts from running
## arbitrary commands under sudo.
## 这也有助于防止编写不当的脚本在 sudo 下执行任意命令。

Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
## 为 sudo 指定固定的安全 PATH 路径。

##
## Uncomment if needed to preserve environmental variables related to the
## FreeBSD pkg utility and fetch.
## 如果需要保留与 FreeBSD pkg 工具和 fetch 相关的环境变量，请取消注释。

# Defaults     env_keep += "PKG_CACHEDIR PKG_DBDIR FTP_PASSIVE_MODE"
## 示例：保留 pkg 缓存/数据库路径与 FTP 被动模式变量。

##
## Additionally uncomment if needed to preserve environmental variables
## related to portupgrade
## 另外，如需保留与 portupgrade 相关的环境变量，请取消注释。

# Defaults     env_keep += "PORTSDIR PORTS_INDEX PORTS_DBDIR PACKAGES PKGTOOLS_CONF"
## 示例：保留 Ports 树、索引、数据库、二进制包与工具配置等变量。

##
## You may wish to keep some of the following environment variables
## when running commands via sudo.
## 通过 sudo 运行命令时，可能需要保留以下某些环境变量。

##
## Locale settings
## 本地化设置（语言/地区）

# Defaults env_keep += "LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET"
## 示例：保留语言与 LC_* 等本地化相关变量。

##
## X11 resource path settings
## X11 资源路径设置

# Defaults env_keep += "XAPPLRESDIR XFILESEARCHPATH XUSERFILESEARCHPATH"
## 示例：保留与 X 应用资源搜索路径相关变量。

##
## Desktop path settings
## 桌面相关路径设置

# Defaults env_keep += "QTDIR KDEDIR"
## 示例：保留 Qt/KDE 的安装路径变量（旧版 Qt3/KDE3 时代变量，现代系统已不再使用）。

##
## Allow sudo-run commands to inherit the callers' ConsoleKit session
## 允许 sudo 运行的命令继承调用者的 ConsoleKit 会话。

# Defaults env_keep += "XDG_SESSION_COOKIE"
## 示例：保留 XDG 会话 cookie（ConsoleKit 时代的变量）。

##
## Uncomment to enable special input methods.  Care should be taken as
## this may allow users to subvert the command being run via sudo.
## 取消注释可启用特殊输入法。但需谨慎，这可能允许用户绕过 sudo 所运行的命令。

# Defaults env_keep += "XMODIFIERS GTK_IM_MODULE QT_IM_MODULE QT_IM_SWITCHER"
## 示例：保留输入法相关环境变量。

##
## Uncomment to disable "use_pty" when running commands as root.
## 取消注释可在以 root 运行命令时禁用“use_pty”。

## Commands run as non-root users will run in a pseudo-terminal,
## not the user's own terminal, to prevent command injection.
## 以非 root 用户运行的命令将使用伪终端，而非用户的原始终端，以防止命令注入。

# Defaults>root !use_pty
## 对 root 目标用户禁用 use_pty（示例，默认注释）。

##

##
## User privilege specification
## 用户权限规范

##
root ALL=(ALL:ALL) ALL
## root 可在所有主机上，以任意（用户:组）身份运行任意命令（需要认证）。

## Uncomment to allow members of group wheel to execute any command
## 取消注释以允许 wheel 组成员执行任意命令。

# %wheel ALL=(ALL:ALL) ALL
## 示例：授予 wheel 组与 root 类似的 sudo 权限（需密码）。

## Same thing without a password
## 同上，但无需输入密码。

# %wheel ALL=(ALL:ALL) NOPASSWD: ALL
## 示例：wheel 组成员可无密码执行任意命令。

## Uncomment to allow members of group sudo to execute any command
## 取消注释以允许 sudo 组成员执行任意命令。

# %sudo	ALL=(ALL:ALL) ALL
## 示例：授予 sudo 组以任意（用户:组）身份执行任意命令的权限（需密码）。

## Uncomment to allow any user to run sudo if they know the password
## of the user they are running the command as (root by default).
## 取消注释可允许任意用户在知道目标用户（默认为 root）密码的情况下运行 sudo。

# Defaults targetpw  # Ask for the password of the target user
## 使用目标用户密码进行认证（而非调用者的密码）。

# ALL ALL=(ALL:ALL) ALL  # WARNING: only use this together with 'Defaults targetpw'
## 所有用户均可以任意身份运行任意命令（危险！仅与 Defaults targetpw 搭配使用）。

## Read drop-in files from /usr/local/etc/sudoers.d
## 从 /usr/local/etc/sudoers.d 读取附加配置片段（drop-in）。

@includedir sudoers.d
## 包含相对目录 sudoers.d（相对于 /usr/local/etc），读取其中的配置文件。
```

### 测试

```sh
$ sudo su
[sudo: authenticate] Password: # 此处不显示输入内容，无掩码提示
#
```

## 附录：通过 mac\_do 权限提升

参考文献：

* K Rin. FreeBSD MAC 簡單介紹\[EB/OL]. \[2026-03-26]. <https://sandb0x.tw/a/FreeBSD_MAC_%E7%B0%A1%E5%96%AE%E4%BB%8B%E7%B4%B9>. 以中文简要介绍 FreeBSD 强制访问控制框架的基本概念与配置方式。
* FreeBSD Project. mac\_do(4)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=mac_do&sektion=4>. MAC 策略 do 模块手册页。
* OpenBSD. doas -- execute commands as another user\[EB/OL]. \[2026-04-17]. <https://man.openbsd.org/doas.1>. doas 权限提升工具手册页。

## 课后习题

1. 查阅 FreeBSD 中 `mac_do` 模块的源代码，分析其通过 Mandatory Access Control 实现权限提升的机制，梳理其与 `sudo`/`doas` 在权限模型上的本质差异。
2. 查阅 FreeBSD Ports 中 `doas` 工具的源代码实现，分析其配置解析、规则匹配和环境变量处理的设计，评估其在简单性与安全性之间的权衡策略。
3. 修改 `doas` 配置中的 `keepenv` 选项，记录其对环境变量继承行为的影响，分析不同环境变量（如 `PATH`、`HOME`）在权限提升场景下的安全风险。


# 18.1 系统目录结构

FreeBSD 遵循 hier(7) 规范组织文件系统层次结构。系统启动时首先挂载根目录 **/**，其包含进入多用户模式所需的基本系统。本节逐级解释根目录下各子目录的功能与设计原则。

## 目录结构概览

根目录（**/**）是文件系统的顶层目录，系统启动时首先挂载，包含操作系统进入多用户模式所需的基本系统。根目录还包含其他文件系统的挂载点。挂载点是附加文件系统可以挂载到父文件系统（通常是根文件系统）上的目录。标准挂载点包括 **/usr/**、**/var/**、**/tmp/**、**/mnt/** 和 **/media/**。

## FreeBSD 目录结构的设计原则

FreeBSD 的目录结构设计遵循以下原则：

* **单一根目录原则**：与 Windows 等系统采用多根（多盘符）的设计不同，UNIX 系统采用单一根目录（**/**）作为整个文件系统的起点。所有存储设备、分区和网络文件系统均以挂载的方式接入统一的目录树中。
* **功能分离原则**：将不同功能的文件分配到不同的目录中，各文件系统可独立管理、挂载和备份。例如，将系统二进制文件（**/bin**、**/sbin**）与用户应用程序（**/usr/local**）分离，将配置文件（**/etc**）与日志数据（**/var/log**）分离。**/var** 包含日志目录、假脱机目录和临时文件，可能被填满，因此应与 **/** 分离。
* **基本系统与第三方软件分离原则**：FreeBSD 将基本系统与第三方软件严格分离。基本系统组件安装在 **/bin**、**/sbin**、**/usr/bin**、**/usr/sbin**、**/usr/lib** 等目录中，通过 Ports 或 pkg 安装的第三方软件统一安装到 **/usr/local/** 下的对应子目录中（如 **/usr/local/bin**、**/usr/local/lib**、**/usr/local/etc**）。
* **静态与动态数据分离原则**：静态数据（如二进制文件、库文件、文档）与动态数据（如日志、临时文件、运行时数据）分别存储在不同的目录树中。**/usr** 主要存放静态的只读数据，**/var** 则存放可变的运行时数据，**/tmp** 存放临时文件。

## FreeBSD 目录结构

为便于说明，仅列出前三级目录及重要文件。

```sh
/
├── COPYRIGHT FreeBSD 版权信息文件
├── bin 基本的 BSD 用户工具，参见 intro(1)
├── boot 操作系统引导过程中使用的程序和配置文件，参见 boot(8)
│   ├── defaults 存放默认引导配置文件，参见 loader.conf(5)
│   │   └── loader.conf 引导加载程序配置文件，参见 loader.conf(5)
│   ├── device.hints 用于控制驱动程序的内核变量，参见 device.hints(5)
│   ├── dtb 编译的扁平化设备树（FDT）文件，参见 fdt(4) 和 dtc(1)；x86 架构下通常为空
│   │   └── overlays 编译的 FDT 覆盖层，参见 loader.conf(5) 中的 fdt_overlays
│   ├── efi EFI 系统分区（ESP）挂载点，参见 uefi(8)
│   ├── firmware 可加载的二进制固件内核模块；pkg kmod 会安装至此，以及通过 fwget 下载的固件
│   ├── fonts 二进制位图控制台字体，参见 loader.conf(5) 和 vtfontcvt(8)
│   ├── images beastie 启动菜单图像，参见 loader_lua(8)
│   ├── kernel 内核及内核模块，参见 kldstat(8)
│   ├── kernel.old 备用内核及内核模块
│   ├── loader.conf loader 配置文件，参见 loader.conf(5)
│   ├── loader.conf.d loader 补充配置目录，参见 loader.conf(5)
│   ├── lua 引导加载程序的 Lua 脚本，包含启动时显示的 ASCII 艺术字（图）等，参见 loader_lua(8)
│   ├── modules 第三方可加载内核模块，如通过 pkg(8) 或 ports(7) 安装的模块
│   ├── uboot 空目录
│   └── zfs 存放 ZFS 存储池（Zpool）的缓存文件，参见 zpool(8)
│       └── zpool.cache 硬编码的磁盘驱动器路径，参见 zpool(8)
├── compat 支持与其他操作系统二进制兼容的文件
│   └── linux Linux 兼容层运行时的默认位置，参见 linux(4)
├── dev 设备文件和特殊文件，参见 intro(4) 和 devfs(4)
│   ├── ada0 第一块 ATA 存储设备
│   ├── ada0p1 第一块 ATA 存储设备的第一个分区
│   ├── cd0 第一块光盘驱动器
│   ├── cuaU0 第一个 USB 串口，参见 cu(1)
│   ├── da0 第一块 SCSI 存储设备
│   ├── da0s1 第一块 SCSI 存储设备的第一个分区
│   ├── dri 显卡字符设备节点，参见 drm(7)
│   ├── drm 显卡特殊文件节点，参见 drm(7)
│   ├── fd 文件描述符文件，参见 fd(4)；目录下 0、1、2 对应标准输入、标准输出和标准错误
│   ├── gpt 按 GPT 标签划分的存储分区，参见 gpt(8)
│   ├── input 存放输入设备相关的设备文件
│   ├── iso9660 ISO 9660 文件系统的设备节点，如光盘
│   ├── mmcsd0 第一张 SD 存储卡
│   ├── mmcsd0s1 第一张 SD 存储卡的第一个分区
│   ├── nda0 第一块 NVMe 存储设备（通过 cam(4) 连接）
│   ├── nda0p1 第一块 NVMe 存储设备的第一个分区
│   ├── null 空设备，丢弃所有写入的数据，读取时立即返回 EOF
│   ├── nvd0 nda0 的符号链接（旧版 NVMe 直接驱动兼容名，参见 nda(4)）
│   ├── pts 伪终端设备，参见 pts(4)
│   ├── random 熵设备，加密强度的随机数来源，参见 random(4)
│   ├── reroot reboot -r 使用的重引导设备
│   ├── usb USB 总线
│   ├── vmm 活跃的 bhyve(8) 虚拟机
│   └── zvol ZFS 卷，参见 zfs(8)
├── entropy 为随机数生成器提供初始状态，参见 save-entropy(8)
├── etc 基本系统配置文件和脚本，参见 intro(5)
│   ├── auto_master autofs 配置文件，参见 automount(8)
│   ├── autofs 存放自动挂载相关的配置文件，参见 autofs(4)
│   ├── bluetooth 蓝牙相关配置文件
│   ├── cron.d 存放系统级的定时任务配置文件，参见 crontab(5)
│   ├── crontab root 用户的 crontab 文件
│   ├── defaults 存放了一组默认配置文件，如 rc.conf、periodic.conf，参见 rc(8)
│   ├── devd 存放设备管理器（devd）的配置文件，如监控蓝牙、鼠标插拔，参见 devd(8)
│   ├── devfs.conf 启动时 devfs 设备规则配置，参见 devfs.conf(5)
│   ├── dma DMA 邮件代理相关，参见 dma(8)
│   ├── freebsd-update.conf 基本系统更新工具 freebsd-update 的配置文件，参见 freebsd-update(8)
│   ├── fstab 文件分区表，参见 fstab(5)
│   ├── gss GSSAPI 相关文件、含 Kerberos 5
│   ├── hosts hosts 文件，优先于 DNS 的本地 IP 域名映射表
│   ├── inetd.conf 配置 BSD inetd，参见 inetd(8)
│   ├── jail.conf.d 用于 jail 配置的模块化管理，默认为空（jail.conf(5)）
│   ├── kyua Kyua 测试框架的全局配置目录（kyua(1)、kyua.conf(5)）
│   ├── localtime 本地时区文件，参见 ctime(3)。在测试系统中，localtime 链接至 /usr/share/zoneinfo/Asia/Shanghai
│   ├── login.conf 登录类功能数据库，参见 login.conf(5)
│   ├── machine-id 系统的 UUID，供 D-Bus 使用；FreeBSD 通过 hostid_save 脚本生成（与 /etc/hostid 相同 UUID，去除连字符），D-Bus 端口读取 /usr/local/etc/machine-id
│   ├── mail 邮件系统配置文件（别名、mailer.conf），参见 mailwrapper(8)
│   │   ├── aliases 用于投递系统邮件的地址
│   │   └── mailer.conf mailwrapper(8) 配置文件
│   ├── motd.template TTY 登录后显示的信息，参见 motd(5)
│   ├── mtree 系统初始化与验证，可用于系统审计，参见 mtree(8)
│   ├── newsyslog.conf.d newsyslog 的配置文件，参见 newsyslog.conf(5)
│   ├── ntp NTP 相关，参见 ntp.conf(5)、ntpd(8)
│   ├── ntp.conf NTP 客户端配置文件，参见 ntpd(8)
│   ├── pam.d 可插拔认证模块（PAM）相关的配置文件，参见 pam(3)
│   ├── periodic 存放定期执行的维护脚本，由 cron 调用，参见 periodic(8)
│   ├── pf.conf PF 防火墙配置文件，参见 pf(4)
│   ├── pkg PKG 相关配置文件，参见 pkg(8)
│   ├── profile.d 存放用户登录时可执行的 shell 脚本，不会自动加载
│   ├── rc.conf 系统启动配置文件，参见 rc.conf(5)
│   ├── rc.conf.d 存放特定服务的配置文件，默认为空
│   ├── rc.d 用于启动和管理系统服务的 RC 脚本，参见 rc(8)
│   ├── resolv.conf DNS 解析配置文件，参见 resolv.conf(5)
│   ├── resolvconf.conf DNS 配置管理器配置，通常由 local-unbound 生成，参见 local-unbound(8) 或 resolvconf(8)
│   ├── security OpenBSM 审计配置文件，参见 audit(8)
│   ├── ssh SSH 和 SSHD 相关配置文件，参见 ssh(1)
│   ├── ssl SSL/TLS 证书、密钥等
│   │   ├── cert.pem 系统信任库的捆绑形式，参见 certctl(8)
│   │   ├── certs 系统信任库的 OpenSSL 哈希目录形式，参见 certctl(8)
│   │   ├── openssl.cnf OpenSSL 配置文件，参见 openssl.cnf(5)
│   │   └── untrusted 明确不信任的证书，参见 certctl(8)
│   ├── sysctl.conf 内核状态默认值，参见 sysctl.conf(5)
│   ├── sysctl.kld.d 特定内核模块的配置文件，默认为空，参见：D40886[EB/OL]. [2026-03-26]. <https://reviews.freebsd.org/D40886>.
│   ├── syslog.conf 系统日志配置文件
│   ├── syslog.d syslogd 的配置文件，参见 syslogd(8)
│   ├── ttys 创建 TTY 的规则文件，参见 getty(8)
│   ├── unbound Unbound 配置文件
│   ├── wpa_supplicant.conf 连接 WiFi 的配置文件，参见 wpa_supplicant.conf(5)
│   ├── X11 X11 相关，如 XRDP
│   └── zfs ZFS 相关配置文件，参见 zfs(8)
├── home 普通用户家目录；典型用户 beastie 的家目录为 /home/beastie/
│   └── ykla 普通用户 ykla 的家目录
├── lib /bin、/sbin 所需的关键库文件
│   ├── geom GEOM 库，参见 geom(8)
│   └── nvmecontrol NVMe 相关工具，参见 nvmecontrol(8)
├── libexec 系统辅助程序，供 /bin、/sbin 中的二进制文件调用
│   └── resolvconf 管理 DNS 解析配置的程序，参见 resolvconf.conf(5)
├── media 媒体文件挂载点，如 U 盘、光盘；参见 automount(8)，或使用桌面环境时参见 bsdisks(8)
├── mnt 用作临时挂载点的空目录
├── net NFS 共享挂载点，参见 auto_master(5)
├── nonexistent 不存在的目录；按照惯例，作为不需要家目录的用户账户的家目录；参见 /var/empty/。守护进程账户（如 www、nobody、bind）的家目录通常设为此路径，表示这些账户不需要可写的家目录
├── proc 现代 FreeBSD 默认不使用 procfs，该目录通常为空；参见 procfs(4)
├── rescue 静态链接的系统工具，紧急模式时使用，参见 rescue(8)
├── root root 的家目录
├── sbin 基本的 BSD 系统管理工具，参见 intro(8)
├── tmp 通常在系统重启后仍会保留的临时文件；参见 rc.conf(5) 中的 clear_tmp_enable
├── usr 包含大多数用户实用程序和应用程序
│   ├── bin 用户实用程序、编程工具和应用程序，参见 intro(1)
│   ├── freebsd-dist 发行文件（如 base.txz），参见 release(7) 和 bsdinstall(8)
│   ├── include 标准 C 头文件
│   ├── lib 共享库和 ar(1) 类型库，参见 intro(3)
│   │   ├── clang 系统编译程序 clang(1) 的共享库
│   │   ├── compat 兼容性共享库
│   │   ├── debug 内核和基本系统库及二进制文件的独立调试数据
│   │   ├── dtrace dtrace(1) 库脚本
│   │   ├── engines OpenSSL（加密/SSL 工具包）动态可加载引擎
│   │   ├── flua FreeBSD Lua 共享库
│   │   └── i18n 国际化共享库
│   ├── lib32 32 位兼容库
│   ├── libdata 杂项实用数据文件
│   │   ├── ldscripts 链接器脚本，参见 ld(1)
│   │   └── pkgconfig 编译程序和链接器标志集合，用于 pkgconf(1) 开发工具
│   ├── libexec 由程序执行的系统守护进程和实用程序
│   │   ├── bsdconfig ncurses FreeBSD 配置向导调用的实用程序
│   │   ├── bsdinstall bsdinstall(8) 的实用程序
│   │   ├── dwatch dwatch(1) 的配置文件
│   │   ├── fwget fwget(8) 调用的实用程序
│   │   ├── hyperv 与 Hyper-V 虚拟机管理程序通信的脚本
│   │   ├── sendmail sendmail(8) 二进制文件，参见 mailwrapper(8)
│   │   ├── sm.bin sendmail(8) 的受限 shell，参见 smrsh(8)
│   │   └── zfs Z 文件系统实用程序
│   ├── local 本地可执行文件、库等，由 pkg(7) 或 ports(7) 安装
│   │   ├── bin 本地用户实用程序，参见 intro(1)
│   │   ├── etc 本地程序配置文件
│   │   ├── include 本地库头文件
│   │   ├── lib 本地库文件
│   │   ├── lib32 本地 32 位兼容库
│   │   ├── libdata 本地实用数据文件
│   │   ├── libexec 本地实用程序调用的实用程序
│   │   ├── sbin 本地管理实用程序
│   │   ├── share 本地架构无关文件
│   │   ├── share/doc 本地文档
│   │   ├── share/doc/freebsd/ FreeBSD 项目的文章、书籍、FAQ 和手册
│   │   └── share/man 本地手册页，参见 man(1)
│   ├── obj 架构特定的目标树，用于从源代码构建 FreeBSD，参见 build(7)
│   ├── ports FreeBSD Ports，参见 ports(7)
│   │   └── distfiles 下载的源代码包的存放位置
│   ├── sbin 系统守护进程和面向用户执行的管理实用程序，参见 intro(8)
│   ├── share 架构无关文件
│   │   ├── atf 自动化测试框架脚本，参见 ATF(7)
│   │   ├── bhyve bhyve(8) 键盘映射
│   │   ├── calendar 系统级日历文件，参见 calendar(1)
│   │   ├── certs openssl(1) 的 TLS 证书
│   │   ├── dict 词表，参见 look(1)
│   │   │   ├── freebsd FreeBSD 特有的术语、专有名词和行话
│   │   │   └── web2 韦氏第二版国际词典的词汇
│   │   ├── doc 杂项文档
│   │   ├── dtrace 动态跟踪编译程序脚本，参见 dtrace(1)
│   │   ├── examples 用户和程序员的各种示例
│   │   ├── firmware 用户态程序加载的固件镜像
│   │   ├── games BSD 传统游戏使用的 ASCII 文本文件，参见 intro(6)
│   │   ├── keys 已知可信和已撤销的密钥
│   │   │   └── pkg pkg(7) 和 pkg(8) 的指纹
│   │   ├── locale 本地化文件，参见 setlocale(3)
│   │   ├── man 系统手册页，参见 man(1)
│   │   ├── misc 杂项系统级文件
│   │   │   ├── ascii ASCII 码表
│   │   │   ├── flowers 花语含义
│   │   │   ├── magic file(1) 使用的魔术数字
│   │   │   └── termcap 终端特性数据库，参见 termcap(5)
│   │   ├── mk make 模板，参见 make(1)
│   │   ├── nls 国家语言支持文件
│   │   ├── security 安全策略数据文件，如 mac_lomac(4)
│   │   ├── sendmail sendmail(8) 配置文件
│   │   ├── skel 新账户的示例点文件
│   │   ├── snmp SNMP 守护进程的 MIB、示例文件和树定义
│   │   │   ├── defs 用于 gensnmptree(1) 的树定义文件
│   │   │   └── mibs 管理信息库（MIB）文件
│   │   ├── sysroot -sysroot 编译程序/链接器参数构建非本机二进制文件所需的文件
│   │   │   └── VERSION FreeBSD 发行版 VERSION 的文件；"VERSION" 匹配 uname(1) -r
│   │   │       └── MACHINE.MACHINE_ARCH 表示这些文件的二进制 ABI；"MACHINE" 匹配 uname(1) -m；"MACHINE_ARCH" 匹配 uname(1) -p
│   │   ├── vi vi(1) 编辑器的本地化支持和实用程序
│   │   ├── vt 系统控制台使用的文件，参见 vt(4)
│   │   │   ├── fonts 控制台字体，参见 vidcontrol(1)、vidfont(1) 和 vtfontcvt(8)
│   │   │   └── keymaps 控制台键盘映射，参见 kbdcontrol(1) 和 kbdmap(1)
│   │   └── zoneinfo 时区配置信息，参见 tzfile(5)
│   ├── src FreeBSD 源代码，参见 development(7)；源代码树的布局由顶层 README.md 文件描述
│   └── tests FreeBSD 测试套件，参见 tests(7)
├── var 多种用途的日志、临时、瞬态、缓存文件
│   ├── account 默认为空，系统审计用，参见 accton(8)
│   │   └── acct 执行审计文件，参见 acct(5)
│   ├── at 存放 at 命令调度的任务文件，参见 at(1)
│   │   ├── jobs 作业文件
│   │   └── spool 输出假脱机文件
│   ├── audit 存储安全审计日志文件，属于 audit 组，参见 audit(8)
│   ├── authpf 用于认证网关用户的 shell，参见 authpf(8)，默认为空
│   ├── backups 用于存放系统的备份文件，如用户名和密钥、pkg 数据库。由 /etc/periodic/daily 下的 200、210 等文件生成
│   ├── cache 缓存文件
│   │   ├── cups CUPS 的缓存打印机，参见 cups(1)
│   │   └── pkg pkg(8) 的缓存包
│   ├── crash 存放崩溃转储文件，参见 crash(8) 和 savecore(8)
│   ├── cron 存放 cron 定时任务相关文件，参见 cron(8)
│   │   └── tabs crontab 文件，参见 crontab(5)
│   ├── db 自动生成的系统特定数据库文件
│   │   ├── etcupdate etcupdate(8) 的临时文件和日志
│   │   ├── freebsd-update freebsd-update(8) 的下载和临时文件
│   │   └── pkg 包数据库
│   ├── empty 默认为空，旨在提供一个始终保持为空的目录供特定程序使用①
│   ├── games 存放与游戏相关的数据文件，默认为空
│   ├── heimdal Kerberos 5 用，默认为空，参见 kdc(8)
│   ├── lib 移植的 Linux 应用程序的状态信息
│   ├── log 各种系统日志文件
│   │   ├── Xorg.0.log X 服务器日志（如果安装 X(7)），轮替为 Xorg.0.log.old
│   │   ├── auth.log 系统认证日志
│   │   ├── bsdinstall_log 系统安装日志
│   │   ├── cron 定时任务日志，参见 cron(8)
│   │   ├── cups CUPS 日志，参见 cups(1)
│   │   ├── daemon.log 系统守护进程的默认日志
│   │   ├── debug.log 未丢弃的调试 syslog 消息
│   │   ├── devd.log 设备状态变更守护进程的默认日志
│   │   ├── dmesg.today 系统消息缓冲区日志，轮替为 dmesg.yesterday
│   │   ├── maillog 邮件系统日志，轮替并压缩为 maillog.0.bz2
│   │   ├── messages 通用系统日志，参见 syslogd(8)
│   │   ├── mount.today 当前加载的 fstab(5)，轮替为 mount.yesterday
│   │   ├── pf.today 包过滤防火墙日志，参见 pf(4)
│   │   ├── pflog pflogd(8) 捕获的已保存数据包
│   │   ├── security 安全事件日志
│   │   ├── setuid.today 以提升权限运行的可执行文件列表，轮替为 setuid.yesterday
│   │   ├── userlog 用户或组变更日志
│   │   ├── utx.lastlogin 最后登录日志，参见 getutxent(3)
│   │   └── utx.log 登录/注销日志，参见 getutxent(3)
│   ├── mail 系统邮件，用户邮箱文件
│   ├── msgs 用于存放系统消息文件，参见 msgs(1)
│   ├── quotas UFS 配额信息文件
│   ├── run 用来存放 PID 文件和运行时数据，包含自系统启动以来的操作系统信息
│   │   ├── bhyve bhyve(8) 虚拟机的 unix(4) 域套接字
│   │   ├── utx.active 当前用户数据库，参见 getutxent(3)
│   │   └── wpa_supplicant IEEE 802.11 WiFi 运行时文件
│   ├── spool 存放等待处理的任务文件，如待打印机打印的文件
│   │   ├── clientmqueue 未投递的提交邮件队列，参见 sendmail(8)
│   │   ├── cups CUPS 的打印作业和临时文件，参见 cups(1)
│   │   ├── dma DragonFly 邮件代理的未投递邮件队列，参见 dma(8)
│   │   ├── lock 串行设备锁，参见 uucplock(3)
│   │   └── mqueue sendmail(8) 的未投递邮件队列
│   ├── tmp 通常会在系统重启后保留的临时文件
│   │   └── vi.recover vi(1) 编辑器的恢复文件
│   ├── unbound Unbound 服务器的相关文件和配置，参见 unbound(8)
│   └── yp NIS 的配置等文件，参见 yp(8)
└── zroot 由 ZFS 在创建存储池 "zroot" 时自动生成的挂载点目录；zroot 是 FreeBSD 安装程序默认的根池名称（参见 zpool(8) 和 zfs(8) 的 mountpoint 属性）。该目录自身通常为空，其子文件系统（如 zroot/ROOT、zroot/usr、zroot/var 等）分别挂载到对应路径；仅当直接在 zpool 根数据集下创建文件时，内容才会出现在此目录中
```

①：目录 **/var/empty** 设置了 schg 标志，即系统不可变标志。

```sh
# ls -lod /var/empty
dr-xr-xr-x   2 root    wheel   schg  2 Apr 13 12:38 /var/empty
```

参数解释：在长格式（`-l`）输出中包含文件标志（`-o`），且将目录视为普通文件列出而不递归（`-d`）。

> **技巧**
>
> OpenSSH 使用特权分离（privilege separation）架构，预认证阶段的 chroot 目录为 **/var/empty**，该目录必须为空且仅 root 可写。

## 设备与设备节点

设备是系统中与硬件活动相关的主要概念，包括磁盘、打印机、显卡和键盘。

每个设备都有一个设备名称和编号。例如，`ada0` 是第一块 SATA 硬盘，而 `kbd0` 代表键盘。

FreeBSD 中的大多数设备通过称为设备节点的特殊文件访问，这些文件位于 **/dev** 目录中。

在 FreeBSD 中，设备节点由 devfs(4) 文件系统自动管理。devfs 是一个虚拟文件系统，在系统启动时由内核自动挂载到 **/dev**，并根据当前系统中存在的硬件设备动态创建和删除设备节点。这与传统 UNIX 系统需要手动使用 `mknod` 命令创建设备节点的做法不同。devfs 确保了 **/dev** 目录中只包含当前系统实际存在的设备节点。

传统 UNIX 中，设备节点分为字符设备（character device）和块设备（block device）两种类型。字符设备以字节流方式访问数据，如终端（**/dev/ttyv0**）和串口；块设备以固定大小的块为单位访问数据，通过操作系统的缓冲缓存访问。然而，在现代 FreeBSD 中，块设备已移除，所有设备节点均为字符设备。

在 `ls -l /dev/` 的输出中，所有设备均显示为 `c`（字符设备），不会出现 `b`（块设备）标识。

例如，磁盘 **/dev/ada0** 在现代 FreeBSD 上是字符设备，而非块设备。

```sh
crw-r-----  1 root operator 0x69 May 10 09:49 ada0
```

设备命名遵循一定的约定：

| 设备类型              | 前缀    | 示例            | 说明       |
| ----------------- | ----- | ------------- | -------- |
| SATA 硬盘           | `ada` | `ada0`、`ada1` | 编号从 0 开始 |
| SCSI 硬盘和 USB 存储设备 | `da`  | `da0`         | 编号从 0 开始 |
| NVMe 存储（CAM 框架）   | `nda` | `nda0`        | 默认       |
| NVMe 存储（非 CAM）    | `nvd` | `nvd0`        | 旧版兼容别名   |
| CD-ROM 驱动器        | `cd`  | `cd0`         | 编号从 0 开始 |

GPT 分区在设备名后附加 `p` 加分区号（如 `ada0p1`），MBR 切片附加 `s` 加切片号（如 `ada0s1`）。

如下所示：

```sh
crw-r-----  1 root operator 0x69 May 10 09:49 ada0	# SATA 硬盘
crw-r-----  1 root operator 0x7c May 10 09:56 ada0s1	# SATA 硬盘 MBR 分区的首个切片
crw-r-----  1 root operator 0x6b May 10 09:49 da0	# SCSI 硬盘
crw-r-----  1 root operator 0x60 May 10 09:49 nda0	# NVMe 硬盘
crw-r-----  1 root operator 0x62 May 10 09:49 nda0p1	# GPT 分区的首个分区
lrwxr-xr-x  1 root wheel       4 May 10 09:49 nvd0 -> nda0	# nda0 的兼容性别名（旧版 NVMe 直接驱动兼容名）
lrwxr-xr-x  1 root wheel       6 May 10 09:49 nvd0p1 -> nda0p1	# nda0p1 的兼容性别名
crw-r-----  1 root operator 0x68 May 10 09:49 cd0	# 光学介质
```

## 参考文献

* Linux Foundation. Filesystem Hierarchy Standard 3.0\[EB/OL]. (2015-06-03)\[2026-04-23]. <https://refspecs.linuxfoundation.org/fhs.shtml>.
* FreeBSD Project. hier(7)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=hier&sektion=7>. 系统阐述 FreeBSD 文件系统层次结构。
* FreeBSD Project. chflags(1)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=chflags&sektion=1>.
* FreeBSD Project. ls(1)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=ls&sektion=1>.

## 课后习题

1. 查阅 FreeBSD 源代码中 hier(7) 的定义，分析其目录结构设计所遵循的层次化原则。
2. 修改 **/tmp** 目录的默认权限配置（如将权限从 `1777` 改为 `1755`），记录修改后对临时文件创建和系统服务运行的影响。


# 18.2 bsdconfig

## bsdconfig 系统配置工具概述

`bsdconfig` 是 FreeBSD 的文本界面配置工具，用于新系统安装和已有系统的配置设置。与 `bsdinstall`（安装过程中使用）不同，`bsdconfig` 可随时用于配置管理。

`bsdconfig` 的源代码托管在 <https://github.com/freebsd/freebsd-src/tree/main/usr.sbin/bsdconfig>

> **技巧**
>
> `bsdconfig` 也支持纯字符命令行。

## bsdconfig 主菜单的功能与操作

`bsdconfig` 主菜单提供了系统配置的各个功能模块。如已安装 FreeBSD，可使用此菜单自定义配置系统。可使用 pkg 工具安装额外的第三方软件，这些软件不包含在基本系统中。

执行命令：

```sh
# bsdconfig
```

将输出如下：

```sh
┌--------------------┤Main Menu├-------------------┐
│ If you've already installed FreeBSD, you may use │
│ this menu to customize it somewhat to suit your  │
│ particular configuration.  Most importantly, you │
│ can use the Packages utility to load extra '3rd  │
│ party' software not provided in the base         │
│ distributions.                                   │
│ ┌----------------------------------------------┐ │
│ │         X Exit                               │ │
│ │         1 Usage                              │ │
│ │         2 Documentation installation         │ │
│ │         3 Packages                           │ │
│ │         4 Root Password                      │ │
│ │         5 Disk Management                    │ │
│ │         6 Login/Group Management             │ │
│ │         7 Console                            │ │
│ │         8 Timezone                           │ │
│ │         9 Mouse                              │ │
│ │         A Networking Management              │ │
│ │         B Security                           │ │
│ │         C Startup                            │ │
│ │         D Ttys                               │ │
│ └----------------------------------------------┘ │
├--------------------------------------------------┤
│[      OK      ] [Exit bsdconfig] [     Help     ]│
└--------------------------------------------------┘
```

快捷键说明：选项名称前的编号或字母表示按相应键可选择该项，例如按 `1` 键选择 `1 Usage`，按大写 `A` 键选择 `A Networking Management`。

| 选项                           | 解释               |
| ---------------------------- | ---------------- |
| X Exit                       | 退出               |
| 1 Usage                      | `bsdconfig` 使用说明 |
| 2 Documentation installation | 安装文档             |
| 3 Packages                   | 软件包              |
| 4 Root Password              | root 密码          |
| 5 Disk Management            | 磁盘管理             |
| 6 Login/Group Management     | 登录管理/组管理         |
| 7 Console                    | 终端               |
| 8 Timezone                   | 时区               |
| 9 Mouse                      | 鼠标               |
| A Networking Management      | 网络管理             |
| B Security                   | 安全               |
| C Startup                    | 启动项              |
| D Ttys                       | TTY              |
| OK                           | 确认               |
| Exit bsdconfig               | 退出               |
| Help                         | 帮助               |

## 1 Usage 使用说明

选中该项将弹出窗口，展示详细的使用指引，内容如下：

**如何使用此系统**

\======================

\[阅读完本屏幕内容后，按 PageDown 键进入下一屏]

在本次安装过程中，大多数对话框都支持以下按键操作：

| 按键          | 操作                             |
| ----------- | ------------------------------ |
| 空格键         | 选择或切换当前项目。                     |
| 回车键         | 完成菜单或项目的操作。                    |
| ↑（上箭头）      | 移动到上一个项目（或在文本显示框中向上移动）。        |
| ↓（下箭头）      | 移动到下一个项目（或在文本显示框中向下移动）。        |
| Tab         | 移动到下一个项目或分组。                   |
| →（右箭头）      | 移动到下一个项目或分组（与 Tab 相同）。         |
| SHIFT + Tab | 移动到上一个项目或分组。                   |
| ←（左箭头）      | 移动到上一个项目或分组（与 SHIFT + Tab 相同）。 |
| PAGE UP     | 在文本显示框中向上滚动一页。                 |
| PAGE DOWN   | 在文本显示框中向下滚动一页。                 |
| F1          | 显示相关的帮助文本。                     |

如果在菜单的边缘看到小的 `^(-)` 或 `v(+)` 符号，则表示由于屏幕空间不足，当前项目的上/下方还有更多未显示的内容。在文本显示框中，当前位置以上的文本数量会以百分比形式显示在右下角。使用 **上 ↑ / 下 ↓ 箭头键** 可逐行滚动，**PageUp/PageDown** 键可整页滚动。

在菜单中选择 **OK** 将确认其控制的操作。选择 **Cancel** 将取消操作，随后通常会返回上一级菜单。使用 **Tab** 可移动光标并选择按钮。

大多数界面都有 **Help** 按钮，建议充分利用该功能，其通常提供有用的上下文提示；如果在某个配置菜单中不确定操作方式，请选择 **Help**。

**特殊功能**

\======================

如菜单项名称的首字母是唯一的，输入该字母即可选择菜单项。通常它是项目的编号。

控制台驱动程序包含回滚缓冲区，用于查看已滚动出屏幕的内容。要使用回滚功能，请按键盘上的 **Scroll Lock** 键，随后使用箭头键或 **Page Up/Page Down** 键滚动查看保存的文本。要退出回滚模式，再次按 **Scroll Lock** 键。此功能对查看启动信息颇为实用，同时也适用于处理不使用菜单且输出往往滚动到屏幕顶部的子 shell 或其他“专家模式”。

FreeBSD 还支持多个“虚拟控制台”，可以使用它们同时进行多个活动会话。使用 **ALT + F<数字>** 切换屏幕，其中 `F<数字>` 是对应希望查看的屏幕的功能键。在默认情况下，系统启用了 8 个虚拟控制台（ttyv0 至 ttyv7）；可以通过编辑 **/etc/ttys** 文件，将相关 vty 条目的“off”字段改为“on”来启用更多虚拟控制台（启用第 9 个及以上时还需手动添加新条目），默认内核最多支持 12 个虚拟终端（可通过修改内核选项 `VT_MAXWINDOWS` 重新构建内核至多增加至 16 个）。

## 2 Documentation installation 安装文档

可通过 `bsdconfig` 安装 FreeBSD 文档。

```sh
┌---------------┤FreeBSD Documentation Installation├---------------┐
│ This menu allows you to install the whole documentation set from │
│ the FreeBSD Documentation Project: Handbook, FAQ, and articles.  │
│                                                                  │
│ Please select the language versions you wish to install. At      │
│ minimum, you should install the English version, the original    │
│ version of the documentation.                                    │
│ ┌--------------------------------------------------------------┐ │
│ │         [ ] bn    Bengali Documentation                      │ │
│ │         [ ] da    Danish Documentation                       │ │
│ │         [ ] de    German Documentation                       │ │
│ │         [ ] el    Greek Documentation                        │ │
│ │         [X] en    English Documentation (recommended)        │ │
│ │         [ ] es    Spanish Documentation                      │ │
│ │         [ ] fr    French Documentation                       │ │
│ │         [ ] hu    Hungarian Documentation                    │ │
│ │         [ ] id    Indonesian Documentation                   │ │
│ │         [ ] it    Italian Documentation                      │ │
│ │         [ ] ja    Japanese Documentation                     │ │
│ │         [ ] ko    Korean Documentation                       │ │
│ │         [ ] mn    Mongolian Documentation                    │ │
│ │         [ ] nl    Dutch Documentation                        │ │
│ │         [ ] pl    Polish Documentation                       │ │
│ │         [ ] pt    Portuguese Documentation                   │ │
│ │         [ ] ru    Russian Documentation                      │ │
│ │         [ ] tr    Turkish Documentation                      │ │
│ └-↓↓↓----------------------------------------------------- 90%-┘ │
├------------------------------------------------------------------┤
│                       [  OK  ]     [Cancel]                      │
└----------------- Use arrows, SPACE, TAB or ENTER ----------------┘
```

选择并安装所需语言的文档。

> **注意**
>
> 不建议安装中文文档（无论简体或繁体），其内容更新远落后于英文文档。

## 3 Packages 软件包

`3 Packages` 菜单用于设置 FreeBSD 软件包的安装方式。

```sh

┌-----------------------┤Choose Installation Media├-----------------------┐
│ FreeBSD can be installed from a variety of different installation       │
│ media, ranging from floppies to an Internet FTP server.  If you're      │
│ installing FreeBSD from a supported CD/DVD drive then this is generally │
│ the best media to use if you have no overriding reason for using other  │
│ media.                                                                  │
│ ┌---------------------------------------------------------------------┐ │
│ │   1 CD/DVD      Install from a FreeBSD CD/DVD                       │ │
│ │   2 HTTP Proxy  Install from an FTP server through an HTTP proxy    │ │
│ │   3 HTTP Direct Install from an HTTP server                         │ │
│ │   4 Directory   Install from the existing filesystem                │ │
│ │   5 NFS         Install over NFS                                    │ │
│ │   6 DOS         Install from a DOS partition                        │ │
│ │   7 UFS         Install from a UFS partition                        │ │
│ │   8 USB         Install from a USB drive                            │ │
│ │   X Options     View/Set various media options                      │ │
│ └---------------------------------------------------------------------┘ │
├-------------------------------------------------------------------------┤
│                   [  OK  ]     [Cancel]     [ Help ]                    │
└------ Choose Help for more information on the various media types ------┘

```

| 选项          | 说明                    |
| ----------- | --------------------- |
| CD/DVD      | 从 FreeBSD CD/DVD 安装   |
| HTTP Proxy  | 通过 HTTP 代理从 FTP 服务器安装 |
| HTTP Direct | 从 HTTP 服务器直接安装        |
| Directory   | 从现有文件系统安装             |
| NFS         | 通过 NFS 安装             |
| DOS         | 从 DOS 分区安装            |
| UFS         | 从 UFS 分区安装            |
| USB         | 从 USB 设备安装            |
| Options     | 查看/设置多项媒体选项           |

### 3 HTTP Direct

选择最适合的站点，或选择“其他”以指定不同站点。“Main Site”会通过 GeoDNS 将用户引导至最近的官方镜像站（提供完整分发文件并支持 IPv4 和 IPv6）。其他站点称为“社区镜像”，并非所有站点都提供基础分发包之外的内容。选择一个站点。

```sh
┌-------------┤Please select a FreeBSD HTTP distribution site├-------------┐
│ Please select the best suitable site for you or "other" if you want to   │
│ specify a different choice. The "Main Site" directs users to the nearest │
│ project managed mirror via GeoDNS (they carry the full range of possible │
│ distributions and support both IPv4 and IPv6). All other sites are known │
│ as "Community Mirrors"; not every site listed here carries more than the │
│ base distribution kits. Select a site!                                   │
│ ┌----------------------------------------------------------------------┐ │
│ │      pkg Main Site (GeoDNS) pkg.freebsd.org                          │ │
│ │      URL                    Specify some other http site by URL      │ │
│ └----------------------------------------------------------------------┘ │
├--------------------------------------------------------------------------┤
│                           [  OK  ]     [Cancel]                          │
└----------------------------- Select a site! ------------------------------
```

如选择“pkg Main Site (GeoDNS) pkg.freebsd.org”，将会引导至 FreeBSD 官方镜像站；

如选择“URL Specify some other http site by URL”：

```sh
┌------------------┤Package Selection├------------------┐
│ Please specify the URL of a FreeBSD distribution on a │
│ remote http site.                                     │
│ A URL looks like this: http://<hostname>/<path>       │
│ ┌---------------------------------------------------┐ │
│ │                                                   │ │
│ └---------------------------------------------------┘ │
├-------------------------------------------------------┤
│                 [  OK  ]     [Cancel]                 │
└-------------------------------------------------------┘
```

指定国内镜像站可能无法使用。

### Options

```sh
----------┤Options Editor├-----------┐
│ ┌---------------------------------┐ │
│ │  NFS Secure      NO             │ │
│ │  NFS Slow        NO             │ │
│ │  NFS TCP         NO             │ │
│ │  NFS version 3   YES            │ │
│ │  Debugging       NO             │ │
│ │  Yes to All      NO             │ │
│ │  DHCP            NO             │ │
│ │  IPv6            NO             │ │
│ │  Editor          /usr/bin/ee    │ │
│ │  Release Name    15.0-CURRENT   │ │
│ │  Media Type      <not yet set>  │ │
│ │  Media Timeout   300            │ │
│ │  Package Temp    /var/tmp       │ │
│ │  Re-scan Devices <*>            │ │
│ │  Use Defaults    [RESET!]       │ │
│ └---------------------------------┘ │
├-------------------------------------┤
│   [  OK  ]   [ Done ]   [ Help ]    │
└---- Press arrows, TAB or ENTER -----┘
```

| 选项              | 说明         |
| --------------- | ---------- |
| NFS Secure      | NFS 安全     |
| NFS Slow        | NFS Slow   |
| NFS TCP         | NFS TCP    |
| NFS version 3   | NFS 版本 3   |
| Debugging       | 调试         |
| Yes to All      | 全部选是       |
| DHCP            | DHCP       |
| IPv6            | IPv6       |
| Editor          | 编辑器        |
| Release Name    | RELEASE 版本 |
| Media Type      | 介质类型       |
| Media Timeout   | 介质超时       |
| Package Temp    | 软件包缓存      |
| Re-scan Devices | 重新扫描设备     |
| Use Defaults    | 还原默认配置     |

## 4 Root Password root 密码

此菜单用于修改 root 用户密码。输入的密码在屏幕上以 `***` 形式显示。

```sh
┌--------------------┤Root Password├-------------------┐
│ Enter New Password                                   │
│ ┌--------------------------------------------------┐ │
│ │                                                  │ │
│ └--------------------------------------------------┘ │
├------------------------------------------------------┤
│                 [  OK  ]     [Cancel]                │
└---- Use alpha-numeric, punctuation, TAB or ENTER ----┘
```

## 5 Disk Management 磁盘管理

```sh
┌--------------------┤Partition Editor├---------------┐
│ Create partitions for FreeBSD, F1 for help.         │
│ No changes will be made until you select Finish.    │
│                                                     │
│                                                     │
├-----------------------------------------------------┤
│  mmcsd0          116 GB    GPT                      │
│    mmcsd0p1      260 MB    efi                      │
│    mmcsd0p2      116 GB    freebsd-zfs              │
│  mmcsd0boot0     4.0 MB                             │
│  mmcsd0boot1     4.0 MB                             │
│  nda0            466 GB    GPT                      │
│    nda0p1        277 MB    efi                      │
│    nda0p2        200 GB    ms-basic-data            │
│    nda0p3        148 GB    ms-basic-data            │
│    nda0p4        85 GB     ms-basic-data            │
├---vvv----------------------------------------83%----┤
├-----------------------------------------------------┤
│[Create] [Delete] [Modify] [Revert] [ Auto ] [Finish]│
```

此界面与 `bsdinstall` 中的分区管理界面相同，操作方法也一致。

## 6 Login/Group Management 登录管理/组管理

```sh
┌------┤Login/Group Management├------┐
│ ┌--------------------------------┐ │
│ │        X Exit                  │ │
│ │        1 Add Login             │ │
│ │        2 Edit/View Login       │ │
│ │        3 Delete Login          │ │
│ │        - -                     │ │
│ │        4 Add Group             │ │
│ │        5 Edit/View Group       │ │
│ │        6 Delete Group          │ │
│ └--------------------------------┘ │
├------------------------------------┤
│   [  OK  ]   [Cancel]   [ Help ]   │
└---- Press arrows, TAB or ENTER ----┘
```

| 操作              | 说明            |
| --------------- | ------------- |
| X Exit          | 退出            |
| Add Login       | 添加登录          |
| Edit/View Login | 编辑登录用户/查看登录用户 |
| Delete Login    | 删除登录用户        |
| - -             | 分隔符           |
| Add Group       | 添加组           |
| Edit/View Group | 编辑组/查看组       |
| Delete Group    | 删除组           |

### “Edit/View Login”编辑登录用户

以创建的用户账户 ykla 为例：

```sh
┌----------┤Edit/View User: ykla├-----------┐
│ Choose Save/Exit when finished or Cancel. │
│ ┌---------------------------------------┐ │
│ │     X Save/Exit                       │ │
│ │     1 Login: ykla                     │ │
│ │     2 Full Name: User &               │ │
│ │     3 Password: -----                 │ │
│ │     4 UID: 1001                       │ │
│ │     5 Group ID: 1001 (ykla)           │ │
│ │     6 Member of Groups: wheel         │ │
│ │     7 Login Class:                    │ │
│ │     8 Password Expires on:            │ │
│ │     9 Account Expires on:             │ │
│ │     A Home Directory: /home/ykla      │ │
│ │     B Shell: /bin/sh                  │ │
│ │     - Create Home Directory: N/A      │ │
│ │     D Create Dotfiles: No             │ │
│ └---------------------------------------┘ │
├-------------------------------------------┤
│           [  OK  ]     [Cancel]           │
└------- Press arrows, TAB or ENTER --------┘
```

可修改 ykla 的以下信息：

| 项目                         | 说明              |
| -------------------------- | --------------- |
| X Save/Exit                | 保存并退出           |
| Login: ykla                | 登录名：ykla        |
| Full Name: User &          | 姓名：User &       |
| Password: -----            | 密码：-----，可以修改密码 |
| UID: 1001                  | 用户 ID：1001      |
| Group ID: 1001 (ykla)      | 组 ID：1001（ykla） |
| Member of Groups: wheel    | 所属组：wheel       |
| Login Class:               | 登录类别：           |
| Password Expires on:       | 密码过期日期：         |
| Account Expires on:        | 账户过期日期：         |
| Home Directory: /home/ykla | 主目录：/home/ykla  |
| Shell: /bin/sh             | Shell：/bin/sh   |
| Create Home Directory: N/A | 创建主目录：N/A       |
| Create Dotfiles: No        | 创建点文件：否         |

### “Edit/View Group”编辑组/查看组

以创建的用户账户 ykla 所在 ykla 组为例：

```sh
┌----------┤Edit/View Group: ykla├----------┐
│ Choose Save/Exit when finished or Cancel. │
│ ┌---------------------------------------┐ │
│ │           X Save/Exit                 │ │
│ │           1 Group: ykla               │ │
│ │           2 Password: -----           │ │
│ │           3 Group ID: 1001            │ │
│ │           4 Group Members:            │ │
│ └---------------------------------------┘ │
├-------------------------------------------┤
│           [  OK  ]     [Cancel]           │
└------- Press arrows, TAB or ENTER --------┘
```

| 项目              | 内容        |
| --------------- | --------- |
| X Save/Exit     | 保存并退出     |
| Group: ykla     | 组：ykla    |
| Password: ----- | 密码：-----  |
| Group ID: 1001  | 组 ID：1001 |
| Group Members:  | 组成员：      |

## 7 Console 终端

```sh
┌-------------------┤System Console Configuration├--------------------┐
│ The system console driver for FreeBSD has a number of configuration │
│ options which may be set according to your preference.              │
│                                                                     │
│ When you are done setting configuration options, select Cancel.     │
│ ┌-----------------------------------------------------------------┐ │
│ │          X Exit      Exit this menu                             │ │
│ │          2 Font      Choose an alternate screen font            │ │
│ │          3 Keymap    Choose an alternate keyboard map           │ │
│ │          4 Repeat    Set the rate at which keys repeat          │ │
│ │          5 Saver     Configure the screen saver                 │ │
│ │          6 Screenmap Choose an alternate screenmap              │ │
│ │          7 Ttys      Choose console terminal type               │ │
│ └-----------------------------------------------------------------┘ │
├---------------------------------------------------------------------┤
│                        [  OK  ]     [Cancel]                        │
└-------------- Configure your system console settings ---------------┘
```

| 菜单          | 说明        |
| ----------- | --------- |
| X Exit      | 退出此菜单     |
| 2 Font      | 选择备用屏幕字体  |
| 3 Keymap    | 选择备用键盘布局  |
| 4 Repeat    | 设置按键重复速率  |
| 5 Saver     | 配置屏幕保护程序  |
| 6 Screenmap | 选择备用屏幕映射  |
| 7 Ttys      | 选择控制台终端类型 |

* “2 Font”主要针对西欧字符集配置。
* “5 Saver”配置屏幕保护程序参见其他章节。
* “6 Screenmap”主要针对西欧字符集配置。
* “7 Ttys”主要针对西欧或俄罗斯等区域配置。

## 8 Timezone 时区

配置同 `bsdinstall`，不再赘述。

## 9 Mouse 鼠标

可运行 mouse 守护进程以在文本控制台中进行剪切和粘贴。需指定端口和鼠标协议类型后启用守护进程，如不使用此功能，可选择 6 禁用守护进程。

启用鼠标守护进程后，在运行 X 配置工具时可将 **/dev/sysmouse** 设置为鼠标设备，并选择 `SysMouse` 或 `MouseSystems` 作为鼠标协议（参见配置菜单）。

```sh
┌----------------------┤Please configure your mouse├---------------------┐
│ You can cut and paste text in the text console by running the mouse    │
│ daemon.  Specify a port and a protocol type of your mouse and enable   │
│ the mouse daemon.  If you don't want this feature, select 6 to disable │
│ the daemon.                                                            │
│ Once you've enabled the mouse daemon, you can specify "/dev/sysmouse"  │
│ as your mouse device and "SysMouse" or "MouseSystems" as mouse         │
│ protocol when running the X configuration utility (see Configuration   │
│ menu).                                                                 │
│ ┌--------------------------------------------------------------------┐ │
│ │               X Exit    Exit this menu                             │ │
│ │               2 Enable  Test and run the mouse daemon              │ │
│ │               3 Type    Select mouse protocol type                 │ │
│ │               4 Port    Select mouse port                          │ │
│ │               5 Flags   Set additional flags                       │ │
│ │               6 Disable Disable the mouse daemon                   │ │
│ └--------------------------------------------------------------------┘ │
├------------------------------------------------------------------------┤
│                          [  OK  ]     [Cancel]                         │
└------------------------------------------------------------------------┘
```

| 菜单        | 说明            |
| --------- | ------------- |
| X Exit    | 退出此菜单         |
| 2 Enable  | 启用测试并运行鼠标守护进程 |
| 3 Type    | 选择鼠标协议类型      |
| 4 Port    | 选择鼠标端口        |
| 5 Flags   | 设置附加参数        |
| 6 Disable | 禁用鼠标守护进程      |

### 2 Enable 启用测试并运行鼠标守护进程

```sh
┌------------┤User Confirmation Requested├-----------┐
│ Now move the mouse and see if it works.            │
│ (Note that buttons don't have any effect for now.) │
│                                                    │
│          Is the mouse cursor moving?               │
│                                                    │
├----------------------------------------------------┤
│                [ Yes  ]     [  No  ]               │
└------------ Press arrows, TAB or ENTER ------------┘


现在移动鼠标，验证鼠标是否可用。
（注意，鼠标的按钮目前无效。）
鼠标光标是否在移动？
```

### 3 Type 选择鼠标协议类型

如鼠标连接到 PS/2 鼠标端口和总线鼠标端口，无论鼠标的型号和品牌是什么，都应始终选择“Auto”。所有其他协议类型适用于串口鼠标，不应与 PS/2 端口鼠标或总线鼠标一起使用。如有串口鼠标，且不确定它的协议，也应尝试选择“Auto”。如鼠标不支持即插即用（PnP）标准，可能无法正常工作，但也无不良影响。许多 2 按钮（左键和右键）串口鼠标与“Microsoft”或“MouseMan”兼容，3 按钮串口鼠标（左右键、中间按钮）可能与“MouseSystems”或“MouseMan”兼容。如串口鼠标有滚轮，可能与“IntelliMouse”兼容。

```sh
┌------------------┤Select a protocol type for your mouse├------------------┐
│ If your mouse is attached to the PS/2 mouse port or the bus mouse port,   │
│ you should always choose "Auto", regardless of the model and the brand    │
│ of the mouse.  All other protocol types are for serial mice and should    │
│ not be used with the PS/2 port mouse or the bus mouse.  If you have       │
│ a serial mouse and are not sure about its protocol, you should also try   │
│ "Auto".  It may not work for the serial mouse if the mouse does not       │
│ support the PnP standard.  But, it won't hurt.  Many 2-button serial mice │
│ are compatible with "Microsoft" or "MouseMan". 3-button serial mice       │
│ may be compatible with "MouseSystems" or "MouseMan".  If the serial       │
│ mouse has a wheel, it may be compatible with "IntelliMouse".              │
│ ┌-----------------------------------------------------------------------┐ │
│ │    1 Auto          Bus mouse, PS/2 style mouse or PnP serial mouse    │ │
│ │    2 GlidePoint    ALPS GlidePoint pad (serial)                       │ │
│ │    3 Hitachi       Hitachi tablet (serial)                            │ │
│ │    4 IntelliMouse  Microsoft IntelliMouse (serial)                    │ │
│ │    5 Logitech      Logitech protocol (old models) (serial)            │ │
│ │    6 Microsoft     Microsoft protocol (serial)                        │ │
│ │    7 MM Series     MM Series protocol (serial)                        │ │
│ │    8 MouseMan      Logitech MouseMan/TrackMan models (serial)         │ │
│ │    9 MouseSystems  MouseSystems protocol (serial)                     │ │
│ │    A ThinkingMouse Kensington ThinkingMouse (serial)                  │ │
│ └-----------------------------------------------------------------------┘ │
├---------------------------------------------------------------------------┤
│                           [  OK  ]     [Cancel]                           │
└---------------------------------------------------------------------------┘
```

| 菜单              | 说明                           |
| --------------- | ---------------------------- |
| 1 Auto          | 总线鼠标，PS/2 风格鼠标、PnP 串口鼠标      |
| 2 GlidePoint    | ALPS GlidePoint 触摸板（串口）      |
| 3 Hitachi       | 日立平板（串口）                     |
| 4 IntelliMouse  | 微软 IntelliMouse（串口）          |
| 5 Logitech      | 罗技协议（旧款）（串口）                 |
| 6 Microsoft     | 微软协议（串口）                     |
| 7 MM Series     | MM 系列协议（串口）                  |
| 8 MouseMan      | 罗技 MouseMan/TrackMan（串口）     |
| 9 MouseSystems  | MouseSystems 协议（串口）          |
| A ThinkingMouse | Kensington ThinkingMouse（串口） |

## A Networking Management 网络管理

```sh

┌--------┤Network Management├--------┐
│ ┌--------------------------------┐ │
│ │    X Exit                      │ │
│ │    1 Hostname/Domain           │ │
│ │    2 Network Interfaces        │ │
│ │    3 Wireless Networks         │ │
│ │    4 Default Router/Gateway    │ │
│ │    5 DNS nameservers           │ │
│ └--------------------------------┘ │
├------------------------------------┤
│        [  OK  ]     [Cancel]       │
└---- Press arrows, TAB or ENTER ----┘
```

> **注意**
>
> 由于无法输入密码，该界面无法连接 Wi-Fi，此问题已报告至 Bug，参见 [Cannot select any wifi or input password in bsdconfig](https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=229883)。

| 菜单                       | 说明        |
| ------------------------ | --------- |
| X Exit                   | 退出        |
| 1 Hostname/Domain        | 主机名/域名    |
| 2 Network Interfaces     | 网络接口      |
| 3 Wireless Networks      | 无线网络      |
| 4 Default Router/Gateway | 默认路由/默认网关 |
| 5 DNS nameservers        | DNS 域名服务器 |

## B Security 安全

此菜单用于配置操作系统安全策略。修改设置前，应仔细阅读系统文档，以免操作不当导致服务中断。大多数设置只有在系统重启后才会生效。

```sh
┌-----------------------┤System Security Options Menu├-----------------------┐
│ This menu allows you to configure aspects of the operating system security │
│ policy.  Please read the system documentation carefully before modifying   │
│ these settings, as they may cause service disruption if used improperly.   │
│                                                                            │
│ Most settings will take effect only following a system reboot.             │
│ ┌------------------------------------------------------------------------┐ │
│ │    X Exit            Exit this menu                                    │ │
│ │    2 [ ] Securelevel Configure securelevels for the system             │ │
│ │    3 [X] NFS port    Require that the NFS clients use reserved ports   │ │
│ └------------------------------------------------------------------------┘ │
├----------------------------------------------------------------------------┤
│                            [  OK  ]     [Cancel]                           │
└------------------------ Press arrows, TAB or ENTER ------------------------┘
```

| 菜单                 | 解释               |
| ------------------ | ---------------- |
| X Exit             | 退出此菜单            |
| 2 \[ ] Securelevel | 配置系统的安全级别        |
| 3 \[X] NFS port    | 要求 NFS 客户端使用保留端口 |

### `2 [ ] Securelevel` 配置系统的安全级别

此菜单可选择系统运行的安全级别。

在 securelevel 安全级别下，某些 root 权限会被禁用，这可能增加对攻击的抵抗力并保护系统完整性。

```sh
┌---------------------┤Securelevel Configuration Menu├---------------------┐
│ This menu allows you to select the securelevel your system runs with.    │
│ When operating at a securelevel, certain root privileges are disabled,   │
│ which may increase resistance to exploits and protect system integrity.  │
│ In secure mode system flags may not be overridden by the root user,      │
│ access to direct kernel memory is limited, and kernel modules may not    │
│ be changed.  In highly secure mode, mounted file systems may not be      │
│ modified on-disk, tampering with the system clock is prohibited.  In     │
│ network secure mode configuration changes to firewalling are prohibited. │
│                                                                          │
│ ┌----------------------------------------------------------------------┐ │
│ │                  Disabled       Disable securelevels                 │ │
│ │                  Secure         Secure mode                          │ │
│ │                  Highly Secure  Highly secure mode                   │ │
│ │                  Network Secure Network secure mode                  │ │
│ └----------------------------------------------------------------------┘ │
├--------------------------------------------------------------------------┤
│                    [  OK  ]     [Cancel]     [ Help ]                    │
└------------------- Select a securelevel to operate at -------------------┘
```

安全模式说明：

* 在 Secure 安全模式下，root 用户无法覆盖系统标志（参数或配置），访问内核内存受限，且不能更改内核模块。
* 在 Highly Secure 高安全模式下，挂载的文件系统无法直接修改，系统时钟也无法更改。
* 在 Network Secure 网络安全模式下，不允许修改防火墙配置。

## C Startup 启动项

```sh
┌----------------┤Startup├---------------┐
│ ┌------------------------------------┐ │
│ │  X Exit                            │ │
│ │  1 Toggle Startup Services         │ │
│ │  2 View/Edit Startup Configuration │ │
│ │  3 Miscellaneous Startup Services  │ │
│ └------------------------------------┘ │
├----------------------------------------┤
│          [  OK  ]     [Cancel]         │
└------ Press arrows, TAB or ENTER ------┘
```

| 菜单                                | 说明              |
| --------------------------------- | --------------- |
| X Exit                            | X 退出            |
| 1 Toggle Startup Services         | 1 切换启动服务        |
| 2 View/Edit Startup Configuration | 2 查看启动配置/编辑启动配置 |
| 3 Miscellaneous Startup Services  | 3 其他启动服务        |

### 1 Toggle Startup Services 1 切换启动服务

```sh
┌------------------------------┤Toggle Startup Services├------------------------------┐
│ ┌---------------------------------------------------------------------------------┐ │
│ │ X Exit                     Exit this menu                                       │ │
│ │ accounting_enable          [ ] /etc/rc.d/accounting; Default: NO                │ │
│ │  apm_enable                [ ] /etc/rc.d/apm; Default: NO                       │ │
│ │  auditd_enable             [ ] /etc/rc.d/auditd; Default: NO                    │ │
│ │  auditdistd_enable         [ ] /etc/rc.d/auditdistd; Default: NO                │ │
│ │  autofs_enable             [ ] /etc/rc.d/automount; Default: NO                 │ │
│ │  autofs_enable             [ ] /etc/rc.d/automountd; Default: NO                │ │
│ │  autofs_enable             [ ] /etc/rc.d/autounmountd; Default: NO              │ │
│ │  avahi_daemon_enable       [ ] /usr/local/etc/rc.d/avahi-daemon; Default: NO    │ │
│ │  avahi_dnsconfd_enable     [ ] /usr/local/etc/rc.d/avahi-dnsconfd; Default: NO  │ │
│ │ background_fsck            [X] /etc/rc.d/bgfsck; Default: YES                   │ │
│ │  blacklistd_enable         [ ] /etc/rc.d/blacklistd; Default: NO                │ │
│ │  bootparamd_enable         [ ] /etc/rc.d/bootparams; Default: NO                │ │
│ │  bsnmpd_enable             [ ] /etc/rc.d/bsnmpd; Default: NO                    │ │
│ │  bthidd_enable             [ ] /etc/rc.d/bthidd; Default: NO                    │ │
│ │ cfumass_enable             [ ] /etc/rc.d/cfumass; Default: NO                   │ │
│ │  cleanvar_enable           [X] /etc/rc.d/cleanvar; Default: YES                 │ │
│ │  cron_enable               [X] /etc/rc.d/cron; Default: YES                     │ │
│ │  ctld_enable               [ ] /etc/rc.d/ctld; Default: NO                      │ │
│ │  cupsd_enable              [ ] /usr/local/etc/rc.d/cupsd; Default: NO           │ │
│ │ dbus_enable                [X] /usr/local/etc/rc.d/dbus; Default: YES           │ │
│ │  ddb_enable                [ ] /etc/rc.d/ddb; Default: NO                       │ │
│ │  devd_enable               [X] /etc/rc.d/devd; Default: YES                     │ │
│ │  devmatch_enable           [X] /etc/rc.d/devmatch; Default: YES                 │ │
│ └-↓↓↓------------------------------------------------------------------------ 17%-┘ │
├-------------------------------------------------------------------------------------┤
│                                [  OK  ]     [Cancel]                                │
└---------------------------- Press arrows, TAB or ENTER -----------------------------┘
```

可启用或禁用当前所有可用的系统启动项。

### 2 View/Edit Startup Configuration 2 查看启动配置/编辑启动配置

```sh
┌---------┤View/Edit Startup Configuration├--------┐
│ ┌----------------------------------------------┐ │
│ │  X Exit              Return to previous menu │ │
│ │  > Add New           Add new directive       │ │
│ │  > Delete            Delete directive(s)     │ │
│ │  blanktime           300                     │ │
│ │  dbus_enable         YES                     │ │
│ │   dumpdev            AUTO                    │ │
│ │  firewall_enable     NO                      │ │
│ │  gateway_enable      YES                     │ │
│ │  hostname            ykla                    │ │
│ │  ifconfig_igc0       DHCP                    │ │
│ │   ifconfig_igc0_ipv6 inet6 accept_rtadv      │ │
│ │  kld_list            i915kms fusefs          │ │
│ │  lightdm_enable      YES                     │ │
│ │  moused_enable       YES                     │ │
│ │  ntpd_enable         YES                     │ │
│ │   ntpd_sync_on_start YES                     │ │
│ │  powerd_enable       YES                     │ │
│ │  resolv_enable       NO                      │ │
│ │  saver               beastie                 │ │
│ │   sshd_enable        YES                     │ │
│ │  xrdp_enable         YES                     │ │
│ │   xrdp_sesman_enable YES                     │ │
│ │  zfs_enable          YES                     │ │
│ └----------------------------------------------┘ │
├--------------------------------------------------┤
│       [  OK   ]     [Cancel ]     [Details]      │
└----------- Press arrows, TAB or ENTER -----------┘
```

| 菜单                             | 说明         |
| ------------------------------ | ---------- |
| X Exit Return to previous menu | 退出 返回上一级菜单 |
| > Add New Add new directive    | 添加 新增指令    |
| > Delete Delete directive(s)   | 删除 删除指令    |

查看配置当前正在使用的启动项。

#### Details 详情

```sh
┌--------------------------┤Choose View Details├-------------------------┐
│ ┌--------------------------------------------------------------------┐ │
│ │  R Reset                  Reset to default view settings           │ │
│ │  D [X] Description        Toggle display of system description     │ │
│ │  1 (*) Show Value         Show configured startup value (fast)     │ │
│ │  2 ( ) Show Default/Value Show default/configured values (slow)    │ │
│ │  3 ( ) Show Configured    Calculate rc.conf(5) locations (slowest) │ │
│ └--------------------------------------------------------------------┘ │
├------------------------------------------------------------------------┤
│                          [  OK  ]     [Cancel]                         │
└---------------------- Press arrows, TAB or ENTER ----------------------┘
```

| 菜单                                                             | 解释                                   |
| -------------------------------------------------------------- | ------------------------------------ |
| R Reset Reset to default view settings                         | R 重置 恢复默认视图设置                        |
| D \[X] Description Toggle display of system description        | D \[X] 描述 切换显示系统描述                   |
| 1 (\*) Show Value Show configured startup value (fast)         | 1 (\*) 显示值 显示已配置的启动值（加载速度快速）         |
| 2 ( ) Show Default/Value Show default/configured values (slow) | 2 ( ) 显示默认/值 显示默认值/已配置的值（加载速度较慢）     |
| 3 ( ) Show Configured Calculate rc.conf(5) locations (slowest) | 3 ( ) 显示配置 计算 rc.conf(5) 的位置（加载速度最慢） |

### 3 Miscellaneous Startup Services 3 其他启动服务

此菜单用于配置系统启动配置的各个方面。

```sh
┌----------------------┤Miscellaneous Startup Services├----------------------┐
│ This menu allows you to configure various aspects of your system's         │
│ startup configuration.  Use [SPACE] or [ENTER] to select items, and        │
│ [TAB] to move to the buttons.  Select Exit to leave this menu.             │
│ ┌------------------------------------------------------------------------┐ │
│ │  X Exit               Exit this menu                                   │ │
│ │                        --                                              │ │
│ │  1 [X] Startup dirs   Set the list of dirs to look for startup scripts │ │
│ │  2 [ ] named          Run a local name server on this host             │ │
│ │  3 [ ] named flags    Set default flags to named (if enabled)          │ │
│ │  4 [ ] NIS client     This host wishes to be an NIS client.            │ │
│ │  5 [ ] NIS domainname Set NIS domainname (if enabled)                  │ │
│ │  6 [ ] NIS Server     This host wishes to be an NIS server.            │ │
│ │                        --                                              │ │
│ │  7 [ ] Accounting     This host wishes to run process accounting.      │ │
│ │  8 [ ] lpd            This host has a printer and wants to run lpd.    │ │
│ └------------------------------------------------------------------------┘ │
├----------------------------------------------------------------------------┤
│                            [  OK  ]     [Cancel]                           │
└------------------------ Press arrows, TAB or ENTER ------------------------┘
```

使用 \[空格键] 或 \[回车键] 选择项目，使用 \[Tab] 移动到按钮。选择 Exit 以离开此菜单。

| 菜单                                                                   | 解释                                   |
| -------------------------------------------------------------------- | ------------------------------------ |
| X Exit Exit this menu                                                | X 退出 退出此菜单                           |
| --                                                                   | --                                   |
| 1 \[X] Startup dirs Set the list of dirs to look for startup scripts | 1 \[X] 启动目录 设置查找启动脚本的目录列表            |
| 2 \[ ] named Run a local name server on this host                    | 2 \[ ] named 在此主机上运行本地域名服务器          |
| 3 \[ ] named flags Set default flags to named (if enabled)           | 3 \[ ] named 参数 设置默认的 named 参数（如果启用） |
| 4 \[ ] NIS client This host will be an NIS client                    | 4 \[ ] NIS 客户端 此主机将作为 NIS 客户端        |
| 5 \[ ] NIS domainname Set NIS domainname (if enabled)                | 5 \[ ] NIS 域名 设置 NIS 域名（如启用）         |
| 6 \[ ] NIS Server This host will be an NIS server                    | 6 \[ ] NIS 服务器 此主机将作为 NIS 服务器        |
| --                                                                   | 分割线                                  |
| 7 \[ ] Accounting This host will run process accounting              | 7 \[ ] 记账 此主机将运行进程记账                 |
| 8 \[ ] lpd This host has a printer and will run lpd                  | 8 \[ ] lpd 此主机有打印机且需运行 lpd           |

## D Ttys TTY

```sh
┌-------------------┤User Confirmation Requested├-------------------┐
│ Configuration of system TTYs requires editing the /etc/ttys file. │
│ Typical configuration activities might include enabling getty(8)  │
│ on the first serial port to allow login via serial console after  │
│ reboot, or to enable xdm.  The default ttys file enables normal   │
│ virtual consoles, and most sites will not need to perform manual  │
│ configuration.                                                    │
│                                                                   │
│ To load /etc/ttys in the editor, select [Yes], otherwise, [No].   │
├-------------------------------------------------------------------┤
│                       [ Yes  ]     [  No  ]                       │
└------------------- Press arrows, TAB or ENTER --------------------┘


系统 TTY 的配置需要编辑 /etc/ttys 文件。典型的配置活动可能包括启用第一个串口上的 getty(8)，以允许在重启后通过串口控制台登录，或者启用 xdm。默认的 ttys 文件启用了正常的虚拟控制台，大多数站点无需进行手动配置。

要在编辑器中加载 /etc/ttys 文件，选择 [Yes]，否则选择 [No]。
```

如选择 `[Yes]`，会使用文本编辑器打开 **/etc/ttys** 文件。

## 参考文献

* FreeBSD Project. bsdconfig(8)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=bsdconfig&sektion=8>. FreeBSD 系统配置工具手册页。

## 课后习题

1. 通过 bsdconfig 的“View/Edit Startup Configuration”添加自定义 sysctl 配置，追踪该配置如何写入 `rc.conf` 并最终通过启动脚本生效。
2. 使用 bsdconfig 的命令行模式配置网络接口，对比图形界面与命令行两种方式的操作路径差异。
3. 对比 bsdconfig 与传统的 rc.conf 手动编辑方式在配置效率与易用性上的差异。


# 18.3 OpenSSH

## SSH 与 OpenSSH 概述

OpenSSH 是一套网络连接工具集，专门用于安全访问远程主机，TCP/IP 连接也可经 SSH 隧道安全地转发或封装。OpenSSH 会对所有流量加密，因而可防范窃听、连接劫持及其他网络层攻击。如果数据以明文形式通过网络传输，客户端与服务器之间任一位置的网络嗅探器都能窃取用户名、密码或会话中传输的数据。OpenSSH 则提供多种认证与加密机制来防范此类风险。

OpenSSH 由 OpenBSD 项目维护，并默认随 FreeBSD 安装。OpenSSH 位于 [/crypto/openssh](https://github.com/freebsd/freebsd-src/tree/main/crypto/openssh)，通过 `ChangeLog` 可获取当前内置的版本号。

本节介绍基本系统自带的 OpenSSH。Ports 中另有 security/openssh-portable，提供了额外配置选项且更新更为频繁。

## SSH 服务端配置文件

SSH 相关配置文件和目录结构如下：

```sh
/
├── etc/
│   └── ssh/
│       ├── sshd_config          # SSH 服务端配置文件
│       ├── ssh_config           # SSH 客户端配置文件
│       ├── ssh_host_rsa_key     # RSA 主机密钥文件（私钥）
│       ├── ssh_host_ecdsa_key   # ECDSA 主机密钥文件（私钥）
│       └── ssh_host_ed25519_key # Ed25519 主机密钥文件（私钥）
└── 用户主目录 (~)/
    └── .ssh/
        ├── id_ed25519           # Ed25519 私钥
        ├── id_ed25519.pub       # Ed25519 公钥
        └── authorized_keys       # 授权登录的公钥列表
```

sshd 是 OpenSSH 的服务端守护进程，负责监听来自客户端的连接请求、执行认证并建立安全会话。sshd 的运行时配置由 `sshd_config` 文件控制，该文件定义了服务端的所有行为参数，包括监听端口、认证方式、加密算法、日志级别等。

客户端配置则由 `ssh_config` 文件控制。

## 启用 SSH 服务器

除内置的 SSH 客户端工具外，也可将 FreeBSD 系统配置为 SSH 服务器，接受来自其他 SSH 客户端的连接。

要让 SSH 服务器在系统重启后自动运行，执行以下命令启用 sshd 服务：

```sh
# service sshd enable
```

随后重启 sshd 服务：

```sh
# service sshd restart
```

sshd 首次在 FreeBSD 系统启动时，会自动生成主机密钥并将指纹显示在控制台上。应将这些指纹告知用户，以便用户在首次连接时校验。

关于启动 sshd 时可用的选项，以及认证流程、登录过程和各类配置文件的完整说明，详见 sshd(8)。

至此，sshd 已对系统上所有已设置密码的账户开放。

## 基于密钥的认证

除密码方式外，客户端也可配置为通过密钥连接远程主机。从安全角度出发，推荐使用密钥认证。

将 OpenSSH 配置为使用公钥认证，可借助非对称加密技术增强安全性。这种方式能消除密码带来的诸多风险，如弱密码、传输遭拦截等，同时也能抵御各类基于密码的攻击。不过，务必妥善保护私钥，以防未授权访问。

### 生成密钥

`ssh-keygen` 可用于生成认证密钥。指定密钥类型并按提示操作，即可产生公钥和私钥对。建议设置易记且难以猜解的密码短语来保护私钥。

```sh
# ssh-keygen
```

FreeBSD 13.1 及后续版本内置的 OpenSSH 版本均不低于 8.8。查看当前 OpenSSH 版本：

```sh
# ssh -V
OpenSSH_10.0p2, OpenSSL 3.5.6 7 Apr 2026
```

可直接使用默认值生成密钥：

```sh
# ssh-keygen
Generating public/private ed25519 key pair.
Enter file in which to save the key (/root/.ssh/id_ed25519): # 此处按回车键，使用默认存储位置
Created directory '/root/.ssh'.
Enter passphrase for "/root/.ssh/id_ed25519" (empty for no passphrase):	# 此处输入密码，按回车键将不设置密码（为了安全建议设置密码）
Enter same passphrase again: # 此处重复输入密码
Your identification has been saved in /root/.ssh/id_ed25519
Your public key has been saved in /root/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:7qHl6mBUpoGFhWowFkACTPjL08FVOmR4I5ZppEWKThI root@ykla
The key's randomart image is:
+--[ED25519 256]--+
|E+.**+o..        |
|==o*Bo+.         |
|==++.+=.         |
|=.. o= .         |
|.o oo.  S        |
|  +..  .         |
|   .o   +        |
|   . . = .       |
|     .+.o        |
+----[SHA256]-----+
```

> **技巧**
>
> 上述示例中的 **192.168.179.128**、**192.168.1.32**、`ykla`、`1022`、**/home/ykla** 为占位符，须替换为实际的值。

### 配置密钥

检查权限（默认创建的权限如下）：

```sh
drwx------  2 root  wheel   512 Mar 22 18:27 /root/.ssh # 权限为 700
-rw-------  1 root  wheel   419 Mar 22 18:27 /root/.ssh/id_ed25519  # 私钥，权限为 600
-rw-r--r--  1 root  wheel    99 Mar 22 18:27 /root/.ssh/id_ed25519.pub # 公钥，权限为 644
```

生成验证公钥：

```sh
# cat /root/.ssh/id_ed25519.pub >> /root/.ssh/authorized_keys # 将公钥存储到 /root/.ssh/authorized_keys
-rw-------  1 root  wheel    99 Mar 22 18:39 /root/.ssh/authorized_keys # 检查权限是否为 600，如果不是需要手动修改权限
```

使用 WinSCP 将私钥和公钥保存到本地后，可删除服务器上的密钥文件：

> **警告**
>
> 删除私钥前，请确认已将其安全保存到本地。私钥一旦删除将无法恢复，若未备份将导致无法通过密钥认证登录远程服务器。

```sh
# rm /root/.ssh/id_ed25519*
```

### 配置 sshd 采用预期的认证方式

> **警告**
>
> 禁用密码认证前，请确认密钥认证已配置成功并测试通过。若密钥认证失败且密码登录已被禁用，将无法远程登录服务器。建议先保留密码登录方式，待密钥认证验证无误后再行禁用。

编辑 **/etc/ssh/sshd\_config** 文件。在 `sshd_config` 文件中找到对应配置项并按需修改，去掉行首 `#`，并将参数设置为 `yes` 或 `no`，如下所示：

```ini
PermitRootLogin yes                          # 允许 root 用户直接登录系统
AuthorizedKeysFile     .ssh/authorized_keys  # 修改使用用户目录下密钥文件，默认已经正确配置，可再检查
PasswordAuthentication no                    # 不允许用户使用密码方式登录，仅通过公钥认证
KbdInteractiveAuthentication no              # 禁用键盘交互式密码验证
PermitEmptyPasswords no                      # 禁止空密码的用户进行登录
```

### 重启 sshd 服务

重启 SSH 服务以应用配置更改：

```sh
# service sshd restart
```

使用 Xshell 登录，输入密钥密码，导入私钥 `id_ed25519`，即可登录。

如使用其他 SSH 软件无法登录，应转换密钥格式。

## 允许 root 用户登录 SSH

> **提示**
>
> 从系统安全角度考虑，通常不建议允许 root 用户直接通过 SSH 登录，应使用普通用户登录后通过 `su` 或 `sudo` 切换到 root 权限。如必须启用，应确保系统采用强密码或密钥认证。

> **技巧**
>
> 视频教程见 FreeBSD 中文社区. 004-FreeBSD14.2 允许 root 登录 ssh\[EB/OL]. (2024-12-04)\[2026-04-04]. <https://www.bilibili.com/video/BV1gji2YLE2o>.

编辑 **/etc/ssh/sshd\_config** 文件，去掉相应行首的 `#` 并根据需要将参数设置为 `yes` 或 `no`：

```ini
PermitRootLogin yes          # 允许 root 登录
PasswordAuthentication yes   #（可选）设置是否使用 SSH 密码认证，默认值为 no；注意 FreeBSD 下 PAM 的 challenge-response 机制可能绕过此限制
```

> **技巧**
>
> 如找不到 `#PasswordAuthentication no` 这一行，应确认修改的是 **/etc/ssh/sshd\_config** 文件，而不是 **/etc/ssh/ssh\_config** 文件。只有 `sshd_config` 是 SSH 服务的配置文件。

## 远程登录客户端

`ssh` 是 OpenSSH 远程登录客户端，用于通过加密连接登录远程主机并执行命令。

登录 SSH 服务器时，使用 `ssh` 并指定该服务器上的有效用户名、IP 地址或主机名，以及端口。

```sh
$ ssh -p 端口 用户名@IP
```

如使用 SSH 连接到远程主机 **192.168.179.128** 的 1022 端口，用户名为 ykla：

```sh
$ ssh -p 1022 ykla@192.168.179.128
```

若是首次连接该服务器，会先要求用户验证服务器指纹：

```sh
The authenticity of host '192.168.179.128 (192.168.179.128)' can't be established.
ED25519 key fingerprint is SHA256:9RDBe66fTckKniNjdfAk1maQwKcrJRZgGx7BEYQs6hM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.179.128' (ED25519) to the list of known hosts.
```

SSH 通过密钥指纹机制在客户端连接时验证服务器的真实性。首次连接输入 `yes` 接受指纹后，其指纹将存入文件 **\~/.ssh/known\_hosts**。此后的每次登录都会与已保存的密钥进行比对。若服务器密钥与记录不符，ssh 将发出警告。遇到这种情况，应先查清密钥变更的原因，再决定是否继续连接。

密钥变更的排查方法不在本章讨论范围内。

## 安全地复制文件

`scp` 可用于在本地与远程主机之间安全地复制文件。

下面的示例将远程系统上的 `COPYRIGHT` 复制到本地当前目录中，文件名不变：

```sh
# scp 用户@主机:/COPYRIGHT COPYRIGHT
```

> **技巧**
>
> SSH 客户端不支持 `用户名@IP:端口` 这种冒号语法指定端口（SCP 中冒号用于分隔主机名和远程路径，指定端口需使用 `-P` 参数）。如需在连接字符串中嵌入端口号，可使用 URI 格式 `ssh://用户名@IP:端口`。

`scp` 的参数与 cp 类似：源文件为第一个参数，目标路径为第二个参数。由于文件需经网络传输，参数采用 `用户@主机:<远程文件路径>` 格式。

> **注意**
>
> 在递归复制目录时，`scp` 使用 `-r` 选项（注意是小写 r，而非大写 R，这与某些 FTP 工具不同）。

示例：

```sh
$ scp ykla@192.168.179.128:/COPYRIGHT COPYRIGHT
(ykla@192.168.179.128) Password for ykla@ykla:
COPYRIGHT                                                                             100% 6070   846.8KB/s   00:00
```

此前已校验过该主机的指纹，系统会在提示输入密码前自动检查服务器密钥。

如需交互式地复制文件，可使用 `sftp`，操作方式与 FTP 客户端类似。以下示例将 D 盘的 `FreeBSD-16.0-CURRENT-amd64-20260413-e9fc0c538264-285005-disc1.iso` 文件上传至 **/home/ykla**。

```powershell
PS C:\WINDOWS\system32> sftp ykla@192.168.179.128
(ykla@192.168.179.128) Password for ykla@ykla:
Connected to 192.168.179.128.
sftp> lcd D:\ # l=local，切换本地目录
sftp> lpwd # lpwd 显示本地当前路径
Local working directory: d:\
sftp> pwd # 列出远程路径
Remote working directory: /home/ykla
sftp> lls # 列出本地目录内容
 Volume in drive D has no label.
 Volume Serial Number is 6071-07CB

 Directory of D:\

……省略其他文件……

2026/05/02  12:23     4,405,243,904 FreeBSD-15.0-RELEASE-amd64-dvd1.iso

              34 File(s)  7,825,364,753 bytes
               5 Dir(s)  249,192,701,952 bytes free
sftp> put  FreeBSD-16.0-CURRENT-amd64-20260413-e9fc0c538264-285005-disc1.iso
Uploading FreeBSD-16.0-CURRENT-amd64-20260413-e9fc0c538264-285005-disc1.iso to /home/ykla/FreeBSD-16.0-CURRENT-amd64-20260413-e9fc0c538264-285005-disc1.iso
FreeBSD-16.0-CURRENT-amd64-20260413-e9fc0c538264-285005-disc1.iso                     100% 1313MB  13.9MB/s   01:34
sftp> ls # 列出远程目录内容
FreeBSD-16.0-CURRENT-amd64-20260413-e9fc0c538264-285005-disc1.iso
sftp> exit # 退出
```

## SSH 隧道

OpenSSH 能够创建隧道，将其他协议封装在加密会话中。

以下命令可要求 SSH 创建隧道：

```sh
$ ssh -D 8080 用户@主机
```

此示例使用了以下选项：

选项 `-D` 指定一个本地“动态”应用层端口转发。

`用户@主机` 是在指定的远程 SSH 服务器上使用的登录名。

SSH 隧道的工作原理是在 `localhost` 的 `localport` 端口创建侦听套接字。

这种方法可以封装任意数量的不安全 TCP 协议，如 SMTP、POP3 和 FTP。

## 保持 SSH 连接不断线

### screen

`screen`（意为“屏幕”）提供了一个虚拟终端环境，允许用户在单个物理终端中运行多个独立的 shell 会话。

使用 pkg 安装：

```sh
# pkg install screen
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/sysutils/screen/
# make install clean
```

screen 使用方法：

```sh
# screen -S xxx
```

使用 `-S` 可指定 `xxx` 为名称，便于查找。

随后可通过 SSH 连接远程主机，之后即使关闭终端窗口，会话也不会中断。

查看当前有哪些正在运行的 screen 会话：

使用以下命令可列出当前用户下所有 screen 会话，包括已附着和分离的会话：

```sh
# screen -ls
There are screens on:
	18380.pts-0.ykla	(Attached)
	70812.xxx	(Detached)
	67169.pts-0.ykla	(Detached)
3 Sockets in /tmp/screens/S-root.
```

`Detached` 可直接使用 `-r` 恢复。

```sh
# screen -r xxx	# 重新附着（恢复）screen 会话 xxx（名称或 ID）
```

`Attached` 必须先分离再重新附着：

```sh
# screen -d 18380 # 将 ID 为 18380 的 screen 会话从当前终端分离（detach），保持会话在后台运行
[18380.pts-0.ykla detached.]

# screen -r 18380 # 恢复
```

### tmux

`tmux`（Terminal Multiplexer，终端多路复用器）来自 OpenBSD，采用 ISC 许可证，是 GNU Screen 的现代替代品。与 screen 相比，tmux 原生支持分屏、更灵活的配置体系以及客户端 - 服务器架构，在 SSH 远程管理场景中同样能保持会话不中断。

使用 pkg 安装：

```sh
# pkg install tmux
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/sysutils/tmux/
# make install clean
```

tmux 采用客户端 - 服务器模型，核心概念包括：

* **会话（session）**：一个服务器可包含多个会话，会话可脱离（detach）后在后台运行。
* **窗口（window）**：一个会话可包含多个窗口，类似于标签页。
* **面板（pane）**：一个窗口可划分为多个面板，实现分屏操作。

创建新会话并指定名称：

```sh
# tmux new -s 123
```

使用 `-s` 可指定 `123` 为会话名称，便于后续查找。

随后可通过 SSH 连接远程主机，即使关闭终端窗口，会话也不会中断。

查看当前正在运行的 tmux 会话：

```sh
# tmux ls
123: 1 windows (created Fri Jun 12 11:41:41 2026) (attached)
```

重新附着（恢复）已脱离的会话：

```sh
# tmux attach -t 123	# 重新附着会话 123（名称或编号）
```

如果会话仍处于附着状态，需先脱离再重新附着：

```sh
# tmux detach -t 123	# 将会话 123 从当前终端脱离，保持会话在后台运行
# tmux attach -t 123	# 恢复
```

tmux 的所有快捷键均以 **前缀键** `Ctrl+b` 触发（键入前缀键后松开再键入功能按键），常用操作如下：

| 快捷键            | 功能       |
| -------------- | -------- |
| `Ctrl+b` `d`   | 脱离当前会话   |
| `Ctrl+b` `c`   | 创建新窗口    |
| `Ctrl+b` `n`   | 切换到下一个窗口 |
| `Ctrl+b` `p`   | 切换到上一个窗口 |
| `Ctrl+b` `%`   | 左右分屏     |
| `Ctrl+b` `"`   | 上下分屏     |
| `Ctrl+b` `方向键` | 在面板之间切换  |
| `Ctrl+b` `x`   | 关闭当前面板   |

> **技巧**
>
> tmux 的示例配置文件位于 **/usr/local/share/examples/tmux/example\_tmux.conf**，可将其复制为 **/usr/local/etc/tmux.conf**。

### mosh

`mosh`（Mobile Shell，移动 Shell）适合在移动设备（如手机、平板）通过移动网络远程控制服务器时使用。

Mosh 不支持多窗口、分屏模式，也不支持多个客户端连接同一服务器。客户端重启或切换设备时无法自动重新连接。如果需实现这些功能，可在 Mosh 会话中使用 GNU Screen、OpenBSD tmux 等终端多路复用器，参见 [Mosh: A State-of-the-Art Good Old-Fashioned Mobile Shell](https://www.usenix.org/system/files/login/articles/winstein.pdf)。

要使用 mosh：① 服务端和客户端都需要配置相同的 UTF-8 编码，② 双方都需要安装 mosh。

使用 pkg 安装：

```sh
# pkg install mosh
```

或者使用 Ports 安装：

```sh
# cd /usr/ports/net/mosh/
# make install clean
```

编辑 **\~/.login\_conf** 文件，加入：

* 默认的系统：

```ini
me:\
        :charset=UTF-8:\
        :lang=en_US.UTF-8:\
        :setenv=LC_COLLATE=C:
```

* 支持中文的系统（配置 locale 设置）：

```ini
me:\
        :charset=UTF-8:\
        :lang=zh_CN.UTF-8:\
        :setenv=LC_COLLATE=zh_CN.UTF-8:
```

客户端也需做相同配置。由于 Mosh 是为移动终端设计的，本节使用 Android 设备上的 [JuiceSSH](https://play.google.com/store/apps/details?id=com.sonelli.juicessh) 软件测试。

![juicessh](/files/tS8N2HStigeWXpwlwYO7)

选择“服务端命令”，设置如下：

```sh
mosh-server new -s -l LANG=zh_CN.UTF-8
```

将 mosh 服务器新会话的语言环境设置为 zh\_CN.UTF-8。

其余配置（用户名、密码）与 SSH 相同，仍通过端口 22 验证。

列出系统中所有监听的 IPv4 套接字：

```sh
# sockstat -4l
USER     COMMAND    PID   FD  PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
root     mosh-serve 19493 4   udp4   192.168.31.187:60001  *:*
root     sshd        1140 4   tcp4   *:22                  *:*
ntpd     ntpd        1068 21  udp4   *:123                 *:*
ntpd     ntpd        1068 24  udp4   127.0.0.1:123         *:*
ntpd     ntpd        1068 26  udp4   192.168.31.187:123    *:*
root     syslogd     1017 7   udp4   *:514                 *:*
```

根据上述输出，主机端口为 60001，故需开放 60000-61000 端口。

测试连接：

![juicessh 的 mosh](/files/OPplOmdpJEMybPUqOh3M)

![juicessh 的 mosh](/files/iFiPReromMEnEviiSWJj)

![juicessh 的 mosh](/files/ml0oYxQpDXlHAtguTg5x)

断开测试：

![juicessh 的 mosh 断开 Wi-Fi](/files/sU1VH4v2bXZ4TjspAPWM)

![juicessh 的 mosh 再次恢复连接 Wi-Fi](/files/wfAggWcgNXicQFTAGwcL)

断开后将显示提示，重连网络后将自动恢复，与未断开时无差异（已结合 `screen` 使用）。

## SSH 服务器安全选项

虽然 sshd 是 FreeBSD 中使用最广泛的远程管理工具，但暴露于公网的系统通常面临暴力破解与端口扫描攻击。本节将介绍几项附加参数，用以阻断此类攻击。所有配置均写入 **/etc/ssh/sshd\_config**。

> **注意**
>
> 不应将 **/etc/ssh/sshd\_config** 与 **/etc/ssh/ssh\_config** 混淆（注意第一个文件名中多了一个 `d`）。前者配置的是服务器端，后者配置的是客户端。

可使用 OpenSSH 服务器配置文件中的 `AllowUsers` 关键字限制允许登录的用户及其来源地址。例如，要仅允许 `user` 从 **192.168.1.32** 登录，在 **/etc/ssh/sshd\_config** 中添加以下行：

```ini
AllowUsers user@192.168.1.32
```

如果要允许 `user` 从任意位置登录，则单独列出用户名，无需附带 IP 地址：

```ini
AllowUsers user
```

多个用户可写在同一行上，如：

```ini
AllowUsers root@192.168.1.32 user
```

完成所有修改后，在重启服务之前，建议先执行以下命令验证配置是否正确：

```sh
# sshd -t
```

若配置无误，将不会有任何输出；如果有误，则会显示类似：

```sh
/etc/ssh/sshd_config: line 3: Bad configuration option: sdadasdasdasads
/etc/ssh/sshd_config: terminating, 1 bad configuration options
```

在确认配置文件无误之后，执行以下命令让 sshd 重新加载即可：

```sh
# service sshd reload
```

## 附录：OpenSSH 服务端配置详解

[/crypto/openssh/sshd\_config](https://github.com/freebsd/freebsd-src/blob/main/crypto/openssh/sshd_config) 是默认的 sshd 配置文件，以下对其主要配置项进行简单注解。

OpenSSH 默认分发的 `sshd_config` 中，选项采用以下策略：

* 尽可能写出选项及其默认值，但保持为注释状态（将默认值列出供参考，但以注释形式呈现；若不显式覆盖，实际生效的仍将是这些值）。
* 未被注释的选项将覆盖默认值（即通过显式覆盖来生效）。

FreeBSD 的某些默认值与 OpenBSD 不同，并且 FreeBSD 还有一些额外的选项。

```ini
#Port 22	# 指定 sshd 监听的 Port 号，默认是 22
#AddressFamily any	# 指定使用的地址族，any 表示同时使用 IPv4 和 IPv6
#ListenAddress 0.0.0.0	# 在 IPv4 的所有网络接口地址上监听连接请求
#ListenAddress ::	# 在 IPv6 的所有网络接口地址上监听连接请求

#HostKey /etc/ssh/ssh_host_rsa_key	# 指定 RSA 主机密钥文件路径
#HostKey /etc/ssh/ssh_host_ecdsa_key  # 指定 ECDSA 主机密钥文件路径
#HostKey /etc/ssh/ssh_host_ed25519_key  # 指定 Ed25519 主机密钥文件路径

# 指定加密算法和密钥协商设置
#RekeyLimit default none	# 指定重新密钥的限制，默认不限制

# 登录
#SyslogFacility AUTH  # 指定日志记录的系统设施为认证相关
#LogLevel INFO  # 指定日志详细级别为 INFO（信息）

# 认证

#LoginGraceTime 2m  # 指定登录许可超时时间为 2 分钟
#PermitRootLogin no  # 禁止 root 用户通过 SSH 登录
#StrictModes yes  # 启用严格模式，检查主机文件和目录权限
#MaxAuthTries 6  # 设置最大认证尝试次数为 6 次
#MaxSessions 10  # 设置每个连接允许的最大会话数为 10

#PubkeyAuthentication yes  # 启用公钥认证

# 默认会检查 .ssh/authorized_keys 和 .ssh/authorized_keys2
# 但此设置已被覆盖，因此系统只会检查 .ssh/authorized_keys

AuthorizedKeysFile	.ssh/authorized_keys  # 指定用户公钥文件路径

#AuthorizedPrincipalsFile none	# 指定授权主体文件路径，默认不使用任何文件

#AuthorizedKeysCommand none  # 指定用于获取公钥的命令，默认不使用任何命令
#AuthorizedKeysCommandUser nobody  # 指定运行 AuthorizedKeysCommand 的用户，默认是 nobody

# 要使此功能生效，还需要在 /etc/ssh/ssh_known_hosts 中配置主机密钥
#HostbasedAuthentication no  # 禁用基于主机的认证
# 如果不信任 ~/.ssh/known_hosts，用于 HostbasedAuthentication，可改为 yes
#IgnoreUserKnownHosts no  # 是否忽略用户的已知主机文件
# 不读取用户的 ~/.rhosts 和 ~/.shosts 文件
#IgnoreRhosts yes  # 启用以忽略 rhosts 文件

# 将此项改为“yes”可启用内置密码认证
# 注意，也可能通过 KbdInteractiveAuthentication 接受密码
#PasswordAuthentication no  # 禁用密码认证
#PermitEmptyPasswords no  # 不允许空密码登录

# 将此项改为“no”可禁用键盘交互式认证
# 根据系统配置，这可能涉及密码、质询 - 响应、一次性密码，或这些方法与其他方法的组合
# 键盘交互式认证也用于 PAM 认证
#KbdInteractiveAuthentication yes  # 启用键盘交互式认证

# Kerberos 选项
#KerberosAuthentication no  # 禁用 Kerberos 认证
#KerberosOrLocalPasswd yes  # 如果 Kerberos 认证失败，允许使用本地密码
#KerberosTicketCleanup yes  # 登录后清理 Kerberos 凭证票据
#KerberosGetAFSToken no  # 禁止获取 AFS 令牌

# GSSAPI 选项
#GSSAPIAuthentication no  # 禁用 GSSAPI 认证
#GSSAPICleanupCredentials yes  # 登录后清理 GSSAPI 凭证

# 将此项设置为 'no' 可禁用 PAM 认证、账户处理和会话处理
# 如果启用，通过 KbdInteractiveAuthentication 和 PasswordAuthentication 将允许 PAM 认证
# 根据 PAM 配置，通过 KbdInteractiveAuthentication 的 PAM 认证可能会绕过“PermitRootLogin prohibit-password”的设置
# 如果只想运行 PAM 的账户和会话检查而不启用 PAM 认证，可启用此项，
# 但将 PasswordAuthentication 和 KbdInteractiveAuthentication 设置为 'no'
#UsePAM yes  # 启用 PAM 认证

#AllowAgentForwarding yes  # 允许 SSH 代理转发
#AllowTcpForwarding yes  # 允许 TCP 转发
#GatewayPorts no  # 禁止网关端口转发
#X11Forwarding no  # 禁止 X11 转发
#X11DisplayOffset 10  # 设置 X11 显示偏移量为 10
#X11UseLocalhost yes  # X11 转发仅绑定到 localhost
#PermitTTY yes  # 允许分配伪终端
#PrintMotd yes  # 登录时显示 MOTD（信息）
#PrintLastLog yes  # 登录时显示最后登录信息
#TCPKeepAlive yes  # 启用 TCP KeepAlive
#PermitUserEnvironment no  # 禁止读取用户环境文件
#Compression delayed  # 启用延迟压缩
#ClientAliveInterval 0  # 客户端存活检查间隔，0 表示禁用
#ClientAliveCountMax 3  # 最大未响应客户端存活检查次数
#UseDNS yes  # 使用 DNS 反向解析客户端地址
#PidFile /var/run/sshd.pid  # 指定 sshd PID 文件路径
#MaxStartups 10:30:100  # 限制同时未认证连接数
#PermitTunnel no  # 禁止 VPN 隧道
#ChrootDirectory none  # 不启用 chroot 目录
#UseBlocklist no  # 不启用阻止列表
#VersionAddendum FreeBSD-20250801  # SSH 版本附加信息

# 默认没有登录横幅路径
#Banner none  # 禁用登录横幅

# 覆盖默认不启用任何子系统的设置
Subsystem	sftp	/usr/libexec/sftp-server  # 指定 SFTP 子系统及其执行路径

# 按用户覆盖设置的示例
#Match User anoncvs  # 仅对用户 anoncvs 生效的配置块
# X11Forwarding no  # 禁止 X11 转发
# AllowTcpForwarding no  # 禁止 TCP 转发
# PermitTTY no  # 禁止分配伪终端
# ForceCommand cvs server  # 强制执行 cvs server 命令
```

以上配置基于 FreeBSD 源码树中的 [sshd\_config](https://github.com/freebsd/freebsd-src/commit/7238317403b95a8e35cf0bc7cd66fbd78ecbe521)，具体配置可能随版本更新而变化。

## 参考文献

* OpenBSD. ssh(1)\[EB/OL]. \[2026-04-17]. <https://man.openbsd.org/ssh.1>.
* FreeBSD Project. FreeBSD 13.1-RELEASE Announcement\[EB/OL]. \[2026-04-17]. <https://www.freebsd.org/releases/13.1R/announce/>. 13.1 起内置 OpenSSH 8.8p1。
* mosh. mosh FAQ\[EB/OL]. \[2026-03-26]. <https://mosh.org/#faq>. 解答 mosh 的常见问题，包括连接原理与平台支持情况。
* silbertmonaphia. ssh && mosh\[EB/OL]. \[2026-03-26]. <https://silbertmonaphia.github.io/ssh%E7%99%BB%E5%BD%95%E3%81%AE%E5%91%A8%E8%BE%BA-&&-Mosh.html>. 介绍 SSH 与 mosh 的配合使用及配置要点。
* OpenBSD. scp — OpenSSH secure file copy\[EB/OL]. \[2026-03-26]. <https://man.openbsd.org/scp.1>.
* OpenBSD. OpenSSH 8.0 Release Notes\[EB/OL]. \[2026-04-17]. <https://www.openssh.com/txt/release-8.0>. “ssh-keygen(1): Increase the default RSA key size to 3072 bits,following NIST Special Publication 800-57's guidance for a 128-bit equivalent symmetric security level.”自 8.0 版本起，ssh-keygen 默认 RSA 密钥长度从 2048 位提升至 3072 位。

## 课后习题

1. 配置 SSH 仅允许密钥登录并禁用密码认证，分析 `sshd_config` 中各认证选项的优先级关系与生效条件。
2. 分别创建一个 screen 会话和一个 tmux 会话运行长时间任务，模拟网络断开后重连恢复会话，对比有会话管理器与无会话管理器两种场景下进程的生命周期差异，并比较 screen 与 tmux 在操作方式上的异同。
3. 修改 sshd 的 `ClientAliveInterval` 和 `ClientAliveCountMax` 参数，测试不同设置下的连接保持行为，分析 keepalive 机制对网络中断检测的影响。


# 18.4 设备资源提示

设备资源提示文件（**device.hints**）是 FreeBSD 引导过程中的配置文件。系统启动时，loader(8) 读取该文件，其内容被传递给内核，用于控制内核的引导行为，但也可包含任何内核可调参数值。

**device.hints** 存储了内核启动时使用的配置变量，通常称作“设备提示（device hints）”，供设备驱动程序在设备配置过程中使用。

配置文件按层级结构构建，**/boot/device.hints** 是系统启动时由 loader(8) 读取的静态配置文件。

## device.hints 文件结构

```sh
/
├── boot/ 操作系统引导过程中使用的程序和配置文件
│    └── device.hints 设备资源提示文件
└── sys/
     └── ARCH/ 某架构，具体参见内核
          └── conf/ 内核配置相关文件
               ├── GENERIC.hints GENERIC 内核的设备资源提示示例
               └── NOTES 关于内核配置文件和设备资源提示的说明
```

## 基本系统中的 device.hints

基本系统中 **device.hints** 文件的默认内容根据架构的不同而变化：

```ini
# 下面的驱动大多数已被现代计算机淘汰，或在个人 PC 上较为罕见

# AT 键盘控制器驱动 atkbdc(4) AT 机，1980 年代产物
hint.atkbdc.0.at="isa"  # at：指定设备所连接的总线
hint.atkbdc.0.port="0x060"  # port：即指定设备将使用的 I/O Port 起始地址
hint.atkbd.0.at="atkbdc"
hint.atkbd.0.irq="1"  # irq：要使用的中断线路编号

# PS/2 外设 IBM 兼容鼠标驱动 psm(4)，1980 年代产物

#isa
# └── atkbdc0
#       ├── atkbd0
#       └── psm0

hint.psm.0.at="atkbdc"
hint.psm.0.irq="12"

# syscons(4) 传统控制台驱动
# 注意：syscons(4) 自 FreeBSD 9.x 起已被 vt(4)（Newcons）逐步取代。
# vt(4) 提供了更好的 Unicode 支持、KMS 集成和现代显卡兼容性，已成为默认控制台驱动。
# 以下 hint.sc 条目仅为历史参考，现代 FreeBSD 默认使用 vt(4)。
hint.sc.0.at="isa"
hint.sc.0.flags="0x100"  # flags：为设备设置标志位

# 串口驱动 uart(4)
hint.uart.0.at="acpi"  # 即设置 COM1
hint.uart.0.port="0x3F8"
hint.uart.0.flags="0x10"
hint.uart.1.at="acpi"  # 即设置 COM2
hint.uart.1.port="0x2F8"

# RTC 驱动（实时时钟 atrtc(4)）
hint.atrtc.0.at="isa"
hint.atrtc.0.port="0x70"
hint.atrtc.0.irq="8"

# i8254 可编程间隔定时器（AT 定时器）驱动 attimer(4)
hint.attimer.0.at="isa"
hint.attimer.0.port="0x40"
hint.attimer.0.irq="0"

# 禁用 ACPI CPU throttle 驱动，参见 cpufreq(4)
hint.acpi_throttle.0.disabled="1"  # disabled：设置为“1”意味着禁用该设备

# 禁用 Pentium 4 热控制，参见 cpufreq(4)
hint.p4tcc.0.disabled="1"
```

根据源代码分析，[sys/amd64/conf/GENERIC.hints](https://github.com/freebsd/freebsd-src/blob/main/sys/amd64/conf/GENERIC.hints) 即为 amd64 架构默认的 **device.hints** 文件。

文件版本：[amd64 GENERIC: Switch uart hints from “isa” to “acpi”](https://github.com/freebsd/freebsd-src/commit/9cc06bf7aa2846c35483de567779bb8afc289f53)。

## **device.hints** 语法

**device.hints** 采用每行一个变量的格式，语法如下：

```ini
hint.驱动.单元编号.关键字="值"
```

该行用于为驱动程序的指定单元编号设备实例设置资源或属性（注释标记为 `#`）。

其中，`驱动` 为设备驱动名称，`单元编号` 为设备驱动的单元编号，`关键字` 为提示关键字。关键字可以是以下选项：

| 关键字        | 说明               |
| ---------- | ---------------- |
| `at`       | 指定设备所连接的总线       |
| `port`     | 指定要使用的 I/O 起始地址  |
| `portsize` | 指定设备使用的 I/O 端口数量 |
| `irq`      | 指定要使用的中断请求号      |
| `drq`      | 指定 DMA 通道号       |
| `maddr`    | 指定设备所占用的物理内存地址   |
| `msize`    | 指定设备所占用的物理内存大小   |
| `flags`    | 为设备设置各种标志位       |
| `disabled` | 如果设置为 `1`，则禁用该设备 |

解释：

```sh
hint.atkbdc.0.at="isa"
```

将驱动 atkbdc（AT 键盘控制器）的设备实例 0 附加（attach）到 ISA 总线，即指定 0 号 atkbdc 设备位于 ISA 总线上。

## 第 3 阶段引导加载器

可以在第 3 阶段引导加载器提示符处指定设备提示，将覆盖 **/boot/device.hints** 中的变量。引导加载器中输入的设备提示仅在当次启动会话中生效，重启后即失效。

第 3 阶段引导加载器的语法为：

```sh
set hint.驱动.单元编号.关键字=值
```

使用 set 添加变量，用 unset 删除变量，用 show 查看变量。

## 参考文献

* FreeBSD Project. device.hints(5)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=device.hints&sektion=5>. 设备资源提示文件手册页。
* FreeBSD Project. loader(8)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=loader&sektion=8>. 系统引导加载程序手册页。
* FreeBSD Project. atkbdc -- AT keyboard controller driver\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=atkbdc&sektion=4>. AT 键盘控制器驱动手册页。

## 课后习题

1. 查阅 `device.hints` 中某个已禁用设备（如 `hint.acpi_throttle.0.disabled`）的源代码实现，分析 `disabled` 标志在设备探测流程中的作用机制。
2. 创建一个自定义 `device.hints` 文件，为某个虚拟设备设置资源提示，验证其是否被内核正确读取，记录提示参数的传递路径。
3. 对比 `device.hints` 文件与 `loader.conf` 文件中内核可调参数的加载时机差异，在两个文件中设置同一参数并观察哪个生效，分析加载顺序的优先级规则。


# 18.5 Cron 和 Periodic

## Cron 和 Periodic 的目录结构

periodic.conf(5) 文件定义了每日、每周和每月系统维护任务的运行方式。`periodic` 是 FreeBSD 的系统维护任务框架，负责定期执行日志轮转、安全检查等维护工作。这些任务通过 `periodic` 命令执行，由 `cron` 守护进程按预设时间表自动调用。

与 `periodic`、`cron` 有关的配置和路径如下：

```sh
/
├── etc/
│   ├── defaults/                   # 存放一些系统的默认配置文件
│   │   └── periodic.conf           # 默认配置文件，包含所有系统默认变量和值
│   ├── periodic.conf               # 系统特定的变量覆盖文件（常规覆盖，默认不存在）
│   ├── periodic.conf.local         # 额外覆盖文件，用于共享或分发场景（默认不存在）
│   └── periodic/                   # 基本系统的任务脚本目录
│       ├── daily/                  # 每日维护任务脚本
│       ├── weekly/                 # 每周维护任务脚本
│       ├── monthly/                # 每月维护任务脚本
│       └── security/               # 安全相关任务脚本
├── usr/
│   └── local/                      # 第三方软件安装目录
│       └── etc/
│           └── periodic/           # 第三方应用的任务脚本目录
│               ├── daily/          # 每日维护任务脚本
│               ├── weekly/         # 每周维护任务脚本
│               └── security/       # 安全相关任务脚本
└── var/
    └── cron/
        ├── allow                   # 允许使用 crontab 的用户列表（默认不存在）
        ├── deny                    # 禁止使用 crontab 的用户列表（默认不存在）
        └── tabs/                   # 个人 crontab 文件目录
```

periodic.conf(5) 文件位于 **/etc/defaults** 目录下，其部分内容可由 **/etc** 目录下同名文件覆盖，而 **/etc** 下的文件又可由 **/etc/periodic.conf.local** 文件覆盖。

源代码路径结构：

* 与 periodic 有关的源代码主要位于 [usr.sbin/periodic/](https://github.com/freebsd/freebsd-src/blob/main/usr.sbin/periodic)
* 与 cron 有关的源代码主要位于 [usr.sbin/cron](https://github.com/freebsd/freebsd-src/tree/main/usr.sbin/cron)。
* periodic 脚本的源代码位于 [usr.sbin/periodic/etc/](https://github.com/freebsd/freebsd-src/tree/main/usr.sbin/periodic/etc)。

## Cron

工具 cron(8) 在后台运行，定期检查 **/etc/crontab** 中的任务，并在 **/var/cron/tabs** 中查找自定义的 crontab 文件。

这些文件用于调度任务，cron 将在指定的时间执行这些任务。

> **警告**
>
> FreeBSD 基本系统使用的 Vixie cron 与某些 Linux 上常见的 Cronie 并不完全兼容，设置前请务必查阅相关文档，切勿完全依赖经验！
>
> 例如：Vixie cron **不支持** 设置 `CRON_TZ` 变量来改变调度时区——Cron 调度始终基于系统本地时间进行。`TZ` 仅影响命令执行时被执行方对时间时区的理解，完全不影响 Cron 判断“何时触发任务”。

每个 crontab 条目定义一个要执行的任务，称为 **cron 作业**。

使用两种不同类型的配置文件：

* 系统 crontab，不应修改；系统 crontab **/etc/crontab** 包含 `who` 列，这在用户 crontab 中不存在。在系统 crontab 中，cron 将以该列指定的用户身份运行命令。
* 用户 crontab，可以根据需要创建和编辑。在用户 crontab 中，所有命令都以创建该 crontab 的用户身份运行。用户 crontab 允许每个用户调度自己的任务。`root` 用户也可以拥有其用户 `crontab`，用于调度系统 `crontab` 中不存在的任务。

以下示例条目来自系统 crontab **/etc/crontab**：

```sh
# /etc/crontab - system crontab for FreeBSD # 以 `#` 字符开头的行是注释
#
#
SHELL=/bin/sh # ① = 等号字符用于定义环境设置
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
#
#minute	hour	mday	month	wday	who	command
#
# Save some entropy so that /dev/random can re-seed on boot.
*/11	*	*	*	*	operator /usr/libexec/save-entropy # ②③
#
# Rotate log files every hour, if necessary.
0	*	*	*	*	root	newsyslog
#
# Perform daily/weekly/monthly maintenance.
1	3	*	*	*	root	periodic daily
15	4	*	*	6	root	periodic weekly
30	5	1	*	*	root	periodic monthly
#
# Adjust the time zone if the CMOS clock keeps local time, as opposed to
# UTC time.  See adjkerntz(8) for details.
1,31	0-5	*	*	*	root	adjkerntz -a
```

* ① 在此示例中，它用于定义 `SHELL` 和 `PATH`。如果省略 `SHELL`，cron 将使用默认的 Bourne shell。如果省略 `PATH`，则必须提供命令或脚本的完整路径。
* ② 这一行定义了系统 crontab 中使用的七个字段：`minute`、`hour`、`mday`、`month`、`wday`、`who` 和 `command`。`minute` 字段是指定命令运行的分钟数，`hour` 是命令运行的小时数，`mday` 是日期，`month` 是月份，`wday` 是星期几。这些字段必须是数字值，表示 24 小时制，或者是 \*，表示该字段的所有值。`who` 字段仅存在于系统 crontab 中，指定命令应该以哪个用户身份运行。最后一个字段是要执行的命令。
* ③ 这个条目定义了这个 cron 作业的值。`*/11` 后面跟着多个 \* 字符，表示 **/usr/libexec/save-entropy** 将由 `operator` 每 11 分钟执行一次，每天、每周、每月都如此。命令可以包含多个选项。如果命令跨越多行，必须使用反斜杠 `\` 延续字符。

### 创建用户 Crontab

要创建用户 crontab，可以在编辑模式下调用 `crontab`：

```sh
$ crontab -e
```

这将使用默认文本编辑器打开用户的 crontab。用户第一次运行此命令时，会打开一个空文件。用户创建了 crontab 后，此命令将打开该文件编辑。

将以下行添加到 crontab 文件顶部以设置环境变量，同时建议保留 crontab 字段说明注释以便参考：

```ini
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
# crontab 字段顺序
# 分钟 小时 日期 月份 星期 命令
```

为每个要运行的命令或脚本添加一行，指定运行命令的时间。此示例每天在下午两点运行指定的自定义 Bourne shell 脚本。`PATH` 中未指定脚本的路径，故给出脚本的完整路径：

```ini
0 14 * * * /home/ykla/bin/自定义脚本.sh
```

> **技巧**
>
> 上述示例中的 **/home/ykla/bin**、`email1@example.com`、`email2@example.com` 为占位符，须替换为实际的值。

> **技巧**
>
> 使用自定义脚本前，请确保其可执行性，并在 cron 设置的有限环境变量下测试。为模拟上述 cron 条目所使用的环境，可执行以下命令：
>
> ```sh
> $ env -i SHELL=/bin/sh PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin HOME=/home/user LOGNAME=user /home/user/bin/自定义脚本.sh
> ```
>
> 检查脚本在 cron 环境下是否正常运行至关重要，尤其是脚本中包含使用通配符删除文件的命令时。

编辑完 crontab 后，保存文件。crontab 将自动安装生效，cron 会读取 crontab 并在指定时间运行 cron 作业。要列出 crontab 中的 cron 作业，可以使用以下命令：

```sh
$ crontab -l
```

输出应类似于以下内容：

```sh
0 14 * * * /home/ykla/bin/自定义脚本.sh
```

要删除用户 crontab 中的所有 cron 作业：

```sh
$ crontab -r
```

输出应类似于以下内容：

```sh
remove crontab for ykla? y
```

## Periodic

FreeBSD 提供了一组系统管理脚本，用于检查各种子系统的状态，执行与安全相关的检查，轮转日志文件等。这些脚本按周期执行：每日、每周或每月。这些任务由 periodic(8) 管理，其配置位于 periodic.conf(5) 中。周期性任务由系统 crontab 中的条目启动，如上所示。

periodic(8) 执行的脚本位于 **/etc/periodic/**（基本工具）和 **/usr/local/etc/periodic/**（第三方软件）中。

它们分布在 4 个子目录中：**daily**、**weekly**、**monthly** 和 **security**。

### 启用或禁用周期性任务

FreeBSD 默认启用了某些脚本以定期运行。

如要启用 `daily_status_zfs_enable`，将以下内容添加到文件 **/etc/periodic.conf** 中：

```sh
daily_status_zfs_enable="YES"
```

要禁用默认启用的任务，只需将 `YES` 更改为 `NO`。

### 配置周期性任务的输出

在 **/etc/periodic.conf** 文件中，变量 `daily_output`、`weekly_output` 和 `monthly_output` 指定了脚本执行结果的发送位置。

默认情况下，周期性脚本的输出会发送到 root 用户的邮件，因此建议阅读 root 的邮件，或者将 root 的邮件别名为一个被监控的邮箱。

要将结果发送到其他邮件地址，可以在 **/etc/periodic.conf** 文件中添加以空格分隔的邮件地址：

```ini
daily_output="email1@example.com email2@example.com"
weekly_output="email1@example.com email2@example.com"
monthly_output="email1@example.com email2@example.com"
```

如果希望将周期性输出记录到日志文件，而不是通过邮件接收，可以将以下行添加到 **/etc/periodic.conf** 文件中。newsyslog(8) 将在适当的时间轮转这些文件：

```ini
daily_output=/var/log/daily.log
weekly_output=/var/log/weekly.log
monthly_output=/var/log/monthly.log
```

### 附录：`locate` 命令示例分析

以 `locate` 命令所依赖的路径数据库 **/var/db/locate.database** 文件为例，该数据库由 **/etc/periodic/weekly/310.locate** 脚本每周自动更新一次。

如需立即更新数据库，可直接执行该脚本：

```sh
# locate locate.database # 试图寻找 locate.database
locate: the locate database '/var/db/locate.database' does not exist.

To create a new database, please run the following command as root:

  /etc/periodic/weekly/310.locate
# /etc/periodic/weekly/310.locate  # 未找到数据库，按提示刷新

Rebuilding locate database:
# locate locate.database # 再次查找，已找到
/var/db/locate.database
```

## 参考文献

* FreeBSD Project. periodic.conf(5)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=periodic.conf&sektion=5>. 定期任务配置文件手册页。
* FreeBSD Project. crontab(5)\[EB/OL]. \[2026-04-17]. <https://man.freebsd.org/cgi/man.cgi?query=crontab&sektion=5>. cron 定时任务表手册页。

## 课后习题

1. 创建一个自定义 periodic 脚本放入 **/usr/local/etc/periodic/daily/**，配置 `periodic.conf` 使其运行，分析 periodic 脚本的命名规则与执行顺序机制。
2. 修改 **/etc/crontab** 文件中 periodic 任务的执行时间，对比修改前后系统日志中任务执行时间的变化。
3. 禁用某个默认的 periodic 任务（如 weekly 的 `310.locate`），观察其对 `locate` 命令数据库更新频率的影响。


# 18.6 系统日志管理

本节介绍 FreeBSD 的系统日志管理。

## 配置本地日志记录

配置文件 **/etc/syslog.conf** 定义了 syslogd 在接收到日志条目时的处理方式。此文件通过 **设施 facility** 和 **级别 level** 两个参数控制日志行为：

* **设施 facility** 标识消息来源的子系统（如内核或守护进程）。
* **级别 level** 表示事件的严重性。

可按 **设施 facility** 和 **级别 level** 决定日志消息的记录位置，也可按发送消息的应用程序筛选日志消息。在远程日志记录中，还可按生成日志事件的主机名过滤。

该配置文件每行定义一个操作，由选择器字段和操作字段组成。

* 选择器字段的语法是 **设施.级别**，匹配来自 **设施 facility** 且级别为 **级别 level** 或更高的日志消息。
  * 也可以在级别之前添加可选的比较标志，以更精确地指定记录内容。
  * 多个选择器字段可以用于同一操作
    * 以分号 (`;`) 分隔。
    * 使用 \* 匹配所有内容。
* 操作字段指定日志消息的发送目标，如文件或远程日志主机。

以下是 FreeBSD 默认的 **/etc/syslog.conf** 文件示例，其源文件为 **usr.sbin/syslogd/syslog.conf**：

```ini
#
#	Spaces ARE valid field separators in this file. However,
#	other *nix-like systems still insist on using tabs as field
#	separators. If you are sharing this file between systems, you
#	may want to use only tabs as field separators here.
#	Consult the syslog.conf(5) manpage.
*.err;kern.warning;auth.notice;mail.crit		/dev/console # ①
*.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err	/var/log/messages
security.*					/var/log/security
auth.info;authpriv.info				/var/log/auth.log
mail.info					/var/log/maillog # ②
cron.*						/var/log/cron
!-devd
*.=debug					/var/log/debug.log # ③
*.emerg						*
daemon.info					/var/log/daemon.log
# uncomment this to log all writes to /dev/console to /var/log/console.log
# touch /var/log/console.log and chmod it to mode 600 before it will work
#console.info					/var/log/console.log
# uncomment this to enable logging of all log messages to /var/log/all.log
# touch /var/log/all.log and chmod it to mode 600 before it will work
#*.*						/var/log/all.log
# uncomment this to enable logging to a remote loghost named loghost
#*.*						@loghost
# uncomment these if you're running inn
# news.crit					/var/log/news/news.crit
# news.err					/var/log/news/news.err
# news.notice					/var/log/news/news.notice
# Uncomment this if you wish to see messages produced by devd
# !devd
# *.>=notice					/var/log/devd.log # ④
!*
include						/etc/syslog.d
include						/usr/local/etc/syslog.d
```

* ① 匹配所有级别为 `err` 及更高的消息，以及 `kern.warning`、`auth.notice` 和 `mail.crit`，并将这些日志消息发送到控制台（**/dev/console**）。

  ```sh
  # ls -al /dev/console
  crw-------  1 root wheel 0x8 May 16 10:09 /dev/console
  ```
* ② 匹配来自 `mail` 子系统的所有级别为 `info` 或更高的消息，并将日志记录到 **/var/log/maillog** 文件。
* ③ 使用比较标志 (`=`) 只匹配级别为 `debug` 的消息，并将其记录到 **/var/log/debug.log** 文件。
* ④ 此示例演示了指定程序的用法：后续规则仅对指定程序生效。本例中，仅将 devd(8) 生成的消息记录到 **/var/log/devd.log** 文件。

## 日志记录设施

设施（facility）标识生成消息的子系统，用于将不同来源的消息分开，便于日志查阅。

**表 syslog 设施**

| 名称              | 说明                                   |
| --------------- | ------------------------------------ |
| auth            | 授权系统：login(1)、su(1)、getty(8) 等。      |
| authpriv        | 与 auth 相同，但日志记录到只有 root 可读的文件中。      |
| console         | 由内核控制台输出驱动程序写入 **/dev/console** 的消息。 |
| cron            | 由 cron(8) 守护进程写入的消息。                 |
| daemon          | 系统守护进程，例如 routed(8)，此类进程没有专用的日志记录设施。 |
| ftp             | FTP 守护进程。                            |
| kern            | 由内核生成的消息。此类消息不能由任何用户进程生成。            |
| lpr             | 打印机排队系统：lpr(1)、lpc(8)、lpd(8) 等。      |
| mail            | 邮件系统。                                |
| mark            | 此设施每 20 分钟添加一条记录。                    |
| news            | 网络新闻系统。                              |
| ntp             | 网络时间协议系统。                            |
| security        | 安全子系统，例如 ipfw(4)。                    |
| syslog          | syslogd(8) 内部生成的消息。                  |
| user            | 随机用户进程生成的消息。**这是未指定时的默认设施标识符**。      |
| uucp            | UUCP 子系统。                            |
| local0 至 local7 | 保留给本地使用。                             |

## 日志记录级别

级别（level）表示消息的严重性，以下是按优先级从高到低的关键词列表：

**表 syslog 级别**

| 名称      | 说明                   |
| ------- | -------------------- |
| emerg   | 紧急条件。通常广播给所有用户。      |
| alert   | 须立即修正的条件，例如损坏的系统数据库。 |
| crit    | 严重条件，例如硬件设备错误。       |
| err     | 错误。                  |
| warning | 警告消息。                |
| notice  | 非错误条件，但可能需要特别处理的条件。  |
| info    | 信息性消息。               |
| debug   | 调试程序时方可发挥作用的消息。      |
| none    | 此特殊级别禁用特定设施。         |

## 阅读日志消息

FreeBSD 的 syslogd(8) 支持两种输出格式，通过 `-O` 选项切换：

* **BSD/RFC 3164 格式**（默认格式，`-O bsd` 或 `-O rfc3164`）：传统 BSD syslog 格式。
* **Syslog/RFC 5424 格式**（`-O syslog` 或 `-O rfc5424`）：较新的标准格式，采用 [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) 时间戳（含微秒精度），并在每条消息中包含结构化的设施与严重级别字段。

**RFC 3164 格式** 的日志通常使用以下语法：

```ini
日期 时间 主机名 程序[进程ID]: 信息
```

以下是 **/var/log/cron** 文件的输出示例：

```ini
[此处省略其他输出]
May 15 15:30:00 ykla /usr/sbin/cron[1812]: (root) CMD (/usr/libexec/atrun)
May 15 15:33:00 ykla /usr/sbin/cron[1814]: (operator) CMD (/usr/libexec/save-entropy)
[此处省略其他输出]
```

可以通过运行以下命令在 syslogd(8) 中启用详细日志记录，此时每条消息将附带设施和级别：

```sh
# sysrc syslogd_flags="-vv"
```

启用此功能后，日志中将显示设施和级别，如下所示：

```ini
[此处省略其他输出]
May 17 18:55:00 <cron.info> ykla /usr/sbin/cron[1771]: (operator) CMD (/usr/libexec/save-entropy)
May 17 18:55:00 <cron.info> ykla /usr/sbin/cron[1772]: (root) CMD (/usr/libexec/atrun)
[此处省略其他输出]
```

若要切换到 RFC 5424 格式，可以在 **/etc/rc.conf** 文件中配置：

```sh
# sysrc syslogd_flags="-O syslog"
```

以下是 RFC 5424 格式下 **/var/log/cron** 文件的输出示例：

```sh
<78>1 2026-05-17T19:00:00.004642+08:00 ykla /usr/sbin/cron 1781 - - (root) CMD (newsyslog)
<78>1 2026-05-17T19:00:00.011902+08:00 ykla /usr/sbin/cron 1783 - - (operator) CMD (/usr/libexec/save-entropy)
<78>1 2026-05-17T19:00:00.017709+08:00 ykla /usr/sbin/cron 1785 - - (root) CMD (/usr/libexec/atrun)
```

RFC 5424 格式下默认启用详细日志记录，无需选项 `-vv`。

```sh
<优先级>版本号 时间戳 主机名 程序名[进程ID] 消息ID [结构化数据] 日志信息
```

## 日志管理与轮替

日志文件增长迅速，占用磁盘空间，且增加查找有效信息的难度。为此，FreeBSD 使用 newsyslog(8) 来管理日志文件。

newsyslog 定期轮替并压缩日志文件，可选择性地创建缺失的日志文件，并在日志文件移动时向程序发送信号。newsyslog 的默认配置源文件为 **usr.sbin/newsyslog/newsyslog.conf**。

```ini
# configuration file for newsyslog
#
# Entries which do not specify the '/pid_file' field will cause the
# syslogd process to be signalled when that log file is rotated.  This
# action is only appropriate for log files which are written to by the
# syslogd process (ie, files listed in /etc/syslog.conf).  If there
# is no process which needs to be signalled when a given log file is
# rotated, then the entry for that file should include the 'N' flag.
#
# Note: some sites will want to select more restrictive protections than the
# defaults.  In particular, it may be desirable to switch many of the 644
# entries to 640 or 600.  For example, some sites will consider the
# contents of maillog, messages, and lpd-errs to be confidential.  In the
# future, these defaults may change to more conservative ones.
#
# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]
/var/log/all.log			600  7	   *	@T00  J
/var/log/auth.log			600  7	   1000 @0101T JC
/var/log/console.log			600  5	   1000	*     J
/var/log/cron				600  3	   1000	*     JC
/var/log/daemon.log			644  5	   1000	@0101T JC
/var/log/daily.log			640  7	   *	@T00  JN
/var/log/debug.log			600  7	   1000 *     JC
/var/log/devd.log			644  3	   1000	*     JC
/var/log/init.log			644  3	   1000	*     J
/var/log/kerberos.log			600  7	   1000	*     J
/var/log/maillog			640  7	   *	@T00  JC
/var/log/messages			644  5	   1000	@0101T JC
/var/log/monthly.log			640  12	   *	$M1D0 JN
/var/log/security			600  10	   1000	*     JC
/var/log/utx.log			644  3	   *	@01T05 B
/var/log/weekly.log			640  5	   *	$W6D0 JN

<include> /etc/newsyslog.conf.d/[!.]*.conf
<include> /usr/local/etc/newsyslog.conf.d/[!.]*.conf
```

字段说明：

* `logfilename` - 要归档的系统日志文件的名称。
* `[owner:group]` - 指定归档文件的所有者和组。
* `mode` - 指定日志文件和归档文件的文件模式。有效模式位为 0666，即可为归档日志指定所有者、组和其他用户的读写权限。
* `count` - 指定可存在的最大归档文件数。
* `size` - 日志文件的大小达到指定值（以 KB 为单位）时，将轮替日志文件。如果该字段包含星号（\*），则不按大小轮替。
* `when` - 包含时间间隔、特定时间或两者。
* `flags` - 表示 newsyslog 接受的标志。
* `[/pid_file]` - 指定包含守护进程的进程 ID 的文件名，或查找组进程 ID。
* `[sig_num]` - 指定在轮替文件时将发送到守护进程的信号号。

> **技巧**
>
> 最后两个字段 `[/pid_file]`、`[sig_num]` 是可选的，指定进程的 PID 文件名以及在轮替文件时发送给该进程的信号编号。

### 手动轮替日志

虽然 newsyslog(8) 默认由 cron(8) 每小时调用一次，但也可以使用选项 `-F` 手动触发轮替：

```sh
# newsyslog -F
```

强制轮替所有满足条件的日志文件。轮替后的文件示例如下：

```sh
/var/log/auth.log          /var/log/devd.log          /var/log/ppp.log
/var/log/auth.log.0.bz2    /var/log/devd.log.0.bz2    /var/log/ppp.log.0.bz2
```

若要轮替特定文件，可指定文件路径：

```sh
# newsyslog -F /var/log/auth.log
```

轮替结果如下：

```sh
auth.log.0.bz2
auth.log
auth.log.1.bz2
```

## 配置远程日志记录

系统数量增多后，监控多个主机的日志文件将增加管理负担。配置集中式日志记录可以减轻此负担。

在 FreeBSD 中，可以使用 syslogd 和 newsyslog 配置集中式日志文件聚合、合并和轮替。

本节的示例配置中，主机 `A`（**192.168.5.18**）作为日志客户端，命名为 `logclient.example.com`。

主机 `A` 将传递日志信息给日志服务器 `B`。

### 设置 DNS 解析

日志服务器和所有客户端主机必须在本地 DNS 中具有正向和反向条目。如果网络没有 DNS 服务器，请在每个系统的 **/etc/hosts** 中创建条目。名称解析必须正确，以确保日志条目不会被日志服务器拒绝。

分别在日志客户端 `A` 和日志服务器 `B` 中的 **/etc/hosts** 文件添加以下两行：

```ini
192.168.5.18            logclient.example.com
192.168.5.17            logserv.example.com
```

> **技巧**
>
> 上述示例中的 **192.168.5.18**、**192.168.5.17**、`logclient.example.com`、`logserv.example.com` 为占位符，须替换为实际的值。

其中主机 `B` 作为日志服务器（**192.168.5.17**），命名为 `logserv.example.com`，将收集本地网络的日志信息。

### 日志客户端配置

日志客户端将日志条目发送到网络上的日志服务器。客户端还会保留自己的日志副本。

在日志客户端 A 上执行以下命令，设置 syslogd 开机自启：

```sh
# service syslogd enable
```

阻止此客户端接收来自其他主机的日志（`-s`），同时增加日志消息的详细程度：

```sh
# sysrc syslogd_flags="-s -v -v"
```

此后，在客户端的 **/etc/syslog.conf** 文件中定义日志服务器。在此示例中，所有记录的设施都通过 `@` 符号发送到指定的主机：

```sh
*.*  @logserv.example.com
```

保存编辑后，重新启动 syslogd 以使更改生效：

```sh
# service syslogd restart
```

### 日志服务器配置

日志服务器是配置为接受来自其他主机日志信息的系统。

配置好日志客户端 A 后，在日志服务器 B 上，编辑 **/etc/syslog.conf** 文件：

```ini
+logclient.example.com
*.*     /var/log/logclient.log
```

以上示例在日志服务器的配置中，添加了日志客户端的主机名作为过滤条件。凡是来自主机 **logclient.example.com** 所有设施和级别的日志条目，都统一存储在服务器本地的 **/var/log/logclient.log** 文件中。

为每个客户端添加类似的两行条目便可添加多个日志客户端。

执行以下命令，设置 syslogd 开机自启：

```sh
# service syslogd enable
```

允许来自指定客户端的日志条目：

```sh
# sysrc syslogd_flags="-a logclient.example.com -v -v"
```

* `-v -v` 提高了日志消息的详细程度，有助于管理员查看每个设施下记录的消息类型。
* 要允许来自多个客户端的日志记录，可以指定多个 `-a` 选项。还可以指定 IP 地址和整个网段。

最后，创建日志文件 **logclient.log**：

```sh
# touch /var/log/logclient.log
```

此时，应重新启动 syslogd 并验证：

```sh
# service syslogd restart
# pgrep syslogd
```

如果返回 PID，则表示服务器已成功重新启动。

```sh
1958
1961
1962
```

如果服务器未能重新启动，请通过 **/var/log/messages** 文件获取错误信息。

为了测试日志消息是否通过网络发送，可以在客户端使用 logger(1) 发送一条消息到 syslogd：

```sh
# logger "Test Message by logclient."
```

此消息应同时存在于客户端的 **/var/log/messages** 文件和日志服务器的 **/var/log/logclient.log** 文件中。

```sh
May 17 21:58:08 <user.notice> logclient ykla[1881]: Test Message by logclient.
```

### 调试日志服务器

如果日志服务器和日志客户端之间有防火墙，请确保防火墙规则集放行客户端和服务器之间的 UDP 端口 514。

```sh
# nc -uvz logserv.example.com 514
Connection to logserv.example.com 514 port [udp/syslog] succeeded!
```

```sh
# nc -uvz logclient.example.com 514
Connection to logclient.example.com 514 port [udp/syslog] succeeded!
```

如果日志服务器没有接收到任何消息，原因通常为网络连接问题、主机名解析问题或配置文件中的拼写错误。为排除故障，请确保日志服务器和日志客户端能够使用 **/etc/rc.conf** 文件中指定的主机名互相 `ping`。如果失败，请检查网络布线、防火墙规则集，以及日志服务器和客户端中的 DNS 服务器或 **/etc/hosts** 中的主机名条目。反复检查直至 `ping` 测试成功。

如果两个主机的 `ping` 都成功，但服务器仍未接收到日志消息，可临时提高日志详细度以缩小配置问题的范围。在以下示例中，日志服务器上的 **/var/log/logclient.log** 为空，而日志客户端上的 **/var/log/messages** 未显示失败原因。

为增加调试输出，编辑日志服务器上的 `syslogd_flags` 条目并执行重启：

```sh
# sysrc syslogd_flags="-d -a logclient.example.com -v -v"
```

> **警告** 请首先尝试使用 IP 地址代替域名测试。
>
> 调试成功后必须修改回原有设置，否则将影响系统正常开机。

```sh
# service syslogd restart
```

重启后，调试数据将立即输出到控制台，类似于以下内容：

```sh
……省略部分输出……

logmsg: pri 56, flags 0, from logserv, msg restart
syslogd: restarted
logmsg: pri 6, flags 0, from logserv, msg kernel boot file is /boot/kernel/kernel
kernel boot file is /boot/kernel/kernel
received sa_len = 16
cvthname(2) len = 16
cvthname(192.168.5.18)
validate: dgram from IP 192.168.5.18, port 514, name logclient.example.com;
accepted in rule 1.
logmsg: pri 15, flags 0, from logclient, msg Test Message by logclient.
Logging to FILE /var/log/logclient.log
Logging to FILE /var/log/messages
```

此时，消息已正确接收并写入正确的文件。

### 安全考量

与所有网络服务一样，在实施日志服务器之前应考虑安全需求。日志文件可能包含有关本地主机上启用的服务、用户账户和配置数据的敏感信息。

**网络安全**：

从客户端发送到服务器的网络数据未经加密或密码保护。如果需要加密传输，可考虑以下方案：

* 使用 **security/stunnel** 创建 SSL 加密隧道传输 syslog 数据。
* 在受信任的内部网络中部署日志服务器，配合防火墙限制访问。

**接收端安全**：

通过 UDP 接收日志消息等效于“未经认证的远程磁盘填充服务”。因此：

* 强烈建议使用 `-a` 选项明确限制允许发送日志的主机，而非接受所有来源的日志。
* 如果不需要接收远程日志，应使用 `-s` 参数启用安全模式。指定两次 `-ss` 将完全禁用网络套接字。
* 可在防火墙上限制 UDP 514 端口的访问来源。

**本地安全**：

日志文件在使用过程中或日志轮替后并未加密。本地用户可能通过访问日志文件获取系统配置的额外信息。因此，对日志文件设置适当的权限十分必要。newsyslog 支持对新创建的和已轮替的日志文件设置权限。将日志文件（如 `auth.log`）设置为模式 `600` 可防止本地用户的未经授权访问。

## 参考文献

* FreeBSD Project. syslog.conf(5)\[EB/OL]. \[2025-05-17]. <https://man.freebsd.org/cgi/man.cgi?query=syslog.conf&sektion=5>. syslog 配置文件手册页。
* FreeBSD Project. syslogd(8)\[EB/OL]. \[2025-05-17]. <https://man.freebsd.org/cgi/man.cgi?query=syslogd&sektion=8>. syslog 守护进程手册页。
* FreeBSD Project. newsyslog.conf(5)\[EB/OL]. \[2025-05-17]. <https://man.freebsd.org/cgi/man.cgi?query=newsyslog.conf&sektion=5>. newsyslog 配置文件手册页。
* FreeBSD Project. logger(1)\[EB/OL]. \[2025-05-17]. <https://man.freebsd.org/cgi/man.cgi?query=logger&sektion=1>. 命令行日志发送工具手册页。

## 课后习题

1. 配置 `syslog.conf` 将所有 `auth` 设施的日志单独记录到 **/var/log/auth.log** 文件中。
2. 修改 `newsyslog.conf` 配置，将 **/var/log/messages** 的保留备份数量从 5 增加到 10。
3. 使用 `grep` 命令搜索最近的 SSH 登录失败尝试记录。
4. 手动触发 `newsyslog` 轮替 **/var/log/auth.log** 文件，观察轮替结果。




---

[Next Page](/llms-full.txt/1)

