Product SiteDocumentation Site

8.10. 编译核心

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

8.10.1. 简介和先决条件

Debian 以软件包方式管理核心,与传统的编译安装不同调。核心还是在软件包系统的控制下,可以被完整移除,或布建在多个机器上。与该等软件包有关的脚本自动与启动程序和 initrd 产生器交互。
上游的 Linux 源代码包括建置 Debian 核心软件包所需的一切。但是仍可再安装 build-essential 以确保拥有创建 Debian 软件包所需的所有工具。而且,配置核心时需要 libncurses5-dev 软件包。最后,fakeroot 软件包将在不使用管理者权限的前提下,启用添加 Debian 软件包。

8.10.2. 获取源代码

Like anything that can be useful on a Debian system, the Linux kernel sources are available in a package. To retrieve them, just install the linux-source-version package. The apt search ^linux-source command lists the various kernel versions packaged by Debian. The latest version is available in the Unstable distribution: you can retrieve them without much risk (especially if your APT is configured according to the instructions of 第 6.2.6 节 “在多个发行版工作”). Note that the source code contained in these packages does not correspond precisely with that published by Linus Torvalds and the kernel developers; like all distributions, Debian applies a number of patches, which might (or might not) find their way into the upstream version of Linux. These modifications include backports of fixes/features/drivers from newer kernel versions, new features not yet (entirely) merged in the upstream Linux tree, and sometimes even Debian specific changes.
The remainder of this section focuses on the 4.9 version of the Linux kernel, but the examples can, of course, be adapted to the particular version of the kernel that you want.
We assume the linux-source-4.9 package has been installed. It contains /usr/src/linux-source-4.9.tar.xz, a compressed archive of the kernel sources. You must extract these files in a new directory (not directly under /usr/src/, since there is no need for special permissions to compile a Linux kernel): ~/kernel/ is appropriate.
$ mkdir ~/kernel; cd ~/kernel
$ tar -xaf /usr/src/linux-source-4.9.tar.xz

8.10.3. 配置核心

下个步骤是根据需要配置核心。确切的进程视需要而订。
重新编译较新版本的核心 (可能连同其补丁) 时,应尽量采用 Debian 建议的配置。在此情况下,与其从最基本开始重新编译,不妨复制 /boot/config-version 文件 (核心正在使用的版本,可以 uname -r 命令查看) 进入核心原始所在文件夹内的 .config 文件。
$ cp /boot/config-4.9.0-3-amd64 ~/kernel/linux-source-4.9/.config
需要改变配置的话,就跳至 第 8.10.4 节 “编译与创建软件包”。或者从基本开始重新配置,就需花时间配置核心。在核心源代码的文件夹内有很多专属接口,供调用 make target 命令,让 target 是下列的其中一个值。
make menuconfig 编译并运行文本模式接口 (即 libncurses5-dev 软件包必备) 以阶层结构浏览可用的选项。按 空格 键改变选定的值,并按屏幕下方的 Enter 钮;Select 送回选定的次菜单;Exit 关闭当前的屏幕并回到上个阶层;Help 显示选项的详细信息。箭头键在选项及按钮清单内动。按主菜单的 Exit 钮,就可离开配置程序。此程序可保存改变的配置;接受改变后的配置。
其他的接口也有类似的功能,但在现代化的图形接口运作;诸如 make xconfig 使用 Qt 图形接口,而 make gconfig 使手 GTK+。前者用到 libqt4-dev,后者依赖 libglade2-devlibgtk2.0-dev
使用这些配置接口时,建议从合理的缺省配置开始。提供该等配置的核心在 arch/arch/configs/*_defconfig,然后可将选定的配置置于像 make x86_64_defconfig (64 位电脑) 或 make i386_defconfig (32 位电脑) 这样的命令。

8.10.4. 编译与创建软件包

核心配置完成后,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 环境变量覆写它们。
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-4.9.30-ckt4-falcot_4.9.30-1_amd64.deb
../linux-image-4.9.30-ckt4-falcot_4.9.30-1_amd64.deb
../linux-image-4.9.30-ckt4-falcot-dbg_4.9.30-1_amd64.deb
../linux-libc-dev_4.9.30-1_amd64.deb

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
$ sudo apt install xtables-addons-dkms

[...]
Setting up xtables-addons-dkms (2.12-0.1) ...
Loading new xtables-addons-2.12 DKMS files...
Building for 4.9.0-3-amd64
Building initial module for 4.9.0-3-amd64
Done.

xt_ACCOUNT:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.9.0-3-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
xtables-addons, 2.12, 4.9.0-3-amd64, x86_64: installed
$ sudo modinfo xt_ACCOUNT
filename:       /lib/modules/4.9.0-3-amd64/updates/dkms/xt_ACCOUNT.ko
license:        GPL
alias:          ipt_ACCOUNT
author:         Intra2net AG <opensource@intra2net.com>
description:    Xtables: per-IP accounting for large prefixes
[...]

8.10.6. 选择内核补丁

因为不够成熟或核心维护者意见不一致,很多功能未列入标准的核心。这种功能就以补丁的型式发行,任何人都可以自由地把它维入核心源代码。
Debian sometimes provides some of these patches in linux-patch-* packages but they often don't make it into stable releases (sometimes for the very same reasons that they are not merged into the official upstream kernel). These packages install files in the /usr/src/kernel-patches/ directory.
在源文件文件夹内,以 patch 命令编译核心,就能够纳入前述安装的补丁。
$ cd ~/kernel/linux-source-4.9
$ make clean
$ zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-3.1-4.9.11-201702181444.patch.gz | patch -p1
有些补丁不见得适用于每个核心版本;以 patch 可能无法应用于核心源代码。将出现错误消息且提示错误的原因;在此情况下,参照 Debian 补丁软件包的文档 (位于 /usr/share/doc/linux-patch-*/ 文件夹)。大部分的情况下,维护者会指出其补丁适用的核心版本。