---
title: 第 9 章 配置FreeBSD的内核
part: 部分 II. 常见的任务
prev: books/handbook/multimedia
next: books/handbook/printing
---

[[kernelconfig]]
= 配置FreeBSD的内核
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:source-highlighter: rouge
:experimental:
:skip-front-matter:
:toc-title: 目录
:table-caption: 表
:figure-caption: 图
:example-caption: 例
:xrefstyle: basic
:relfileprefix: ../
:outfilesuffix:
:sectnumoffset: 9

ifeval::["{backend}" == "html5"]
:imagesdir: ../../../images/books/handbook/kernelconfig/
endif::[]

ifeval::["{backend}" == "pdf"]
:imagesdir: ../../../../static/images/books/handbook/kernelconfig/
endif::[]

ifeval::["{backend}" == "epub3"]
:imagesdir: ../../../../static/images/books/handbook/kernelconfig/
endif::[]

include::shared/authors.adoc[]
include::shared/releases.adoc[]
include::shared/zh-cn/mailing-lists.adoc[]
include::shared/zh-cn/teams.adoc[]
include::shared/zh-cn/urls.adoc[]

toc::[]

[[kernelconfig-synopsis]]
== 概述

内核是 FreeBSD 操作系统的核心。 它负责管理内存、 执行安全控制、 网络、 磁盘访问等等。 尽管 FreeBSD 可以动态修改的现在已经越来越多， 但有时您还是需要重新配置和编译您的内核。

读完这章，您将了解：

* 为什么需要建立定制的内核。
* 如何编写内核配置文件，或修改已存在的配置文件。
* 如何使用内核配置文件创建和联编新的内核。
* 如何安装新内核。
* 如何处理出现的问题。

这一章给出的命令应该以 `root` 身份执行， 否则可能会不成功。

[[kernelconfig-custom-kernel]]
== 为什么需要建立定制的内核?

过去， FreeBSD 采用的是被人们称作 "单片式" 的内核。 这种内核本身是一个大的程序， 它支持的设备不能够动态地加以改变， 而当希望改变内核的行为时， 就必须编译一个新的内核， 并重新启动计算机才可以使用它。

如今， FreeBSD 正在迅速地迁移到一种新的模型， 其特点是将大量内核功能放进可以动态加载和卸载的内核模块来提供。 这使得内核能够适应硬件的调整 (例如笔记本计算机中的 PCMCIA 卡)， 以及为内核引入新的功能， 而无需在编译内核时就将其添加进去。 这种做法称为模块化内核。

尽管如此， 仍然有一些功能需要静态地联编进内核。 有时， 这是由于这些功能与内核的结合非常紧密而无法实现动态加载， 还有一些情况是暂时没有人将这些功能改写为可动态加载的模块。

联编定制的内核是成为高级 BSD 用户所必须经历的一关。 尽管这一过程需要花费一些时间， 但它能够为您的 FreeBSD 系统带来一些好处。 与必须支持大量硬件的 [.filename]#GENERIC# 内核不同， 定制的内核可以只包含对于 _您_ PC 硬件的支持。 这样做有很多好处， 例如：

* 更快地启动。 因为内核只需要检测您系统上的硬件， 启动时所花费的时间将大大缩短。
* 使用更少的内存。 由于可以删去不需要的功能和设备驱动， 通常定制的内核会比 [.filename]#GENERIC# 使用的内存更少。 节省内核使用的内存之所以重要是因为内核必须常驻于物理内存中， 从而使应用程序能够用到更多的内存。 正因为这样， 对 RAM 较小的系统来说定制内核就更为重要了。
* 支持更多的硬件。 定制的内核允许您增加类似声卡这样的 [.filename]#GENERIC# 内核没有提供内建支持的硬件。

[[kernelconfig-devices]]
== 发现系统硬件

在尝试配置内核以前，比较明智的做法是先获得一份机器硬件的清单。 当 FreeBSD 并不是主操作系统时，通过查看当前操作系统的配置可以很容易的 创建一份机器硬件的配置清单。举例来说， Microsoft(R) 的 设备管理器 里通常含有关于已安装硬件的重要信息。 设备管理器 位于控制面板。

[NOTE]
====
某些版本的 Microsoft(R) Windows(R) 有一个 系统 图标会指明 设备管理器 的位置。
====

如果机器上并不存在其他的操作系统， 系统管理员只能手动寻找这些信息了。其中的一个方法是使用 man:dmesg[8] 工具以及 man:man[1] 命令。FreeBSD 上大多数的驱动程序都有一份手册页（manual page）列出了所支持的硬件， 在系统启动的时候，被发现的硬件也会被列出。举例来说， 下面的这几行表示 [.filename]#psm# 驱动找到了一个鼠标：

[.programlisting]
....
psm0: <PS/2 Mouse> irq 12 on atkbdc0
psm0: [GIANT-LOCKED]
psm0: [ITHREAD]
psm0: model Generic PS/2 mouse, device ID 0
....

这个驱动需要被包含在客户制定的内核配置文件里， 或着使用 man:loader.conf[5] 加载。

有时，`dmesg` 里只会显示来自系统消息的数据， 而不是系统启动时的检测信息。在这样的情况下，你可以查看文件 [.filename]#/var/run/dmesg.boot#。

另一个查找硬件信息的方法是使用 man:pciconf[8] 工具， 它能提供更详细的输出，比如：

[.programlisting]
....
ath0@pci0:3:0:0:        class=0x020000 card=0x058a1014 chip=0x1014168c rev=0x01 hdr=0x00
    vendor     = 'Atheros Communications Inc.'
    device     = 'AR5212 Atheros AR5212 802.11abg wireless'
    class      = network
    subclass   = ethernet
....

这个片断取自于 `pciconf -lv` 命令的输出，显示 [.filename]#ath# 驱动找到了一个无线以太网设备。输入命令 `man ath` 就能查阅有关 man:ath[4] 的手册页（manual page）了。

还可以传给 man:man[1] 命令 `-k` 选项， 同样能获得有用的信息。例如：

[source,bash]
....
# man -k Atheros
....

能得到一份包含特定词语的手册页（manual page）:

[.programlisting]
....
ath(4)                   - Atheros IEEE 802.11 wireless network driver
ath_hal(4)               - Atheros Hardware Access Layer (HAL)
....

手头备有一份硬件的配置清单， 那么编译制定内核的过程就显得不那么困难了。

[[kernelconfig-modules]]
== 内核驱动，子系统和模块

在编译一个制定的内核之前请三思一下这么做的理由， 如果仅是需要某个特定的硬件支持的话， 那么很可能已经存在一个现成的模块了。

