Ich hatte einen Linux-Kernel kompiliert und wollte ihn in QEMU debuggen. Ich habe eine Datei zum Booten erstellt, indem ich die Befehle ausgeführt habe
$ qemu-img create -f raw disk.img 200M
$ mkfs.ext2 -F disk.img
# mkdir /mnt/rootfs
# mount -o loop disk.img /mnt/rootfs
Dann habe ich qemu -kernel bzImage -initrd disk.img
den Bildschirm unten bekommen, auf dem steht:
Kernel panic - not syncing: VFS: unable to mount root fs on unknown block
Was habe ich falsch gemacht und was kann ich tun, um das Problem zu beheben?
linux-kernel
qemu
initrd
Coder404
quelle
quelle
Antworten:
Der Kernel teilt Ihnen mit, dass er nicht weiß, auf welchem Gerät sich das Root-Dateisystem befindet. Ihre Schlaufenhalterung ist nicht erforderlich. (Hängen Sie es aus, bevor Sie fortfahren).
Versuchen Sie einen Befehl wie
qemu -kernel bzImage -hda disk.img -append root=/dev/sda
Der
-hda disk.img
Parameter weist qemu an, ein Festplattengerät basierend auf Ihrem zu simulierendisk.img
.Der
-append root=/dev/sda
Schalter wird von qemu verwendet, um dem Kernel das Root-Gerät mitzuteilen. Dies erfolgt durch Anhängen derroot=/dev/sda
an die Kernel-Befehlszeile. Sie können dies mit der Kernel-Befehlszeile Ihres eigenen Kernels vergleichen, indem Sie Folgendes tuncat /proc/cmdline
(Dies ist sicher). Sie sollten dort auch einenroot
Parameter sehen.quelle
umount /mnt/rootfs
init
in ausführeninitrd
. Hier übergeben Siedisk.img
beide als Festplatte und eine,initrd
die keinen Sinn ergibt.-initrd
dass das nicht hätte sein sollen.Was passiert ist, dass Sie versuchen, Linux auf "veraltete" Weise zu booten. Hier
initrd
handelt es sich um eine Ramdisk im Gegensatz zu einem komprimierten CPIO-Archiv, das vom Kernel in einem Ramfs entpackt wurde, und mit der alten Methode, zum Endgerät zu wechseln.In diesem Modus stellt der Kernel die Datei disk.img als Ramdisk als Root-Dateisystem bereit und wird
/linuxrc
dort ausgeführt. In Ihrem Fall gibt es höchstwahrscheinlich keine solche Datei. Wenn/linuxrc
(was alles tun soll, was erforderlich ist, um das Blockgerät für das echte Root-Dateisystem aufzurufen) beendet wird, stellt der Kernel das echte Root-Dateisystem bereit.Die obigen Meldungen zeigen, dass die RAM-Festplatte erfolgreich bereitgestellt wird (1,0: 1 ist für
ram
, also/dev/ram0
), aber nicht das echte Root-Dateisystem / dev / sda1 (8,1: 8 istsd
, 1 ista1
). Vermutlich, da Sie keine Kernel-Befehlszeile (-append
) angegeben haben,/dev/sda1
stammt diese von einer CONFIG_CMDLINE, die zur Kernel-Kompilierungszeit oder mit übergeben wurderdev
.Wenn Ihre disk.img ein Root-Dateisystem enthalten soll, beispielsweise eine kleine Linux-Distribution mit
/sbin/init
..., möchten Sie sie wahrscheinlich stattdessen schreiben:Dann würde der Kernel die RAM-Disk als das echte Root-Dateisystem behandeln (obwohl Sie immer noch ein
pivot_root
anderes verwenden könnten ).Um die Kernel-Nachrichten leichter sehen zu können, würde ich die Verwendung der seriellen Ausgabe empfehlen:
Alternativ können Sie ein Init-Ramfs anstelle eines Init-Ramdisk verwenden:
(vorausgesetzt, es
busybox
handelt sich um die statisch verknüpfte Version) und Sie erhalten eine Shell und andere Busybox-Dienstprogramme in diesem Kernel.Beachten Sie, dass der Kernel jetzt
/init
im Gegensatz zu/linuxrc
oder/sbin/init
in diesem Modus ausgeführt wird.quelle
CONFIG_BLK_DEV_INITRD=y
Diese Kernel-Konfigurationsoption ist ebenfalls erforderlich. Es aktiviert die initrd-Unterstützung auf dem Linux-Kernel.
Glücklicherweise legt Buildroot es für uns standardmäßig fest, wenn
BR2_TARGET_ROOTFS_CPIO=y
es gegeben wird.Anschließend übergeben Sie den CPIO mit der
qemu -initrd
Option an QEMU . Mein vollständiger QEMU-Befehl lautet:Hier ist ein minimalistisches vollautomatisches Buildroot + QEMU-Beispiel: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/b3868a3b009f2ab44fa6d3db3d174930b3cf7b69#initrd
quelle