Kernel

Was ist ein Kernel?


Der Kernel stellt die Schnittstelle zwischen elementarer Hardware (unterste Ebene = Treiber) und dem System dar. Er regelt z.B. den Umgang mit dem Dateisystem oder einem CD-ROM-Laufwerk. Kurz gesagt, er ist der zentrale Teil des Systems, der "Kern". Deshalb bekam er wohl auch den Namen "Kernel".

Alles, was nicht im Kernel eingebunden oder einkompiliert ist, kann auch nicht benutzt werden. Wenn ich eine SCSI-Karte in meinen PC einbaue, kann ich sie nicht nutzen, wenn mir der Kernel keine Unterstützung in irgendeiner Weise bietet.

Diese Unterstützung kann auf 3 Arten erfolgen:

  1. fest: Die entsprechenden Treiber sind fest im Kernel eingebunden.

  2.  
  3. modular: Die Treiber werden als Module geladen, das heisst, sie werden zur Laufzeit eingebunden und entfernt. Um dies hat sich der Admin dann selbst zu kümmern (alles halb so wild!).

  4.  
  5. gar nicht: Das Gerät erhält keine/hat keine Unterstützung und hängt nutzlos im System rum, oder die entspechenden Treiber werden nicht benötigt.
nach oben

Wer braucht ein Kernelupdate?


Auf diese Frage kann ich nur einen Spruch zitieren, der damals im RedHat5.2 Benutzerhandbuch stand:

"Solange man nicht weiss, warum man einen Kernel updaten/kompilieren soll, braucht man es nicht zu tun!"

Dieser Meinung schließe ich mich an. Aber für all jene, die es nicht lassen können oder denken, sie bräuchten ein Kernelupdate, will ich das Thema kurz ansprechen:

  • Man hat neue Hardware gekauft (z.B. eine TV.Karte - so wars bei mir) die erst von neueren Kernel-Versionen richtig unterstützt wird.

  •  
  • Der neue Kernel hat ein Feature, von dem man überzeugt ist, es zu brauchen (z.B. Advanced-Powermanagement, damit sich der PC nach dem Herunterfahren automatisch ausschaltet).

  •  
  • Man will sein System anpassen/tunen/auf Vordermann bringen/schlanker machen - sprich: alles raus, was man nicht braucht. Standardkernel haben nämlich die Eigenschaft, auf fast allen Systemen zu laufen und sind folglich nicht speziell auf Deinen Rechner ausgerichtet und ziemlich groß. Aber ein angepasster Kernel läuft nur mit genau dem PC, auf den er abgestimmt ist. Dies ist v.a. dann problematisch, wenn man mal Hardware tauscht/aufrüstet. Denn dann muss der Kernel wieder neu angepasst werden.

  •  
  • Oder man will es einfach mal gemacht haben, um zu wissen, ob's schwer ist bzw., um mehr zu lernen
nach oben

Vorbereitung der Kernelkompilierung


Zunächst schauen wir, ob alles vorhanden ist, was wir benötigen. Die Kernelquellen und -Includes müssen installiert sein.

Die kompletten Kernelquellen finden wir bei ftp.kernel.org im Verzeichnis /pub/linux/kernel/v2.4. Wir können uns entscheiden, ob wir alle Patches auf die aktuelle Version oder alle Quellen holen wollen. Bei Patches ist darauf zu achten, dass man nacheinander alle Versionen von der vorhandenen bis zur aktuellen patchen muss. Im allgemeinen wird es also weniger Aufwand bedeuten, sich gleich die Kernelquellen zu holen.

Noch ein Hinweis: Die geraden Versionsnummern (zB. 2.4.x) sind stabile Kernel. Die ungeraden Versionsnummern (zB. 2.5.x) sind Entwicklerkernel, die nach der Freigabe dann die nächsthöhere gerade Nummer erhalten.

Wir holen uns also zB. das Paket linux-2.4.0.tar.gz oder linux-2.4.0.tar.bz2 (der Download dauert mit ISDN ca. 45 Minuten bis eine Stunde). Beide haben den gleichen Inhalt. Nur, das mit bz2 gepackte ist rund 6MB kleiner.