内核模块存放在目录 [.filename]#/boot/kernel# 中，并能由 man:kldload[8] 命令加载入正在运行的内核。 基本上所有的内核驱动都有特定的模块和手册页。比如， 下面提到的 [.filename]#ath# 无线以太网驱动。 在这个设备的联机手册中有以下信息：

[.programlisting]
....
Alternatively, to load the driver as a module at boot time, place the
following line in man:loader.conf[5]:

    if_ath_load="YES"
....

遵照示例，在 [.filename]#/boot/loader.conf# 中加入 `if_ath_load="YES"` 则能在机器启动的时候动态加载这个模块。

某些情况下，则没有相关的模块。通常是一些子系统和非常重要的驱动， 比如，快速文件系统 (FFS) 就是一个内核必需的选项。 同样的还有网络支持 (INET)。不幸的是， 分辨一个驱动是否必需的唯一方法就是检查测试以下那个模块本身。

[WARNING]
====

去除某个驱动的支持或某个选项会非常容易得到一个坏掉的内核。 举例来说，如果把 man:ata[4] 驱动从内核配置文件中去掉， 那么一个使用 ATA 磁盘设备的系统可能就变得无法引导，除非有在 [.filename]#loader.conf# 中加载。当你无法确定的时候， 请检查一下那个模块并把它留在你的内核配置中。
====

[[kernelconfig-building]]
== 建立并安装一个定制的内核

首先对内核构建目录做一个快速的浏览。 这里所提到的所有目录都在 [.filename]#/usr/src/sys# 目录中； 也可以通过 [.filename]#/sys# 来访问它。 这里的众多子目录包含了内核的不同部分， 但对我们所要完成的任务最重要的目录是 [.filename]#arch/conf#， 您将在这里编辑定制的内核配置； 以及 [.filename]#compile#， 编译过程中的文件将放置在这里。 _arch_ 表示 [.filename]#i386#、 [.filename]#amd64#、 [.filename]#ia64#、 [.filename]#powerpc#、 [.filename]#sparc64#， 或 [.filename]#pc98# (在日本比较流行的另一种 PC 硬件开发分支)。 在特定硬件架构目录中的文件只和特定的硬件有关； 而其余代码则是与机器无关的， 则所有已经或将要移植并运行 FreeBSD 的平台上都共享这些代码。 文件目录是按照逻辑组织的， 所支持的硬件设备、 文件系统， 以及可选的组件通常都在它们自己的目录中。

这一章提供的例子假定您使用 i386 架构的计算机。 如果您的情况不是这样， 只需对目录名作相应的调整即可。

[NOTE]
====
如果您的系统中 _没有_[.filename]#/usr/src/sys# 这样一个目录， 则说明没有安装内核源代码。 安装它最简单的方法是通过以 root 身份运行 `sysinstall`， 选择 [.guimenuitem]#Configure#， 然后是 [.guimenuitem]#Distributions#、 [.guimenuitem]#src#， 选中其中的 [.guimenuitem]#base# 和 [.guimenuitem]#sys#。 如果您不喜欢 sysinstall 并且有一张 "官方的" FreeBSD CDROM， 也可以使用下列命令， 从命令行来安装源代码：

[source,bash]
....
# mount /cdrom
# mkdir -p /usr/src/sys
# ln -s /usr/src/sys /sys
# cat /cdrom/src/ssys.[a-d]* | tar -xzvf -
# cat /cdrom/src/sbase.[a-d]* | tar -xzvf -
....

====

接下来， 进入 [.filename]#arch/conf# 目录下面， 复制 [.filename]#GENERIC# 配置文件， 并给这个文件起一个容易辨认的名称， 它就是您的内核名称。例如：

[source,bash]
....
# cd /usr/src/sys/i386/conf
# cp GENERIC MYKERNEL
....

通常，这个名称是大写的，如果您正维护着多台不同硬件的FreeBSD机器， 以您机器的域名来命名是非常好的主意。我们把它命名为 [.filename]##MYKERNEL##就是这个原因。 

[TIP]
====

将您的内核配置文件直接保存在 [.filename]#/usr/src# 可能不是一个好主意。 如果您遇到问题， 删掉 [.filename]#/usr/src# 并重新开始很可能是一个诱人的选择。 一旦开始做这件事， 您可能几秒钟之后才会意识到您同时会删除定制的内核配置文件。 另外， 也不要直接编辑 [.filename]#GENERIC#， 因为下次您 crossref:cutting-edge[updating-upgrading,更新代码] 时它会被覆盖， 而您的修改也就随之丢失了。

您也可以考虑把内核配置文件放到别的地方， 然后再到 [.filename]#i386# 目录中创建一个指向它的符号链接。

例如：

[source,bash]
....
# cd /usr/src/sys/i386/conf
# mkdir /root/kernels
# cp GENERIC /root/kernels/MYKERNEL
# ln -s /root/kernels/MYKERNEL
....

====

[NOTE]
====
必须以 `root` 身份执行这些和接下来命令， 否则就会得到  的错误提示。 
====

现在就可以用您喜欢的文本编辑器来编辑 [.filename]#MYKERNEL# 了。 如果您刚刚开始使用 FreeBSD， 唯一可用的编辑器很可能是 vi， 它的使用比较复杂， 限于篇幅， 这里不予介绍， 您可以在 crossref:bibliography[bibliography,参考书目] 一章中找到很多相关书籍。 不过， FreeBSD 也提供了一个更好用的编辑器， 它叫做 ee， 对于新手来说， 这很可能是一个不错的选择。 您可以修改配置文件中的注释以反映您的配置， 或其他与 [.filename]#GENERIC# 不同的地方。

如果您在SunOS(TM)或者其他BSD系统下定制过内核，那这个文件中的绝大部分将对您非常熟悉。 如果您使用的是诸如DOS这样的系统，那[.filename]##GENERIC##配置文件看起来就非常困难， 所以在下面的 <<kernelconfig-config,配置文件>>章节将慢慢地、仔细地进行介绍。 

[NOTE]
====
如果您和 FreeBSD project 进行了 crossref:cutting-edge[updating-upgrading,代码同步]， 则一定要在进行任何更新之前查看 [.filename]#/usr/src/UPDATING#。 这个文件中描述了更新过的代码中出现的重大问题或需要注意的地方。 [.filename]#/usr/src/UPDATING# 总是和您的 FreeBSD 源代码对应， 因此能够提供比手册更具时效性的新内容。
====

现在应该编译内核的源代码了。

[.procedure]
====
*Procedure: 联编内核*

