Aus Linux-Magazin 02/2007

Vorbereitung auf die LPIC-1 Prüfung: Teil 7

©Alexander Chelmodeev, Fotolia

Den Kernel kompilieren war viele Jahre lang ein zentraler Aspekt der erfolgreichen Linux-Administration. Dank des modularen Kerns ist heute oft der Einsatz eines Standardsystems möglich, aber spätestens wenn ein wichtiges Patch in den Kernel soll, führt kein Weg an den Linux-Sourcen vorbei.

Um LPI-geprüfter Linux-Administrator zu werden, sind im Rahmen des Examens 102 auch Kenntnisse über den Kernel und dessen Module notwendig. Welche Themengebiete hier relevant sind, hat das LPI in der Aufgabengruppe 1.105 festgelegt [1]. Im Wesentlichen geht es um die Beherrschung des Umgangs mit Modulen (also das Laden und Entladen sowie um Automatisierungen dieses Vorgangs) und das gekonnte Übersetzen des Kernels aus den Quellen.

Alles modular

Der Linux-Kernel ist modularisiert, das bedeutet: Seine Komponenten finden sich nicht in der eigentlichen Kerneldatei (»vmlinuz«), die der Bootloader beim Systemstart von der Platte lädt und initialisiert, sondern sie stehen als separate Moduldateien mit den Dateiendungen ».ko« (Kernel Object File) oder ».o« für ältere Kernelversionen bereit, die das System bei Bedarf automatisch nachlädt. Alternativ erledigt der Administrator das manuell. Module werden dadurch Teil des Kernels; es spielt keine (wesentliche) Rolle, ob sie fest einkompiliert oder dynamisch nachgeladen werden.

Der große Vorteil dieses Modells ist, dass beim Kompilieren des Kernels mit Standardvorgaben ein schlanker Basiskernel entsteht, der nur die wichtigsten Komponenten enthält. Zusammen mit den über 1000 Modulen ist das Paket dann auf sehr vielen Systemen lauffähig und unterstützt eine große Zahl von Geräten, ohne sämtliche Treiber unnütz im Speicher zu halten.

In einigen Situationen scheint der Ansatz problematisch: Wenn beispielsweise ein spezieller SCSI- oder IDE-Adapter einen Treiber benötigt, der kein fester Teil des Kernels ist, weiß der frisch gebootete Kernel nicht, wie er die Festplatte ansprechen kann, um das Root-Dateisystem zu mounten, auf dem der Treiber für den Controller liegt. Eine Initial-RAM-Disk löst dieses Problem: Alle Module, die das System noch vor dem Einbinden von »/« laden muss, landen in diesem Dateisystem, der Bootmanager bindet es zusammen mit dem Kernel ein.

Informationsbedarf

Eine schnelle Auskunft über die Kernelversion gibt der Befehl »uname« (Unix Name); das funktioniert auch auf anderen Unix-Systemen. Meist ist nur die Versionsnummer interessant, dann reicht »uname -r« (Release), um beispielsweise die Antwort »2.6.11.4-20a-default« zu erhalten. Maximale Informationen gibt das Tool aus, wenn der Benutzer den Parameter »-a« (all) einsetzt, etwa:

$ uname -a
Linux amd64 2.6.11.4-20a-default #1 Wed Mar 23 21:52:37 UTC 2005 i686 athlon i386  GNU/Linux

Die genaue Bezeichnung der Version und das Kompilierdatum geben auch Hinweise darauf, ob es sich um einen Standardkernel des Linux-Distributors oder um einen selbst gebauten handelt. Zu wissen, welcher Kernel läuft, ist aber nur die halbe Miete, denn für einen Großteil der Funktionalität sind die Module zuständig. Der Befehl »lsmod« zeigt alle aktuell geladenen Module mit einigen Statusinformationen (Abbildung 1). Taucht ein gesuchter Eintrag hier nicht auf, kann das dreierlei bedeuten:

  • Der betreffende Treiber ist fester Bestandteil des Kernels.
  • Der Kernel-Übersetzer hat ein Modul erzeugt, das noch nicht geladen ist.
  • Der Support für diese Funktion ist vollständig deaktiviert.

