Linux内核未正确找到initrd


11

我已经编译了一个Linux内核,并且想在QEMU中对其进行调试。我通过执行以下命令创建了一个要启动的文件

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

然后我做了qemu -kernel bzImage -initrd disk.img,得到下面的屏幕:

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

我的QEMU屏幕

我做错了什么,该如何解决?



相同的错误消息,因为这,但没有指定他把到达它的步骤:unix.stackexchange.com/questions/48302/...
西罗桑蒂利冠状病毒审查六四事件法轮功

Answers:


8

内核告诉您,它不知道哪个设备拥有根文件系统。不需要循环安装。(将其卸载,然后继续)。

尝试类似的命令

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

-hda disk.img参数告诉qemu根据您的来模拟磁盘设备disk.img

-append root=/dev/sdaqemu使用该开关将其根设备告知内核。这是通过将附加root=/dev/sda到内核​​命令行来完成的。您可以通过这样做将其与您自己的内核的内核命令行进行比较cat /proc/cmdline(这很安全)。您也应该在那里看到一个root参数。


我将如何卸载文件?
Coder404

umount /mnt/rootfs
t-8ch

当我这样做时,我得到umount:/ mnt / rootfs未挂载(根据mtab)
Coder404 2013年

大概Coder404不想将磁盘附加到那台机器上并initinitrd。在这里,您将disk.img两者都作为硬盘传递,这initrd没有意义。
斯特凡Chazelas

@StephaneChazelas感谢有关-initrd应该不存在的提示。
t-8ch 2013年

8

发生的事情是您试图以“过时”的方式引导Linux。那是initrd一个ramdisk,而不是内核在ramfs中解压缩的cpio压缩归档文件,并且使用了旧方法切换到终端设备。

在这种模式下,内核将disk.img作为ramdisk挂载为根文件系统,然后/linuxrc在其中执行。根据您的情况,很可能没有此类文件。/linuxrc退出时(应该做任何事情来调出真正的根文件系统的块设备),然后内核会挂载真正的根文件系统。

上面的消息表明它成功安装了ram磁盘(1,0:1是ram,所以/dev/ram0),但不是真正的根文件系统/ dev / sda1(8,1:8是sd,1是a1)。大概是因为您没有指定内核命令行(-append),所以/dev/sda1它来自在内核编译时或使用传递的CONFIG_CMDLINE rdev

如果您的disk.img打算包含一个带有/sbin/init... 的小型Linux发行版的根文件系统,那么您可能想要编写它:

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

然后,内核会将ram磁盘视为真实的根文件系统(尽管您仍然pivot_root可以使用另一个)。

为了能够更轻松地查看内核消息,我建议使用串行输出:

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

或者,您可以使用初始化ramfs代替初始化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

(提供的busybox是静态链接版本),您将在该内核中获得一个shell和其他busybox实用程序。

请注意,内核现在/init相对于该模式/linuxrc/sbin/init以该模式运行。


显示的输出的第3行显示,内核安装了initramdisk的ext2文件系统。因此,它可能不是缺少的模块。
t-8ch 2013年

哦,是的,我错过了,谢谢@ t-8ch。我想我知道发生了什么,并更新了我的答案。
斯特凡Chazelas

0

CONFIG_BLK_DEV_INITRD=y

此内核配置选项也是必需的。它在Linux内核上启用了initrd支持。

幸运的Buildroot在BR2_TARGET_ROOTFS_CPIO=y给定默认情况下会为我们设置它。

然后,使用该qemu -initrd选项将CPIO传递给QEMU 。我完整的QEMU命令是:

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

这是一个简约的全自动Buildroot + QEMU示例:https : //github.com/cirosantilli/linux-kernel-module-cheat/tree/b3868a3b009f2ab44fa6d3db3d174930b3cf7b69#initrd

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.