. 进入 [.filename]#/usr/src# 目录：
+
[source,bash]
....
# cd /usr/src
....
+
. 编译内核：
+
[source,bash]
....
# make buildkernel KERNCONF=MYKERNEL
....
+
. 安装新内核：
+
[source,bash]
....
# make installkernel KERNCONF=MYKERNEL
....
====

[NOTE]
====
使用这种方法联编内核时， 需要安装完整的 FreeBSD 源代码。
====

[TIP]
====

默认情况下， 在联编您所定制的内核时， _全部_ 内核模块也会同时参与构建。 如果您希望更快地升级内核， 或者只希望联编您所需要的模块， 则应在联编之前编辑 [.filename]#/etc/make.conf#：

[.programlisting]
....
MODULES_OVERRIDE = linux acpi sound/sound sound/driver/ds1 ntfs
....

这个变量的内容是所希望构建的模块列表。

[.programlisting]
....
WITHOUT_MODULES = linux acpi sound ntfs
....

这个变量的内容是将不在联编过程中编译的顶级模块列表。 如果希望了解更多与构建内核有关的变量， 请参见 man:make.conf[5] 联机手册。
====

新内核将会被复制到 [.filename]#/boot/kernel# 目录中成为 [.filename]#/boot/kernel/kernel# 而旧的则被移到 [.filename]#/boot/kernel.old/kernel#。 现在关闭系统， 然后用新的内核启动计算机。 如果出现问题， 后面的一些 <<kernelconfig-trouble,故障排除方法>> 将帮您摆脱困境。 如果您的内核 <<kernelconfig-noboot,无法启动>>， 请参考那一节。

[NOTE]
====
其他与启动过程相关的文件， 如 man:loader[8] 及其配置， 则放在 [.filename]#/boot#。 第三方或定制的模块也可以放在 [.filename]#/boot/kernel#， 不过应该注意保持模块和内核的同步时很重要的， 否则会导致不稳定和错误。
====

[[kernelconfig-config]]
== 配置文件

配置文件的格式是非常简单的。 每一行都包括一个关键词， 以及一个或多个参数。 实际上， 绝大多数行都只包括一个参数。 在 `\#` 之后的内容会被认为是注释而忽略掉。 接下来几节, 将以 [.filename]##GENERIC## 中的顺序介绍所有关键字。 [[kernelconfig-options]] 如果需要与平台有关的选项和设备的详细列表， 请参考与 [.filename]##GENERIC## 文件在同一个目录中的那个 [.filename]##NOTES##， 而平台无关的选项， 则可以在 [.filename]##/usr/src/sys/conf/NOTES## 找到。

配置文件中还可以使用 `include` 语句。 这个语句能够在内核配置文件中直接引用其他配置文件的内容， 使得您能够使用较小的、 仅包含相对于现存配置的变动而减少维护所需的工作。 例如， 如果您只需对 [.filename]#GENERIC# 内核进行少量定制， 在其中添加几个驱动程序和附加选项， 则只要维护相对于 GENERIC 的变化就可以了：

[.programlisting]
....
include GENERIC
ident MYKERNEL

options         IPFIREWALL
options         DUMMYNET
options         IPFIREWALL_DEFAULT_TO_ACCEPT
options         IPDIVERT
....

许多系统管理员会发现， 这种方法与先前从头开始写配置文件的方法相比， 可以带开相当多的好处： 本地采用的配置文件只表达与 [.filename]#GENERIC# 内核的差异， 这样， 在升级的时候往往就不需要做任何改动， 而新加入 [.filename]#GENERIC# 的功能就会自动加入到本地的内核， 除非使用 `nooptions` 或 `nodevice` 语句将其排除。 这一章余下的部分将着重介绍典型的配置文件， 以及内核选项和设备的作用。

[NOTE]
====
如果您需要一份包含所有选项的文件， 例如用于测试目的， 则应以 `root` 身份执行下列命令：

[source,bash]
....
# cd /usr/src/sys/i386/conf && make LINT
....

====

下面是一个 [.filename]#GENERIC# 内核配置文件的例子， 它包括了一些需要解释的注释。 这个例子应该和您复制的 [.filename]#/usr/src/sys/i386/conf/GENERIC# 非常接近。

[.programlisting]
....
machine		i386
....

这是机器的架构， 它只能是 `amd64`, `i386`, `ia64`, `pc98`, `powerpc`, 或 `sparc64` 中的一种。

[.programlisting]
....
cpu          I486_CPU
cpu          I586_CPU
cpu          I686_CPU
....

上面的选项指定了您系统中所使用的 CPU 类型。 您可以使用多个 CPU 类型 (例如， 您不确定是应该指定 `I586_CPU` 或 `I686_CPU`)。 然而对于定制的内核， 最好能够只指定您使用的那种 CPU。 如果您对于自己使用的 CPU 类型没有把握， 可以通过查看 [.filename]#/var/run/dmesg.boot# 中的启动信息来了解。

[.programlisting]
....
ident          GENERIC
....

这是内核的名字。 您应该取一个自己的名字， 例如取名叫 `MYKERNEL`， 如果您一直在按照前面的说明做的话。 您放在 `ident` 后面的字符串在启动内核时会显示出来， 因此如果希望能够容易区分常用的内核和刚刚定制的内核， 就应该采取不同的名字 (例如， 您想定制一个试验性的内核)。

[.programlisting]
....
#To statically compile in device wiring instead of /boot/device.hints
#hints          "GENERIC.hints"         # Default places to look for devices.
....

man:device.hints[5] 可以用来配置设备驱动选项。 在启动的时候 man:loader[8] 将会检查缺省位置 [.filename]##/boot/devicehints##。 使用 `hints` 选项您就可以把这些 hints 静态编译进内核。 这样就没有必要在 [.filename]##/boot##下创建[.filename]##devicehints##。

[.programlisting]
....
makeoptions     DEBUG=-g          # Build kernel with gdb(1) debug symbols
....

一般的 FreeBSD 联编过程， 在所联编的内核指定了 `-g` 选项时， 由于此选项将传递给 man:gcc[1] 表示加入调试信息， 因此会将调试符号也包含进来。

[.programlisting]
....
options          SCHED_ULE         # ULE scheduler
....

这是 FreeBSD 上使用的默认系统调度器。 请保留此选项。

[.programlisting]
....
options          PREEMPTION         # Enable kernel thread preemption
....

允许内核线程根据优先级的抢占调度。 这有助于改善交互性， 并可以让中断线程更早地执行， 而无须等待。

[.programlisting]
....
options          INET              # InterNETworking
....

网络支持，即使您不打算连网，也请保留它，大部分的程序至少需要回环网络（就是和本机进行网络连接），所以强烈要求保留它。 

[.programlisting]
....
options          INET6             # IPv6 communications protocols
....

