基于Qemu ARM64搭建XEN Hypervisor运行环境

prtos, info 嵌入式虚拟化技术13字数 13865阅读46分13秒阅读模式

本文概述

本文介绍了ARM Xen Hypervisor架构和设计理念,并基于Qemu ARM64仿真平台搭建了Uboot+Xen+Dom0 Linux +Dom1 Linux的运行环境,以方便对Xen Hypervisor的内核实现、以及Linux客户操作系统的虚拟化支持做进一步研究和学习, 也欢迎搭建留言讨论,或者mail to: cwsun@prtos.org。

1 Xen Hypervisor

Xen是一个轻量级、高性能、开源的Hypervisor,由 LinuxFoundation托管。 Xen 的占用空间非常小:ARM版本的全部代码行数不到9万行。Xen 采用GPLv2许可,并拥有一个健康多元化的社区来支持它[1]。

Xen是type-1 Hypervisor,直接运行在裸机上,系统中的其他所有组件都作为 Xen 之上的客户虚拟机运行,包括第一个虚拟机 Dom0。 Dom0 由 Xen 创建,具有特权并驱动平台上的设备。Xen 虚拟化 CPU、内存、中断和计时器,为虚拟机提供一个或多个虚拟CPU、系统内存的一部分、一个虚拟中断控制器和一个虚拟计时器。 Xen 将 SATA 控制器和网卡等设备分配给 Dom0,负责重新映射 MMIO 区域和 IRQ。 Dom0(通常是 Linux,但也可以是 FreeBSD 或其他操作系统)为这些设备运行与本机执行相同的设备驱动程序。

Dom0 还运行一组称为半虚拟化后端的驱动程序,以允许其他非特权虚拟机访问磁盘、网络等。作为 DomU(Xen术语中的非特权Guest OS)运行的操作系统通过运行相应的半虚拟化前端驱动程序来访问一组通用虚拟设备, 单个后端服务多个前端。所有最常见的设备类别都存在一对半虚拟化驱动程序:磁盘、网络、控制台、帧缓冲区、鼠标、键盘等。它们通常存在于操作系统内核(比如Linux Kernel)中。一些 PV(Para-Virtualization) 后端也可以在 Qemu 的用户空间中运行。前端使用简单的环协议通过内存中的共享页面连接到后端。 Xen 提供了用于发现和设置初始通信的工具, 同时还提供了一种让前端和后端共享额外页面并通过软件中断相互通知的机制,图1所示。

基于Qemu ARM64搭建XEN Hypervisor运行环境

图1 Xen Hypervisor架构

1.1 ARM Xen介绍

ARM Xen消除了对仿真的任何需要,仿真模拟接口速度慢且不安全。虽然Qemu用于x86 Xen,是一个维护良好的开源项目,但在二进制大小和源代码行数方面都很大。ARM Xen不需要 Qemu,它通过尽可能多地利用硬件中的虚拟化支持并使用半虚拟化接口来实现目标。因此ARM Xen 更快、更安全。

在 x86 上,两种不同类型的Xen客户系统共存:

  • PV(Para-Virtualization)半虚拟化客户系统,例如 Linux 和其他开源操作系统
  • HVM(Hardware Virtual Machine)硬件虚拟化客户系统,通常是Windows

从Hypervisor的角度来看,PV客户系统和HVM客户系统完全不同, 这种差异一直暴露给用户,用户需要通过设置虚拟机配置文件来选择如何运行客户操作系统。ARM Xen不引入这种区分,仅支持一种两全其美的客户系统:它不需要任何仿真,并且在引导序列中尽可能早地依赖半虚拟化接口进行 IO(类似 x86 PV客户系统),它尽可能地利用硬件中的虚拟化支持,并且不需要对客户操作系统内核进行显著的更改即可运行(类似x86 HVM客户系统)。 总之,ARM Xen新架构设计目标时更简洁、更简单,结果也证明它与硬件非常匹配。

1.2 XEN ARM虚拟化扩展

ARM 虚拟化扩展提供 3 个执行级别:

  • EL0用户模式
  • EL1内核模式和
  • EL2 Hypervisor模式

