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.
Die "Upstream"-Linux-Quellen enthalten alles, was Sie benötigen, um ein Debian Paket des Kernels zu bauen. Aber Sie müssen trotzdem build-essential installieren, um zu überprüfen, ob Sie die benötigten Werkzeuge zum Erstellen eines Linux-Kernels haben. Des weiteren benötigt der Schritt zur Konfiguration des Kernels das Paket libncurses5-dev. Und schlussendlich erlaubt das Paket fakeroot die Erstellung des Debian-Pakets, ohne dabei Administratorrechte zu verwenden.
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-cache 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ückwärtsportierungen von Korrekturen/Funktionalitäten/Treibern von neueren Kernel-Versionen, neuen Funktionalitäten, die noch nicht (vollständig) in den "Upstream"-Zweig von Linux eingearbeitet sind, und manchmal sogar debianspezifische Änderungen.
Der Rest dieses Abschnitts befasst sich mit der Version 3.2 des Linux-Kernels, aber die Beispiele können natürlich an jede gewünschte Kernel-Version angepasst werden.
Wir gehen davon aus, dass das Paket linux-source-3.2 installiert worden ist. Es enthält /usr/src/linux-source-3.2.tar.bz2
, ein komprimiertes Archiv der Kernelquellen. Sie müssen diese Dateien in ein neues Verzeichnis entpacken (nicht direkt in /usr/src/
, da besondere Berechtigungen für die Kompilierung eines Linux-Kernels nicht erforderlich sind): ~/kernel/
wäre geeignet.
$
mkdir ~/kernel; cd ~/kernel
$
tar -xjf /usr/src/linux-source-3.2.tar.bz2
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.
Wenn eine neuere Version des Kernels (möglicherweise mit einem zusätzlichen Patch) rekompiliert wird, wird die Konfigurierung höchstwahrscheinlich möglichst nah an der von Debian vorgeschlagenen gehalten werden. In diesem Fall, und anstatt alles von Grund auf neu zu konfigurieren, genügt es, die Datei /boot/config-version
(die Version entspricht der des zur Zeit verwendeten Kernels, die mit dem Befehl uname -r
gefunden werden kann) in eine Datei namens .config
im Verzeichnis, das die Kernelquellen enthält, zu kopieren.
$
cp /boot/config-3.2.0-4-amd64 ~/kernel/linux-source-3.2/.config
Falls Sie die Konfiguration nicht zu ändern brauchen, können Sie hier aufhören und zum nächsten Abschnitt 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
kompiliert eine Schnittstelle im Textmodus und führt sie aus (an dieser Stelle ist das Paket libncurses5-dev erforderlich), die es ermöglicht, durch die in einer hierarchischen Struktur verfügbaren Optionen zu navigieren. Ein Druck auf die Leer-Taste ändert den Wert der ausgewählten Option, und Enter bestätigt die am unteren Bildschirmrand ausgewählte Schaltfläche; Select geht zum ausgewählten Untermenü zurück; Exit schließt den aktuellen Bildschirm und kehrt aufwärts in die Hierarchie zurück; Help zeigt ausführlichere Informationen zur Rolle der ausgewählten Option an. Mit den Pfeiltasten ist es möglich, sich innerhalb der Liste von Optionen und Schaltflächen zu bewegen. Um das Konfigurierungsprogramm zu verlassen, wählt man Exit im Hauptmenü. Das Programm bietet dann an, die vorgenommenen Änderungen zu speichern; nehmen Sie diesen Vorschlag an, wenn Sie mit Ihrer Auswahl zufrieden sind.
Andere Schnittstellen verfügen über ähnliche Merkmale, arbeiten jedoch mit moderneren grafischen Schnittstellen, wie zum Beispiel make xconfig
, das eine grafische Schnittstelle auf der Basis von Qt verwendet, und make gconfig
, das GTK+ benutzt. Ersteres erfordert libqt4-dev, während Letzteres von libglade2-dev und libgtk2.0-dev abhängt.
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
Ist die Kernelkonfiguration fertig, generieren Sie mit make deb-pkg
bis zu fünf Debian-Pakete: linux-image-version
enthält das Kernelabbild und die zugehörigen Module, linux-headers-version
, das die Header-Dateien, die benötigt werden, um externe Module Module zu erstellen, linux-firmware-image-version
enthält die Firmware-Dateien, die von manchen Treibern benöigt werden, linux-image-version
-dbg mit den Symbolen für das Debugging der Kernel-Images und deren Module und linux-libc-dev, das die relevanten Header für einige Bibliotheken des User-Space, wie die glibc von GNU, bereithält.
Die Version
wird definiert durch das Zusammenfügen der "upstream"-Version (wie sie von den Variablen VERSION
, PATCHLEVEL
, SUBLEVEL
and EXTRAVERSION
in Makefile
) festgelegt wird, vom Konfigurationsparameter LOCALVERSION
, und von der Umgebungsvariable LOCALVERSION
. Die Paket-Version nutzt die gleiche Versionszeichenkette mit einer angehängten Revisionsnummer die regelmäßig erhöht (und in .version
gespeichert) wird, es sei denn, Sie überschreiben sie mit der Umgebungsvariable KDEB_PKGVERSION
.
$
make deb-pkg LOCALVERSION=-falcot KDEB_PKGVERSION=1
[...]
$
ls ../*.deb
../linux-firmware-image-3.2.46-falcot_1_amd64.deb
../linux-headers-3.2.46-falcot_1_amd64.deb
../linux-image-3.2.46-falcot_1_amd64.deb
../linux-image-3.2.46-falcot-dbg_1_amd64.deb
../linux-libc-dev_1_amd64.deb
8.10.5. Externe Module kompilieren
Einige Module werden außerhalb des offiziellen Linux-Kernels verwaltet. Um sie verwenden zu können, müssen sie neben dem passenden Kernel kompiliert werden. Eine Anzahl gebräuchlicher Fremdmodule wird von Debian in speziellen Paketen bereitgestellt: virtualbox-source (Kernel-Unterstützung für die Virtualisierungslösung VirtualBox) oder oss4-source (Open Sound System, einige alternative Audiotreiber).
Diese externen Pakete sind zahlreich und vielfältig, und wir werden sie hier nicht alle aufführen; der Befehl apt-cache search source$
kann den Suchbereich eingrenzen. Jedoch ist eine vollständige Liste nicht sehr nützlich, da es keinen besonderen Grund gibt, externe Module zu kompilieren, außer wenn Sie wissen, dass Sie sie benötigen. In diesen Fällen führt die Dokumentation des Geräts normalerweise die einzelnen Module auf, die es benötigt, um unter Linux zu funktionieren.
Schauen wir beispielsweise auf das virtualbox-source-Paket: nach der Installation wird ein .tar.bz2
mit den Quellen der Module in /usr/src/
abgelegt. Obwohl wir das tar-Paket händisch entpacken und das Modul erzeugen könnten, tun wir das in der Praxis lieber automatisch mittels DKMS. Die meisten Module bieten bereits die nötige DKMS-Integration in einem Paket mit der Endung -dkms
an. In unserem Fall müssen wir lediglich virtualbox-dkms installieren um das Kernelmodul für den aktuellen Kernel zu übersetzen, vorausgesetzt, wir haben das Paket linux-headers-* passend zum installierten Kernel. Wenn Sie beispielsweise linux-image-amd64 benutzen, würden Sie entsprechend linux-headers-amd64 installieren.
$
sudo apt-get install virtualbox-dkms
[...]
Loading new virtualbox-4.1.18 DKMS files...
First Installation: checking all kernels...
Building only for 3.2.0-4-amd64
Building initial module for 3.2.0-4-amd64
Done.
vboxdrv:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/3.2.0-4-amd64/updates/dkms/
[...]
DKMS: install completed.
$
sudo dkms status
virtualbox, 4.1.18, 3.2.0-4-amd64, x86_64: installed
virtualbox-guest, 4.1.18, 3.2.0-4-amd64, x86_64: installed
$
sudo modinfo vboxdrv
filename: /lib/modules/3.2.0-4-amd64/updates/dkms/vboxdrv.ko
version: 4.1.18_Debian (0x00190000)
license: GPL
description: Oracle VM VirtualBox Support Driver
[...]
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 verbreitet einige dieser Patches in den Paketen linux-patch-* und kernel-patch-* (zum Beispiel linux-patch-grsecurity2, das einige der Sicherheitsrichtlinien des Kernels verschärft). Diese Pakete installieren Dateien in das Verzeichnis /usr/src/kernel-patches/
.
Um einen oder mehrere dieser installierten Patches anzuwenden, rufen Sie den Befehl patch
im Quellenverzeichnis auf und beginnen dann wie oben beschrieben mit der Kompilierung des Kernels.
$
cd ~/kernel/linux-source-3.2
$
make clean
$
zcat /usr/src/kernel-patches/diffs/grsecurity2/grsecurity-2.9.1-3.2.21-201206221855.patch.gz | patch -p1
$
make deb-pkg LOCALVERSION=-grsec
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.