这将打开IPv6连接协议。

[.programlisting]
....
options          FFS               # Berkeley Fast Filesystem
....

这是最基本的硬盘文件系统，如果打算从本地硬盘启动，请保留它。

[.programlisting]
....
options          SOFTUPDATES       # Enable FFS Soft Updates support
....

这个选项会启用内核中的 Soft Updates 支持， 它会显著地提高磁盘的写入速度。 尽管这项功能是由内核直接提供的， 但仍然需要在每个磁盘上启用它。 请检查 man:mount[8] 的输出， 以了解您系统中的磁盘上是否已经启用了 Soft Updates。 如果没有看到 `soft-updates` 选项， 则需要使用 man:tunefs[8] (对于暨存系统) 或 man:newfs[8] (对于新系统) 命令来激活它。

[.programlisting]
....
options          UFS_ACL           # Support for access control lists
....

这个选项将启用内核中的访问控制表的支持。 这依赖于扩展属性以及 UFS2， 以及在 crossref:security[fs-acl,文件系统访问控制表] 中所介绍的那些特性。 ACL 默认是启用的， 并且如果已经在文件系统上使用了这一特性， 就不应再关掉它， 因为这会去掉文件的访问控制表， 并以不可预期的方式改变受保护的文件的访问方式。

[.programlisting]
....
options          UFS_DIRHASH       # Improve performance on big directories
....

通过使用额外的内存，这个选项可以加速在大目录上的磁盘操作。 您应该在大型服务器和频繁使用的工作站上打开这个选项，而在磁盘操作不是很重要的 小型系统上关闭它，比如防火墙。

[.programlisting]
....
options          MD_ROOT           # MD is a potential root device
....

这个选项将打开以基于内存的虚拟磁盘作为根设备的支持。

[.programlisting]
....
options          NFSCLIENT         # Network Filesystem Client
options          NFSSERVER         # Network Filesystem Server
options          NFS_ROOT          # NFS usable as /, requires NFSCLIENT
....

网络文件系统。 如果您不打算通过 TCP/IP 挂接 UNIX(R) 文件服务器的分区， 就可以注释掉它。

[.programlisting]
....
options          MSDOSFS           # MSDOS Filesystem
....

MS-DOS(R) 文件系统。 只要您不打算在启动时挂接由 DOS 格式化的硬盘分区， 就可以把它注释掉。 如前面所介绍的那样， 在您第一次挂接 DOS 分区时， 内核会自动加载需要的模块。 此外， package:emulators/mtools[] 软件提供了一个很方便的功能， 通过它您可以直接访问 DOS 软盘而无需挂接或卸下它们 (而且也完全不需要 `MSDOSFS`)。

[.programlisting]
....
options          CD9660            # ISO 9660 Filesystem
....

用于 CDROM 的 ISO 9660 文件系统。 如果没有 CDROM 驱动器或很少挂接光盘数据 (因为在首次使用数据 CD 时会自动加载)， 就可以把它注释掉。 音乐 CD 并不需要这个选项。

[.programlisting]
....
options          PROCFS            # Process filesystem (requires PSEUDOFS)
....

进程文件系统。 这是一个挂接在 [.filename]#/proc# 的一个 "假扮的" 文件系统， 其作用是允许类似 man:ps[1] 这样的程序给出正在运行的进程的进一步信息。 多数情况下， 并不需要使用 `PROCFS`， 因为绝大多数调试和监控工具， 已经进行了一系列修改， 使之不再依赖 `PROCFS`： 默认安装的系统中并不会挂接这一文件系统。

[.programlisting]
....
options          PSEUDOFS          # Pseudo-filesystem framework
....

如果希望使用 `PROCFS`， 就必须加入 `PSEUDOFS` 的支持。

[.programlisting]
....
options          GEOM_GPT          # GUID Partition Tables.
....

这个选项提供了在磁盘上使用大量的分区的能力。

[.programlisting]
....
options          COMPAT_43         # Compatible with BSD 4.3 [KEEP THIS!]
....

使系统兼容4.3BSD。不要去掉这一行，不然有些程序将无法正常运行。 

[.programlisting]
....
options          COMPAT_FREEBSD4   # Compatible with FreeBSD4
....

如果希望支持在旧版 FreeBSD 上编译的使用旧式接口的应用程序， 就需要加入这一选项。 一般来说， 推荐在所有的 i386(TM) 系统上启用这个选项， 因为难免可能会用到一些旧的应用； 到 5.X 才开始支持的平台， 如 ia64 和 sparc64， 则不需要这个选项。

[.programlisting]
....
options          COMPAT_FREEBSD5   # Compatible with FreeBSD5
....

如果希望支持在 FreeBSD 5.X 版本上编译， 且使用 FreeBSD 5.X 系统调用接口的应用程序， 则应加上这个选项。

[.programlisting]
....
options          COMPAT_FREEBSD6   # Compatible with FreeBSD6
....

如果希望支持在 FreeBSD 6.X 版本上编译， 且使用 FreeBSD 6.X 系统调用接口的应用程序， 则应加上这个选项。

[.programlisting]
....
options          COMPAT_FREEBSD7   # Compatible with FreeBSD7
....

如果希望支持在 FreeBSD 8 以上版本的操作系统中运行在 FreeBSD 7.X 版本上编译， 且使用 FreeBSD 7.X 系统调用接口的应用程序， 则应加上这个选项。

[.programlisting]
....
options          SCSI_DELAY=5000  # Delay (in ms) before probing SCSI
....

这将让内核在探测每个 SCSI 设备之前等待 5 秒。 如果您只有 IDE 硬盘驱动器， 就可以不管它， 反之您可能会希望尝试降低这个数值以加速启动过程。 当然， 如果您这么做之后 FreeBSD 在识别您的 SCSI 设备时遇到问题， 则您还需要再把它改回去。

[.programlisting]
....
options          KTRACE            # ktrace(1) support
....

这个选项打开内核进程跟踪，在调试时很有用。

[.programlisting]
....
options          SYSVSHM           # SYSV-style shared memory
....

提供System V共享内存(SHM)的支持，最常用到SHM的应该是X Window的XSHM延伸， 不少绘图相关程序会自动使用SHM来提供额外的速度。如果您要使用X Window，您最好加入这个选项。 

[.programlisting]
....
options          SYSVMSG           # SYSV-style message queues
....

支持 System V 消息。 这只会在内核中增加数百字节的空间占用。

[.programlisting]
....
options          SYSVSEM           # SYSV-style semaphores
....

支持System V 信号量， 不常用到， 但只在kernel中占用几百个字节的空间。

[NOTE]
====
man:ipcs[1] 命令的 `-p` 选项可以显示出任何用到这些 System V 机制的进程。
====