ARM引入了一个新指令 HVC,用于在内核模式和Hypervisor模式之间切换。MMU 支持2个翻译阶段,通用定时器和 GIC 中断控制器是虚拟化感知的,如图2所示。

基于Qemu ARM64搭建XEN Hypervisor运行环境

图2 ARM Xen Hypervisor特权模式划分

1.3 ARM 虚拟化扩展非常适合 Xen 架构

  • Xen仅在Hypervisor模式下运行
  • Xen为客户操作系统内核保留内核模式,同时也为客户系统用户空间应用程序保留 EL0。 Type-2 类型 Hypervisor需要频繁地在Hypervisor模式和内核模式之间切换。 ARM Xen 通过完全在 EL2中运行,显着减少了所需的上下文切换次数
  • 内核使用新指令 HVC 向 Xen 发出超级调用
  • Xen 在 MMU 中使用2阶段转换为虚拟机分配内存
  • Xen 使用通用计时器来接收计时器中断以及截获计时器中断并将计数器投递给虚拟机
  • Xen 使用 GIC 接收中断以及将中断注入客户操作系统

 

Xen通过设备树发现硬件,并通过重新映射相应的MMIO区域和中断将所有不使用的设备分配给 Dom0。它为 Dom0 生成一个扁平化的设备树二进制文件,并准确地描述了暴露给它的外部环境。

Dom0 的设备树包含:

  • Xen 为其创建的虚拟 CPU 的确切数量(可能小于平台上的物理 CPU 数量)
  • Xen 提供给它的确切内存量(肯定小于可用的物理内存量)
  • Xen 重新分配给它的设备(并非所有设备都分配给 Dom0,至少一个 UART 不是(XEN自己使用))
  • 一个管理程序节点,用于在平台上宣传 Xen 的存在
  • Dom0 的启动方式与本机启动方式完全相同。通过使用设备树来发现硬件,Dom0 找出可用的设备并为其加载驱动程序。它不会尝试访问不存在的接口,因此Xen不需要进行任何模拟。通过找到Xen管理程序节点,Dom0 知道它在 Xen 上运行,因此可以初始化半虚拟化后端,而其他 DomU 将改为加载半虚拟化前端。

1.4 Xen ARM 代码大小

ARM Xen新架构与硬件非常匹配。代码大小证明了这一点:越小越好。 Xen-4.4.0中Arm平台代码量是 x86_64平台代码量的 1/6,同时仍提供相似级别的功能[1], 表格如下。

基于Qemu ARM64搭建XEN Hypervisor运行环境

Note:在我们使用的Xen-4.12.0中,Arm平台代码量上升至 x86_64平台代码量的 28.4%。

  1. Qemu ARM64仿真平台搭建Xen Hypervisor

一直想搭建一个基于Qemu  Arm64平台的Xen Hypervisor,刚好在查看资料时,看到国外的一篇博文[2]也在做同样的事情,这里的搭建过程参考了这篇博文,也修正了原文中的几个错误。因此大家在参考本文搭建运行环境的过程中,有任何疑问都可以留言或者Mail to cwsun@prtos.org。

2.1 主机环境

本文所使用的主机平台 Ubuntu 20.04.2 LTS

创建工作目录:

cd ~
export WORK_DIR=/home/tom/hdd/xen-qemu/xenonarm
mkdir -pv $WORK_DIR
export BUILD_DIR=/home/tom/hdd/xen-qemu/xenonarm/build
mkdir -pv $BUILD_DIR/busybox_arm64
cd $WORK_DIR

 

2.2.下载并安装Qemu arm64

源码安装qemu-3.1.0:

首先安装Qemu所依赖的安装包[3]:

sudo apt-get install git-email
sudo apt-get install libaio-dev libbluetooth-dev libbrlapi-dev libbz2-dev
sudo apt-get install libcap-dev libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev
sudo apt-get install libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev
sudo apt-get install librbd-dev librdmacm-dev
sudo apt-get install libsasl2-dev libsdl1.2-dev libseccomp-dev libsnappy-dev libssh2-1-dev
sudo apt-get install libvde-dev libvdeplug-dev libvte-2.90-dev libxen-dev liblzo2-dev
sudo apt-get install valgrind xfslibs-dev 
sudo apt-get install libnfs-dev libiscsi-dev