Unter manchen Modulen bestehen Abhängigkeiten. Das bedeutet, dass bestimmte Module vor anderen zu laden sind. Für jede Kernelversion erstellt das Kommando »depmod« eine Datei »/lib/modules/Kernelversion/modules.dep« (also etwa »/lib/modules/2.6.11.4-20a-default/modules.dep«), mit deren Hilfe das weiter unten beschriebene Kommando »modprobe« die Abhängigkeiten auflöst und alle zusätzlich benötigten Module gleich mitlädt.

LPI-Aufgabengruppen

Das Linux Professional Institute gliedert die Prüfungsfragen in Aufgabengruppen. Dieser Artikel erklärt die Abschnitte:

  • 1.105.1 Verwalten/Abfragen des Kernels und der Kernelmodule zur Laufzeit
  • 1.105.2 Konfiguration, Erstellung und Installation eines angepassten Kernels und von Kernelmodulen
Abbildung 1: Die Ausgabe von »lsmod« verrät nicht nur, welche Kernelmodule geladen sind, sondern zeigt auch an, welche Abhängigkeiten untereinander bestehen.

Abbildung 1: Die Ausgabe von »lsmod« verrät nicht nur, welche Kernelmodule geladen sind, sondern zeigt auch an, welche Abhängigkeiten untereinander bestehen.

Modul-Informationen

Das Tool »modinfo« gibt einige hilfreicher Informationen über Module aus: Es verrät, welche Parameter ein Modul bietet und welche Abhängigkeiten von anderen Modulen bestehen (Abbildung 2). Über den Parameter »-F« (Field) ist es auch möglich, einzelne Felder abzufragen, beispielsweise nur die Abhängigkeiten (»depends«) oder die Beschreibung (»description«). Hier das Feld »filename« anzugeben ist auch eine schnelle Methode, den vollen Pfadnamen eines Moduls herauszufinden.

Abbildung 2: Für einen schnellen Überblick über ein bestimmtes Modul eignet sich das Tool »modinfo«: Es gibt neben dem vollen Pfad auch Autor, Beschreibung, Lizenz sowie Abhängigkeiten von anderen Modulen aus.

Abbildung 2: Für einen schnellen Überblick über ein bestimmtes Modul eignet sich das Tool »modinfo«: Es gibt neben dem vollen Pfad auch Autor, Beschreibung, Lizenz sowie Abhängigkeiten von anderen Modulen aus.

Unter Kernel 2.4.x hat das Tool andere Optionen, bietet aber die gleichen Features; Details verrät die Manpage. Systeme, die für eine Parallelinstallation der Kernel 2.4 und 2.6 vorbereitet sind, stellen die Manpage meist unter »modinfo.modutils(8)« zur Verfügung.

Module laden und entladen

Um Module im laufenden Betrieb zu laden, stehen zwei Kommandos bereit: »insmod« (insert Module) ist der spartanische Klassiker, »modprobe« die komfortable Alternative. Beide Programme benötigen Root-Rechte, denn nur der Administrator darf (über das Laden von Modulen) Veränderungen am laufenden Kernel vornehmen.

Ein Aufruf von »insmod« lädt ein einzelnes Modul. Das Kommando erwartet dabei den vollen Pfad zur Moduldatei. Falls diese von weiteren Modulen abhängt, die noch nicht geladen wurden, schlägt der Aufruf fehl:

# insmod /lib/modules/2.6.8-2-686/kernel/fs/msdos/msdos.ko
insmod: error inserting '/lib/modules/2.6.8-2-686/kernel/fs/msdos/msdos.ko': -1 Unknown symbol in module

Im Beispiel fehlt das Modul »fat.ko«; die richtige Reihenfolge wäre, zunächst »fat.ko« und dann »msdos.ko« zu laden.

Meist ist daher »modprobe« das Tool der Wahl: Es löst Abhängigkeiten automatisch auf und erfordert auch nicht die Angabe des vollen Pfads; für das obige Beispiel reicht etwa »modprobe msdos«, um die Module »fat.ko« und »msdos.ko« zu laden. Über den Parameter »-v« (verbose) zeigt »modprobe« dann auch gleich an, welche Module es (mit »insmod«) lädt:

