8.10. 编译核心

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

说明 安全更新

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

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

进一步 The Debian Kernel Handbook

The Debian kernel team maintains the “Debian Kernel Handbook” (also available in the debian-kernel-handbook package) with comprehensive documentation about most kernel related tasks and about how official Debian kernel packages are handled. This is the first place you should look into if you need more information than what is provided in this section.

https://kernel-team.pages.debian.net/kernel-handbook/

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. 获取源代码

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.

  1. $

文化 核心源代码的位置

Traditionally, Linux kernel sources would be placed in /usr/src/linux/ thus requiring root permissions for compilation. However, working with administrator rights should be avoided when not needed. There is a src group that allows members to work in this directory, but working in /usr/src/ should be avoided, nevertheless. By keeping the kernel sources in a personal directory, you get security on all counts: no files in /usr/ unknown to the packaging system, and no risk of misleading programs that read /usr/src/linux when trying to gather information on the used kernel.

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. 编译与创建软件包

说明 创建前先清除

If you have already compiled once in the directory and wish to rebuild everything from scratch (for example, because you substantially changed the kernel configuration), you will have to run make clean to remove the compiled files. make distclean removes even more generated files, including your .config file too, so make sure to backup it first. If you copied the configuration from /boot/, you must change the system trusted keys option, providing an empty string is enough: CONFIG_SYSTEM_TRUSTED_KEYS = "".

核心配置完成后,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. 编译外部模块

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.

  1. $

其他 module-assistant

Before DKMS, module-assistant was the simplest solution to build and deploy kernel modules. It can still be used, in particular for packages lacking DKMS integration: with a simple command like module-assistant auto-install dadhi (or m-a a-i dahdi for short), the modules are compiled for the current kernel, put in a new Debian package, and that package gets installed on the fly.

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 命令编译核心,就能够纳入前述安装的补丁。

  1. $

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