用Xen同时启动dom0和domU的中文帖子——Xen On Qemu for arm64
由于我的第一份工作也是有关hypervisor虚拟化的,此前玩过minos-hypervisor,但是与xen-hypervisor相比代码量与稳定性都相差较大,我找了很多帖子,有关xen的项目都很零碎,在csdn看到了一篇文章,参考这篇文章复现利用xen实现双系统的运行。参考文章的链接:Xen On Qemu for arm64_qemu xen-CSDN博客。这篇文章也是为了记录复现时遇到的问题,及其解决办法,欢迎讨论交流。文中提到的log和脚本的源文件在文章末尾下载,复现有其他问题欢迎联系交流:1665575244@qq.com
Ubuntu:20.04
Linux-4.20.11
xen-4.12.0
一、Failed to execute /sbin/init(error -2):root cause是由于dom0内核挂载根文件导致的error
此前已经排除掉xen通过设备树传递根文件错误的可能性,xen将制作好的根文件系统的镜像文件的地址加载到dom0的的内核地址的一块区域,linux内核启动时从设备树读出来的根文件的地址是无误的。
接下来从log中看到错误最先是发生在linux内核启动后的第一个进程中sbin/init
从Failede to execute /sbin/init 开始分析找到这个error-2是在加载过程中的哪里发生的,ret是由run_init_process(ramdisk_execute_command)产生的:
return do_execve(getname_kernel(init_filename):
return do_execveat_common(AT_FDCWD, filename, argv, envp, 0):
return __do_execve_file(fd, filename, argv, envp, flags, NULL):
对比log1图和2图会发生1图的/sbin/init是从3544->3548,2图的/lib/ld-linux-aarch64.so.1是3544->3561,这个error也就是Failed to execute /sbin/init(error -2)的root cause。缺失了某个库而导致内核对根文件的挂载出现问题
那么要解决这个缺少动态库文件有两种解决办法:一、手动添加链接动态库。二、配置静态编译,再编译时就无需依赖其他库了。
静态编译会在编译器在编译可执行文件时,把需要用到的对应动态链接库(.so或.ilb)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行时不需要依赖于动态链接库.
.动态编译: 动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令。所以其优点一方面是缩小了执行文件本身的体积,另一方面是加快了编译速度,节省了系统资源。缺点一是哪怕是很简单的程序,只用到了链接库中的一两条命令,也需要附带一个相对庞大的链接库;二是如果其他计算机上没有安装对应的运行库,则用动态编译的可执行文件就不能运行。
参考文章:动态链接库和静态链接库-CSDN博客
二、Busybox的静态编译
Busybox的.config文件用于配置和编译设置。
在Busybox中,.config文件是一个重要的配置文件,它包含了用于配置和编译Busybox的各种设置和选项。这个文件通常在使用make menuconfig等工具进行配置时生成,其中可以指定交叉编译器路径、想要的命令、busybox的支持特性、安装路径等配置。通过修改.config文件,用户可以定制Busybox的功能和特性,以满足特定的需求。
确认.config中添加的CONFIG_STATIC=y是否生效,理论上生效了就不会有上文的缺失动态库问题。
对比.config文件和xen_dom0_test.sh会发现CONFIG_STATIC=y这个宏却处于not set:
确认CONFIG_STATIC=y未生效的原因,通过echo确实将CONFIG_STATIC=y写进了.config文件:
紧接着执行的make命令修改了config的配置,自动删除了CONFIG_STATIC=y:
正确的解决方法是手动修改这个宏,需要删掉原来注解的一行,这样就.comfig的配置就不会受之后的make编译影响,后续脚本编译过程,Busybox的.config配置就保留,不要再更改:
注释掉Busybox的编译脚本,重新执行xen_dom0_test.sh,最终会进入到uboot界面:
对比修改Busybox的.config配置加入静态编译之后,根文件系统rootfs相比之前大了几MB:
0x47000000是linux内核Image.gz的地址,0x42000000是linux内核所需要的根文件的系统地址,将两者的大小替换为对应显示的大小,这样就可以通过uboot就能启动linux内核以及加载根文件系统:
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 0x7F3025>
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 0x11BEAB>
booti 0x49000000 - 0x44000000
dom0启动之后,出现命令行之后,用uname查看显示linux,到此xen所创建的dom0就运行了:
如果出现无Xen或者dom0运行期间无故出现killed的情况,可以通过dmesg查看killed是否是内存溢出导致,或者top新开窗口实时查看内存使用情况。
出现killed的解决方法:一、可以减少dom0分配的内存。二、增加虚拟机的虚拟内存:
每次killded的位置可能会不一样,这样每次虚拟机就能稳定运行dom0了。
利用Xen同时运行dom0和domU:
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,addr=0x47000000 -device loader,file=ImageU,addr=0x53000000 -device loader,file=virt-gicv3.dtb,addr=0x44000000 -device loader,file=rootfs.img.gz,addr=0x42000000 -device loader,file=rootfs.img.gz,addr=0x58000000 -nographic -no-reboot -chardev socket,id=qemu-monitor,host=localhost,port=7777,server,nowait,telnet -mon qemu-monitor,mode=readline
setenv xen_bootargs 'dom0_mem=512M' fdt addr 0x44000000 fdt resize 8192 fdt set /chosen \#address-cells <1> fdt set /chosen \#size-cells <1> fdt set /chosen xen,xen-bootargs \"$xen_bootargs\" 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> fdt mknod /chosen domU1 fdt set /chosen/domU1 compatible "xen,domain" fdt set /chosen/domU1 \#address-cells <1> fdt set /chosen/domU1 \#size-cells <1> fdt set /chosen/domU1 \cpus <1> fdt set /chosen/domU1 \memory <0 548576> fdt set /chosen/domU1 vpl011 fdt mknod /chosen/domU1 module@0 fdt set /chosen/domU1/module@0 compatible "multiboot,kernel" "multiboot,module" fdt set /chosen/domU1/module@0 reg <0x53000000 0x1271A00> fdt set /chosen/domU1/module@0 bootargs "rw root=/dev/ram rdinit=/sbin/init console=ttyAMA0" fdt mknod /chosen/domU1 module@1 fdt set /chosen/domU1/module@1 compatible "multiboot,ramdisk" "multiboot,module" fdt set /chosen/domU1/module@1 reg <0x58000000 0x11BEB7> booti 0x49000000 - 0x44000000
log及其脚本资源下载链接:通过百度网盘分享的文件:xen_dom0_sbin-init.zip
链接:https://pan.baidu.com/s/1HD3yD_hEOzO7_eNX22LWvw
提取码:1234