Jetzt entpacken wir den Kernel nach /usr/src/linux/, nachdem wir ggf. vorhandene Daten in ein Unterverzeichnis ( zB. /usr/src/linux/2.2.6, also einfach die Versionsnummer zum UnterverzeichnisNamen machen) gesichert haben. Die Kompilierung kann zwar grundsätzlich in jedem Verzeichnis durchgeführt werden (dann ggf. einen Link auf /usr/src/linux/ legen), doch etliche meist hardwarenahe Programme erwarten die Kernelquellen in diesem Verzeichnis. Also werden wir wohl den oben beschriebenen Weg wählen.

Um den Befehl make auführen zu können, muss im genannten Verzeichnis auch ein Makefile existieren. Es sollte nach der Installation der Kernelquellen auch dort vorhanden sein.

Nun können wir uns noch Patches für Features besorgen, die nicht standardmäßig beim Kernel dabei sind. Hier wäre zB. an eines der Journaling Filesysteme ReiserFS oder ext3 zu denken. ReiserFS ist zu finden bei ftp.exinferis.de/reiserfs/.

Die Kernelkompilierung muss im Verzeichnis /usr/src/linux durchgeführt werden, wir wechseln ins Verzeichnis:

root@sonne> cd /usr/src/linux

Ggf. vorhandene Patches werden nun mit folgendem Befehl eingespielt:

root@sonne> zcat NameDesPatches.gz | patch -p0

Ein Patch lässt sich auch wieder rückgängig machen. Wenngleich... es soll nicht verschwiegen werden, dies wird nicht immer gelingen.

root@sonne> patch -R < NameDesPatches

 

Man sollte über seine Hardware genauestens Bescheid wissen, also Chipsatz, Hersteller (v.a. auch des MainBoards!). Es werden aber trotzdem während der Konfiguration einige Fragen auftauchen. Dann sollte man sein Englisch auffrischen und die Readmes lesen, die mit dem Kernel kommen. Das ist wirklich wichtig, weil das alles GENAU drinsteht, genauer als in diesem Dokument. Man sollte sich hier mindestens die README und CHANGES zu Gemüte führen.

In der CHANGES steht drin, wie man die Programme, die während des Kernelbaus zum Einsatz kommen, auf die Version hin überprüft. Ggf. müssen diese nämlich upgedatet werden. (Dies ist i.a. nicht auf die leichte Schulter zu nehmen; ich bin hinterher drangesessen und hab mich gewundert, warum ich keine Module laden kann, um dann feststellen zu müssen, das ich die neuesten modutils nicht hatte.) Speziell der gcc ist nachher wichtig, weil mit ihm der Kernel kompiliert wird. Also erstmal die Programme auf Vordermann bringen, was allerdings weiter kein Problem ist.
Übrigens: Das gilt auch für die README  der externen Patches
 

nach oben

Kompilieren konform mit der Rechnerarchitektur


Aus Performancegründen ist es sehr sinnvoll, den Kernel konform zur Rechnerarchitektur zu erstellen. Für welche Architektur kompiliert wird, hägnt von den Optionen ab, die im Makefile eingegeben werden, bzw. davon, was der default ist. Dabei wird in der Regel das System erkannt, und die entsprechenden Flags für den Compiler werden gesetzt (-O2, -mpentium etc.). Das Makefile kann anschließend editiert werden, um dann die Wunscheinstellungen vorzunehmen.

Weiterhin haben wir auch die Möglichkeit, dem System durch Setzen der Umgebungsvariable CFLAGS mitteilen, für welche Architektur wir den Kernel, aber auch Libs und weitere Programme, die wir selbst kompilieren, erstellen wollen. Hierzu ein Beispiel:

root@sonne> export CFLAGS=-O3 -march=pentium
nach oben

Kernelkompilierung


Der Kernel ist zunächst dem eigenen Bedarf anzupassen. Das Konfigurieren kann auf der Kommandozeile, im Menü im Textmodus oder unter X-Window erfolgen. Die Auswahl erfolgt durch Eingabe eines der drei Befehle:

root@sonne> make config
root@sonne> make menuconfig
root@sonne> make xconfig

Anm.: Für die Konfiguration unter dem X-Window ist es sinnvoll, das X-Window-System als root zu starten, da sonst zusätzliche Massnahmen getroffen werden müssen, um Zugriff auf das Display eines anderen Benutzers zu erhalten.

Bevor wir nun mit der Konfiguration beginnen, sollten wir die bestehende Konfiguration in /usr/src/linux/[*/].config.old sichern.

