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/...を
チロSantilli冠状病毒审查六四事件法轮功

回答:


8

カーネルは、ルートファイルシステムを保持しているデバイスが不明であることを通知しています。ループマウントは必要ありません。(続行する前にアンマウントしてください)。

次のようなコマンドを試してください

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

-hda disk.imgパラメータは、あなたに基づいて、ディスクデバイスをシミュレートするためにQEMUを伝えますdisk.img

-append root=/dev/sdaスイッチは、それのルートデバイスについてのカーネルに伝えるためにQEMUで使用されています。これはroot=/dev/sda、カーネルコマンドラインにを追加することによって行われます。これをあなた自身のカーネルのカーネルコマンドラインと比較することができますcat /proc/cmdline(これは安全です)。あなたはそこに表示されるはずですrootあまりにも、パラメータを。


ファイルをアンマウントするにはどうすればよいですか?
Coder404 2013年

umount /mnt/rootfs
t-8ch


おそらく、Coder404はそのマシンにディスクを接続せず、単にで実行したいと考えてinitinitrdます。ここでは、disk.img両方をハードディスクとして渡しているので、initrd意味がありません。
ステファンChazelas

@StephaneChazelas -initrdそれがあったはずのないことについてのヒントについての感謝。
t-8ch 2013年

8

何が起こっているのかというと、Linuxを「廃止された」方法で起動しようとしているということです。これはinitrd、ramfsでカーネルによって解凍された圧縮されたcpioアーカイブとは対照的にramdiskであり、古い方法でエンドデバイスに切り替える方法です。

そのモードでは、カーネルは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"

別の方法として、init ramdiskの代わりにinit ramfsを使用できます。

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は、静的にリンクされたバージョンです)。そのカーネルには、シェルと他のbusyboxユーティリティが含まれます)。

カーネルがそのモード/initとは対照的に、/linuxrcまたは/sbin/initそのモードで実行されることに注意してください。


表示された出力の3行目は、カーネルがinitramdiskのext2ファイルシステムをマウントしたことを示しています。したがって、おそらくモジュールが不足しているわけではありません。
t-8ch 2013年

ああはい、私はそれを逃していた、@ t-8chのおかげで。何が起こっているのかはわかっていて、私の答えが更新されたと思います。
ステファンChazelas

0

CONFIG_BLK_DEV_INITRD=y

このカーネル構成オプションも必要です。Linuxカーネルでのinitrdサポートを有効にします。

Luckly 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の例を次に示します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.