Product SiteDocumentation Site

8.10. Einen Kernel kompilieren

Die von Debian bereitgestellten Kernel umfassen die größtmögliche Anzahl an Leistungsmerkmalen wie auch ein Maximum an Treibern, um ein möglichst breites Spektrum der existierenden Hardware-Konfigurationen abzudecken. Daher ziehen es einige Anwender vor, den Kernel neu zu kompilieren, um so genau nur das einzuschließen, was sie wirklich brauchen. Es gibt zwei Gründe für diese Entscheidung. Zum einen kann es darum gehen, den Speicherverbrauch zu optimieren, da der Kernelcode, selbst wenn er niemals gebraucht wird, unnötig Speicher belegt (und niemals in den Swap „hinuntergeht“, da es wirkliches RAM ist, das er benutzt), wodurch sich die Gesamtleistung des Systems verringern kann. Ein lokal kompilierter Kernel kann außerdem das Risiko von Sicherheitsproblemen reduzieren, da nur ein Bruchteil des Kernelcodes kompiliert wird und läuft.
Eine Rekompilierung des Kernels ist auch erforderlich, wenn Sie bestimmte Leistungsmerkmale verwenden möchten, die nur als Patches zur Verfügung stehen (und nicht in der Standardversion des Kernels enthalten sind).

8.10.1. Einführung und Voraussetzungen

Wenig überraschend verwaltet Debian den Kernel in Form eines Pakets, was nicht der üblichen Art und Weise entspricht, wie Kernel traditionell kompiliert und installiert wurden. Da der Kernel unter der Kontrolle des Paketierungssystems verbleibt, kann er dann sauber entfernt oder auf mehreren Rechnern eingesetzt werden. Darüber hinaus automatisieren die zu diesen Paketen gehörigen Skripten die Interaktion mit dem Boot-Loader und dem initrd-Generator.
The upstream Linux sources contain everything needed to build a Debian package of the kernel. But you still need to install build-essential to ensure that you have the tools required to build a Debian package. Furthermore, the configuration step for the kernel requires the libncurses-dev package (formerly libncurses5-dev, which is now a transitional package). Finally, the fakeroot package will enable creation of the Debian package without using administrator's rights.

8.10.2. Die Quellen besorgen

Wie alles, was auf einem Debian-System nützlich ist, stehen die Linux-Kernelquellen in einem Paket zu Verfügung. Um sie zu erhalten, installiert man einfach das Paket linux-source-Version. Der Befehl apt search ^linux-source führt die verschiedenen von Debian paketierten Kernelversionen auf. Die jüngste Version ist in der Distribution Unstable enthalten: Sie können sie ohne großes Risiko abrufen (insbesondere wenn Ihr APT in Übereinstimmung mit der Anleitung in Abschnitt 6.2.6, „Mit mehreren Distributionen arbeiten“ konfiguriert ist). Beachten Sie, dass der in diesen Paketen enthaltene Quellcode nicht genau dem von Linus Torvalds und den Kernel-Entwicklern veröffentlichten entspricht. Wie alle Distributionen, so wendet auch Debian eine Reihe von Patches an, die ihren Weg in die "Upstream"-Version von Linux finden (oder auch nicht). Diese Änderungen umfassen auch Rückportierungen von Korrekturen/Funktionalitäten/Treibern von neueren Kernel-Versionen, neuen Funktionalitäten, die noch nicht (vollständig) in den Ursprungszweig von Linux eingearbeitet sind und manchmal sogar Debian-spezifische Änderungen.
The remainder of this section focuses on the 5.10 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-5.10 package has been installed. It contains /usr/src/linux-source-5.10.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-5.10.tar.xz
To build a kernel from the pristine sources, just download the tarball of the version of your choice from kernel.org, verify the integrity after importing the kernel maintainers key, and then proceed as described in the following chapters.

$ wget https://kernel.org/pub/linux/kernel/v5.x/linux-5.10.62.tar.xz
[..]
$ wget https://kernel.org/pub/linux/kernel/v5.x/linux-5.10.62.tar.sign
[..]
$ unxz -c linux-5.10.62.tar.xz | gpg --verify linux-5.10.62.tar.sign -
gpg: Signature made Fri 03 Sep 2021 10:11:35 AM CEST
gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E
gpg: Good signature from "Greg Kroah-Hartman <gregkh@linuxfoundation.org>" [unknown]
gpg:                 aka "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg@kroah.com>" [unknown]
gpg:                 aka "Greg Kroah-Hartman <gregkh@kernel.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E

