Qemu - 模擬自己的系統來測試核心模組
我目前正在通過實現塊設備驅動程序開始核心程式。我能夠進行“簡單”的實現,並且我想進一步了解塊子系統提供的功能。
為此,我想使用 qemu 模擬我自己的作業系統,以避免每次我在核心設備程式碼中出錯時使我的開發作業系統崩潰。
主機系統配置
在我的工作站上,我使用的是執行核心 4.9.0 的 Debian 9。
$ uname -a Linux PC325 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u3 (2018-03-02) x86_64 GNU/Linux
鏡像磁碟創建
為了創建虛擬機,我創建了一個 500M 的原始圖像
dd if=/dev/zero of=vm-image.raw bs=1M count=512
然後將其格式化為 ext4 使用
mkfs.ext4 vm-image.raw
@meuh 評論後更新:
然後我填充了磁碟映像,如下所示:
mount vm-image.raw /mnt mkdir /mnt/dev /mnt/lib /mnt/proc /mnt/root /mnt/run /mnt/sbin /mnt/sys cp -r /etc /mnt/ cp -r /lib/systemd /mnt/lib ln -s /lib/systemd/systemd /mnt/sbin/init
我現在正在嘗試啟動模擬作業系統,但在配置它時遇到了一些問題。
執行命令
$ qemu-system-x86_64 -k fr -kernel /boot/vmlinuz-$(uname -r) -initrd /boot/initrd.img-$(uname -r) -hda vm/vm-image.raw -append "initrd=/boot/initrd.img-$(uname -r) root=/dev/sda rw console=ttyS0" -nographic
引導跟踪
[...] Kernel boot sequence [...] Begin: Loading essential drivers ... done. Begin: Running /scripts/init-premount ... done. Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done. Begin: Running /scripts/local-premount ... [ 2.015241] tsc: Refined TSC clocksource calibration: 3392.292 MHz [ 2.016768] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x30e5dd94d34, max_idle_ns: 440795304975 ns [ 2.895630] random: fast init done Begin: Waiting for suspend/resume device ... Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. [ 11.111765] random: crng init done Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. Begin: Running /scripts/local-block ... done. done. Gave up waiting for suspend/resume device done. Begin: Will now check root file system ... fsck from util-linux 2.29.2 [/sbin/fsck.ext4 (1) -- /dev/sda] fsck.ext4 -a -C0 /dev/sda /dev/sda: clean, 3607/32768 files, 12617/131072 blocks done. [ 35.528453] EXT4-fs (sda): mounted filesystem with ordered data mode. Opts: (null) done. Begin: Running /scripts/local-bottom ... done. Begin: Running /scripts/init-bottom ... done. run-init: /sbin/init: No such file or directory [ 35.569247] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 [ 35.569247] [ 35.570469] CPU: 0 PID: 1 Comm: run-init Not tainted 4.9.0-6-amd64 #1 Debian 4.9.82-1+deb9u3 [ 35.571599] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014 [ 35.572695] 0000000000000000 ffffffff9792e074 ffff974c05e14d00 ffffa66e8003feb8 [ 35.573741] ffffffff9777cfbd ffff974c00000010 ffffa66e8003fec8 ffffa66e8003fe60 [ 35.574780] a4112d94e56af84a ffff974c05e14d80 0000000000000100 ffff974c05e84490 [ 35.575793] Call Trace: [ 35.576132] [<ffffffff9792e074>] ? dump_stack+0x5c/0x78 [ 35.576815] [<ffffffff9777cfbd>] ? panic+0xe4/0x23f [ 35.577453] [<ffffffff9767c2de>] ? do_exit+0xade/0xae0 [ 35.578136] [<ffffffff978058b4>] ? vfs_write+0x144/0x190 [ 35.578830] [<ffffffff9767c313>] ? SyS_exit+0x13/0x20 [ 35.579510] [<ffffffff97603b7f>] ? do_syscall_64+0x8f/0xf0 [ 35.580223] [<ffffffff97c113b8>] ? entry_SYSCALL_64_after_swapgs+0x42/0xb0 [ 35.581209] Kernel Offset: 0x16600000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 35.582584] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000100 [ 35.582584]
問題
1 - 試圖讀取磁片設備
在啟動時,核心似乎試圖從不存在或不可讀的磁片設備中讀取。核心在 30 次嘗試後放棄了,所以這不是一個關鍵問題,但它會使引導序列減慢 30 秒。
我嘗試使用
-no-fd-bootchk
選項執行 qemu,但它沒有改變任何東西更新:
精確地作為 1ko-fda floppy.img
的floppy.img
原始歸零圖像可以抑制磁片相關的錯誤消息,並在啟動時最多節省 20 秒。但是,正如您在引導跟踪中看到的那樣,/scripts/local-block
它仍然會執行幾次,並且在傳遞到下一步之前最多需要 10 秒。2 - 無法初始化系統
@meuh 評論後更新:
核心似乎無法找到有效的初始化腳本。但是
/sbin/init
,它存在於磁碟映像上,並且是指向/lib/systemd/systemd
.我正在經歷核心恐慌,但我不知道是什麼原因造成的。
問題
我對 qemu 很陌生,我認為我離讓我的模擬系統工作不遠了,但我無法走得更遠。
我嘗試使用參數,但找不到能夠完全啟動並使用 bash 提示而不是 initramdisk 提示的解決方案。
@meuh 評論後更新:
我應該將什麼複製到磁碟映像才能初始化系統?
我沒有這樣做,因為通常人們會從 iso 或現有的 qemu 映像安裝 qemu,所以可能有比以下更簡單的方法。您缺少的幾乎等同於chroot所需的文件系統。
要嘗試的一件事是
sudo debootstrap --arch=amd64 unstable ~/debian-tree/
它下降並解壓縮大約 300Mbytes 的文件,您可以將其“啟動”為 systemd 容器並使用它進行測試
sudo systemd-nspawn -D ~/debian-tree/ -b
見
man machinectl
。您可以通過將 qemu 映像設置為塊設備來掛載它:sudo apt-get install qemu-utils sudo modprobe nbd ls /dev/nbd* # gives /dev/nbd0 /dev/nbd1 ... sudo qemu-nbd -c /dev/nbd0 /my/vm-image sudo mount /dev/nbd0 /mnt/... # nbd0p1 if you have partitioned sudo rsync -HSaxX ~/debian-tree/ /mnt/...
並將這棵樹複製到其中。執行 qemu 時,您通常需要提供更大的 VM 大小以避免崩潰:
qemu-system-x86_64 -m 512M ... -machine pc,accel=kvm -cpu host -enable-kvm
使用
-boot d
可能會避免訪問磁片。