# modprobe -v msdos
insmod /lib/modules/2.6.8-2-686/kernel/fs/fat/fat.ko
insmod /lib/modules/2.6.8-2-686/kernel/fs/msdos/msdos.ko

Um Module wieder zu entladen, kommen wahlweise »rmmod« oder wiederum »modprobe« – diesmal mit der Option »-r« (remove) – zum Einsatz. Dabei ist »rmmod« ein ähnlich rudimentäres Tool wie »insmod«. In beiden Fällen ist es nur nötig, den Modulnamen (ohne Endung ».ko«) anzugeben. Doch während »rmmod« lediglich das im Aufruf genannte Modul entlädt, geht »modprobe« einen Schritt weiter und sucht zusätzlich Module, die der Kernel nach dem Entladen nicht mehr benötigt. Diese entfernt es dann ebenfalls.

Module konfigurieren

Besondere Optionen, die »modprobe« beim Laden eines Moduls angeben sollte, legt der Administrator über Einträge in der Modul-Konfigurationsdatei »/etc/modules.conf« fest. Um beispielsweise ein Modul »rtl123« (für eine fiktive Netzwerkkarte) stets mit den Optionen »io=0x200 irq=9« zu laden, müsste in »modules.conf« der Eintrag »options rtl123 io=0x200 irq=9« stehen. Zeilen, die mit »pre-install«, »post-install«, »pre-remove« und »post-remove« beginnen, veranlassen »modprobe« vor und nach dem Laden und Entladen zusätzliche Befehle auszuführen, etwa Starten und Stoppen eines Daemons, der für den Betrieb eines Geräts nötig ist.

In der gleichen Konfigurationsdatei dürfen auch Aliasnamen für Module stehen: Wer etwa zwei Netzwerkkarten verwendet, die ähnlich benannte Module wie »3c501« und »3c509« einsetzen, vermeidet mögliche Verwechslungen, wenn es die Alias-Einträge »eth0« und »eth1« gibt. Das erledigen die zwei Zeilen

alias eth0 3c501
alias eth1 3c509

in der Konfigurationsdatei. Danach ist auch ein Aufruf der Form »modprobe eth0« möglich.

Kernel kompilieren

Den Linux-Kernel neu übersetzen ist eine der traditionelleren Aufgaben des Linux-Administators. Sie ist ein wenig aus der Mode gekommen: Seit die Kernelentwickler Module eingeführt haben, reicht in den meisten Fällen ein Standardkernel aus. Auch das weitgehende Verschwinden von PCs mit ISA-Karten hat einen Beitrag dazu geleistet: Die in den Anfangszeiten von Linux vorherrschende Situation (keine Module, viele ISA-Karten) war besonders problematisch, weil ISA-Karten in der Regel genaue Informationen über verwendete Interrupts und Adressenbereiche benötigen, um zu funktionieren. Für die LPI-Prüfung sind Kenntnisse zur ISA-Konfiguration auch heute relevant: Es gibt noch alte Server mit ISA-Karten.

Das Kernel-Quellverzeichnis sollte immer »/usr/src/linux« heißen. Wer die Quellen mehrerer Linux-Versionen parallel vorrätig halten will, legt die verschiedenen Quellcodes in Verzeichnisse mit Versionsnummern ab (etwa »/usr/src/linux-2.6.20«) und erzeugt einen symbolischen Link »/usr/src/linux« auf das zu verwendende Kernelverzeichnis.

Wie bei normaler Software auch, beginnt die Kernelkompilierung mit der Konfiguration der Quellen. Statt des üblichen »./configure«-Skripts, das selbstständig arbeitet, ist hier Handarbeit gefragt. Traditionalisten starten die Konfiguration mit »make config« im Wurzelverzeichnis der Kernelquellen (»/usr/src/linux/«) und beantworten eine große Anzahl Fragen mit Y (ja), N (nein) oder M (Modul erstellen), vereinzelt fragt das Skript auch nach konkreten Werten.

