qemu使用踩坑

Table of Contents

编译qemu

./configure --target-list=aarch64-softmmu --enable-virtfs --enable-slirp --enable-debug
make -j8

Mac OS 不支持9Pfs

最新的slirp需要从发行版外部来安装 libslirp 包。

运行

qemu-system-aarch64 -machine virt -cpu cortex-a57 -machine type=virt -nographic -smp 4 -m 2048 --append "console=ttyAMA0" --kernel ~/work/src/linux.git/arch/arm64/boot/Image --initrd ~/work/buildroot-2018.05/output/images/rootfs.cpio.bz2

推出

Ctrl-A x

文件共享

9P over virtiofs

9pfs是基于网络的文件共享协议,qemu中的软件可以通过此种方法来访问宿主机中的文件。详见Plan 9 9p remote filesystem protocol
qemu在Mac OS上不支持virtio,故无法使用以下的方法
参数设置:

  • 针对宿主机

    -fsdev local,id=shareid,path=/home/schspa/work/src/share,security_model=none

    上述参数告诉QEMU要设置一个文件系统设备,使用本地的文件系统,id设置为shareid

  • 针对客户机

    -device virtio-9p-device,fsdev=shareid,mount_tag=share

    上面的参数告诉向客户机添加一个设备,设备类型是virtio-9p-device,连接到设备shareid, 挂载时的tag为share

  • 挂载共享文件夹
    在客户系统启动时需要挂载共享的文件夹,上面已经显示出来mount_tag是share
    挂载命令

    mount -t 9p -o trans=virtio share /mnt/share
    

    mount tag也可以通过sysfs来查看

    /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag
    

网络设置

linux Host

  • 设置网络设备

    #!/usr/bin/env bash
    
    sudo ip link add br0 type bridge
    sudo ip link set br0 up
    sudo ip addr add 192.168.123.1/24 broadcast 192.168.123.255 dev br0
    sudo dnsmasq  --strict-order --except-interface=lo --interface=br0 --listen-addr=192.168.123.1 --bind-interfaces --dhcp-range=192.168.123.101,192.168.123.254 --pid-file=/var/run/qemu-dhcp-br0.pid
    
    sudo ip tuntap add tap0 mod tap user $UID
    sudo ip link set dev tap0 up
    sudo ip link set dev tap0 master br0
    
  • 卸载网络设备

    #!/usr/bin/env bash
    
    sudo ip link set dev tap0 nomaster
    sudo ip link set tap0 down
    sudo ip tuntap del tap0 mod tap
    
    sudo ip link set br0 down
    sudo ip link delete br0 type bridge
    sudo kill $(cat /var/run/qemu-dhcp-br0.pid)
    

    上述脚本添加了一个tap设备1,并使用dnsmasq网桥桥开启了dhcp,客户端启动之后即可自动获取ip地址。由于没有将实体网卡加入到br0的网桥之中,目前客户机系统还无法联网。

TODO Macos Host

qemu command line

-netdev tap,ifname=tap0,id=net0,script=no,downscript=no -device virtio-net-device,netdev=net0,mac=52:55:00:fa:ee:10

QMP (QEMU Machine Protocol)

Use TCP Port

  • qemu launch argument

    -qmp tcp:localhost:4444,server,nowait
    
  • connect command

    telnet localhost 4444
    Trying ::1...
    Connected to localhost.
    Escape character is '^]'.
    {"QMP": {"version": {"qemu": {"micro": 1, "minor": 0, "major": 4}, "package": "v4.0.1-193-g8655781df2"}, "capabilities": ["oob"]}}
    

Use Unix Socket

  • qemu launch argument
-qmp unix:./qmp-sock,server,wait=off
  • connect command

    nc -U ~/test/linux-5.19.y-0803/tests/qmp-sock-wq-test-5.19-3
    {"QMP": {"version": {"qemu": {"micro": 0, "minor": 2, "major": 6}, "package": "Debian 1:6.2+dfsg-2ubuntu6.3"}, "capabilities": ["oob"]}}
    

use qmp-shell script

echo "query-status" | ~/work/src/qemu/scripts/qmp/qmp-shell ~/work/tmp/qmp-sock -p

create vmcore

This can be used to create a vmcore file for debug via crash/gdb

{"execute": "qmp_capabilities"}
{"execute":"dump-guest-memory","arguments":{"paging":true,"protocol":"file:/home/schspa/dump/vmcore.img"}}
{"execute": "quit" }

{"execute": "query-machines"}

QEMU状态查询

dump & change dtb

-machine dumpdtb=file.dtb

通过在qemu命令中添加上面的参数, 可以将qemu内部自动生成的device-tree给保存到当
前working文件夹下, 后续可以通过dtc的命令修改, 并指定使用修改后的dtb来启动改。

qemu-system-aarch64: info: dtb dumped to file.dtb. Exiting.
dtc -I dtb -O dts -o file.dts file.dtb
# Do your modify to dts source file
dtc -I dts -O dtb -o file.dtb file.dts

添加下面的参数来指定dtb文件

--dtb file.dtb

查看qemu中的设备状态

qemu-system-aarch64  -M virt -serial pty -monitor stdio

打印设备信息

info qtree

打印内存地址信息

info mtree

参考文档

Footnotes:

Contact me via :)
虚怀乃若谷,水深则流缓。