下载Qemu-3.1.0源码,并编译:

wget http://sources.buildroot.net/qemu/qemu-3.1.0.tar.xz 
tar xvf qemu-3.1.0.tar.xz $cd qemu-3.1.0 
./configure --target-list=aarch64-softmmu $make -j4

将编译出来的qemu-system-aarch64所在路径添加至环境变量PATH:

export PATH=/home/tom/hdd/xen-qemu/xenonarm/qemu-3.1.0/aarch64-softmmu:$PATH

Note:

如果使用Ubuntu20.04默认安装的QEMU emulator version 4.2.1加载Linux Kernel,会遇到amba设备加载失败而导致Kernel panic,bt栈如下:

[    0.834333] Process swapper/0 (pid: 1, stack limit = 0x(____ptrval____))

[    0.836695] Call trace:

[    0.838215]  amba_device_try_add+0x150/0x2a8

[    0.851931]  amba_device_add+0x18/0xd0

[    0.859928]  of_platform_bus_create+0x2e8/0x370

[    0.860953]  of_platform_populate+0x50/0xc8

[    0.865344]  of_platform_default_populate_init+0xac/0xc8

[    0.869535]  do_one_initcall+0x54/0x158

[    0.870997]  kernel_init_freeable+0x188/0x224

[    0.872342]  kernel_init+0x10/0x100

[    0.873476]  ret_from_fork+0x10/0x18

[    0.878239] Code: 35000940 d10082c2 52800000 8b020302 (88dffc41)

[    0.881416] ---[ end trace cdf2d9eb01f921c4 ]---

[    0.884323] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

[    0.893498] SMP: stopping secondary CPUs

[    0.903188] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]---

对于这个问题,正如回溯栈中提示的那样,由于amba设备加载失败而导致Kernel panic。非常感谢Simon同学给出的WA,我们只需要在2.8节生成的设备树中,禁用 ARM PL061 Advanced Microcontroller Bus Architecture即可。

dtc -I dtb -O dts virt-gicv3.dtb > virt-gicv3.dts
sed 's/compatible = "arm,pl061.*/status = "disabled";/g' virt-gicv3.dts > virt-gicv3-edited.dts
dtc -I dts -O dtb virt-gicv3-edited.dts > virt-gicv3.dtb

 

2.3.安装交叉工具链和Xen, Linux, Uboot, Busybox

安装Arm交叉编译工具:

sudo apt install gcc-aarch64-linux-gnu

下载Xen, Linux Kernel, Busybox, UBoot

wget  https://downloads.xenproject.org/release/xen/4.12.0/xen-4.12.0.tar.gz
tar xvf xen-4.12.0.tar.gz

wget  https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.20.11.tar.xz
tar xvf linux-4.20.11.tar.xz

wget https://www.busybox.net/downloads/busybox-1.34.0.tar.bz2
tar xvf https://www.busybox.net/downloads/busybox-1.34.0.tar.bz2

wget  ftp://ftp.denx.de/pub/u-boot/u-boot-2019.01.tar.bz2
tar xvf u-boot-2019.01.tar.bz2

2.3.通过Busybox制作根文件系统

cd $WORK_DIR/busybox-1.34.0
make 0=$BUILD_DIR/busybox_arm64/ ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- defconfig
make 0=$BUILD_DIR/busybox_arm64/ ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- menuconfig

在menuconfig配置界面,进入Setting菜单,选中Build static binary, 如下图所示。

基于Qemu ARM64搭建XEN Hypervisor运行环境

或者不通过menuconfig,直接在"make 0=$BUILD_DIR/busybox_arm64/ ARCH=arm CROSS_COMPILE=aarch64-linux-gnu- defconfig”生成的.config中添加选项“ONFIG_STATIC=y”。

编译并安装busybox:

