了解 QEMU 设备

什么是QEMU

QEMU(全称:Quick Emulator)是一个开源的虚拟化和仿真软件,它允许您在一个主机系统上模拟多个不同的硬件架构和操作系统。QEMU最初是为Linux开发的,但现在已经跨平台支持多个操作系统,包括Linux、Windows、macOS等。

QEMU的主要功能包括:

硬件仿真: QEMU可以模拟多种不同的CPU架构,如x86、ARM、MIPS等,以及各种外部设备,如磁盘驱动器、网卡等。这使得
开发人员可以在单一主机上测试和运行不同体系结构的操作系统和应用程序。

虚拟化: QEMU支持硬件虚拟化,允许您在虚拟机中运行其他操作系统。它与KVM(Kernel-based Virtual Machine)等虚拟化工
具集成良好,可以提供高性能的虚拟化解决方案。

模拟器: QEMU可以用作模拟器,允许您运行和测试不同操作系统和应用程序,而无需实际的硬件。

交叉编译: 开发人员可以使用QEMU来交叉编译软件,以在一个体系结构上构建并运行另一个体系结构的应用程序。

调试支持: QEMU提供了强大的调试功能,使开发人员能够在虚拟化环境中调试操作系统内核和应用程序

对于 QEMU,要记住的一件事是,我们试图模拟操作系统 (OS) 在裸机硬件上看到的内容。大多数裸机基本上是巨大的内存映射,其中软件戳特定地址会产生特定的副作用(最常见的副作用当然是访问内存;但内存中的其他常见区域包括用于控制特定硬件的寄存器库,如硬盘驱动器或网卡,甚至CPU本身)。仿真的最终目标是允许用户空间程序(仅使用正常的内存访问)来管理来宾操作系统预期的所有副作用。

作为实现细节,某些硬件(如 x86)实际上有两个内存空间,其中 I/O 空间使用与正常情况不同的汇编代码;QEMU 必须模拟这些替代访问。同样,许多现代 CPU 在内存映射中为自己提供了一组 CPU 本地寄存器,例如中断控制器。

对于某些硬件,我们有虚拟化钩子,其中 CPU 本身很容易捕获有问题的程序集指令(那些访问 I/O 空间或 CPU 内部寄存器的指令,因此需要与正常内存访问不同的副作用),以便来宾只需执行与裸机上相同的汇编序列, 但是,该执行会导致一个陷阱,让用户空间 QEMU 然后仅使用其正常的用户空间内存访问对指令做出反应,然后再将控制权返回给来宾。这在 QEMU 中通过“加速器”得到支持。

虚拟化加速器(如 KVM)可以让客户机运行速度几乎与裸机一样快,其中速度减慢是由客户机返回到 QEMU(vmexit)以处理困难的汇编指令或内存地址的每个陷阱引起的。QEMU 还支持其他虚拟化加速器(如 HAXM 或 macOS 的 Hypervisor.framework)。

QEMU 还有一个 TCG 加速器,它接受来宾程序集指令并将其动态编译为可比较的主机指令或对主机帮助程序例程的调用;虽然不如硬件加速快,但它允许跨硬件仿真,例如在 x86 上运行 ARM 代码。

接下来要意识到的是操作系统访问各种硬件资源时会发生什么。例如,大多数操作系统附带知道如何管理 IDE 磁盘的驱动程序 - 驱动程序只是编程为向内存映射的特定子集(IDE 总线所在的位置,特定于硬件板)发出特定 I/O 请求的软件。当 IDE 控制器硬件收到这些 I/O 请求时,它会执行相应的操作(通过 DMA 传输或其他硬件操作),将数据从内存复制到持久存储(写入磁盘)或从持久存储复制到内存(从磁盘读取)。

首次购买裸机硬件时,磁盘未初始化;安装使用该驱动程序对内存映射的 IDE 硬件部分进行足够裸机访问的操作系统,然后将磁盘转换为这些分区之上的一组分区和文件系统。

那么,QEMU如何模仿这一点呢?在它提供给客户机的大内存映射中,它模拟与裸机位于相同地址的 IDE 磁盘。当客户机操作系统驱动程序向 IDE 控制寄存器发出特定的内存写入以将数据从内存复制到持久存储时,QEMU 加速器会捕获对该内存区域的访问,并将请求传递给 QEMU IDE 控制器设备型号。然后,设备模型分析 I/O 请求,并通过发出主机系统调用来模拟这些请求。结果是来宾内存被复制到主机存储中。