[.programlisting]
....
options 	     _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
....

在 1993 年 POSIX(R) 添加的实时扩展。 在 Ports Collection 中某些应用程序会用到这些 （比如StarOffice(TM)）。 

[.programlisting]
....
options          KBD_INSTALL_CDEV  # install a CDEV entry in /dev
....

这个选项是在 [.filename]##/dev##下建立键盘设备节点必需的。

[.programlisting]
....
options          ADAPTIVE_GIANT    # Giant mutex is adaptive.
....

内核全局锁 (Giant) 是一种互斥机制 (休眠互斥体) 的名字， 它用于保护许多内核资源。 现在， 这已经成为了一种无法接受的性能瓶颈， 它已经被越来越多地使用保护单个资源的锁代替。 `ADAPTIVE_GIANT` 选项将使得内核全局锁作为一种自适应自旋锁。 这意味着， 当有线程希望锁住内核全局锁互斥体， 但互斥体已经被另一个 CPU 上的线程锁住的时候， 它将继续运行， 直到那个线程释放锁为止。 一般情况下， 另一个线程将进入休眠状态并等待下一次调度。 如果您不确定是否应该这样做的话， 一般应该打开它。

[NOTE]
====
请注意在 FreeBSD 8.0-RELEASE 及以后的版本，所有的互斥体默认都是自适应的， 除非在编译时使用 `NO_ADAPTIVE_MUTEXES` 选项， 明确的指定为非自适应。因此，内核全局锁（Giant）目前默认也是自适应的, 而且 `ADAPTIVE_GIANT` 选项已经从内核配置文件中移出。
====

[.programlisting]
....
device          apic               # I/O APIC
....

apic 设备将启用使用 I/O APIC 作为中断发送设备的能力。 apic 设备可以被 UP 和 SMP 内核使用， 但 SMP 内核必须使用它。 要支持多处理器， 还需要加上 `options SMP`。

[NOTE]
====
只有在 i386 和 amd64 平台上才存在 apic 设备， 在其他硬件平台上不应使用它。
====

[.programlisting]
....
device          eisa
....

如果您的主机板上有EISA总线，加入这个设置。使用这个选项可以自动扫描并设置所有连接在EISA总线上的设备。

[.programlisting]
....
device          pci
....

如果您的主板有PCI总线，就加入这个选项。使用这个选项可以自动扫描PCI卡，并在PCI到ISA之间建立通路。

[.programlisting]
....
# Floppy drives
device          fdc
....

这是软驱控制器。

[.programlisting]
....
# ATA and ATAPI devices
device          ata
....

这个驱动器支持所有ATA和ATAPI设备。您只要在内核中加入``device ata``选项， 就可以让内核支持现代计算机上的所有PCI ATA/ATAPI设备。 

[.programlisting]
....
device          atadisk                 # ATA disk drives
....

这个是使用 ATAPI 硬盘驱动器时必须加入的选项。

[.programlisting]
....
device          ataraid                 # ATA RAID drives
....

这个选项需要 `device ata`， 它用于 ATA RAID 驱动。

[.programlisting]
....

device          atapicd                 # ATAPI CDROM drives
....

这个是ATAPI CDROM驱动器所必须的。

[.programlisting]
....
device          atapifd                 # ATAPI floppy drives
....

这个是ATAPI 软盘驱动器所必须的。

[.programlisting]
....
device          atapist                 # ATAPI tape drives
....

这个是ATAPI 磁带机驱动器所必须的.

[.programlisting]
....
options         ATA_STATIC_ID           # Static device numbering
....

这指定对控制器使用其静态的编号； 如果没有这个选项， 则会动态地分配设备的编号。

[.programlisting]
....
# SCSI Controllers
device          ahb        # EISA AHA1742 family
device          ahc        # AHA2940 and onboard AIC7xxx devices
options         AHC_REG_PRETTY_PRINT    # Print register bitfields in debug
                                        # output.  Adds ~128k to driver.
device          ahd        # AHA39320/29320 and onboard AIC79xx devices
options         AHD_REG_PRETTY_PRINT    # Print register bitfields in debug
                                        # output.  Adds ~215k to driver.
device          amd        # AMD 53C974 (Teckram DC-390(T))
device          isp        # Qlogic family
#device         ispfw      # Firmware for QLogic HBAs- normally a module
device          mpt        # LSI-Logic MPT-Fusion
#device         ncr        # NCR/Symbios Logic
device          sym        # NCR/Symbios Logic (newer chipsets + those of `ncr')
device          trm        # Tekram DC395U/UW/F DC315U adapters

device          adv        # Advansys SCSI adapters
device          adw        # Advansys wide SCSI adapters
device          aha        # Adaptec 154x SCSI adapters
device          aic        # Adaptec 15[012]x SCSI adapters, AIC-6[23]60.
device          bt         # Buslogic/Mylex MultiMaster SCSI adapters

device          ncv        # NCR 53C500
device          nsp        # Workbit Ninja SCSI-3
device          stg        # TMC 18C30/18C50
....

SCSI控制器。可以注释掉您系统中没有的设备。 如果您只有IDE设备，您可以把这些一起删掉。 `*_REG_PRETTY_PRINT` 这样的配置， 则是对应驱动程序的调试选项。

[.programlisting]
....
# SCSI peripherals
device          scbus      # SCSI bus (required for SCSI)
device          ch         # SCSI media changers
device          da         # Direct Access (disks)
device          sa         # Sequential Access (tape etc)
device          cd         # CD
device          pass       # Passthrough device (direct SCSI access)
device          ses        # SCSI Environmental Services (and SAF-TE)
....

SSCSI外围设备。也可以像上面一样操作。

[NOTE]
====
目前系统提供的 USB man:umass[4] 以及少量其它驱动使用了 SCSI 子系统， 尽管它们并不是真的 SCSI 设备。 因此， 如果在内核配置使用了这类驱动程序， 请务必不要删除 SCSI 支持。
====

[.programlisting]
....
# RAID controllers interfaced to the SCSI subsystem
device          amr        # AMI MegaRAID
device          arcmsr     # Areca SATA II RAID
device          asr        # DPT SmartRAID V, VI and Adaptec SCSI RAID
device          ciss       # Compaq Smart RAID 5*
device          dpt        # DPT Smartcache III, IV - See NOTES for options
device          hptmv      # Highpoint RocketRAID 182x
device          rr232x     # Highpoint RocketRAID 232x
device          iir        # Intel Integrated RAID
device          ips        # IBM (Adaptec) ServeRAID
device          mly        # Mylex AcceleRAID/eXtremeRAID
device          twa        # 3ware 9000 series PATA/SATA RAID

