通过这篇有趣的教程,熟悉运行在赛灵思 Zynq UltraScale+ MPSoC 上的 Xen 管理程序。
赛灵思和 DornerWorks 的系统软件团队在赛灵思的 Zynq® Ultrascale+™ MPSoC 上启动 Xen Project 管理程序时,我们发现可通过运行当年叱诧一时的流行电子游戏 Doom 来演示和测试系统。
如何针对 Zynq UltraScale+ MPSoC 通过 QEMU 在 Xen 上运行 Doom 呢,在详细介绍具体步骤之前,我们先来了解什么是管理程序,以及它们如何与 Zynq UltraScale+ MPSoC 上的处理器协同工作。
管理程序及其工作原理
管理程序是一种可虚拟化处理器的计算机程序。运行在虚拟化处理器上的应用程序和操作系统似乎完全拥有系统,但事实上管理程序负责管理虚拟处理器对物理机资源(例如存储器和处理内核)的访问。管理程序之所以流行,是因为能实现设计分区以及系统上运行的独立软件元素之间的隔离。
为了支持虚拟化,物理处理器必须提供一个供管理程序运行的特殊“模式”。因此,介绍处理器模式有助于理解管理程序如何完成处理器魔法。
所有处理器都有一些指令,这些指令可操作寄存器中存储的值,并可读写存储器。处理器的模式是指令和寄存器的集合,以及利用指令访问寄存器和存储器时要遵守的规则。为了便于解释,我们以通用处理器为例来介绍,并使用与结构无关的术语。在这个实例中,处理器具有特定的寄存器、指令和模式。寄存器包括 RegisterA、RegisterB、RegisterC、UserProgramCounter、Register-Super 和 SuperProgramCounter。指令包括以下内容。
ADD Register3 Register1 Register2 将 Register1 与 Register2 相加,并把结果存入 Register3,即 Register3 = Register1 + Register2。
MOVTO Register2 Register1 将 Register1 中地址所指向的存储器内容移动到 Register2。
MOVFROM Register2 Register1 将 Register1 的内容移动到 Register2 中地址所指向的存储器。
ENTERSUPER 进入处理器的 SUPER 模式。
EXITSUPER 退出 SUPER 模式并进入 USER 模式。
在 USER 模式下,处理器的指令的功能受到限制。本例中,指令可对除 RegisterSuper 和 SuperProgramCounter 以外的所有寄存器进行读和写操作,处理器可执行除 EXITSUPER 以外的所有指令。
此外,在 USER 模式下,所有指令只能读和写一部分存储器,例如从地址 0x0000_0100 到 0x0FFF_FFFF。在 USER 模式下,如果程序尝试执行不应该执行的指令,或者访问无权访问的寄存器或存储器位置,那么处理器将暂停出错指令 (offending instruction)。
SUPER 模式下,处理器的指令可以读/写上述所有寄存器,包括 RegisterSuper 和 SuperProgramCounter。以上所列的所有指令,包括 EXITSUPER,都可以执行,另外,附加的指令 ENTERHYPER 也可执行(后面详细介绍该指令)。此外,在 SUPER 模式下,指令可以访问系统中的全部存储器(从 0x0000_0000 到 0x7FFF_ FFFF)。
采用带模式的处理器,使我们可以利用设计分区来更简单地解决软件工程设计问题。以上实例中,只有一种方法进入 SUPER 模式:执行 ENTERSUPER 指令。同样,只有一种方法退出 SUPER 模式:执行 EXITSUPER。此外,在 USER 模式下程序只能访问机器的部分存储器。有了这种方案,我们可编写一个程序让处理器同时运行多个 USER 模式程序。这个“操作系统”(OS) 程序运行在 SUPER 模式,并管理在 USER 模式中运行的程序。
当 OS 运行时,会查看需要运行的所有 USER 模式程序,选择一个运行,然后使用 EXITSUPER 这样的指令通知处理器切换到 USER 模式以运行程序。所选的程序会一直运行,直到有事件导致处理器切回 SUPER 模式。这类事件可以是来自 USER 模式程序的 ENTERSUPER 指令,或外部事件,例如定时器,它可以不提醒正在 USER 模式下运行的程序将处理器切换到 SUPER 模式。无论切换如何发生,每当事件发生时,我们都可构建 OS 以根据相应策略相继选择和运行程序。当切换快速进行时,用户认为 USER 程序同时运行。
USER HYPER 模式的用处是让很多 SUPER 程序运行。SUPER 模式下的每个程序都可以是 OS;这些 OS 本身会让很多 USER 程序并行运行。
SUPER 处理器模式还能防止 USER 程序干扰运行在 SUPER 模式的程序或其他 USER 模式程序。USER 模式程序的任何错误或违规都可被控制在该程序自身的实例中,不会破坏或干扰为 SUPER 模式操作保留的系统存储器和寄存器。
听起来很好,但能否用另一个模式实现一些功能?
对我们的机器稍加扩展,就可以引入 HYPER 模式。HYPER 模式可以读/写所有初始寄存器(RegisterA、RegisterB、RegisterC、UserProgramCounter、RegisterSuper 和 SuperProgramCounter)以及两个附加寄存器:RegisterHyper 和 HyperProgramCounter。HYPER 模式下的指令包括初始集以及下面的斜体字。
ADD Register3 Register1 Register2 将 Register1 与 Register2 相加并把结果放在 Register3 中,即 Register3 = Register1 + Register2。
MOVTO Register2 Register1 将 Register1 中地址所指向的存储器内容移到 Register2。
MOVFROM Register2 Register1 将 Register1 的内容移到 Register2 中地址所指向的存储器。
MOVTOPHYS Register2 Register1 将 Register1 中物理地址指向的存储器内容移到 Register2。
MOVFROMPHYS Register2 Register1 将 Register1 的内容移到 Register2 中地址指向的物理存储器。
ENTERSUPER 进入处理器的 SUPER 模式。
EXITSUPER 退出 SUPER 模式并进入 USER 模式。
ENTERHYPER 进入处理器的 HYPER 模式。
EXITHYPER 退出处理器的 HYPER 模式。
SWITCHSUPER RegisterHyper 切换到 SUPER 程序,该程序将使用 RegisterHyper 中的值来执行下一个 SUPER 程序。
HYPER 模式中的附加指令和寄存器允许处理器切换哪个程序在 SUPER 模式中运行,就像 SUPER 模式允许处理器切换哪个程序在 USER 模式中运行一样。HYPER 模式的一个特性是能够切换哪个存储器 SUPER 模式能看到;当一个在 HYPER 模式中运行的程序执行 SWITCHSUPER RegisterHyper 时,底层存储器完全断开。这就是说当 HYPER 模式中的程序执行了 EXITHYPER 之后,下个 SUPER 程序运行之时,SUPER 模式看到的实际物理存储器与运行在 SUPER 模式中的另一个程序使用的物理存储器不同。SUPER 模式程序仍使用相同地址访问存储器,但是该地址指向不同的物理位置。图 1 显示了执行 SWITCHSUPER RegisterHyper 前后的处理器存储器视图。
HYPER 模式很有用,是因为它允许很多个 SUPER 程序运行。SUPER 模式中每个程序都可以是 OS;这些 OS 本身可以让很多 USER 程序并列运行.这意味着,我们可以在相同硬件上运行多个 OS,例如 Windows 和 Linux;在一个处理器上运行 20 个 Linux 实例;或者之间的任意组合。由于每个虚拟 OS 实例无法看到另一个 OS 实例,因此如果一个崩溃,不会使另一个实例也崩溃。HYPER 模式的特性还有其他应用:我们可以在多个 OS 之间对系统资源分区;监测 HYPER 模式下每个 OS 的执行,以在崩溃时重启;以及在虚拟 OS 运行时密切关注系统状态。
图 1:HYPER 模式下执行 SWITCHSUPER RegisterHyper 的前后区别
随着处理器从 USER 切换到 SUPER 模式,再从 SUPER 切换到 HYPER 模式,机器会赋予执行代码更多特权。本例中,USER 模式程序只有权使用四个寄存器(RegisterA、RegisterB、RegisterC 和 UserProgramCounter)和四个指令:(ADD、MOVTO、MOVFROM和ENTER-SUPER)。此外,USER 程序只能读写 0x0000_0100 至 0x0FFF_ FFFF 的存储器。一旦进入 SUPER 模式,处理器允许指令与 RegisterSuper 和 SuperProgramCounter 对话,并允许执行 EXITSUPER 和 ENTERHYPER。此外,SUPER 程序可以访问从 0x0000_0000 至 0x7FFF_FFFF 的存储器。
最后,一旦处理器进入 HYPER 模式,其指令就可以操作 RegisterHyper 和 HyperProgramCounter,而且程序可执行 SWITCH-SUPER 和 EXITHYPER。
图 2:各种模式如环形所示
HYPER 模式还允许处理器读写所有虚拟存储器,0x0000_0000 至 0xFFFF_FFFF,以及读写实际物理存储器。这些特权等级通常被直观地用环形来描述(图 2)。主环,即 HYPER 环为特权等级较低的环赋予权限,最终可控制整个系统。
理论结合实践
ARM® 创建处理器设计,供 ARM 合作伙伴构建芯片用。ARM 处理器包含一个或多个内核。每个内核实现一个 ARM 架构。例如,Zynq UltraScale+ MPSoC 包含一个 ARM Cortex™-A53 处理器及四个 ARMv8-A 物理内核(图 3)。
当查看 ARM 处理器的文档和代码时,这种区别很重要;为了全面理解具有一个 ARM 内核的“芯片”,可参考有关架构 (如 ARMv8-A) 和处理器 (如 Cortex-A53) 的文档。ARMv8 架构中有四个例外等级 (来源:ARM 架构参考手册,D1-1404):
1、例外等级 0 (EL0),无需特权即可执行;
2、例外等级 1 (EL1),执行 OS 以及任何执行特权指令的内容;
3、例外等级 2 (EL2),允许硬件被虚拟化;以及
4、例外等级 3 (EL3),允许在安全与非安全处理器状态之间切换。
以下程序通常在这些模式下运行,如ARM 架构参考手册 (D1–1404)中所述:EL0,应用程序;EL1,OS 内核以及通常所描述的相关特权函数;EL2,管理程序;EL3,安全监控器。我们的理论实例直接对应 ARMv8 执行模式 EL0 至 EL2:USER 对应 EL0,SUPER 对应 EL1,HYPER 对应 EL2。ARM 添加第四个特权等级,即 EL3;利用这个特权等级,我们可在安全与非安全环境之间切换 EL0 和 EL1。尽管 EL3 的使用是一个很重要的论题,能够为架构增加大量的功能,但是在本实例中我们将其忽略,并着重介绍 EL0-EL2(利用管理程序的虚拟化)。如果对计算机如何保护金融交易感兴趣,可以参阅 ARMv8 EL3 文档(免费提供,需注册)。这是非常好的参考文档,从中可以获得极为详细的介绍。
图 3:Zynq UltraScale+ MPSoC 架构
进入和退出例外模式
在真实系统中,模式之间的切换比我们的实例更复杂一些。ARM 总结了 ARMv8-A 架构的行为并在参考手册中给出。手册中介绍,只有在接到例外或从例外返回时,才能改变执行所处的例外等级。在接到例外时,例外等级只能升高或保持不变;在从例外返回时,例外等级只能降低或保持不变。只有三个指令能生成针对下个例外等级的例外:SVC (Supervisor Call),生成针对 EL1 的例外;HVC (Hypervisor Call),生成针对 EL2 的例外;SMC (Secure Monitor Call),生成针对 EL3 的例外。这些指令取值范围为 0-65,555,允许每个例外等级有 216 个系统调用。这些指令针对下个例外等级,而且是唯一可供运行在较低例外等级的程序从运行在较高例外等级的程序请求某些内容的机制。在我们的理论实例中,SVC 是 SWITCHSUPER,HVC 是 SWITCHHYPER。
PetaLinux 工具包含一组命令,以供用户在赛灵思 FPGA 和 SoC 上轻松创建和扩展 Linux 系统。
在前一个部分,我们介绍了能够让运行在 USER 模式(EL0)的程序进入 SUPER 模式 (EL1) 的事件。大多数运行在 USER 模式的程序生成的事件是请求存储器。当运行在 EL0 中的用户空间程序从运行在 EL1 中的 OS 请求存储器时,这个用户空间程序的 C 代码可能调用函数 malloc(),再由该函数调用 mmap() 或 sbrk(),以从 OS 请求一个指向可用存储器的指针。在 ARMv8-A 架构中的 Linux 上,这个过程在幕后转化为 SVC 系统调用。该系统调用会把处理器转换为 EL1,从而将控制权送回 OS,后者会解读调用内容并提供正确的响应——本例中是指向所请求存储器区域的指针,或者是一个错误,用以指出没有可用存储器。
演示创建和工具
现在我们来介绍我们团队在 Zynq UltraScale+ QEMU Model 上运行 Doom 时所采用的步骤。这些步骤展示了如何获得和构建运行演示所需的每个组件,如何运行以及以什么顺序运行每个组件,以及如何与演示交互。成功完成该演示之后,你会获得一个环境,用来在上面进行实验,以了解 Xen 管理程序在仿真的 Zynq UltraScale+ MPSoC 上的运行情况。还需要将此迁移植 Zynq UltraScale+ MPSoC 芯片,这可作为练习由用户来完成。
为了让过程更简单,赛灵思提供基础的根文件系统,这样用户就无需花时间和精力自己构建。此演示所需的所有下载内容在以下网址中均有提供: inx.com/Doom+on+Xen+Demo 。
该演示首先通过更新由赛灵思提供的预编译根文件系统 (rootFS),可包含所需的组件。然后,利用赛灵思的 PetaLinux 工具运行演示。rootFS 包含运行于 Linux 系统上的大部分程序——具体来说就是用来启动系统的一组脚本,以及用来实现系统的应用程序与函数库集。我们用来扩展演示中的基础 rootFS 所使用的两个工具分别是 Buildroot 和 PetaLinux。我们使用 Buildroot 为赛灵思提供的基础 rootFS 构建 Doom 二进制文件,同时使用 PetaLinux 创建 rootFS 的剩余部分并引导演示。
Buildroot
Buildroot 是一个简单的构建系统,用于为 Linux 系统创建 rootFS。它使用 make menuconfig 接口,这是一个用来配置 Linux 内核本身的常用方法。Buildroot 包含对 PrBoom 的默认支持,这对于本演示很有帮助。(PrBoom 是我们所使用的 Doom 游戏的 GNU 通用公共许可证 [GPL] 版本。这里我们会穿插使用 PrBoom 和 Doom 这两个术语。 )Buildroot 对 Xen 构建不提供本地支持(尽管它可创建用于构建 Xen 所需的所有库和工具链),因此赛灵思提供 Xen、Xen 工具和为用户预编译的 Xen 库以及其他一些所需的库,以让过程简单直观。
PetaLinux
PetaLinux 工具包含一个命令集,以便让用户在赛灵思 FPGA 和 SoC 上轻松创建和扩展 Linux 系统。该演示使用 petalinux-build 和 petalinux-boot 命令。petalinux-build 命令用于创建全部所需的组件。petalinux-boot 命令(外加几个变量)用于启动在 QEMU 仿真器上运行的所有组件。介绍 PetaLinux 工具中的所有命令超出了本文的范围,但是通过此演示系统应该很容易发掘这两个命令和其他命令的功能。参考PetaLinux 工具文档 — 参考指南 UG1144 (v2015.4) 了解更多信息。
项目先决条件
该项目需要一个运行 Linux 的工作站或虚拟机,具有满足 UG1144 (v2015.4) 中所列的 PetaLinux 工具安装要求的环境,而且环境中需要安装赛灵思 PetaLinux Tools v2015.4 版本。
一旦 Doom 启动,你就可以使用键盘和鼠标控制游戏。应记住,可能需要点击 ESC 键来开始游戏。开始游戏咯!
步骤 1:构建 ROOTFS
首先,我们需要构建 rootFS。从赛灵思下载 doom_demo.tar.gz,打开下载目录中的一个 terminal;你可在以下网址中找到全部所需文件: +on+Xen+Demo 。我们将该目录称为 。
解压文档。
$ cd
$ tar -xzf doom_demo.tar.gz && cd doom_demo
我们会看到一个文件夹,我们将把它存到根文件系统(一个用于 Dom0,另一个用于 DomU)。现在,我们需要构建 PrBoom,并复制到 rootFS。
首先,需要下载 Linux 内核,这样我们随后就可以构建 rootFS。我们使用 v4.3 标签。
$ git clone -b v4.3 https://github.com/tor- valds/linux.git
下载 Buildroot 源文件,并更改到 Buildroot 目录。
$ git clone https://git.buildroot.net/buildroot && cd buildroot
现在我们需要配置 Buildroot,以构建可以使用的套件。
$ make menuconfig
我们选择以下选项:
Target options ---> Target Architecture ---> AArch64 (little endian)
Target packages —> Games ---> prboom ---> [*]
Target packages —> Games ---> shareware Doom WAD file ---> [*]
应自动选择全部所需的库。
$ make # (这需要几分钟时间,取决于机器。)
现在,我们将所有 PrBoom 相关文件复制到 targetfs 目录,确保我们在 buildroot 目录下的 ./output/target/ 目录。
$ for i in $(find ./-name ‘*oom*’); do cp ${i}
/doom_demo/targetfs/${i}; done
现在,我们完成了 Buildroot 操作。我们移到上一个目录 doom_demo 目录。
$ make # Build the host and guest rootFS.(这需要几分钟时间,取决于你的机器。)
注意:可能还存在额外配置选项,这主要取决于使用的内核版本。这些额外配置选项未被我们提供的配置预先选择。使用默认选项即可(需点击回车键)。
步骤 2:构建基础设置
接下来,我们为平台构建嵌入式系统软件的剩余部分,包括引导装载程序、ARM Trusted Firmware (ATF)、Linux 内核和设备树。赛灵思的 PetaLinux 工具让这个过程简单直观。我们创建一个针对赛灵思 ZCU102 开发板的 PetaLinux 项目。参考 2015.4 UG1144 和 AR#66249 中 QEMU 和 MPSoC PetaLinux 的快速入门材料。访问china.xilinx.com ,将 ZCU102 BSP (板支持包)下载到
目录下。
$ cd
$ petalinux-create --type project -s
/ Xilinx-ZCU102-v2015.4-final.bsp -- name doom_demo_zynqMP
这样将在 /doom_demo_zynqMP 中创建我们的 PetaLinux 项目。
我们转到 PetaLinux 项目,并构建 PetaLinux。
$ cd /doom_demo_zynqMP
$ petalinux-build
现在,我们需要为本用例手动编辑设备树。
编辑 xen-overlay.dtsi 文件 (subsystems/linux/ configs/device-tree/xen-overlay.dtsi)。
将 dom0 下的 'reg = <0x0 0x80000 0x3100000>;' 替换为 'reg = <0x0 0x80000 0x4100000>;'
将 dom0 下的 'xen,xen-bootargs = "console=dtuart dtuart=serial0 dom0_mem=512M bootscrub=0 maxcpus=1 time r_ slop=0";' 替换为 'xen,xen-bootargs = "console=dtuart dtuart=serial0 dom0_mem=512M bootscrub=0 maxcpus=4 timer_ slop=0";'
将 dom0 下的 'xen,dom0-bootargs = "console=hvc0 earlycon=xen earlyprintk=xen maxcpus=1";' 替换为 'xen,dom0-bootargs = "rdinit=/bin/sh console=hvc0 earlycon=xen earlyprintk=xen maxcpus=4";'
编辑 zynqmp.dtsi 文件 (subsystems/linux/configs/ device-tree/zynqmp.dtsi)。
将 dom0 下的 'compatible = "cdns,uart-r1p12";' 替换为 'compatible = "cdns,uart-r1p8", "cdns,uart-r1p12";' 现在,手动构建 Xen 设备树。
最后,我们需要将 Peta- Linux 构建的 rootFS 替换为我们此前构建的 rootFS。之所以这样做,是因为 PetaLinux 不包含 PrBoom,因为我们提供自己的 rootFS。我们还需要将 xen.ub 镜像替换为赛灵思预先构建的镜像,因为 Xen 和 Xen 工具版本必须匹配。
$ rm /doom_demo_zynqMP/images/linux/ Image && rm /doom_demo_zynqMP/images/ linux/xen.ub
$ cp /doom_demo/Image /doom_ demo_zynqMP/images/linux/Image && cp / doom_demo/xen.ub /doom_demo_zynqMP/im- ages/linux/xen.ub
使用 u-boot 引导加载程序引导。
$ petalinux-boot --qemu --u-boot --qemuargs= "- net nic -net nic -net nic -net nic -net us- er,net=192.168.129.0,dhcpstart=192.16 8.129.50,host=192.168.129.1,hostfwd=t cp:127.0.0.1:5900-192.168.129.50:5900"
> setenv serverip 192.168.129.1
> tftpb 4000000 xen.dtb; tftpb 0x80000 Image; tftpb 6000000 xen.ub; bootm 6000000 - 4000000
# /boot.sh
# /xen-doom.sh 1
步骤 3:开始演示
现在,我们可以打开虚拟网络计算 (VNC) 查看器,并在运行 QEMU 的机器上连接 localhost:5900 以观看 Doom 游戏。(注意:以上命令行只能重定向 5900 端口,因此当开始演示时只能连接到第一个 Doom 实例。如果想连接多个实例,需要为 QEMU 添加更多 hostfwd 变量,并连接到下个可用的端口[5901 用于下个实例,5902 用于第三个实例,以此类推],然后将这些实例连接。)
一旦 Doom 启动,你就可以使用键盘和鼠标控制游戏。应记住,可能需要点击 ESC 键来开始游戏。
还应记住,你已经很长时间没玩 Doom 游戏了,因此你可能走不了多远。 别气馁。使用自己构建的系统绝对“可行”。
XEN 深入探讨
正如“Zynq MPSoC 获得 Xen 管理程序支持”(赛灵思中国通讯,第 93 期)中所介绍, Type 1 管理程序在本机硬件上运行,Type 2 管理程序不是软件的最底层,而是托管在 OS 上。Xen 属于 Type 1 管理程序(图 4)。
图 4:作为 Type 1 管理程序,Xen 在本机硬件上运行,虚拟机在 Xen 之上运行 (来源:“带虚拟化扩展的 Xen ARM” 白皮书)。
以前,我们提到了虚拟处理器(也称虚拟机)。在 Xen 中,这些被称为域。特权最高的域被称为 Dom0;无特权的客户域是 DomU 域。
Dom0 是 Xen 管理程序在引导时创建的初始域。它是特权域,并驱动平台上的设备。Xen 将 CPU、存储器、中断和定时器虚拟化,为虚拟机提供一个或多个虚拟 CPU、系统存储器的一部分、一个虚拟中断控制器和一个虚拟定时器。除非配置为其他方式,否则 Dom0 可直接访问所有设备并驱动它们。Dom0 还运行一组名为半虚拟化 (PV) 后端的驱动,为无特权虚拟机提供对磁盘、网络等设备的访问权。Xen 提供用于发现和初始通信设置的所有工具。作为 DomU 的 OS 通过运行相应的 PV 前端驱动程序来获得对一组通用虚拟设备的访问权。根据 DomU 的数量,单个后端可服务多个前端。有一对适用于所有最常见设备类型(磁盘、网络、控制台、帧缓冲器、鼠标、键盘等)的 PV 驱动程序。PV 驱动程序通常位于 OS 内核(即 Linux)中。几个 PV 后端也可以在用户空间中运行,通常在 QEMU 中。前端在存储器的共享页上使用简单的环协议连接后端。从 Dom0 与管理程序交互要求程序使用定义的管理程序调用(类似于系统调用)。Xen 提供一个名为 Xen Tools (也可写成 xen-tools)的、带有库的参考工具箱。xen-tools 包含一个名为 xl 的程序,该程序可与其他程序一起检查状态和创建客户机。
利用设备半虚拟化,可在管理程序与客户机之间就如何进行通信达成协议。常见的通信协议为 Xen Bus 和 VirtIO。
xl 中的“create”命令要用到描述客户机的配置文件,如果配置文件规定客户机需要一个由 VNC 会话支持的虚拟帧缓冲器 (VFB),那么 xl 会在 Dom0 用户空间中自动启动虚拟化代码(本演示中,为每个客户机启动一个)。
doom VM 的配置文件如下所示:
# 客户机名称
name = "guest1"
# 要引导的内核镜像
kernel = "/boot/Image"
# 内核命令行选项
extra = "console=hvc0 rdinit=/doom.sh"
# 最初存储器分配 (MB)
memory = 56
# VCPUS 数量
vcpus = 1
vfb = ['type=vnc, vnclisten=0.0.0.0']
XEN 中的设备
为客户机提供设备有三种常用方法:仿真、半虚拟化和直通 (图 5)。对于设备仿真,当客户机向仿真设备的存储器写入时,写入操作会触发陷阱。陷阱通常就是页面错误。陷阱使处理器能够切换到管理程序,以仿真设备。仿真是灵活的,但速度慢,因为要处理所有陷阱,而且要有人为所有需要仿真的设备编写模型。而且,很难找到方法来加速仿真,因为几乎没有硬件加速;完全是软件方法。
图 5:方案、半虚拟化和直通方案的对比
利用设备半虚拟化,可在管理程序与客户机之间就如何进行通信达成协议。通常有一个共享的存储器区域(以及协议),这看起来像一个设备,而且管理程序在该区域处理请求。例如,为了在 Linux 上支持半虚拟化帧缓冲器,Linux 前端驱动会把从用户空间获得的帧缓冲器写入共享存储器区域;然后使用管理程序调用向管理程序发信号,以通过后端驱动来输出帧。客户机只能通过半虚拟化驱动程序与主机 (Dom0)和其他客户机 (DomU) 对话。这种方案的优势是:用户可以在很多客户机之间共享设备;运行快速;客户机可以运行大部分都没修改的内核。要求的变动在标准接口下面,因此对于应用程序以及内核其余部分来说,前端驱动程序看起来就像正常的网络接口、磁盘或其他设备。支持客户机通信的两个常用协议是 Xen Bus 和 VirtIO。
在直通模式下,主机将设备“交给”一个客户机。这意味着每次只有一个客户机可以使用该设备。
设备性能与安全
一般来说,与通过直通方式提供的设备相比,仿真的设备性能比较低;半虚拟化方案则趋向于具备足够性能。半虚拟化方案和仿真方案的优势在于管理程序可以让设备访问多个实体,而不会将这些实体相互暴露。
原理简介
Doom-on-Zynq UltraScale+ MPSoC 的处理上下文环境就像洋葱一样有很多层(图 6)。Cortex-A53 中是四个 ARMv8 内核。在每个内核上,管理程序运行在 EL2 中,客户机(Dom0 或 DomU)运行在 EL0/EL1 中。每个 DomU 客户机都运行 Linux;Doom (PrBoom) 运行在用户空间中。Doom 使用简单直接媒体层 (SDL),通过 SVC 指令(最终)与帧缓冲器前端驱动对话。帧缓冲器前端将缓冲器写入 Dom0 建立的共享存储器区域。前端驱动通过协议(例如 Xen Bus 或 VirtIO)使用 HVC 指令(最终)与 Dom0 上运行的虚拟化代码通信。在 Dom0 上运行的虚拟化代码提供一个用于显示的后端,然后该后端由虚拟化代码的 VNC 服务器进行编码,并通过网络送到 VNC 客户端。
图6:X86 架构上从 PetaLinux 工具启动 QEMU
此信息和演示能够为管理程序的进一步研究和实验提供很好的基础。当你能够在 QEMU 上用仿真来运行演示之后,就可使用 PetaLinux 工具在 Zynq UltraScale+ MPSoC 芯片上运行。
评论
查看更多