Über die Konfiguration selbst kann hier eigentlich nichts gesagt werden. Es geht ja darum, den Kernel den localen Gegebenheiten anzupassen. Wir sollten sehr sorgfältig arbeiten und darauf achten, dass wir Zusammenhänge nicht stören. Es würde zB. nicht genügen, nur das Framebuffer-Device zu wählen, wir müssen auch schauen, welche Zusatzauswahlen getroffen werden müssen bzw., was sich gegenseitig ausschließt. Als letzten Schritt der Konfiguration sollten wir diese in /usr/src/linux/[*/].config sichern. Denn wenn wir nachher feststellen, dass die Auswahl doch noch nicht ganz richtig war, können wir diese Konfiguration laden und den Fehler suchen. Wir brauchen nicht alles noch mal im Detail durchgehen.

Nach der Konfigurierung wird der Kernel nun übersetzt. Soll der Kernel einfach unter /boot installiert werden, ist im Haupt-Makefile (ca. in Zeile 74) das Kommentarzeichen zu entfernen vor der Zeile

INSTALL_PATH=/boot

Zur Kompilierung können die notwendigen Befehle gemeinsam eingegeben werden:

root@sonne> make dep clean bzImage | tee kernel.out

Anm.: Zunächst kann versucht werden, mit zImage einen schlanken Kernel zu bauen. Da dies aber in den meisten Fällen nicht gelingen wird, wird im Beispiel gleich ein grosser Kernel (big), also bzImage generiert.

Wenn genügend Hauptspeicher (über 100 MB) vorhanden ist, kann der Kernel mit dem Parameter -j (also make -j) übersetzt werden. Hierbei wird für jedes zu übersetzende Quellfile ein eigener Compiler gestartet.

Die Anweisung "| tee kernel.out" gilt für die bash und ist nur notwendig, wenn der Kompilationsvorgang mitgeschrieben werden soll, in diesem Beispiel in die Datei kernel.out.

Nach der erfolgreichen Übersetzung ist dann der Kernel im Verzeichnis /usr/src/linux/arch/i386/boot zu finden oder eben im Verzeichnis /boot, wenn das Haupt-Makefile (s.o.) entsprechend geändert wurde.

In aller Regel werden Teile des Kernels als ladbare Module konfiguriert worden sein. Die Module müssen nun übersetzt werden:

root@sonne> make modules

Wer sich die Make-Parameter nicht merken möchte und das Arbeiten mit make etwas einfacher gestalten will, kann unter http://linux.as-rsi.de/ unter Download nachschauen. Dort liegt MKLINUX, ein kleines Script, das den User beim der Kernel-Kompilierung unterstützt.

nach oben

Prüfen, ob die Kernelkompilierung vollständig ist


Um festzustellen, inwieweit die Kernelkompilierung vollständig verlaufen ist oder ob etwas fehlt, könnt Ihr im Verzeichnis /usr/src/linux aufrufen:

root@sonne> NUR make
nach oben

Modulhandhabung


Module können mit Parametern aufgerufen werden; diese werden in der /etc/modules.conf eingetragen. Näheres würde den Rahmen diese Dokuments aber etwas sprengen. Nur folgendes: Mit

root@sonne> modprobe modulname

kann das Modul geladen werden,

root@sonne> modprobe -r modulname

entlädt das Modul wieder.

root@sonne> lsmod

listet die geladenen Module auf. Man sollte hier wie gesagt auf die richtige modutils Version achten. Die modutils beeinhalten Utilities wie modprobe zu Handhabung von Modulen. Sie sind auch auf ftp.kernel.org erhältlich.

nach oben

Kernel installieren


Nachdem der Kernel übersetzt wurde, müssen wir dafür sorgen, dass er künftig auch gebootet wird.

LILO als Bootloader


Falls LILO als Bootloader verwendet wird, könnt Ihr den Kernel entsprechend entsprechend der folgenden Anleitung installieren:

  • Zunächst den alten Kernel sichern,
  • danach erfolgt die Installation.
  • Anschließend ist LILO aufzurufen.
  • Dann sind noch die kompilierten Module zu installieren.

Arbeitet dazu die folgenden Befehle der Reihe nach ab:

root@sonne> cp /boot/vmlinuz /boot/vmlinuz.old
root@sonne> cp /usr/src/linux/arch/i386/boot /boot/vmlinuz
root@sonne> make modules_install

Um bei Bedarf den alten Kernel booten zu können, wird in der /etc/lilo.conf zusätzlich ein Label Linux.old eingetragen und der alte Kernel nach /boot/vmlinuz.old umbenannt. Hier nun ein Beispielaufbau-Auszug aus der /etc/lilo.conf:

