Kernel Linux tidak menemukan initrd dengan benar

11

Saya telah menyusun kernel linux dan saya ingin men-debug-nya di QEMU. Saya membuat file untuk boot dari dengan melakukan perintah

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

Lalu saya lakukan qemu -kernel bzImage -initrd disk.imgdan mendapatkan layar di bawahnya yang mengatakan:

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

Layar QEMU saya

Apa yang telah saya lakukan salah dan apa yang bisa saya lakukan untuk memperbaikinya?

Coder404
sumber
Pesan kesalahan yang sama seperti ini, tetapi tidak menentukan langkah-langkah yang diambil untuk mencapainya: unix.stackexchange.com/questions/48302/…
Ciro Santilli 冠状 冠状 审查 六四 六四 事件 事件

Jawaban:

8

Kernel memberitahu Anda, bahwa ia tidak tahu perangkat mana yang memegang sistem file root. Pemasangan loop Anda tidak perlu. (Lepas pemasangannya sebelum melanjutkan).

Coba perintah seperti

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

The -hda disk.imgparameter memberitahu qemu untuk mensimulasikan perangkat disk berdasarkan Anda disk.img.

The -append root=/dev/sdaswitch digunakan oleh qemu untuk memberitahu kernel tentang itu perangkat root. Ini dilakukan dengan menambahkan baris root=/dev/sdaperintah kernel. Anda dapat membandingkan ini dengan commandline kernel dari kernel Anda sendiri dengan melakukan cat /proc/cmdline(Ini aman). Anda harus melihat ada rootparameter juga.

t-8ch
sumber
Bagaimana cara saya meng-unmount file?
Coder404
umount /mnt/rootfs
t-8ch
Ketika saya melakukan itu, saya mendapatkan umount: / mnt / rootfs tidak di-mount (menurut mtab)
Coder404
Mungkin Coder404 tidak ingin melampirkan disk ke mesin itu dan jalankan saja initdi initrd. Di sini Anda melewati disk.imgkeduanya sebagai hard disk dan initrdyang tidak masuk akal.
Stéphane Chazelas
@StephaneChazelas terima kasih tentang petunjuk tentang hal -initrdyang seharusnya tidak ada di sana.
t-8ch
8

Apa yang terjadi adalah Anda mencoba mem-boot Linux dengan cara "Usang". Di situlah initrdramdisk bukan arsip cpio terkompresi yang dibongkar oleh kernel dalam ramfs, dan dengan cara lama untuk beralih ke perangkat akhir.

Dalam mode itu, kernel memasang disk.img sebagai ramdisk sebagai sistem file root dan kemudian dijalankan /linuxrcdi sana. Kemungkinan besar dalam kasus Anda, tidak ada file seperti itu. Ketika /linuxrc(yang seharusnya melakukan apa pun yang diperlukan untuk membuka perangkat blok untuk filesystem root sebenarnya) keluar, maka kernel mount sistem file root nyata.

Pesan di atas menunjukkan bahwa ia berhasil memasang ram ram (1,0: 1 untuk ram, jadi /dev/ram0) tetapi bukan sistem file root sebenarnya / dev / sda1 (8,1: 8 adalah sd, 1 adalah a1). Mungkin karena Anda tidak menentukan baris perintah kernel ( -append), yang /dev/sda1berasal dari CONFIG_CMDLINE yang dikirimkan pada waktu kompilasi kernel atau menggunakan rdev.

Jika disk.img Anda dimaksudkan untuk berisi sistem file root dari katakanlah distribusi Linux kecil dengan /sbin/init..., maka Anda mungkin ingin menulisnya sebagai gantinya:

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

Kemudian, kernel akan memperlakukan ram disk sebagai sistem file root yang sebenarnya (meskipun Anda masih bisa pivot_rootke yang lain).

Agar dapat melihat pesan kernel dengan lebih mudah, saya sarankan menggunakan keluaran serial:

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

Sebagai alternatif, Anda bisa menggunakan init ramfs alih-alih init ramdisk:

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

(disediakan busyboxadalah versi yang terhubung secara statis) dan Anda akan mendapatkan shell dan utilitas busybox lainnya di kernel itu).

Perhatikan bahwa kernel sekarang berjalan /initsebagai lawan /linuxrcatau /sbin/initdalam mode itu.

Stéphane Chazelas
sumber
Baris 3 dari output yang ditampilkan menunjukkan, bahwa kernel memasang sistem file ext2 dari initramdisk. Jadi itu mungkin bukan modul yang hilang.
t-8ch
Oh ya, saya melewatkannya, terima kasih @ t-8ch. Saya rasa saya tahu apa yang sedang terjadi dan telah memperbarui jawaban saya.
Stéphane Chazelas
0

CONFIG_BLK_DEV_INITRD=y

Opsi konfigurasi kernel ini juga diperlukan. Ini memungkinkan dukungan initrd pada kernel Linux.

Luckly Buildroot menyetelnya secara default untuk kami saat BR2_TARGET_ROOTFS_CPIO=ydiberikan.

Anda kemudian meneruskan CPIO ke QEMU dengan qemu -initrdopsi tersebut. Perintah lengkap QEMU saya adalah:

./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'

Berikut ini adalah contoh Buildroot + QEMU otomatis minimalistik yang minimalis: https://github.com/cirosantilli/linux-kernel-module-cheat/tree/b3868a3b009f2ab44fa6d3db3d174930b3cf7b69#initrd

Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功
sumber