Man verwende das Howto: www.matthew.ath.cx/debian-kernel/ , um einen Kernel nach dem Vorbild der funktionierenden Debian-Kernel zu erstellen. Das oben geschilderte Problem liegt daran, dass der Kernel nicht die Funktionalität zur Verfügung hat, um auf das root Dateisystem zugreifen zu können. Im Debian-Kernel, wie er in obigem Howto erstellt wird, wird das gelöst durch eine initial Ramdisk (initrd).
Es könnte durch die GRUB-Konfigurtion (/boot/grub/menu.lst) beeinflusst sein. Anmerkung: Änderungen an dieser Datei wirken sich sofort, ohne weitere Kommandos, korrekt aus; anders als bei lilo.) Ein fehlender Parameter »initrd« dort für einen selbstkompilierten Kernel ist jedoch kein Fehler, denn üblicherweise wird die »initial ramdisk« für die zusätzlichen Module in binär verteilten Kernels verwendet. Ein selbstkompilierter Kernel braucht keine »inital ram disk«, muss dann aber alle zum Startup benötigten Modul im Kernel selbst einkompiliert haben. Module können in der ersten Startup-Phase ja nicht nachgeladen werden. Vgl. kris.koehntopp.de/inkomploehntopp/00710.html . Um den Fehler zu beheben, muss die folgende Funktionalität fest in den Kernel einkompiliert werden und darf nicht als Modul kompiliert werden:
- CONFIG_BLK_DEV_IDE
- CONFIG_BLK_DEV_IDEDISK
- CONFIG_IDE_GENERIC
- CONDIG_BLK_DEV_IDEPCI
- CONFIG_BLK_DEV_GENERIC
- CONFIG_BLK_DEV_VIA82CXXX
- CONFIG_EXT2_FS
- CONFIG_EXT3_FS
- CONFIG_DEVFS_FS
- CONFIG_DEVFS_MOUNT
Die Liste der geladenen Module eines funktionierenden Kernels mit initrd, direkt nach Systemstart, informiert darüber, welche Dinge in einem eigenen Kernel ohne initrd nicht als Modul kompiliert werden dürfen.
sd_mod ?
ata_piix ?
libata ?
capability ?
commoncap ?
Wenn der Fehler weiterhin besteht:
Wenn man in /boot/grub/menu.lst den Parameter »root=/dev/hda2« entfernt, ändert sich die Fehlermeldung von
-
VFS: Cannot open root device "/dev/hda2" or unknown-block(0,0)
-
Please append a correct "root=" boot option
-
Kernel panic: VFS: Unable to mount root fs on unknown-block(0,0)
in
-
VFS: Cannot open root device "" or unknown-block(3,2)
-
Please append a correct "root=" boot option
-
Kernel panic: VFS: Unable to mount root fs on unknown-block(3,2)
unknown-block(*,*) scheint damit ein Bezeichner für ein Block-Device mit Major- und Minor-Nummern zu sein. Man erstelle eine RAMDDISK (initrd-Image) mit mkinitrd. Alles, was dem Kernel an einkompilierten Modulen fehlt, sollte er nun nachladen können.
Der Fehler scheint also an einem falschen »root=« Parameter zu liegen. Es ist auch möglich, diesen Parameter als Major- und Minor-Nummern anzugeben, etwa »root=0302« (Major 3, Minor 2). Diese Nummern erfährt man über ls -all /dev/[...], hier zum Beispiel:
-
ls -all /dev/hda2
-
brw-rw—- 1 root disk 3, 2 Apr 6 09:27 hda3
Das könnte den Fehler beheben. Ansonsten wird zumindest die Fehlermeldung anders:
-
VFS: Cannot open root device "0302" or unknown-block(3,2)
-
Please append a correct "root=" boot option
-
Kernel panic: VFS: Unable to mount root fs on unknown-block(3,2)
Man sollte ausprobieren, ob der Fehler verschwindet, wenn man (bei i386-Architektur) die Default-Konfigurationsdatei für diese Architektur verwendet, die dem Kernel Source Tree beiliegt: ./arch/i386/defconfig. Man kann auch verschiedene Konfigurationsdateien aus dem Internet probieren: in einem Beitrag zum Thread seclists.org/lists/linux-kernel/2004/Sep/0063.html werden zwei als Attachments angeboten.
In diesem Fall funktionierte der standardmäßig von Debian installierte Kernel (aus der binary-Distribution). Damit sollte es möglich sein, einfach die Konfiguration dieses Kernels zu übernehmen. Sie liegt in /boot/config-<version>.
Zusätzlich muss natürlich ein initrd-image generiert werden. Dazu kann man das initrd-image des laufenden Kernels mounten und prüfen, welche Module dort enthalten sind:
-
mount -t cramfs -o loop /boot/initrd.img-2.6.8-1-386 /media/floppy0/
-
find ./lib/modules -name *.ko
Die so gefundenen Module trägt man dann ein in /etc/mkinitrd/modules. Evtl. ist das bei weitem nicht ausreichend, weil das initrd-Image des laufenden Kernels noch Bibliotheken und weitere Dinge enthält. Stattdessen geht man dann einen anderen Weg:
Eventuell ist es auch möglich, das vorhandene initrd-Image des laufenden Kernels wiederzuverwenden. Dazu ist es nötig, dass der neu kompilierte Kernel genau dieselbe Version hat. Das kann gewährleistet werden, indem man in ./Makefile im Kernel source tree unter »EXTRAVERSION =« die entsprechenden Versionszusätze (z.B. »-1-386«) des laufenden Kernels einträgt. Außerdem muss eine Zeile mit diesen Zusätzen in ./debian/changelog (im Kernel source tree) als oberste Zeile eingefügt werden. Weiterhin muss unter dieser Zeile ein Dummy-Eintrag entsprechend den anderen Einträgen im changelog eingefügt werden, ansonsten schlägt make-kpkg fehl. Weiterhin müssen in ./debian/control (im Kernel source tree) entsprechende Einträge für die neue Kernelversion erzeugt werden. So kann tatsächlich ein .deb-Paket mit dem Kernel in der entsprechenden Version erzeugt werden. Versionsdiskrepanzen führen dazu, dass Module wiederum nicht eingefügt werden können. Bevor man den Kernel deinstalliert, den man durch den selbstkompilierten Kernel ersetzen will, kopiert man sich dann noch dessen initrd-Image, so dass es nicht mit gelöscht wird: /boot/initrd.img-2.6.8-1-386 .
Nun muss zusätzlich in /boot/grub/menu.lst eingetragen werden, dass der neue Kernel das initrd-Image auch verwenden soll (die Debian-Kernel-Installation weiß ja nichts von einem initrd-Image, das man zusätzlich bereitstellen will!).
Mit diesem Verfahren kommt man zwar soweit, dass die initial Ramdisk verwendet wird. Jedoch werden dort die Module nicht gefunden, denn der Kernel meint selbst noch, er sei »2.6.8«, nicht »2.6.8-1-386«. Also: die initial Ramdisk ändern. Mit
-
mount -t cramfs -o loop /boot/initrd.img-2.6.8-1-386 /media/floppy/;
-
cd /media/floppy/lib/modules/;
-
mv 2.6.8-1-386 2.6.8;
ist das jedoch nicht möglich, da man in ein per loopback gemountetes Image anscheinend nicht schreiben kann. Andernfalls hätte man das Image ja problemlos auch auf jede beliebige selbstkompilierte Kernelversion anpassen können, auch auf »2.6.8«, und es wäre gar nicht notwendig gewesen, zu versuchen, einen Kernel »2.6.8-1-386« zu kompilieren.