8.10.3. Den Kernel konfigurieren

Der nächste Schritt besteht darin, den Kernel Ihren Bedürfnissen entsprechend zu kompilieren. Das genaue Vorgehen hängt von den Zielen ab.
When recompiling a more recent version of the kernel (possibly with an additional patch), the configuration will most likely be kept as close as possible to that proposed by Debian. In this case, and rather than reconfiguring everything from scratch, it is sufficient to copy the /boot/config-version file (the version is that of the kernel currently used, which can be found with the uname -r command) into a .config file in the directory containing the kernel sources. Make sure to read sidebar TIP Missing debian/certs/debian-uefi-certs.pem in this case.
$ cp /boot/config-5.10.0-8-amd64 ~/kernel/linux-source-5.10/.config
Falls Sie die Konfiguration nicht zu ändern brauchen, können Sie hier aufhören und zu Abschnitt 8.10.4, „Das Paket kompilieren und erstellen“ springen. Falls Sie sie dagegen ändern müssen oder falls Sie sich dazu entschließen, alles von Grund auf neu zu konfigurieren, müssen Sie sich die Zeit nehmen, Ihren Kernel zu konfigurieren. Es gibt in dem Verzeichnis mit den Kernelquellen mehrere speziell hierfür vorgesehene Schnittstellen, die mit dem Aufruf des Befehls make Ziel verwendet werden können, wobei Ziel einer der unten beschriebenen Werte ist.
make menuconfig compiles and executes a text-mode interface (this is where the libncurses-dev package is required) which allows navigating the options available in a hierarchical structure. Pressing the Space key changes the value of the selected option, and Enter validates the button selected at the bottom of the screen; Select returns to the selected sub-menu; Exit closes the current screen and moves back up in the hierarchy; Help will display more detailed information on the role of the selected option. The arrow keys allow moving within the list of options and buttons. To exit the configuration program, choose Exit from the main menu. The program then offers to save the changes you've made; accept if you are satisfied with your choices.
Other interfaces have similar features, but they work within more modern graphical interfaces; such as make xconfig which uses a Qt graphical interface, and make gconfig which uses GTK+. The former requires qtbase5-dev, while the latter depends on libglade2-dev and libgtk2.0-dev.
Beim Benutzen dieser Konfigurationsschnittstellen ist es immer gut, von einer der Standardkonfigurationen auszugehen. Der Kernel stellt solche Konfigurationen in arch/arch/configs/*_defconfig und Sie können Ihre gewählte Konfiguartion z.B. mit dem Befehl make x86_64_defconfig (im Falle eines 64-bit-Systems) oder mit make i386_defconfig (Im Falle eines 32-bit-PCs) einbinden.

8.10.4. Das Paket kompilieren und erstellen

Once the kernel configuration is ready, a simple make deb-pkg will generate up to 5 Debian packages:
linux-image-version
contains the kernel image and the associated modules,
linux-headers-version
contains the header files required to build external modules,
linux-firmware-image-version
contains the firmware files needed by some drivers (this package might be missing when you build from the kernel sources provided by Debian),
linux-image-version-dbg
contains the debugging symbols for the kernel image and its modules (only created if CONFIG_DEBUG_INFO=y), and
linux-libc-dev
contains headers relevant to some user-space libraries like GNU glibc.
The version is defined by the concatenation of the upstream version (as defined by the variables VERSION, PATCHLEVEL, SUBLEVEL, and EXTRAVERSION in the Makefile), of the LOCALVERSION configuration parameter, and of the LOCALVERSION environment variable. The package version reuses the same version string with an appended revision that is regularly incremented (and stored in .version), except if you override it with the KDEB_PKGVERSION environment variable.
$ make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=$(make kernelversion)-1
[...]
$ ls ../*.deb
../linux-headers-5.10.46-falcot_5.10.46-1_amd64.deb
../linux-image-5.10.46-falcot_5.10.46-1_amd64.deb
../linux-image-5.10.46-falcot-dbg_5.10.46-1_amd64.deb
../linux-libc-dev_5.10.46-1_amd64.deb
The whole process requires around 20 GB of free space, at least 8 GB of RAM, and several hours of compilation (utilizing one core) for a standard amd64 Debian kernel. These requirements can be drastically reduced by disabling the debug information using CONFIG_DEBUG_INFO=n, but this will make it impossible to trace kernel errors (“oops”) using gdb and also stop the creation of the linux-image-version-dbg package.

8.10.5. Externe Module kompilieren

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 telephony hardware) or leds-alix-source (driver of PCEngines ALIX 2/3 boards).
Diese Pakete sind zahlreich und vielfältig, apt-cache rdepends module-assistant$ kann die von Debian bereitgestellte Liste anzeigen. Eine vollständige Liste ist jedoch nicht besonders nützlich, da es keinen besonderen Grund gibt, externe Module zu kompilieren, es sei denn, Sie wissen, dass Sie sie benötigen. In solchen Fällen wird die Dokumentation des Gerätes typischerweise das/die spezifische(n) Modul(e) ausführen, das/die es unter Linux benötigt, um zu funktionieren.
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 the DKMS framework (Dynamic Kernel Module Support). 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 dkms (2.8.4-3) ...
Setting up linux-headers-5.10.0-8-amd64 (5.10.46-4) ...
/etc/kernel/header_postinst.d/dkms:
dkms: running auto installation service for kernel 5.10.0-8-amd64:.
Setting up dahdi-dkms (1:2.11.1.0.20170917~dfsg-7.4) ...
Loading new dahdi-2.11.1.0.20170917~dfsg-7.4 DKMS files...
Building for 5.10.0-8-amd64
Building initial module for 5.10.0-8-amd64
Done.

dahdi_dummy.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.10.0-8-amd64/updates/dkms/

dahdi_dynamic_eth.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/5.10.0-8-amd64/updates/dkms/

[...]
DKMS: install completed.
$ sudo dkms status
dahdi, 2.11.1.0.20170917~dfsg-7.4, 5.10.0-8-amd64, x86_64: installed
$ sudo modinfo dahdi_dummy
filename:       /lib/modules/5.10.0-8-amd64/updates/dkms/dahdi_dummy.ko
license:        GPL v2
author:         Robert Pleh <robert.pleh@hermes.si>
description:    Timing-Only Driver
depends:        dahdi
retpoline:      Y
name:           dahdi_dummy
vermagic:       5.10.0-8-amd64 SMP mod_unload modversions 
parm:           debug:int

8.10.6. Einen Kernel-Patch anwenden

Einige Funktionen sind im Standardkernel nicht enthalten, da sie entweder noch nicht ausgereift sind, oder auch wegen fehlender Übereinstimmung mit dem Entwickler. Solche Funktionen können als Patches verteilt werden, die dann jeder auf die Kernelquellen anwenden kann.
Debian stellt manchmal einige dieser Patches in linux-patch-*-Paketen zur Verfügung, aber sie schaffen es oft nicht in stabile Veröffentlichungen (manchmal aus den gleichen Gründen, aus denen sie nicht in den offiziellen Upstream-Kernel eingebunden werden). Diese Pakete installieren Dateien im Verzeichnis /usr/src/kernel-patches/.
To apply one or more of these installed patches, use the patch command in the sources directory then start compilation of the kernel as described above. The following shows an old example using linux-patch-grsecurity2 and linux-source-4.9.
$ 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
Beachten Sie, dass ein bestimmter Patch nicht unbedingt mit jeder Kernelversion funktioniert; patch kann scheitern, wenn sie auf die Kernelquellen angewendet werden. Dann wird eine Fehlermeldung mit Einzelheiten zu diesem Fehlschlag angezeigt; in diesem Fall sollten Sie in der Dokumentation nachsehen, die im Debian-Paket des Patches zur Verfügung steht (im Verzeichnis /usr/share/doc/linux-patch-*/). Meistens gibt der Betreuer dort an, für welche Kernelversionen sein Patch gedacht ist.