Cod*_*404 11 initrd qemu linux-kernel
我已经编译了一个 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
Run Code Online (Sandbox Code Playgroud)
然后我做了qemu -kernel bzImage -initrd disk.img并得到了下面的屏幕,上面写着:
Kernel panic - not syncing: VFS: unable to mount root fs on unknown block
Run Code Online (Sandbox Code Playgroud)

我做错了什么,我能做些什么来解决它?
内核告诉您,它不知道哪个设备拥有根文件系统。您的循环安装不是必需的。(在继续之前卸载它)。
尝试像这样的命令
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参数。
发生的事情是您试图以“过时”的方式启动 Linux。这就是initrdramdisk,而不是由内核在 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`
Run Code Online (Sandbox Code Playgroud)
然后,内核会将 ram 磁盘视为真正的根文件系统(尽管您仍然pivot_root可以使用另一个)。
为了能够更轻松地查看内核消息,我建议使用串行输出:
kvm -kernel kernel.img -initrd disk.img -nographic -append "root=/dev/ram0 console=ttyS0"
Run Code Online (Sandbox Code Playgroud)
作为替代方案,您可以使用 init ramfs 而不是 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
Run Code Online (Sandbox Code Playgroud)
(提供的busybox是静态链接版本)并且您将在该内核中获得一个 shell 和其他 busybox 实用程序)。
需要注意的是内核现在运行/init,而不是/linuxrc或者/sbin/init在该模式下。
| 归档时间: |
|
| 查看次数: |
21307 次 |
| 最近记录: |