Jądro Linux nie znajduje poprawnie initrd


11

Skompilowałem jądro Linuksa i chciałem go debugować w QEMU. Utworzyłem plik do rozruchu, wykonując polecenia

$ qemu-img create -f raw disk.img 200M
$ mkfs.ext2 -F disk.img
# mkdir /mnt/rootfs
# mount -o loop disk.img /mnt/rootfs

Potem zrobiłem qemu -kernel bzImage -initrd disk.imgi pokazałem poniższy ekran:

Kernel panic - not syncing: VFS: unable to mount root fs on unknown block

Mój ekran QEMU

Co zrobiłem źle i co mogę zrobić, aby to naprawić?



Ten sam komunikat o błędzie jak ten, ale nie określa kroków, które podjął, aby go osiągnąć: unix.stackexchange.com/questions/48302/...
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

Odpowiedzi:


8

Jądro mówi ci, że nie wie, które urządzenie posiada główny system plików. Montaż na pętli nie jest konieczny. (Odłącz to przed kontynuowaniem).

Spróbuj wykonać polecenie takie jak

qemu -kernel bzImage -hda disk.img -append root=/dev/sda

Ten -hda disk.imgparametr nakazuje qemu symulację urządzenia dyskowego na podstawie twojego disk.img.

-append root=/dev/sdaPrzełącznik jest używany przez qemu powiedzieć jądro o jego urządzeniu głównym. Odbywa się to poprzez dołączenie root=/dev/sdado wiersza poleceń jądra. Możesz to porównać do wiersza poleceń jądra własnego jądra, wykonując cat /proc/cmdline(Jest to bezpieczne). Powinieneś zobaczyć tam również rootparametr.


Jak odmontować pliki?
Coder404 10.03.13

umount /mnt/rootfs
t-8ch

Kiedy to robię, dostaję umount: / mnt / rootfs nie jest zamontowany (zgodnie z mtab)
Coder404 10.03.2013

Prawdopodobnie Coder404 nie chce dołączyć dysku do tego komputera i po prostu uruchom go initw initrd. Tutaj podajesz disk.imgoba jako dysk twardy i taki, initrdktóry nie ma sensu.
Stéphane Chazelas,

@StephaneChazelas dziękuje za podpowiedź, -initrdże nie powinno tam być.
t-8ch 11.03.13

8

To, co się dzieje, polega na tym, że próbujesz uruchomić system Linux w sposób „przestarzały”. To właśnie tam initrdjest ramdysk w przeciwieństwie do skompresowanego archiwum CPIO rozpakowanego przez jądro w ramfs i przy starym sposobie przełączania się na urządzenie końcowe.

W tym trybie jądro montuje plik disk.img jako ramdysk jako główny system plików, a następnie wykonuje się /linuxrctam. Najprawdopodobniej w twoim przypadku nie ma takiego pliku. Kiedy /linuxrc(co ma zrobić wszystko, co konieczne, aby uruchomić urządzenie blokujące dla prawdziwego głównego systemu plików) kończy pracę, jądro montuje prawdziwy główny system plików.

Powyższe komunikaty pokazują, że pomyślnie zamontował dysk RAM (1,0: 1 dla ram, więc /dev/ram0), ale nie prawdziwy system plików root / dev / sda1 (8,1: 8 oznacza sd, 1 oznacza a1). Prawdopodobnie, ponieważ nie określono wiersza polecenia jądra ( -append), który /dev/sda1pochodzi z CONFIG_CMDLINE przekazanej podczas kompilacji jądra lub przy użyciu rdev.

Jeśli twój disk.img ma zawierać główny system plików, powiedzmy małą dystrybucję Linuksa z /sbin/init..., prawdopodobnie prawdopodobnie chcesz go napisać:

kvm -kernel kernel.img -initrd disk.img -append 'root=/dev/ram0`

Następnie jądro traktowałoby dysk RAM jako prawdziwy główny system plików (choć nadal można by go użyć pivot_rootdo innego).

Aby móc łatwiej zobaczyć komunikaty jądra, polecam użycie wyjścia szeregowego:

kvm -kernel kernel.img -initrd disk.img -nographic -append "root=/dev/ram0 console=ttyS0"

Alternatywnie możesz użyć ramfs init zamiast ramdisk init:

mkdir -p RAMFS/{bin,dev} 
cd RAMFS/bin
cp /bin/busybox .
"$PWD/busybox" --install .
cd ..
cp -a /dev/{null,tty,zero,console} dev
printf '%s\n' "#! /bin/sh" "exec /bin/sh" > init
chmod +x init
find . | cpio -oHnewc | gzip > ../initramfs.gz
cd ..
kvm -kernel kernel.img -initrd initramfs.gz

(pod warunkiem, że busyboxjest to wersja statycznie powiązana), w tym jądrze otrzymasz powłokę i inne narzędzia typu busybox).

Zauważ, że jądro działa teraz /initw przeciwieństwie do tego trybu /linuxrclub /sbin/initw tym trybie.


Wiersz 3 pokazanych danych wyjściowych pokazuje, że jądro zamontowało system plików ext2 na dysku initramdisk. Więc prawdopodobnie nie jest to brakujący moduł.
t-8ch 11.03.13

O tak, tęskniłem za tym, dzięki @ t-8ch. Myślę, że wiem, co się dzieje i zaktualizowałem swoją odpowiedź.
Stéphane Chazelas

0

CONFIG_BLK_DEV_INITRD=y

Ta opcja konfiguracji jądra jest również wymagana. Umożliwia obsługę initrd w jądrze Linux.

Na szczęście Buildroot ustawia go domyślnie dla nas, kiedy BR2_TARGET_ROOTFS_CPIO=yzostanie podany.

Następnie przekazujesz CPIO do QEMU z qemu -initrdopcją. Moje pełne polecenie QEMU to:

./buildroot/output.x86_64~/host/usr/bin/qemu-system-x86_64 -m 128M -monitor telnet::45454,server,nowait -netdev user,hostfwd=tcp::45455-:45455,id=net0 -smp 1  -M pc -append ' nopat nokaslr norandmaps printk.devkmsg=on printk.time=y console=ttyS0' -device edu -device lkmc_pci_min -device virtio-net-pci,netdev=net0 -kernel ./buildroot/output.x86_64~/images/bzImage  -nographic  -initrd './buildroot/output.x86_64~/images/rootfs.cpio'

Oto minimalistyczny, w pełni zautomatyzowany przykład Buildroot + QEMU: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/b3868a3b009f2ab44fa6d3db3d174930b3cf7b69#initrd

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.