make -j4 0=$BUILD_DIR/busybox_arm64/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
make install  0=$BUILD_DIR/busybox_arm64/ ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

制作根文件系统:

cd _install/
mkdir proc sys dev etc etc/init.d
cd ..
vim _install/etc/init.d/rcS

在rcS文件中插入:

#! /bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
/sbin/mdev -s

将rcS文件添加执行权限 :

chmod +x _install/etc/init.d/rcS

创建rootfs image镜像:

cd _install
find . | cpio -o --format=newc > ../rootfs.img
cd ..
gzip -c rootfs.img > rootfs.img.gz
cp rootfs.img.gz $BUILD_DIR/busybox_arm64/

 

2.4.编译Dom0 Linux Kernel

cd $WORK_DIR/linux-4.20.11/
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

在生成的.config文件中添加下面两个选项(默认情况下这两个选项已经设置):

CONFIG_XEN_DOM0=y
CONFIG_XEN=y

示意图如下:

基于Qemu ARM64搭建XEN Hypervisor运行环境

编译内核,并复制生成的内核映像到指定的目录

make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
cp ./arch/arm64/boot/Image.gz $BUILD_DIR/busybox_arm64/
cp ./arch/arm64/boot/Image $BUILD_DIR/busybox_arm64/

Note:

Image:通用的 Linux 内核二进制映像文件。

Image.gz:Image的gzip格式的压缩文件。

2.5.Qemu上运行Linux Kernel+Busybox

cd $BUILD_DIR/busybox_arm64
qemu-system-aarch64 \
-machine virt,gic_version=3 \
-machine virtualization=true \
-cpu cortex-a57 \
-machine type=virt \
-m 4096 \
-smp 4 \
-kernel Image.gz \
-nographic \
-no-reboot \
-initrd rootfs.img.gz \
-append "rw root=/dev/ram rdinit=/sbin/init earlyprintk=serial,ttyAMA0 \
console=ttyAMA0"

示意图如下:

基于Qemu ARM64搭建XEN Hypervisor运行环境

这一步可以验证,我们制作的Linux Kernel和rootfs.img.gz根文件系统可以工作。

2.6.配置并编译Uboot

cd $WORK_DIR/u-boot-2019.01
make CROSS_COMPILE=aarch64-linux-gnu- qemu_arm64_defconfig

将下面的两个配置项添加到.config文件(默认情况下,这两个选项已添加)

CONFIG_ARCH_QEMU=y
CONFIG_TARGET_QEMU_ARM_64BIT=y

编译Uboot:

make CROSS_COMPILE=aarch64-linux-gnu- -j4

并复制到指定的目录,并进入该目录:

cp u-boot.bin $BUILD_DIR/busybox_arm64/
cd $BUILD_DIR/busybox_arm64/

启动Uboot,并通过Uboot加载Linux Kernel:

qemu-system-aarch64 \
-machine virt,gic_version=3 \
-machine virtualization=true \
-cpu cortex-a57 \
-machine type=virt \
-m 512M \
-bios u-boot.bin \
-device loader,file=Image,addr=0x45000000 \
-nographic -no-reboot \
-chardev socket,id=qemu-monitor,host=localhost,port=7777,server,nowait,telnet \
-mon qemu-monitor,mode=readline

Uboot执行效果如下:

基于Qemu ARM64搭建XEN Hypervisor运行环境

Note

这里使用的是未压缩的Kernel二进制映像。

在Uboot的命令行终端中,输入下面的命令:

booti 0x45000000 - 0x40000000

Kernel启动效果如下:

基于Qemu ARM64搭建XEN Hypervisor运行环境

Note:

0x45000000是我们上面制作的内核映像的地址,0x40000000是Qemu设备树blob的默认地址。由于我们没有在上面的命令中指定根文件系统root.img.gz,所以Linux kernel加载root fs时失败了,这是可预期的行为。

这里我们可以验证,我们编译的Uboot可以正常引导Linux kernel映像。

 

2.7.编译器Xen Hypervisor

cd $WORK_DIR/xen-4.12.0
make dist-xen XEN_TARGET_ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