image = /boot/vmlinuz
root = /dev/hda5
label = Linux

image = /boot/vmlinuz.old
root = /dev/hda5
label = Alter Kernel

Nach der Anpassung ist nun LILO aufzurufen:

root@sonne> lilo

Nach dem Anpassen der /etc/lilo.conf kann die Installation des LILO auch automatisch durchgeführt werden:

root@sonne> cd /usr/src/linux
root@sonne> make bzlilo

Anm.: Auch dieses Beispiel gilt wie bei der Kernelkompilierung für den Fall, dass ein grosser Kernel (big) generiert wurde. Andernfalls wäre der Parameter zlilo an make zu übergeben.
 

Nur als Notanker - den wir aber selbstverständlich nicht brauchen werden , sei erwähnt, daas wir mit dem Befehl

root@sonne> make oldconfig

die alte Kernelkonfiguration noch mal frisch erstellen können, um ggf. noch mal ganz von vorn zu beginnen

nach oben

Bootdiskette erstellen


Wer sich eine Bootdiskette mit dem neuen Kernel erstellen möchte, kann dies mit folgendem Befehl tun:

root@sonne> make bzdisk

Anm.: Auch dieses Beispiel gilt wie bei der Kernelkompilierung für den Fall, dass ein grosser Kernel (big) generiert wurde. Andernfalls wäre der Parameter zdisk an make zu übergeben.

Festplatte nach der Kernelübersetzung aufräumen


Es macht durchaus Sinn, die Objektdateien, die bei der Kernelübersetzung erzeugt wurden, im System zu belassen. Spätere Kernelkompilierungen laufen dann deutlich schneller ab. Das Löschen der Objektdateien wird allerdings bei geringem Plattenplatz sinnvoll sein bzw., wenn später voraussichtlich kein weiterer Kernel mehr kompiliert werden soll. Das Löschen der Dateien geschieht folgendermaßen:

root@sonne> make clean

Der Parameter clean kann dem make-Befehl auch bereits bei der Kernelkompilierung mit übergeben werden. Das wird aber nicht unbedingt zu empfehlen sein. Denn wenn tatsächlich die Kernelkompilierung nicht gelingen sollte - was mitunter an einer falsch zusammengestellten Modulauswahl oder fehlenden installierten Paketen liegen kann - müsste make die Objektdateien erst wieder erstellen, was natürlich wieder die volle Kompilierungszeit erfordern würde.

nach oben

Kernelupdating


Beim Kernelupdating sind folgende Befehle der Reihe nach abzuarbeiten:

root@sonne> cd /usr/src/linux
root@sonne> make mrproper
root@sonne> make xconfig
root@sonne> make dep clean bzImage bzlilo modules modules_config
root@sonne> reboot

bzImage und bzlilo brauchen nicht beide aufgerufen werden. bzlilo kompiliert auch den Kernel, installiert diesen dann und ruft LILO auf.

Aus dem alten Linux-Verzeichnis kann die Datei .config in das neue Linux-Verzeichnis kopiert werden. Dann braucht Ihr z.B. nicht

root@sonne> make xconfig

aufzurufen, sondern

root@sonne> make oldconfig

Hier bekommt Ihr nur die Änderungen angezeigt, die sich aus den Abweichungen aus den beiden Kernelversionen ergeben.

nach oben

Detailliertere Hilfen


Bei der richtigen Sorgfalt und nach dem Studium der gebotenen Hilsmittel ist es durchaus nicht schwer, einen eigenen maßgeschneiderten Kernel zu kompilieren. Als totaler Linux-Frischling hatte ich zB. das große Glück , dass ich dank durch XFree nicht unterstützter Grafikkarte (natürlich eine Hercules Terminator) X nur über ein Framebuffer Device einrichten konnte. Der eigene Kernel, den ich mir hierzu bauen musste, war eine prima Einstiegsübung.

Aber wir wollen ja nicht über die Zeiten plaudern, als Linux wirklich noch schön war (inzwischen ist es leicht geworden). Hier also die Zusammenstellung der wichtigsten Unterlagen, mit Hilfe derer Euch der Kernelbau gut gelingen sollte:

  • Das Distributionshandbuch,
  • Die Kernel HOWTO (vieles hab ich aus ihr gelernt und findet sich auch hier wieder),
  • Die READMES des Kernels
Autor: Baitronic/Omega-X