# RAID controllers
device          aac        # Adaptec FSA RAID
device          aacp       # SCSI passthrough for aac (requires CAM)
device          ida        # Compaq Smart RAID
device          mfi        # LSI MegaRAID SAS
device          mlx        # Mylex DAC960 family
device          pst        # Promise Supertrak SX6000
device          twe        # 3ware ATA RAID
....

支持RAID控制器。如果您没有这些，可以把它们注释掉或是删掉。

[.programlisting]
....
# atkbdc0 controls both the keyboard and the PS/2 mouse
device          atkbdc     # AT keyboard controller
....

键盘控制器（`atkbdc`）提供AT键盘输入以及PS/2指针设备的I/O服务。 键盘驱动程序（`atkbd`）与PS/2鼠标驱动程序（`psm`）需要这个控制器，所以不要删除它。 

[.programlisting]
....
device          atkbd      # AT keyboard
....

``atkbd``驱动程序，与``atkbdc``控制器一起使用， 提供连接到AT键盘控制器的AT 84键盘与AT加强型键盘的访问服务。 

[.programlisting]
....
device          psm        # PS/2 mouse
....

如果您的鼠标连接到PS/2鼠标端口，就使用这个设备驱动程序。

[.programlisting]
....
device          kbdmux        # keyboard multiplexer
....

针对键盘多路选择器的基本支持。 如果您不打算使用多个键盘， 则可以放心地删除这一行。

[.programlisting]
....
device          vga        # VGA video card driver
....

显卡驱动。

[.programlisting]
....

device          splash     # Splash screen and screen saver support
....

启动时的 splash 画面！ 屏幕保护程序也需要这一选项。

[.programlisting]
....
# syscons is the default console driver, resembling an SCO console
device          sc
....

`sc` 是默认的控制台驱动程序， 类似 SCO 控制台。 由于绝大部分全屏幕程序都通过类似 [.filename]#termcap# 这样的终端数据库函数库赖访问控制台， 因此无论您使用这个或与 `VT220` 兼容的 `vt` 都没有什么关系。 如果您在运行这种控制台时使用全屏幕程序时发生问题， 请在登录之后将 `TERM` 变量设置为 `scoansi`。

[.programlisting]
....
# Enable this for the pcvt (VT220 compatible) console driver
#device          vt
#options         XSERVER          # support for X server on a vt console
#options         FAT_CURSOR       # start with block cursor
....

这是一个兼容 VT220 的控制台驱动， 它同时能够向下兼容 VT100/102。 在同 `sc` 硬件不兼容的一些笔记本上它能够运行的很好。 当然， 登录系统时请把 `TERM` 变量设置为 `vt100` 或 `vt220`。 此驱动在连接网络上大量不同的机器时也被证明非常有用， 因为此时 [.filename]#termcap# 或 [.filename]#terminfo# 通常没有可用的 `sc` 设备 - 而 `vt100` 则几乎每种平台都支持。

[.programlisting]
....
device          agp
....

如果您的机器使用 AGP 卡， 请把上面一行加入配置。 这将启用 AGP， 以及某些卡上的 AGP GART 支持。

[.programlisting]
....
# 电源管理支持 (参见 NOTES 了解更多选项)
#device          apm
....

高级电源管理支持。对笔记本有用，不过在 [.filename]#GENERIC# 里默认禁用。

[.programlisting]
....
# 增加 i8254 的 挂起/恢复 支持。
device           pmtimer
....

用于电源管理事件， 例如 APM 和 ACPI 的时钟设备驱动。

[.programlisting]
....
# PCCARD (PCMCIA) support
# PCMCIA and cardbus bridge support
device          cbb               # cardbus (yenta) bridge
device          pccard            # PC Card (16-bit) bus
device          cardbus           # CardBus (32-bit) bus
....

PCMCIA支持。如果您使用膝上型计算机，您需要这个。

[.programlisting]
....
# Serial (COM) ports
device          sio               # 8250, 16[45]50 based serial ports
....

这些串口在 MS-DOS(R)/Windows(R) 的世界中称为 [.filename]#COM# 口。

[NOTE]
====
如果使用内置式的调制解调器， 并占用 [.filename]#COM4# 而您另有一个串口在 [.filename]#COM2#， 则必须把调制解调器的 IRQ 改为 2 (由于晦涩的技术原因， IRQ2 = IRQ 9) 才能够在 FreeBSD 中访问它。 如果有多口的串口卡， 请参考 man:sio[4] 以了解需要在 [.filename]#/boot/device.hints# 中进行的设置。 某些显卡 (特别是基于 S3 芯片的卡) 使用形如 `0x*2e8` 的 IO 地址， 而许多廉价的串口卡不能够正确地对 16-位 IO 地址空间进行解码， 因此它们会产生冲突， 并造成 [.filename]#COM4# 实际上无法使用。

每一个串口都需要有一个唯一的 IRQ (除非您使用支持中断分享的串口卡)， 因此默认的 [.filename]#COM3# 和 [.filename]#COM4# IRQ 是不能使用的。
====

[.programlisting]
....
# Parallel port
device          ppc
....

ISA-bus并行接口。

[.programlisting]
....
device          ppbus      # Parallel port bus (required)
....

提供并行总线的支持。

[.programlisting]
....
device          lpt        # Printer
....

提供并口打印机的支持。

[NOTE]
====
要使用并口打印机，就必须同时加入上面三行设置。
====

[.programlisting]
....
device          plip       # TCP/IP over parallel
....

这是针对并行网络接口的驱动器。

[.programlisting]
....
device          ppi        # Parallel port interface device
....

普通用途的I/O ("geek port") + IEEE1284 I/O.

[.programlisting]
....
#device         vpo        # Requires scbus and da
....

这是针对Iomega Zip驱动器的。它要求``scbus``和``da``的支持。 最好的执行效果是工作在EPP 1.9模式。 

[.programlisting]
....
#device         puc
....

如果您有由 man:puc[4] 支持的 "哑" 串行或并行 PCI 卡， 则应去掉这一行的注释。

[.programlisting]
....
# PCI Ethernet NICs.
device          de         # DEC/Intel DC21x4x (Tulip)
device          em         # Intel PRO/1000 adapter Gigabit Ethernet Card
device          ixgb       # Intel PRO/10GbE Ethernet Card
device          txp        # 3Com 3cR990 (Typhoon)
device          vx         # 3Com 3c590, 3c595 (Vortex)
....

多种PCI网卡驱动器。注释或删除您系统中没有的设备.

[.programlisting]
....
# PCI Ethernet NICs that use the common MII bus controller code.
# NOTE: Be sure to keep the 'device miibus' line in order to use these NICs!
device          miibus     # MII bus support
....