Deutlich komfortabler sind die beiden Konfigurationshilfen, die ein »make menuconfig« oder »make xconfig« (Abbildungen 3 und 4) auf den Schirm zaubern: Sie fassen alle Optionen in Untermenüs oder einer Baumansicht zusammen. Die »xconfig«-Version ist Qt-basiert, benötigt also einen laufenden X-Server. Für GTK-Anhänger gibt es mit »make gconfig« eine Alternative zur Qt-Version.

Abbildung 3: Am komfortabelsten ist die Kernelkonfiguration über das Qt-Frontend, das nach »make xconfig« erscheint. Im dreiteiligen Fenster erscheint zu vielen Kerneloptionen ein kurzer Dokumentationsblock.

Abbildung 3: Am komfortabelsten ist die Kernelkonfiguration über das Qt-Frontend, das nach »make xconfig« erscheint. Im dreiteiligen Fenster erscheint zu vielen Kerneloptionen ein kurzer Dokumentationsblock.

Abbildung 4: Über »make menuconfig« startet der Administrator eine Alternative zur X-basierten Kernelkonfiguration. Die Hilfetexte sind auch hier verfügbar.

Abbildung 4: Über »make menuconfig« startet der Administrator eine Alternative zur X-basierten Kernelkonfiguration. Die Hilfetexte sind auch hier verfügbar.

Konfiguration recyceln

Wer bereits eine ältere Kernelversion übersetzt und das alte Kernelverzeichnis noch nicht gelöscht hat, spart Zeit und Handarbeit, indem er die alte Konfiguration übernimmt: Nach dem Kopieren der Datei ».config« aus dem alten Sourcenverzeichnis ins neue passt »make oldconfig« die Datei an die neuen Verhältnisse an. Sind die nötigen Anpassungen abgeschlossen, folgt die eigentliche Übersetzung: Mit »make && make modules« erzeugt der Systemverwalter in einem Rutsch den Kernel und alle ausgewählten Module. Bei älteren Kernelversionen ist übrigens das Make-Target »bzImage« dafür zuständig, die Kerneldatei zu erstellen.

Wenn auf dem Rechner Lilo als Bootmanager arbeitet, führt »make install« dazu, dass der Kernel am richtigen Ort landet und Lilo den Bootsektor neu schreibt, sodass er beim nächsten Systemstart den neuen Kernel verwendet. Grub-Benutzer kopieren den frisch gebauten Kernel (»bzImage«) aus dem Verzeichnis »arch/i386/boot« nach »/boot« und passen die Grub-Konfiguration an.

Der Dateiname »bzImage« deutet übrigens nicht auf ein »bzip2«-komprimiertes Kernelimage hin; das b steht für big. In älteren Kernelversionen gab es Kerneldateien in zwei Größen, normale »zImage« und größere »bzImage«, heute gibt es die kleine Variante nicht mehr.

Alles drin

Der Befehl »make modules_install« beendet die Installation, indem er auch noch die Module an ihren richtigen Ort (im Verzeichnis »/lib/modules/Kernelversion«) bringt. Sowohl für »make modules_install« als auch für das Kopieren des Kernels sind Root-Rechte erforderlich, alle anderen Schritte darf auch ein normaler Anwender ausführen. Meist scheitert das allerdings daran, dass im Verzeichnis »/usr/src/linux/« nur Root Schreibrechte hat.

Kaum ein Linux-Distributor liefert den Kernel im Originalzustand aus; stattdessen ist es üblich, dass die Hersteller eigene Patches in die Kernelquellen integrieren. Diese Patches sind teilweise mit Konfigurationswerkzeugen der Distributionen oder den Mechanismen für die Hardware-Erkennung verzahnt: Tauscht der Administrator dann den Distributor-Kernel gegen einen so genannten Vanilla-Kernel (also die Original-Kernelquellen), verursacht das oft Schwierigkeiten.

Das Wissen über Kernel und Module prägt sich am besten durch eigene Experimente mit den vorgestellten Tools ein.

Infos

[1] LPI-Seite mit den Prüfungsinhalten: [http://www1.lpi.org/de/obj_102.html]

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 3 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben