Wie man einen Kernel kompiliert - auf CentOS

Version 1.0
Author: Falko Timme


Jede Distribution hat besondere Tools, mit denen sie einen benutzerdefinierten Kernel aus den Quellen kompiliert. Diese Anleitung veranschaulicht, wie man einen Kernel auf CentOS-Systemen kompiliert. Sie beschreibt, wie man einen benutzerdefinierten Kernel baut, unter Verwendung der neusten unveränderten Kernelquellen von www.kernel.org (vanilla kernel) damit Du nicht an die Kernel, die von Deiner Distribution bereitgestellt werden, gebunden bist. Weiterhin wird gezeigt, wie man die Kernelquellen patcht, falls Funktionen benötigt werden, die darin nicht enthalten sind.

Ich habe dies auf CentOs 4.4 getestet.

Ich möchte an dieser Stelle darauf hinweisen, dass dies nicht der einzige Weg ist, ein solches System einzurichten. Es gibt viele Möglichkeiten dieses Ziel zu erreichen - dies ist der Weg, den ich gewählt habe. Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!

1 Vorbemerkung

In dieser Anleitung beschreibe ich zwei Varianten, wie man einen Kernel CentOS Systeme baut. Mit der ersten Variante erhältst Du am Ende ein Kernel rpm Paket, das Du installieren oder mit anderen teilen kannst. Die zweite Variante ist für alle Linux Distributionen die gleiche, Du hast am Ende allerdings kein rpm Paket.

2 Ein Kernel rpm Paket bauen

Dieses Kapitel veranschaulicht, wie man einen Kernel baut und ein rpm Paket erhält, das man installieren und mit anderen teilen kann.

2.1 Die Kernelquellen runter laden