MII总线支持对于一些PCI 10/100 Ethernet NIC来说是必需的。 

[.programlisting]
....
device          bce        # Broadcom BCM5706/BCM5708 Gigabit Ethernet
device          bfe        # Broadcom BCM440x 10/100 Ethernet
device          bge        # Broadcom BCM570xx Gigabit Ethernet
device          dc         # DEC/Intel 21143 and various workalikes
device          fxp        # Intel EtherExpress PRO/100B (82557, 82558)
device          lge        # Level 1 LXT1001 gigabit ethernet
device          msk        # Marvell/SysKonnect Yukon II Gigabit Ethernet
device          nge        # NatSemi DP83820 gigabit ethernet
device          nve        # nVidia nForce MCP on-board Ethernet Networking
device          pcn        # AMD Am79C97x PCI 10/100 (precedence over 'lnc')
device          re         # RealTek 8139C+/8169/8169S/8110S
device          rl         # RealTek 8129/8139
device          sf         # Adaptec AIC-6915 (Starfire)
device          sis        # Silicon Integrated Systems SiS 900/SiS 7016
device          sk         # SysKonnect SK-984x & SK-982x gigabit Ethernet
device          ste        # Sundance ST201 (D-Link DFE-550TX)
device          stge       # Sundance/Tamarack TC9021 gigabit Ethernet
device          ti         # Alteon Networks Tigon I/II gigabit Ethernet
device          tl         # Texas Instruments ThunderLAN
device          tx         # SMC EtherPower II (83c170 EPIC)
device          vge        # VIA VT612x gigabit ethernet
device          vr         # VIA Rhine, Rhine II
device          wb         # Winbond W89C840F
device          xl         # 3Com 3c90x (Boomerang, Cyclone)
....

使用MII总线控制器代码的驱动器。

[.programlisting]
....
# ISA Ethernet NICs.  pccard NICs included.
device          cs         # Crystal Semiconductor CS89x0 NIC
# 'device ed' requires 'device miibus'
device          ed         # NE[12]000, SMC Ultra, 3c503, DS8390 cards
device          ex         # Intel EtherExpress Pro/10 and Pro/10+
device          ep         # Etherlink III based cards
device          fe         # Fujitsu MB8696x based cards
device          ie         # EtherExpress 8/16, 3C507, StarLAN 10 etc.
device          lnc        # NE2100, NE32-VL Lance Ethernet cards
device          sn         # SMC's 9000 series of Ethernet chips
device          xe         # Xircom pccard Ethernet

# ISA devices that use the old ISA shims
#device         le
....

ISA 以太网卡驱动。 参见 [.filename]#/usr/src/sys/i386/conf/NOTES# 以了解关于哪个驱动程序能够驱动您的网卡的细节。

[.programlisting]
....
# Wireless NIC cards
device          wlan            # 802.11 support
....

通用 802.11 支持。 这行配置是无线网络所必需的。

[.programlisting]
....
device          wlan_wep        # 802.11 WEP support
device          wlan_ccmp       # 802.11 CCMP support
device          wlan_tkip       # 802.11 TKIP support
....

针对 802.11 设备的加密支持。 如果希望使用加密和 802.11i 安全协议， 就需要这些配置行。

[.programlisting]
....
device          an         # Aironet 4500/4800 802.11 wireless NICs.
device          ath             # Atheros pci/cardbus NIC's
device          ath_hal         # Atheros HAL (Hardware Access Layer)
device          ath_rate_sample # SampleRate tx rate control for ath
device          awi        # BayStack 660 and others
device          ral        # Ralink Technology RT2500 wireless NICs.
device          wi         # WaveLAN/Intersil/Symbol 802.11 wireless NICs.
#device         wl         # Older non 802.11 Wavelan wireless NIC.
....

用以支持多种无线网卡。

[.programlisting]
....
# Pseudo devices
device   loop          # Network loopback
....

这是 TCP/IP 的通用回环设备。 如果您 telnet 或 FTP 到 `localhost` (也就是 `127.0.0.1`) 则将通过这个设备回到本机。 这个设备是 _必需的_。

[.programlisting]
....
device   random        # Entropy device
....

Cryptographically secure random number generator.

[.programlisting]
....
device   ether         # Ethernet support
....

`ether` 只有在使用以太网卡时才需要。 它包含了通用的以太网协议代码。

[.programlisting]
....
device   sl            # Kernel SLIP
....

`sl` 用以提供 SLIP 支持。 目前它几乎已经完全被 PPP 取代了， 因为后者更容易配置， 而且更适合调制解调器之间的连接， 并提供了更强大的功能。

[.programlisting]
....
device   ppp           # Kernel PPP
....

这一选项用以提供内核级的 PPP 支持， 用于拨号连接。 也有以用户模式运行的 PPP 实现， 使用 `tun` 并提供包括按需拨号在内的更为灵活的功能。

[.programlisting]
....
device   tun           # Packet tunnel.
....

它会被用户模式的 PPP 软件用到。 参考本书的 crossref:ppp-and-slip[userppp,PPP] 以了解更多的细节。

[.programlisting]
....

device   pty           # Pseudo-ttys (telnet etc)
....

这是一个 "pseudo-terminal" 或模拟登入端口。 它用来接收连入的 `telnet` 以及 `rlogin` 会话、 xterm， 以及一些其它程序如 Emacs 等。

[.programlisting]
....
device   md            # Memory disks
....

内存盘伪设备。

[.programlisting]
....
device   gif           # IPv6 and IPv4 tunneling
....

它实现了在 IPv4 上的 IPv6 隧道、 IPv6 上的 IPv4 隧道、 IPv4 上的 IPv4 隧道、 以及IPv6 上的 IPv6隧道。 `gif` 设备是 "自动克隆" 的， 它会根据需要自动创建设备节点。

[.programlisting]
....
device   faith         # IPv6-to-IPv4 relaying (translation)
....

这个伪设备能捕捉发给它的数据包，并把它们转发给 IPv4/IPv6 翻译服务程序。

[.programlisting]
....
# The `bpf' device enables the Berkeley Packet Filter.
# Be aware of the administrative consequences of enabling this!
# Note that 'bpf' is required for DHCP.
device   bpf           # Berkeley packet filter
....

这是 Berkeley 包过滤器。这个伪设备允许网络接口被置于混杂模式， 从而，截获广播网 (例如，以太网) 上的每一个数据包。 截获的数据报可以保存到磁盘上，也可以使用 man:tcpdump[1] 程序来分析。

