Xen on qemu for arm64: 由qemu-system-aarch64导致的kernel-panic

背景描述:

        我在A平台利用qemu实现了xen中dom0的运行,将其移植到B平台运行,dom0的复现遭遇了kernel-panic,在虚拟设备的添加时异常。

一、将运行dom0所需要的可执行文件拷贝到同一个目录

        可执行文件的来源参考Xen On Qemu for arm64_qemu xen-CSDN博客

86d136c3b9ec4e8182a8b0723da71a53.png

二、Kernel-panic现象描述及其解决方法

        在可执行文件的对应目录执行以下命令:

qemu-system-aarch64 -machine virt,gic_version=3 -machine virtualization=true -cpu cortex-a57 -machine type=virt -m 4096 -smp 4 -bios u-boot.bin -device loader,file=xen,force-raw=on,addr=0x49000000 -device loader,file=Image.gz,addr=0x47000000 -device loader,file=virt-gicv3.dtb,addr=0x44000000 -device loader,file=rootfs.img.gz,addr=0x42000000 -nographic -no-reboot -chardev socket,id=qemu-monitor,host=localhost,port=7777,server,nowait,telnet -mon qemu-monitor,mode=readline

        进入uboo界面,等待启动xen:

    8cb3212e76b24a8d97042d89d05b8f02.png

 

        输入以下命令,记得替换0x47000000(linux内核镜像文件)和0x42000000(根文件系统)的大小:

fdt addr 0x44000000
fdt resize
 
fdt set /chosen \#address-cells <1>
fdt set /chosen \#size-cells <1>
 
fdt mknod /chosen module@0
fdt set /chosen/module@0 compatible "xen,linux-zimage" "xen,multiboot-module"
fdt set /chosen/module@0 reg <0x47000000 0x7F2E6A>
fdt set /chosen/module@0 bootargs "rw root=/dev/ram rdinit=/sbin/init earlyprintk=serial,ttyAMA0 console=hvc0 earlycon=xenboot"
fdt mknod /chosen module@1
fdt set /chosen/module@1 compatible "xen,linux-initrd" "xen,multiboot-module"
fdt set /chosen/module@1 reg <0x42000000 0x11BEB7>
 
booti 0x49000000 - 0x44000000

        启动xen,xen加载dom0:

e9bbdb3baaf34d98b1ca6ed7f3ad02c8.png

        Call Trace (调用栈跟踪)
        这部分信息提供了导致问题发生的函数调用序列。每一行代表一个函数调用,并且包含函数名称以及函数的地址范围。

        可以看到是在device_add发生了异常,设备是来源是qemu的做的设备虚拟化,尝试更换A平台的qemu,也就是qemu-3.1.0,统一IDE环境。


 

        查看当前qemu-system-aarch64的版本信息:

whereis qemu-system-aarch64
qemu-system-aarch64 -version

        当前B平台默认qemu-system-aarch64的版本是6.2.0

 f302087c0a394ac39e9772492c61993e.png

 3a5b4d9bf0f04e9084b1f0eaf715555c.png

 

        切换qemu-system-aarch64-3.1.0的版本,重新输入以下命令,其中qemu-3.1.0/aarch64-softmmu/qemu-system-aarch64这个最好是自己的绝对路径:

qemu-3.1.0/aarch64-softmmu/qemu-system-aarch64 -machine virt,gic_version=3 -machine virtualization=true -cpu cortex-a57 -machine type=virt -m 4096 -smp 4 -bios u-boot.bin -device loader,file=xen,force-raw=on,addr=0x49000000 -device loader,file=Image.gz,addr=0x47000000 -device loader,file=virt-gicv3.dtb,addr=0x44000000 -device loader,file=rootfs.img.gz,addr=0x42000000 -nographic -no-reboot -chardev socket,id=qemu-monitor,host=localhost,port=7777,server,nowait,telnet -mon qemu-monitor,mode=readline

        进入uboot界面,重新启动xen,运动dom0:

        3b5937ca7ba94e71a785b368a1d20729.png

        输入以下命令,记得替换内核镜像文件和根文件系统对应的大小:

fdt addr 0x44000000
fdt resize
 
fdt set /chosen \#address-cells <1>
fdt set /chosen \#size-cells <1>
 
fdt mknod /chosen module@0
fdt set /chosen/module@0 compatible "xen,linux-zimage" "xen,multiboot-module"
fdt set /chosen/module@0 reg <0x47000000 0x7F2E6A>
fdt set /chosen/module@0 bootargs "rw root=/dev/ram rdinit=/sbin/init earlyprintk=serial,ttyAMA0 console=hvc0 earlycon=xenboot"
fdt mknod /chosen module@1
fdt set /chosen/module@1 compatible "xen,linux-initrd" "xen,multiboot-module"
fdt set /chosen/module@1 reg <0x42000000 0x11BEB7>
 
booti 0x49000000 - 0x44000000

        出现命令行之后输入uname,可以看到输出linux,dom0就起来了:

374c29b3893a4242800c8adc98fda67a.png

三、qemu-system-aarch64端口被占用

        每次退出时qemu时,7777的端口被占用:

qemu-system-aarch64: -chardev socket,id=qemu-monitor,host=localhost,port=7777,server,nowait,telnet: Failed to find an available port: Address already in use

       4e918c9fe2354a02b9444aaa279c52f2.png

        一般解决方法,筛选出占用7777的进程口并强制killde:

lsof -i:7777
kill -9 PID

        利用shell脚本相关知识,一步到位:

PORT_QEMU=`lsof -i:7777 | grep qemu | awk '{print$2}'`; echo "$PORT_QEMU";kill -9 $PORT_QEMU

        1. PORT_QEMU=lsof -i:7777 | grep qemu | awk '{print$2}'`
 lsof -i:7777:
        lsof 是一个命令行工具,用于列出当前系统中打开的文件。-i:7777 参数用于筛选出监听端口         7777 的进程。
 | grep qemu:
        grep 用于在 lsof 的输出中搜索包含字符串 qemu 的行。这一步是为了确保我们找到的确实是         qemu 进程。
 | awk '{print$2}':
        awk 是一个强大的文本处理工具。这里使用 {print$2} 来打印每行的第二个字段,通常是进程的PID
        PORT_QEMU=...`:
将上述命令的结果赋值给变量 PORT_QEMU。
        2. echo "$PORT_QEMU"
        echo "$PORT_QEMU":
        输出变量 PORT_QEMU 的内容,通常是一个进程的 PID。
        3. kill -9 $PORT_QEMU
        kill -9 $PORT_QEMU:
        使用 kill 命令发送 SIGKILL 信号(信号 9)来强制终止 PID 为 PORT_QEMU 的进程。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值