8.2. 为什么要编译自定义内核

传统上,FreeBSD 使用的是一个宏内核。内核是一个很大的程序,有一个固定支持的设备列表,如果要改变内核的行为,必须先编译再重新启动进入新的内核。

在今天,FreeBSD 内核中的大部分功能都包含在模块中,必要时可以动态地从内核中加载和卸载模块。这使得运行中的内核能够立即适应新的硬件,并将新的功能带入内核。这就是所谓的模块化内核。

偶尔仍有必要进行静态的内核配置。有时,需要的功能与内核紧密相连,以至于不能动态加载。一些安全环境阻止内核模块的加载和卸载,并要求只将需要的功能静态地编译到内核中。

对于高级 BSD 用户来说,编译一个自定义的内核通常是一种仪式。这个过程虽然很耗时,但可以为 FreeBSD 系统带来好处。与必须支持各种硬件的 GENERIC 内核不同,定制的内核可以被调整为只对该计算机的硬件提供支持。这有很多好处,例如:

  • 更快的启动时间。由于内核将只探测系统上的硬件,可以减少系统启动的时间。

  • 更少的内存使用。通过省略不使用的功能和设备驱动,自定义内核通常比 GENERIC 内核使用更少的内存。这一点很重要,因为内核代码在任何时候都驻留在物理内存中,这块空间应用程序无法使用。因此,定制的内核适合运行在拥有少量内存的系统上。

  • 额外的硬件支持。定制内核可以增加对 GENERIC 内核中没有的设备的支持。

在构建定制内核之前,先考虑这样做的原因。如果需要特定的硬件支持,它可能已经作为一个模块存在。

内核模块存在于 /boot/kernel 中,并可以使用 kldload(8)open in new window 将其动态加载到正在运行的内核中。大多数内核驱动都有一个可加载模块和手册页。例如,ath(4)open in new window 无线以太网驱动在其手册页中有如下信息:

Alternatively, to load the driver as a module at boot time, place the
following line in loader.conf(5):
    
if_ath_load="YES"

/boot/loader.conf 中添加 if_ath_load="YES" 将在启动时动态加载该模块。

在某些情况下,/boot/kernel 没有相关的模块。这主要是针对某些子系统而言的。