[NOTE]
====
man:bpf[4] 设备也被用于 man:dhclient[8] 来获取默认路由器(网关)的 IP 地址。如果使用DHCP，就不要注释掉这行。
====

[.programlisting]
....
# USB support
device          uhci          # UHCI PCI->USB interface
device          ohci          # OHCI PCI->USB interface
device          ehci          # EHCI PCI->USB interface (USB 2.0)
device          usb           # USB Bus (required)
#device         udbp          # USB Double Bulk Pipe devices
device          ugen          # Generic
device          uhid          # Human Interface Devices
device          ukbd          # Keyboard
device          ulpt          # Printer
device          umass         # Disks/Mass storage - Requires scbus and da
device          ums           # Mouse
device          ural          # Ralink Technology RT2500USB wireless NICs
device          urio          # Diamond Rio 500 MP3 player
device          uscanner      # Scanners
# USB Ethernet, requires mii
device          aue           # ADMtek USB Ethernet
device          axe           # ASIX Electronics USB Ethernet
device          cdce          # Generic USB over Ethernet
device          cue           # CATC USB Ethernet
device          kue           # Kawasaki LSI USB Ethernet
device          rue           # RealTek RTL8150 USB Ethernet
....

支持各类 USB 设备。

[.programlisting]
....
# FireWire support
device          firewire      # FireWire bus code
device          sbp           # SCSI over FireWire (Requires scbus and da)
device          fwe           # Ethernet over FireWire (non-standard!)
....

支持各类火线设备。

要了解 FreeBSD 所支持的设备的其他情况， 请参考 [.filename]#/usr/src/sys/i386/conf/NOTES#。

=== 大内存支持(PAE)

大内存配置的机器需要超过４GB的虚拟地址。 因为4GB的限制，Intel在Pentium(R)及后续的CPUs上增加了36位物理地址的支持。 

物理地址扩展 (PAE) 是 Intel(R) Pentium(R) Pro和后续的 CPU 提供的一种允许将内存地址扩展到 64GB 的功能， FreeBSD 的所有最新版本均支持此功能， 并通过 `PAE` 选项来启用这个能力。 因为Intel架构的限制， 高于或低于 4GB 都没有什么区别， 超过 4GB 的内存分配只是简单地添加到可用内存池中。

为了让内核支持PAE，只要增加下面这一行到配置文件：

[.programlisting]
....
options		    PAE
....

[NOTE]
====
PAE在FreeBSD里面现在只能支持 Intel(R) IA-32处理器。 同时，还应该注意，FreeBSD的PAE支持没有经过广泛的测试， 和其他稳定的特性相比只能当作是beta版。
====

PAE在FreeBSD下有如下的一些限制：

* 进程不能接触大于4GB的VM空间。
* 没有使用 man:bus_dma[9] 接口的设备驱动程序在打开了 PAE 支持的内核中会导致数据损坏。 因为这个原因， [.filename]#PAE# 内核配置文件 会把所有在打开了 PAE 的内核上不能工作的驱动程序排除在外。
* 一些系统打开了探测系统内存资源使用能力的功能，因为打开了 PAE支持，这些功能可能会被覆盖掉。 其中一个例子就是内核参数``kern.maxvnodes``，它是控制 内核能使用的最大vnodes数目的，建议重新调整它及其他类似参数到合适的值。
* 为了避免KVA的消耗，很有必要增加系统的内核虚拟地址， 或者减少很耗系统资源的内核选项的总量（看上面）。``KVA_PAGES``选项 可以用来增加KVA空间。 

为了稳定和高性能，建议查看man:tuning[7]手册页。man:pae[4]手册页包含 FreeBSD'sPAE支持的最新信息。 

[[kernelconfig-trouble]]
== 如果出现问题怎么办

在定制一个内核时，可能会出现四种问题。它们是：

``config``失败：::
如果 man:config[8] 在给出您的内核描述时失败， 则可能在某些地方引入了一处小的错误。 幸运的是， man:config[8] 会显示出它遇到问题的行号， 这样您就能够迅速地定位错误。 例如， 如果您看到：
+
[source,bash]
....
config: line 17: syntax error
....
+
可以通过与 [.filename]#GENERIC# 或其他参考资料对比， 来确定这里的关键词是否拼写正确。

``make``失败：::
如果 `make` 命令失败， 它通常表示内核描述中发生了 man:config[8] 无法找出的的错误。 同样地， 仔细检查您的配置， 如果仍然不能解决问题， 发一封邮件到 {freebsd-questions} 并附上您的内核配置， 则问题应该很快就能解决。

内核无法启动：[[kernelconfig-noboot]]::
如果您的内核无法启动， 或不识别您的设备， 千万别慌！ 非常幸运的是， FreeBSD 有一个很好的机制帮助您从不兼容的内核恢复。 在 FreeBSD 启动加载器那里简单地选择一下要启动的内核就可以了。 当系统在引导菜单的 10 秒倒计时时进入它， 方法是选择 "Escape to a loader prompt" 选项， 其编号为 6。 输入 `unload kernel`， 然后输入 `boot /boot/kernel.old/kernel`， 或者其他任何一个可以正确引导的内核即可。 当重新配置内核时， 保持一个已经证明能够正常启动的内核永远是一个好习惯。
+
当使用好的内核启动之后您可以检查配置文件并重新尝试编译它。 比较有用的资源是 [.filename]#/var/log/messages# 文件， 它会记录每次成功启动所产生的所有内核消息。 此外， man:dmesg[8] 命令也会显示这次启动时产生的内核消息。
+
[NOTE]
====
如果在编译内核时遇到麻烦， 请务必保留一个 [.filename]#GENERIC# 或已知可用的其他内核， 并命名为别的名字以免在下次启动时被覆盖。 不要依赖 [.filename]#kernel.old# 因为在安装新内核时， [.filename]#kernel.old# 会被上次安装的那个可能不正常的内核覆盖掉。 另外， 尽快把可用的内核挪到 [.filename]#/boot/kernel# 否则类似 man:ps[1] 这样的命令可能无法正常工作。 为了完成这一点， 需要修改目录的名字：

[source,bash]
....
# mv /boot/kernel /boot/kernel.bad
# mv /boot/kernel.good /boot/kernel
....

====

内核工作，但是man:ps[1]根本不工作:::
如果您安装了一个与系统中内建工具版本不同的内核， 例如在 -STABLE 系统上安装了 -CURRENT 的内核， 许多用于检查系统状态的工具如 man:ps[1] 和 man:vmstat[8] 都将无法正常使用。 您应该 crossref:cutting-edge[makeworld,重新编译一个和内核版本一致的系统]。 这也是为什么一般不鼓励使用与系统其他部分版本不同的内核的一个主要原因。