在主机端,模拟持久存储的最简单方法是将主机文件系统中的文件视为原始数据(主机文件中偏移量与来宾驱动程序访问的磁盘偏移量的 1:1 映射),但 QEMU 实际上能够将许多不同的主机格式(原始、 qcow2, qed, vhdx, …)和协议(文件系统、块设备、NBD、Ceph、gluster 等),其中主机格式和协议的任意组合都可以作为后端,然后绑定到提供来宾设备的 QEMU 仿真。

因此,当您告诉 QEMU 使用主机 qcow2 文件时,客户机不必知道 qcow2,而只需让其正常驱动程序进行与裸机相同的寄存器读取和写入,这会导致 vmexit 进入 QEMU 代码,然后 QEMU 将这些访问映射到 qcow2 文件的适当偏移量中的读取和写入。首次安装客户机时,客户机看到的只是一个空白的未初始化线性磁盘(无论该磁盘在主机中是线性的(如原始格式)还是针对随机访问进行了优化(如 qcow2 格式);由客户机操作系统决定如何对其硬件视图进行分区并在此之上安装文件系统,QEMU 不关心客户机使用什么文件系统,只关心发出哪种模式的原始磁盘 I/O 寄存器控制序列。

接下来要意识到的是,模拟IDE并不总是最有效的。每次客户机写入控制寄存器时,都必须经过特殊处理,并且 vmexit 会减慢仿真速度。当然,不同的硬件型号在虚拟化时具有不同的性能特征。然而,一般来说,最适合实际硬件的东西并不一定最适合虚拟化,直到最近,硬件在被 QEMU 等软件模拟时还不是设计为快速运行。因此,QEMU 包括专门为此目的设计的半虚拟化设备。

这里的“半虚拟化”的含义与原来的“通过来宾和主机之间的合作实现虚拟化”的含义略有不同。QEMU 开发人员为一组硬件寄存器和这些寄存器的行为制定了规范,这些寄存器旨在尽可能减少 vmexit 次数,同时仍然完成硬盘必须执行的操作,即在普通来宾内存和持久存储之间传输数据。此规范称为 virtio;使用它需要在客户机中安装 Virtio 驱动程序。虽然不存在遵循与 virtio 相同的寄存器布局的物理设备,但概念是相同的:virtio 磁盘的行为类似于内存映射寄存器组,然后来宾操作系统驱动程序知道要写入该存储体的寄存器命令序列,以使数据被复制到其他来宾内存中。virtio 中的许多加速都来自其设计 - 来宾为其大部分命令队列留出一部分常规内存,并且只需启动单个寄存器即可告诉 QEMU 读取命令队列(更少的映射寄存器访问意味着更少的 vmexits),再加上握手保证来宾驱动程序在 QEMU 对其进行操作时不会更改正常内存。

顺便说一句,就像最近的硬件模拟相当有效一样,virtio 正在发展到在硬件中实现的效率更高,当然不会牺牲仿真或虚拟化的性能。因此,在未来,您也可能偶然发现物理virtio设备。

同样,许多操作系统都支持许多网卡,一个常见的例子是PCI总线上的e1000卡。在裸机上,操作系统将探测 PCI 空间,看到填充了具有 e1000 签名的寄存器库,并加载驱动程序,然后该驱动程序知道要写入哪些寄存器序列,以便让硬件卡将网络流量传入和传出来宾。因此,QEMU 拥有 e1000 设备,作为其众多网卡仿真之一,该设备映射到与真实访客内存区域相同的客户机内存区域。

再一次,e1000寄存器布局往往需要大量的寄存器写入(因此需要vmexits)来处理硬件执行的工作量,因此QEMU开发人员添加了virtio-net卡(PCI硬件规范,尽管还没有实际实现它的裸机硬件),这样在来宾操作系统中安装virtio-net驱动程序可以最大限度地减少vmexit的数量,同时仍然获得发送网络的相同副作用。交通。如果您告诉 QEMU 使用 virtio-net 卡启动客户机,则客户机操作系统将探测 PCI 空间并看到带有虚拟网签名的寄存器库,并像加载任何其他 PCI 硬件一样加载适当的驱动程序。

总之,尽管 QEMU 最初是作为模拟硬件内存映射以虚拟化来宾操作系统的一种方式编写的,但事实证明,最快的虚拟化也依赖于虚拟硬件:具有特定记录副作用的寄存器的内存映射,没有裸机对应物。归根结底,所有虚拟化实际上意味着运行一组特定的汇编指令(来宾操作系统)来操纵巨型内存映射中的位置,以引起一组特定的副作用,其中 QEMU 只是一个用户空间应用程序,提供内存映射并模仿您在适当的裸机硬件上执行这些来宾指令时会得到的相同副作用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

写一封情书

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值