8.10. 编译核心

Debian 的核心尽量纳入所有的功能,以及最多的驱动程序,以便涵盖现在的硬件配置。所以,有些用户宁愿自行编译只包括所需的核心。这么做有两个理由。第一,内存用量较小,核心代码,即使未用到,也占有内存的空间 (而且永远不 “离开” 置换内存,因为它用到实际的 RAM),降低系统的整体性能。本地自行编译的核心也限制了安全问题的范围,因为只编译与运行部分核心码。

说明 安全更新

决定编译自己的核心后,必须接受一个事实:Debian 不能确认客制化核心的安全更新。使用 Debian 的核心,可以使用 Debian 计划提供的更新。

使用只在补丁内的功能 (不在标准的核心内) 时,就必须重新编译核心。

进一步 The Debian Kernel Handbook

Debian 核心团队维护的 “Debian Kernel Handbook” (全文见 debian-kernel-handbook 软件包) 详述核心相关的工作与 Debian 核心软件包的处理方式。欲知可节所述事宜的详情,请参见此网址。

http://kernel-handbook.alioth.debian.org

8.10.1. 简介和先决条件

Debian 以软件包方式管理核心,与传统的编译安装不同调。核心还是在软件包系统的控制下,可以被完整移除,或布建在多个机器上。与该等软件包有关的脚本自动与启动程序和 initrd 产生器交互。

上游的 Linux 源代码包括建置 Debian 核心软件包所需的一切。但是仍可再安装 build-essential 以确保拥有创建 Debian 软件包所需的所有工具。而且,配置核心时需要 libncurses5-dev 软件包。最后,fakeroot 软件包将在不使用管理者权限的前提下,启用添加 Debian 软件包。

文化 kernel-package 的美好岁月

在 Linux 构建系统能够创建适当的 Debian 软件包前,使用 make-kpkg,来自 kernel-package 软件包。

8.10.2. 获取源代码

就像 Debian 系统内其他有用的东西,Linux 核心源代码也位在软件包内。只要安装 linux-source-version 软件包,就能取得全部的源代码。apt-cache search ^linux-source 命令行出 Debian 内各种版本的核心软件包。最新的版本在 Unstable 发行版内:可以毫不费力的取得 (尤其是把 APT 根据 第 6.2.6 节 “在多个发行版工作” 的指示配置后)。这些软件包内的源代码并未完全吻合 Linus Torvalds 与其他核心开发者发布的内容;如同其他的发行版,Debian 以一系列的补丁搭配,这些补丁可能 (或不可能) 以自己的方法纳入 Linux 上游的版本。包括从较新核心版本的 fixes/features/drivers 反向迁移,功能较新但尚未 (全部) 合并入上游的Linux 树,甚至 Debian 特别的改变。

本节其他内容以 Linux 核心 3.16 版为准,范例则不以此为限,可以调整为特定的核心版本。

假设 linux-source-3.16 软件包已安装好了。包括 /usr/src/linux-source-3.16.tar.xz,核心源代码的压缩档。在另个文件夹解缩 (不能直接在 /usr/src/ 之下,因为不需特别的授权就可以重新编译 Linux 核心):~/kernel/ 是个不错的选择。

  1. $

文化 核心源代码的位置

传统上,Linux 核心源代码置于 /usr/src/linux/,需要根权限才能编译。然而,管理者的权限就够了。src 群组的成员也可以使用该文件夹,但是应避免使用 /usr/src/。把核心源代码置于个人文件夹时,应把安全置于第一位:在 /usr/ 内的文件都应明确其在软件包系统内的作用,试图聚集使用核心的信息时,不能在读取 /usr/src/linux 时误导程序。

8.10.3. 配置核心

下个步骤是根据需要配置核心。确切的进程视需要而订。

重新编译较新版本的核心 (可能连同其补丁) 时,应尽量采用 Debian 建议的配置。在此情况下,与其从最基本开始重新编译,不妨复制 /boot/config-*version* 文件 (核心正在使用的版本,可以 uname -r 命令查看) 进入核心原始所在文件夹内的 .config 文件。

  1. $

需要改变配置的话,就跳至 第 8.10.4 节 “编译与创建软件包”。或者从基本开始重新配置,就需花时间配置核心。在核心源代码的文件夹内有很多专属接口,供调用 make *target* 命令,让 target 是下列的其中一个值。

make menuconfig 编译并运行文本模式接口 (即 libncurses5-dev 软件包必备) 以阶层结构浏览可用的选项。按 空格 键改变选定的值,并按屏幕下方的 Enter 钮;Select 送回选定的次菜单;Exit 关闭当前的屏幕并回到上个阶层;Help 显示选项的详细信息。箭头键在选项及按钮清单内动。按主菜单的 Exit 钮,就可离开配置程序。此程序可保存改变的配置;接受改变后的配置。