Note:

编译时若报错:error: taking address of packed member of ‘struct <anonymous>’ may result in an unaligned pointer value”,则修改xen/Rules.mk文件,去掉-Werror。

复制Xen映像到指定目录:

cp xen/xen $BUILD_DIR/busybox_arm64/

2.8.生成设备树blob

cd $BUILD/busybox_arm64/
qemu-system-aarch64 \
-machine virt,gic_version=3 \
-machine virtualization=true \
-cpu cortex-a57 \
-machine type=virt \
-m 4096 \
-smp 4 \
-display none \
-machine dumpdtb=virt-gicv3.dtb

 

2.9.运行Qemu Xen Dom0 Linux

现在我们已经有了在Qemu上运行Uboot , Xen, Linux Kernel映像,Root FS, 设备树文件:

基于Qemu ARM64搭建XEN Hypervisor运行环境

在Qemu上运行Xen,并由Xen启动Linux Kernel作为Dom0上的OS:

cd $BUILD/busybox_arm64/
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 \
-nographic \
-no-reboot \
-chardev socket,id=qemu-monitor,host=localhost,port=7777,server,nowait,telnet \
-mon qemu-monitor,mode=readline

为了启动Dom0上的Linux Kernel,我们通过写入以下fdt命令来修改设备树blob(在/chosen/module@0中填写我们制作出来的Image.gz的大小):

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 0x7cd104>
fdt set /chosen/module@0 bootargs "earlyprintk=serial,ttyAMA0 console=ttyAMA0,115200n8 earlycon=xenboot"

booti 0x49000000 - 0x44000000

Note:

通过下面的命令,我们可以计算出Image.gz的大小:

printf "0x%x\n" $(stat -c %s Image.gz)

实际计算结果

基于Qemu ARM64搭建XEN Hypervisor运行环境

运行效果:

基于Qemu ARM64搭建XEN Hypervisor运行环境

由于我们没有在上述命令中指定根文件系统root.img.gz,所以kernel在加载rootfs时出错了,这是可预期的行为。

现在我们在Qemu上启动Xen, Linux, Busybox时,并指定rootfs:

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中输入以下fdt命令:

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 0x7cd104>
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 0x11b577>
booti 0x49000000 - 0x44000000

Note:

基于Qemu ARM64搭建XEN Hypervisor运行环境

通过上述命令更新/chosen/module@1 中rootfs.img.gz的大小为0x11b577。

基于Qemu ARM64搭建XEN Hypervisor运行环境

在我们输入Enter键后,可进入Dom0 Linux Kernel的console,示意图如下:

基于Qemu ARM64搭建XEN Hypervisor运行环境

 

10.运行Qemu Xen Dom0 Linux 和Dom1 Linux

10.1 Dom0和Dom1使用同一个Linux内核映像

可以直接使用同一个内核映像Image 作为Dom0和Dom1的Linux Kernel使用,执行命令:

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=Image,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

Note:

在这种场景下,由于某些限制,我们这里使用未压缩的 Linux 内核 映像(因此我们需要测量它们的大小并在 fdt 命令中更改它们,确保各个映像不会在内存中重叠),这和上面使用的压缩内核映像Image.gz不同:

基于Qemu ARM64搭建XEN Hypervisor运行环境

输入的fdt命令:

setenv xen_bootargs 'dom0_mem=512M'
fdt addr 0x44000000
fdt resize
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 0x1241200>
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 0x11b577>
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 0x1241200>
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 0x11b577>
booti 0x49000000 - 0x44000000

 

fdt命令执行状态:

基于Qemu ARM64搭建XEN Hypervisor运行环境

执行效果:

基于Qemu ARM64搭建XEN Hypervisor运行环境

 

10.2 Dom0和Dom1使用不同的Linux内核映像

cd $WORK_DIR
mkdir linux-for-domU
cp linux-4.20.11.tar.xz linux-for-domU/
cd linux-for-domU/
tar xvf linux-4.20.11.tar.xz
cd linux-4.20.11
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig

 