Zuerst laden wir unseren gewünschten Kernel nach /usr/src. Gehe zu www.kernel.org und wähle den Kernel aus, den Du installieren möchtest, z.B. linux-2.6.18.3.tar.bz2 (hier findest Du alle 2.6 Kernel: http://www.kernel.org/pub/linux/kernel/v2.6/). Dann kannst Du ihn wie folgt nach /usr/src runter laden:

cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.3.tar.bz2

Dann entpacken wir die Kernelquellen und erstellen einen Symlink linux zum Kernelquellen Verzeichnis:

tar xjf linux-2.6.18.3.tar.bz2
ln -s linux-2.6.18.3 linux
cd /usr/src/linux

2.2 /etc/modprobe.conf modifizieren

Jetzt müssen wir das mptscsi Modul in /etc/modprobe.conf auskommentieren, da wir sonst eine Fehlermeldung wie diese erhalten:

No module mptscsi found for kernel 2.6.18.3-default, aborting.

wenn wir versuchen eine Ramdisk für unseren neuen Kernel zu erstellen.

vi /etc/modprobe.conf


alias eth0 pcnet32
alias scsi_hostadapter mptbase # alias scsi_hostadapter1 mptscsi alias scsi_hostadapter2 mptfc alias scsi_hostadapter3 mptspi alias scsi_hostadapter4 mptsas alias scsi_hostadapter5 mptscsih

2.3 Anbringen von Patches in den Kernelquellen (optional)

Manchmal benötigst Du Treiber für Hardware, die von dem neuen Kernel nicht standardmäßig unterstützt wird, oder Du benötigst Unterstützung für Virtualisierungstechniken oder eine andere brandneuen Technologie, die beim Kernel noch nicht angekommen ist. In all diesen Fällen musst Du die Kernelquellen patchen (vorausgesetzt es ist ein Patch verfügbar...).

Gehen wir davon aus, Du hast den benötigten Patch (ich nenne ihn in diesem Beispiel patch.bz2) nach /usr/src geladen. So bringst Du ihn in Deinen Kernelquellen an (immer noch im /usr/src/linux Verzeichnis):

bzip2 -dc /usr/src/patch.bz2 | patch -p1 --dry-run
bzip2 -dc /usr/src/patch.bz2 | patch -p1

Der erste Befehl ist nur ein Test und ändert nichts an Deinen Quellen. Wenn er keine Fehler anzeigt, kannst Du den zweiten Befehl ausführen, der den Patch tatsächlich anbringt. Tu das nicht, wenn der erste Befehl Fehler angezeigt hat!

Wenn Deine Patches mit gzip (.gz) anstelle von bzip2 (.bz2) komprimiert sind, dann patchst Du Deinen Kernel wie folgt:

gunzip -c /usr/src/patch.gz | patch -p1 --dry-run
gunzip -c /usr/src/patch.gz | patch -p1

Du kannst auch Kernel Prepatches in Deinen Kernelquellen anbringen. Wenn Du zum Beispiel eine Funktion brauchst, die nur in Kernel 2.6.19-rc6 verfügbar ist, die gesamten Quellen für diesen Kernel aber noch nicht veröffentlicht wurden. Stattdessen ist ein patch-2.6.19-rc6.bz2 verfügbar. Du kannst diesen Patch in den 2.6.18 Kernelquellen anbringen, aber nicht in Kernel 2.6.18.1 oder 2.6.18. oder 2.6.18.3 etc. Dies wird auf http://kernel.org/patchtypes/pre.html erklärt:

"Prepatches are the equivalent to alpha releases for Linux; they live in the testing directories in the archives. They should be applied using the patch(1) utility to the source code of the previous full release with a 3-part version number (for example, the 2.6.12-rc4 prepatch should be applied to the 2.6.11 kernel sources, not, for example, 2.6.11.10.)"
Wenn Du also einen 2.6.19-rc6 Kernel kompilieren möchtest, musst Du die 2.6.18 Kernelquellen (http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.18.tar.bz2) in Schritt 2.1 anstelle des Kernels 2.6.18.3 runter laden!

So bringst Du den 2.6.19-rc6 Patch im Kernel 2.6.18 an:

cd /usr/src
wget http://www.kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.19-rc6.bz2
cd /usr/src/linux
bzip2 -dc /usr/src/patch-2.6.19-rc6.bz2 | patch -p1 --dry-run
bzip2 -dc /usr/src/patch-2.6.19-rc6.bz2 | patch -p1

2.4 Konfiguration des Kernels

Es ist eine gute Idee, die Kofiguration Deines derzeit funktionstüchtigen Kernels als Basis für Deinen neuen Kernel zu verwenden. Daher kopieren wir die vorhandene Konfiguration nach /usr/src/linux:

make clean && make mrproper
cp /boot/config-`uname -r` ./.config

Dann führen wir dies aus

make menuconfig

was das Kernelkonfigurationsmenü aufruft. Gehe zu Load an Alternate Configuration File und wähle .config (was die Konfiguration Deines derzeit funktionstüchtigen Kernels enthält) als die Konfigurationsdatei aus:



Durchblättere dann das Kernelkonfigurationsmenü und treffe Deine Auswahl. Vergewissere Dich, dass Du eine Versionskennzeichnung Deines Kernels unter General Setup ---> () Local version - append to kernel release festlegst. Ich verwende -default also heißt unser Kernel rpm Paket kernel-2.6.18.3default-1.i386.rpm. Du kannst die Kennzeichnung leer lassen oder eine andere festlegen, die Dir hilft, den Kernel zu identifizieren (z.B. -custom oder was auch immer Du möchtest).

Bitte beachte: Nachdem Du kernel-2.6.18.3default-1.i386.rpm installiert hast und Dich dazu entschieden hast ein anderes  2.6.18.3 Kernel rpm Paket zu kompilieren, ist es wichtig, dass Du eine andere Versionskennzeichnung verwendest, z.B. -default1, -default2, etc. Anderenfalls kannst Du Deinen neuen Kernel nicht installieren, da sich rpm beschwert, dass kernel-2.6.18.3default-1.i386.rpm bereits installiert ist!





Wenn Du damit fertig bist und Exit wählst, beantworte folgende Frage (Do you wish to save your new kernel configuration?) mit Yes:

2.5 Den Kernel bauen

Führe diesen Befehl aus, um den Kernel zu bauen:

make rpm

Nun musst Du geduldig sein, da die Kernel Kompilierung einige Stunden dauern kann, je nach Kernel Konfiguration und  Deiner Prozessorgeschwindigkeit.

2.6 Den neuen Kernel installieren

Nach der erfolgreichen Kompilierung des Kernels, wurde ein src.rpm und ein rpm Paket erstellt. Das src.rpm Paket findest Du im /usr/src/redhat/SRPMS/ Verzeichnis, seine Bezeichnung erfährst Du indem Du dies ausführst

ls -l /usr/src/redhat/SRPMS/

Auf meinem System hieß es kernel-2.6.18.3default-1.src.rpm.

Das rpm Paket findest Du in /usr/src/redhat/RPMS/i386/, /usr/src/redhat/RPMS/i586/, /usr/src/redhat/RPMS/i686/, /usr/src/redhat/RPMS/x86_64/, etc., das hängt von Deiner Architektur ab. Auf meinem System befand es sich in /usr/src/redhat/RPMS/i386/, als ich dies ausführte

ls -l /usr/src/redhat/RPMS/i386/

fand ich heraus, dass es die Bezeichnung kernel-2.6.18.3default-1.i386.rpm trug.

Nun können wir unser Kernel rpm Paket wie folgt installieren:

cd /usr/src/redhat/RPMS/i386/
rpm -ivh --nodeps kernel-2.6.18.3default-1.i386.rpm

Bitte beachte die --nodeps Option: wenn Du sie nicht verwendest, siehst Du folgende Fehlermeldung:

error: Failed dependencies:
kernel >= 2.6.10 conflicts with lksctp-tools-1.0.2-6.4E.1.i386

Ich habe festgestellt, dass das Ignorieren dieser Abhängigkeit keine Probleme auf meinem System verursacht.

Nun kannst Du das Kernel rpm Paket sogar zu anderen CentOS Systemen transferieren und es dort auf gleiche Art und Weise installieren, was bedeutet, dass Du den Kernel dort nicht noch einmal kompilieren musst.

Als Nächstes erstellen wir für unseren neuen Kernel eine Ramdisk, da das System unseren neuen Kernel wahrscheinlich sonst nicht starten wird:

mkinitrd /boot/initrd-2.6.18.3-default.img 2.6.18.3-default


2.7 Den GRUB Boot Loader konfigurieren

Nun müssen wir unseren GRUB Boot Loader konfigurieren, so dass unser neuer Kernel gestartet wird, wenn das System hochfährt.

Führe dies aus

ls -l /boot

um Deinen neuen Kernel (beginnt normalerweise mit vmlinuz, z.B. vmlinuz-2.6.18.3-default) und Ramdisk (beginnt normalerweise mit initrd, z.B. initrd-2.6.18.3-default.img) ausfindig zu machen.

Bearbeite dann /boot/grub/menu.lst. Sieh Dir Deine vorhandenen (funktionstüchtigen) Kernel Zeilen an. Nimm eine von ihnen als Muster für Deine neu Zeile und ersetze den Kernel und die Ramdisk, füge die Zeile dann über alle anderen Zeilen ein.

vi /boot/grub/menu.lst

Zum Beispiel sieht meine menu.lst so aus, bevor ich die neue Zeile hinzufüge:
# grub.conf generated by anaconda
# # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00 # initrd /initrd-version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.9-42.0.3.EL) root (hd0,0) kernel /vmlinuz-2.6.9-42.0.3.EL ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.9-42.0.3.EL.img title CentOS-4 i386 (2.6.9-42.EL) root (hd0,0) kernel /vmlinuz-2.6.9-42.EL ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.9-42.EL.img
und so danach:
# grub.conf generated by anaconda
# # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00 # initrd /initrd-version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.18.3-default) root (hd0,0) kernel /vmlinuz-2.6.18.3-default ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.18.3-default.img title CentOS (2.6.9-42.0.3.EL) root (hd0,0) kernel /vmlinuz-2.6.9-42.0.3.EL ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.9-42.0.3.EL.img title CentOS-4 i386 (2.6.9-42.EL) root (hd0,0) kernel /vmlinuz-2.6.9-42.EL ro root=/dev/VolGroup00/LogVol00 initrd /initrd-2.6.9-42.EL.img
Starte das System jetzt neu:

shutdown -r now

Wenn alles klappt, sollte der neue Kernel gestartet werden. Um zu überprüfen, ob auch wirklich Dein neuer Kernel verwendet wird, kannst Du dies ausführen

uname -r

Dies sollte etwas in der Art anzeigen

2.6.18.3-default

Wenn das System nicht startet, starte es neu und wenn Du dies siehst:


drücke irgendeine Taste um zum GRUB Menü zu gelangen:


Wähle Deinen alten Kernel aus und starte das System. Nun kannst Du noch einmal versuchen einen funktionstüchtigen Kernel zu kompilieren. Vergiss nicht die Zeilen des defekten Kernels aus /boot/grub/menu.lst zu entfernen.

0 Kommentar(e)

Zum Posten von Kommentaren bitte