Linuxkernel selbstgebaut
Autor: Karsten Kruse
In diesem Beitrag werde ich erklären wie ein Kernel den eigenen Anforderungen und der eigenen Hardware angepasst werden kann. Natürlich kann man sagen das der derzeitige Kernel doch gut Arbeitet, aber ist er optimal an die Bedürfnisse des Systems angepasst? Ich behaupte das er das nicht ist. Es gibt zu viele unterschiedliche Architekturen und Hardwareanforderungen. Dem tragen die generischen Kernels der Distributoren Rechnung indem sie so gut wie alles mit einkompilieren. Doch wofür brauche ich Unterstützung für 20 verschiedene Netzwerkkarten wenn ich doch nur eine eingebaut habe? Doch bevor wir ans Eingemachte gehen sind einige Vorbereitungen zu erledigen und Voraussetzungen zu klären.
Wir sollten sicherstellen das wir eine funktionierende Bootdiskette haben. Im weiteren Verlauf werden wir den Bootloader Lilo benutzen, da kann ein letzter Ausweg nützlich sein ;).
Die Versionsnummern des Kernels bestehen aus drei Teilen die etwa so aussehen: linux-major.minor.patch wobei major und minor die Version darstellen und patch den Patchlevel angibt. Wenn wir von Kernelversion 2.0 zu 2.2 oder von 2.2 zu 2.4 ugraden wird es definitiv nicht ohne weiteres mit meiner Erklärung funktionieren. Warum steht in der Dokumentation zu den Kernelsourcen in der Datei changes. Ich gehe im folgenden davon aus einen 2.2.xx Kernel zu einem 2.2.18 Kernel upzugraden.
Als erstes besorgen wir uns die Quellen des Linuxkernels von www.kernel.org oder einem seiner Mirrors. Wir downloaden das Paket linux-2.2.18.tar.gz und kopieren es in das Verzeichnis /usr/src . Schauen wir uns das Verzeichnis /usr/src mit "ls- l" vorher etwas genauer an:
lrwxrwxrwx 1 root root 21 Jan 23 17:37 linux -> /usr/src/linux-2.2.16 drwxr-xr-x 3 root root 4096 Dec 21 03:14 linux-2.2.16 drwxr-xr-x 7 root root 4096 Dec 21 03:32 packages
Der Link linux verweist auf linux-2.2.16, das werden wir ändern. Der Link soll auf die Sourcen des
gerade downgeloadetn Kernels verweisen. Löschen wir also den Link erstmal mit "rm linux
" und
verschieben und entpacken die Sourcen:
mv /home/karsten/linux-2.2.18.tar.gz /usr/src/linux-2.2.18 tar xzvf linux-2.2.18.tar.gz
Jetzt wird das neue Verzeichnis umbenannt und der Link wieder angelegt:
mv linux linux-2.2.18 ln -s /usr/src/linux-2.2.18 /usr/src/linux
Programme die irgendwelche Dateien aus dem Linuxsourcen-Dateibaum zum kompilieren benötigen werden jetzt
die aktuellen Sourcen finden. Wir wechseln in unseren neuen Dateibaum mit "cd /usr/src/linux
"
und schmökern erstmal in Ruhe im README mit "less README
". Soweit die Vorbereitungen. Die
Sourcen sind installiert. Jetzt fangen wir an den Kernel zu konfigurieren.
Das erste was wir machen ist ... aufräumen. Die Tester und Entwickler des Kernels lassen manchmal
Objektdateien oder Abhängigkeiten herumliegen. Meister Proper erledigt das für uns: "make
mrproper
". Wir kopieren unsere vorherige Kernelkonfigurationsdatei als Vorlage in das neue
Kernelverzeichnis:
cp /usr/src/linux-2.2.16/.config /usr/src/linux
Jetzt kommen wir zum schwierigsten Teil, der Kernelkonfiguration. Wir müssen entscheiden welche
Hardwaretreiber und Features in unseren Kernel einkompiliert werden sollen. Starten wir also das
Konfigurationsprogramm mit "make menuconfig
". Sollte menuconfig mit einem Fehler abbrechen
oder wir nur eine langsame Telnetverbindung haben nehmen wir "make config
". Menuconfig ist
aber wesentlich bequemer und übersichtlicher. Haben wir X-Windows am laufen geht auch "make
xconfig
".
Wie auch immer wir vorgehen, wir müssen jetzt entscheiden welche Features oder Treiber in den Kernel kompiliert werden sollen. Aber wir haben uns ja die alte .config kopiert. Mit ihr als Basis fällt uns die Entscheidung leichter. Entweder wir behalten die Konfiguration bei und sagen zu allen neuen Features das sie als Modul mitkompiliert werden oder wir nehmen so viele überflüssige Treiber raus wie es möglich ist. Ich versuche den Kernel immer so klein wie möglich zu halten. Ich benötige keinen USB-Support, wozu sollte er dann also in meinen Kernel einkompiliert werden? Ich habe auch keine TV-Karte in meinem System, also brauche ich keine TV-Kartenunterstützung.
Jetzt wird es Zeit die Abhängigkeiten der gewünschten Kernelfeatures untereinander abzuklären. Das
Kommando "make dep
" erledigt das zuverlässig. Kommen wir zu den eigentlichen
Kompilationsläufen. Diese können schon mal, je nach Hardwareausstattung, einige Zeit in Anspruch nehmen.
Erstmal kompilieren wir die Module mit "make modules
", danach installieren wir sie mit
"make modules_install
"
Als nächstes erstellen wir das neue Kernelimage mit "make bzImage
". In der Zwischenzeit
können wir uns schon mal mit einem Schluck Kaffee stärken. Und weil das erstellen des Kernelimages so lange
dauert überprüfen wir die Datei /etc/lilo.conf.
Sie wird vom Bootloader-Installationsprogramm Lilo ausgelesen, Deshalb kommt ihr eine besondere Bedeutung zu. Sollte sie falsch konfiguriert sein kann unser System nicht Booten, es ist also mit entsprechender Sorgfalt an das Editieren der Datei zu gehen.
Wir lassen am besten die bestehenden Einträge erstmal unangetastet stehen und fügen nur unsere neue
Kernelkonfiguration ein. Hier ist eine Beispieldatei, aber bitte auch die Manpage zu Lilo lesen. Mit
"man lilo
" rufe wir sie auf und lassen uns reichlich Zeit dabei, das Kernelimage ist eh noch
im Bau.
append="vga=0x0301" boot=/dev/hda lba32 vga=1 message=/boot/message menu-scheme=Wg:kw:Wg:Wg read-only rompt timeout=200 image = /boot/vmlinuz root = /dev/hdb3 label = Test initrd = /boot/initrd optional other = /dev/hda1 label = Windows98 table = /dev/hda optional image = /boot/vmlinuz.suse root = /dev/hdb3 label = 2.2.18 initrd = /boot/initrd.suse
Der Kernel ist fertig, wir haben die Datei lilo.conf angepasst. Jetzt können wir den frischen Kernel und die Datei System.map in das Verzeichnis /boot kopieren. Danach legen wir Links mit den Standardnamen auf diese Dateien an. Sind diese Links schon vorhanden müssen wir sie löschen und die Datei /etc/lilo.conf nochmal überprüfen.
rm /boot/System.map rm /boot/vmlinuz cp /usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz.test cp /usr/src/linux/System.map /boot/System.map.test ln -s /boot/vmlinuz.test /boot/vmlinuz ln -s /boot/System.map.test /boot/System.map
Als letztes geben wir noch ein "/sbin/lilo
" ein um den Bootloader neu zu installieren. Die
Ausgabe diese Befehls sollte etwa so aussehen:
root@nethunter > /sbin/lilo Added test * Added linux Added windows
Wenn jetzt eine Bootdiskette für den Notfall vorliegt und bis hier alles glatt gelaufen ist können wir neu Booten um den Kernel auszutesten. Kommentare, Wünsche und Anträge an Karsten Kruse tecneeq(at)tecneeq(dot)de.