在生成的.config中把“CONFIG_XEN_DOM0=y”注释掉,保留”CONFIG_XEN=y”

编译内核,并将编译后的内核镜像拷贝到指定目录:

make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
cp ./arch/arm64/boot/Image $BUILD_DIR/busybox_arm64/ImageU

运行命令:

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

使用10.1相同的FDT命令,运行效果和10.1相同。

 

参考资料

[1] https://wiki.xenproject.org/wiki/Xen_ARM_with_Virtualization_Extensions_whitepaper

[2] https://medium.com/@denisobrezkov/xen-on-arm-and-qemu-1654f24dea75

[3] https://wiki.qemu.org/Hosts/Linux

[4] https://www.starlab.io/blog/how-the-xen-hypervisor-supports-cpu-virtualization-on-arm

 

 

 

 

继续阅读
prtos, info
  • 本文由 发表于 2021年9月11日 16:30:30
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
  • Qemu,Xen,arm64,uboot,hypervisor
评论  13  访客  13
    • 123
      123 0

      感谢作者的好文! 非常感谢!

      • simon
        simon 0

        amba设备加载失败而导致Kernel panic:
        禁用 ARM PL061 Advanced Microcontroller Bus Architecture
        dtc -I dtb -O dts virt-gicv3.dtb > virt-gicv3.dts
        sed ‘s/compatible = “arm,pl061.*/status = “disabled”;/g’ virt-gicv3.dts > virt-gicv3-edited.dts
        dtc -I dts -O dtb virt-gicv3-edited.dts > virt-gicv3.dtb

          • prtos, info
            prtos, info

            @ simon Hi Simon,非常感谢你给出的WA,It works。我已经将你提供的WA更新到doc中O(∩_∩)O~

          • 崩玉
            崩玉 0

            你好,我在配置不同kernel的DOMU时,倒数第二步报错,这是什么原因,如何解决呢?感谢!
            => fdt set /chosen/domU1/module@1 compatible “multiboot,ramdisk” “multiboot,module”
            libfdt fdt_setprop(): FDT_ERR_NOSPACE
            => fdt set /chosen/domU1/module@1 reg
            => booti 0x49000000 – 0x44000000
            Bad Linux ARM64 Image magic!

              • prtos, info
                prtos, info

                @ 崩玉 请留意出错提示,已经显示出错原因。

                • yan_36998
                  yan_36998 0

                  @ 崩玉 FDT_ERR_NOSPACE 这个出错如何解决呢,能否给说明一下,谢谢

                    • prtos, info
                      prtos, info

                      @ yan_36998 我没有遇到过这个问题,如果你采用跟我相同的host os,应该不会遇到这个问题。

                      • Joy
                        Joy 0

                        @ yan_36998 在出现 FDT_ERR_NOSPACE 报错的对应fdt 指令前,执行 fdt resize ,可以理解为扩充了 dts blob 的空间,然后再接着用fdt命令其他指令就OK了

                    • lixingshuai
                      lixingshuai 1

                      博主:我运行到这里就卡住了,可以按Ctrl+a切换,但没有后续的内核打印信息,您可以帮忙解答一些吗?
                      (XEN) No support for ARM_SMCCC_ARCH_WORKAROUND_1.
                      (XEN) Please update your firmware.
                      (XEN) ***************************************************
                      (XEN) 3… 2… 1…
                      (XEN) *** Serial input to DOM0 (type ‘CTRL-a’ three times to switch input)
                      (XEN) *** LOADING DOMU cpus=1 memory=85ee0KB ***
                      (XEN) Loading Domd1 kernel from boot module @ 0000000053000000
                      (XEN) Loading ramdisk from boot module @ 0000000058000000
                      (XEN) Loading zImage from 0000000053000000 to 0000000040080000-000000004084cbcc
                      (XEN) Loading dom0 initrd from 0000000058000000 to 0x0000000048200000-0x000000004831c20d
                      (XEN) Loading dom0 DTB to 0x0000000048000000-0x00000000480004d5
                      (XEN) Freed 312kB init memory.

                    匿名

                    发表评论

                    匿名网友

                    :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

                    确定