其他的接口也有类似的功能,但在现代化的图形接口运作;诸如 make xconfig 使用 Qt 图形接口,而 make gconfig 使手 GTK+。前者用到 libqt4-dev,后者依赖 libglade2-dev 与 libgtk2.0-dev。

使用这些配置接口时,建议从合理的缺省配置开始。提供该等配置的核心在 arch/*arch*/configs/*_defconfig,然后可将选定的配置置于像 make x86_64_defconfig (64 位电脑) 或 make i386_defconfig (32 位电脑) 这样的命令。

秘诀 处理过时的 .config 文件

使用其他 (通常是较旧的) 核心版本的 .config 文件时,需要先更新它。可以使用 make oldconfig 命令,以交互方式询问对新配置的选择。可以用 make olddefconfig 命令使用问题缺省的答案。以 make oldnoconfig 命令,可以对问题提供缺省的负面答案。

8.10.4. 编译与创建软件包

说明 创建前先清除

若已在文件夹内编译过,希望从基础重新创建 (或许更换核心配置),需运行 make clean 命令移除已编译的文件。make distclean 命令可移除更多的文件,包括客制的 .config 文件,别忘了先备份。

核心配置完成后,make deb-pkg 命令可产生至多 5 个 Debian 软件包:linux-image-version 包括核心映像与相关的模块,linux-headers-version 包括创建外部模块所需的头文件,linux-firmware-image-version 包括某些驱动程序所需的固件 (由 Debian 提供的核心源文件创建时,可能没有该软件包),linux-image-version-dbg 包括供软件包映像及其模块的调试符号,以及linux-libc-dev 包括 GNU glibc 之类与用户程序库相关的标头。

version 由并列的上游版本决定 (如同变量 VERSIONPATCHLEVELSUBLEVELEXTRAVERSIONMakefile 内所定)、并列的 LOCALVERSION 配置参数、以及并列的 LOCALVERSION 环境变量。软件包版本使用同版本字符串以及添加的附加版本 (并保存在 .version),除非以 KDEB_PKGVERSION 环境变量覆写它们。

  1. $

8.10.5. 编译外部模块

部分模块由 Linux 官方核心之外维护。使用时,必须与匹配的核心一起编译。若干常见的第三方模块由 Debian 指定软件包提供,诸如 xtables-addons-source (iptables 的外部模块) 或 oss4-source (Open Sound System,某些额外的音效驱动程序)。

这些外部软件包极多且杂,在此无法全部枚举;apt-cache search source$ 命令可缩小搜索的范围。然而,完整的清单没什么用处,只有明确知道需要时,才会编译特定的外部模块。在这个情况下,设备的文档会详述 Linux 环境所需的模块。

以 xtables-addons-source 软件包为例:安装之后,模块源文件 .tar.bz2 保存在 /usr/src/。可以手动解开该压缩档并创建模块,也可用 DKMS 自动做它。大部分模块提供必要的 DKMS 以 -dkms 后置文本集成入软件包。在本例中,安装 xtables-addons-dkms 就是为当前核心编译核心模块,前提是有匹配已安装核心的 linux-headers-* 软件包。例如,使用 linux-image-amd64,则应同时安装 linux-headers-amd64。

  1. $

其他 module-assistant

DKMS 出现以前,module-assistant 是创建与布署核心模块的最简单解决方案。目前还能用,特别是缺少 DKMS 集成的情况:以 module-assistant auto-install xtables-addons (或较短的 m-a a-i xtables-addons) 命令,就能编译出给当前核心使用的模𦈡,置于新的 Debian 软件包,让该软件包可以即时安装。

8.10.6. 选择内核补丁

因为不够成熟或核心维护者意见不一致,很多功能未列入标准的核心。这种功能就以补丁的型式发行,任何人都可以自由地把它维入核心源代码。

Debian 以 linux-patch-* 或 kernel-patch-* 方式散布这些软件包 (例如,linux-patch-grsecurity2,可以紧缩核心的安全政策)。这些软件包安装的文件在 /usr/src/kernel-patches/ 文件夹内。

在源文件文件夹内,以 patch 命令编译核心,就能够纳入前述安装的补丁。

  1. $

有些补丁不见得适用于每个核心版本;以 patch 可能无法应用于核心源代码。将出现错误消息且提示错误的原因;在此情况下,参照 Debian 补丁软件包的文档 (位于 /usr/share/doc/linux-patch-*/ 文件夹)。大部分的情况下,维护者会指出其补丁适用的核心版本。