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.19 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.19 package has been installed. It contains /usr/src/linux-source-4.19.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.19.tar.xz

8.10.3. 配置内核

下个步骤是根据需要配置内核。确切的进程视需要而订。
重新编译较新版本的内核 (可能连同其补丁) 时,应尽量采用 Debian 建议的配置。在此情况下,与其从最基本开始重新编译,不妨复制 /boot/config-version 文件 (内核正在使用的版本,可以 uname -r 命令查看) 进入内核原始所在文件夹内的 .config 文件。
$ cp /boot/config-4.19.0-5-amd64 ~/kernel/linux-source-4.19/.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.19.37-falcot_4.19.37-1_amd64.deb
../linux-image-4.19.37-falcot_4.19.37-1_amd64.deb
../linux-libc-dev_4.19.37-1_amd64.deb

8.10.5. 编译外部模块

Some modules are maintained outside of the official Linux kernel. To use them, they must be compiled alongside the matching kernel. A number of common third party modules are provided by Debian in dedicated packages, such as vpb-driver-source (extra modules for Voicetronix telefony hardware) or leds-alix-source (driver of PCEngines ALIX 2/3 boards).
These packages are many and varied, apt-cache rdepends module-assistant$ can show the list provided by Debian. However, a complete list isn't particularly useful since there is no particular reason for compiling external modules except when you know you need it. In such cases, the device's documentation will typically detail the specific module(s) it needs to function under Linux.
For example, let's look at the dahdi-source package: after installation, a .tar.bz2 of the module's sources is stored in /usr/src/. While we could manually extract the tarball and build the module, in practice we prefer to automate all this using DKMS. Most modules offer the required DKMS integration in a package ending with a -dkms suffix. In our case, installing dahdi-dkms is all that is needed to compile the kernel module for the current kernel provided that we have the linux-headers-* package matching the installed kernel. For instance, if you use linux-image-amd64, you would also install linux-headers-amd64.
$ sudo apt install dahdi-dkms

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

dahdi_dummy.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.19.0-5-amd64/updates/dkms/
[...]
DKMS: install completed.
$ sudo dkms status
dahdi, DEB_VERSION, 4.19.0-5-amd64, x86_64: installed
$ sudo modinfo dahdi_dummy
filename:       /lib/modules/4.19.0-5-amd64/updates/dkms/dahdi_dummy.ko
license:        GPL v2
author:         Robert Pleh <robert.pleh@hermes.si>
description:    Timing-Only Driver
[...]

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-*/ 文件夹)。大部分的情况下,维护者会指出其补丁适用的内核版本。