第 10 章. 技术背景

目录

10.1. Oracle VM VirtualBox 文件存储位置
10.1.1. 虚拟机文件夹
10.1.2. 全局设置
10.1.3. 配置数据位置摘要
10.1.4. Oracle VM VirtualBox XML 文件
10.2. Oracle VM VirtualBox 可执行文件和组件
10.3. 硬件虚拟化
10.4. 硬件虚拟化详情
10.5. 半虚拟化提供者
10.6. 嵌套分页和 VPID

本章为熟悉计算机架构和技术的读者提供了更多信息,旨在深入探讨 Oracle VM VirtualBox 的内部工作原理。成功使用 Oracle VM VirtualBox 并不要求阅读本章内容。

10.1. Oracle VM VirtualBox 文件存储位置

在 Oracle VM VirtualBox 中,虚拟机及其设置通过 XML 格式的虚拟机设置文件进行描述。此外,大多数虚拟机都带有一个或多个虚拟硬盘。这些通常由磁盘镜像表示,例如 VDI 格式的磁盘镜像。这些文件的位置可能因主机操作系统而异。参见第 10.1.1 节,“虚拟机文件夹”

Oracle VM VirtualBox 的全局配置数据保存在主机的另一个位置。参见第 10.1.2 节,“全局设置”

10.1.1. 虚拟机文件夹

默认情况下,每个虚拟机都在您的主机计算机上有一个目录,用于存储该机器的所有文件:带有 .vbox 文件扩展名的 XML 设置文件及其磁盘镜像。这被称为虚拟机文件夹

默认情况下,此虚拟机文件夹位于一个名为 VirtualBox VMs 的公共文件夹中,该文件夹由 Oracle VM VirtualBox 在当前系统用户的主目录中创建。此主目录的位置取决于主机操作系统的约定,具体如下:

  • 在 Windows 上,这是 Windows 系统库 Shell32.dll 的 SHGetFolderPath 函数返回的位置,用于查询用户配置文件。典型位置是 C:\Users\username

  • 在 Linux、macOS 和 Oracle Solaris 上,这通常取自环境变量 $HOME,但对于用户 root,则从账户数据库中获取。这是为了解决用户将 Oracle VM VirtualBox 与工具 sudo 结合使用时经常遇到的问题,因为 sudo 默认不重置环境变量 $HOME

    在 Linux 和 Oracle Solaris 上的典型位置是 /home/username,在 macOS 上是 /Users/username

为简化起见,我们将主目录的位置缩写为 $HOME。根据此约定,所有虚拟机的公共文件夹是 $HOME/VirtualBox VMs

例如,当您创建一台名为“Example VM”的虚拟机时,Oracle VM VirtualBox 会创建以下内容:

  • 虚拟机文件夹:$HOME/VirtualBox VMs/Example VM/

  • 在虚拟机文件夹中,一个设置文件:Example VM.vbox

  • 在虚拟机文件夹中,一个虚拟磁盘镜像:Example VM.vdi

如果您使用第 1.8 节,“创建您的第一台虚拟机”中描述的创建新虚拟机向导,这是默认布局。一旦您开始使用虚拟机,就会添加额外的文件。日志文件位于名为 Logs 的子文件夹中,如果您拍摄了快照,它们则位于 Snapshots 子文件夹中。对于每个虚拟机,您都可以在虚拟机设置中更改其快照文件夹的位置。

您可以通过在 Oracle VM VirtualBox 主窗口中选择文件菜单下的偏好设置来更改默认的虚拟机文件夹。然后,在显示的窗口中,点击常规选项卡。或者,使用 VBoxManage setproperty machinefolder 命令。参见第 8.40 节,“VBoxManage setproperty”

10.1.2. 全局设置

除了虚拟机文件之外,Oracle VM VirtualBox 还在以下目录中维护全局配置数据:

  • Linux 和 Oracle Solaris: $HOME/.config/VirtualBox

  • Windows: $HOME/.VirtualBox

  • macOS: $HOME/Library/VirtualBox

如有必要,Oracle VM VirtualBox 会自动创建此配置目录。您可以通过设置 VBOX_USER_HOME 环境变量,或者在 Linux 或 Oracle Solaris 上使用标准 XDG_CONFIG_HOME 变量来指定备用配置目录。由于全局 VirtualBox.xml 设置文件指向所有其他配置文件,这使得可以在多个 Oracle VM VirtualBox 配置之间切换。

在此配置目录中,Oracle VM VirtualBox 存储其全局设置文件,一个名为 VirtualBox.xml 的 XML 文件。此文件包含全局配置选项以及已注册虚拟机的列表,并指向其 XML 设置文件。

10.1.3. 配置数据位置摘要

下表简要概述了 Oracle VM VirtualBox 主机上的配置数据位置。

表 10.1. 配置文件位置

设置

位置

默认虚拟机文件夹

$HOME/VirtualBox VMs

默认磁盘镜像位置

在每个虚拟机的文件夹中

虚拟机设置文件扩展名

.vbox

媒体注册表

每个虚拟机设置文件

当存储介质连接到虚拟机时,会自动进行媒体注册

10.1.4. Oracle VM VirtualBox XML 文件

Oracle VM VirtualBox 对虚拟机设置文件和全局配置文件 VirtualBox.xml 都使用 XML 格式。

所有 Oracle VM VirtualBox XML 文件都是版本化的。当创建一个新的设置文件时,例如因为创建了一个新的虚拟机,Oracle VM VirtualBox 会自动使用当前 Oracle VM VirtualBox 版本的设置格式。如果您降级到早期版本的 Oracle VM VirtualBox,这些文件可能无法读取。但是,当 Oracle VM VirtualBox 遇到来自早期版本的设置文件时,例如在升级 Oracle VM VirtualBox 之后,它会尽可能地保留设置格式。只有当当前设置无法以旧格式表示时(例如,因为您启用了早期版本的 Oracle VM VirtualBox 中不存在的功能),它才会静默升级设置格式。

在这种情况下,Oracle VM VirtualBox 会在虚拟机的配置目录中备份旧的设置文件。如果您需要恢复到早期版本的 Oracle VM VirtualBox,则需要手动将这些备份文件复制回来。

我们故意不提供 Oracle VM VirtualBox XML 文件的规范文档,因为我们保留未来修改它们的权利。因此,我们强烈建议您不要手动编辑这些文件。Oracle VM VirtualBox 通过其命令行工具 VBoxManage(参见第 8 章,《VBoxManage》)及其 API(参见第 11 章,《Oracle VM VirtualBox 编程接口》)提供对其配置数据的完全访问权限。

10.2. Oracle VM VirtualBox 可执行文件和组件

Oracle VM VirtualBox 设计为模块化和灵活的。当 Oracle VM VirtualBox 图形用户界面 (GUI) 打开并启动虚拟机时,至少会运行以下三个进程:

  • VBoxSVC,始终在后台运行的 Oracle VM VirtualBox 服务进程。此进程由第一个 Oracle VM VirtualBox 客户端进程自动启动,并在最后一个客户端退出后不久退出。第一个 Oracle VM VirtualBox 服务可以是 VirtualBox 管理器、VBoxManageVBoxHeadless 或 Web 服务等。该服务负责簿记、维护所有虚拟机的状态,并提供 Oracle VM VirtualBox 组件之间的通信。此通信通过 COM/XPCOM 实现。

    注意

    这里我们提到的客户端是指特定 VBoxSVC 服务器进程的本地客户端,而非网络中的客户端。Oracle VM VirtualBox 采用自己的客户端/服务器设计以使其进程协同工作,但所有这些进程都在主机操作系统上的同一用户账户下运行,这对用户来说是完全透明的。

  • GUI 进程 VirtualBoxVM,一个基于跨平台 Qt 库的客户端应用程序。当不带 --startvm 选项启动时,此应用程序充当 VirtualBox 管理器,显示虚拟机及其设置。然后,它将设置和状态更改通信给 VBoxSVC,并反映通过其他方式(例如 VBoxManage 命令)生效的更改。

  • 如果 VirtualBoxVM 客户端应用程序通过 --startvm 参数启动,它会加载包含实际 Hypervisor 的 VMM 库,然后运行虚拟机并为客户机提供输入和输出。

任何 Oracle VM VirtualBox 前端或客户端都将与服务进程通信,并且可以控制和反映当前状态。例如,无论是虚拟机选择器、虚拟机窗口还是 VBoxManage 都可以用于暂停正在运行的虚拟机,而其他组件将始终反映更改后的状态。

Oracle VM VirtualBox GUI 应用程序,称为 VirtualBox 管理器,只是几个可用前端或客户端之一。Oracle VM VirtualBox 附带的完整列表如下:

  • VirtualBoxVM:实现 VirtualBox 管理器并运行虚拟机的 Qt 前端。

  • VBoxManage:一个不太用户友好但功能更强大的替代方案。参见第 8 章,《VBoxManage》

  • VBoxHeadless:一个不直接提供视频输出、键盘或鼠标输入的虚拟机前端,但可以通过 VirtualBox 远程桌面扩展实现重定向。参见第 7.1.2 节,“VBoxHeadless,远程桌面服务器”

  • vboxwebsrv:Oracle VM VirtualBox Web 服务进程,可实现对 Oracle VM VirtualBox 主机的远程控制。这在 Oracle VM VirtualBox 软件开发工具包 (SDK) 参考中详细描述。参见第 11 章,《Oracle VM VirtualBox 编程接口》

  • Oracle VM VirtualBox Python shell:VBoxManage 的 Python 替代方案。这也在 SDK 参考中进行了描述。

在内部,Oracle VM VirtualBox 由许多或多或少独立的组件组成。您在分析 Oracle VM VirtualBox 内部错误消息或日志文件时可能会遇到这些组件。其中包括以下内容:

  • IPRT:一个可移植的运行时库,它抽象了文件访问、线程和字符串操作。每当 Oracle VM VirtualBox 访问主机操作系统功能时,都会通过此库进行,以实现跨平台可移植性。

  • VMM (Virtual Machine Monitor,虚拟机监视器):Hypervisor 的核心。

  • EM (Execution Manager,执行管理器):控制客户机代码的执行。

  • TRPM (Trap Manager,陷阱管理器):拦截和处理客户机陷阱和异常。

  • HM (Hardware Acceleration Manager,硬件加速管理器):提供对 VT-x 和 AMD-V 的支持。

  • GIM (Guest Interface Manager,客户机接口管理器):为客户机提供各种半虚拟化接口的支持。

  • PDM (Pluggable Device Manager,可插拔设备管理器):VMM 和模拟设备之间的抽象接口,它将设备实现与 VMM 内部结构分离,并使添加新的模拟设备变得容易。通过 PDM,第三方开发人员可以向 Oracle VM VirtualBox 添加新的虚拟设备,而无需更改 Oracle VM VirtualBox 本身。

  • PGM (Page Manager,页面管理器):一个控制客户机分页的组件。

  • TM (Time Manager,时间管理器):处理计时器和客户机内部时间的所有方面。

  • CFGM (Configuration Manager,配置管理器):提供一个树形结构,其中包含虚拟机和所有模拟设备的配置设置。

  • SSM (Saved State Manager,保存状态管理器):保存和加载虚拟机状态。

  • VUSB (Virtual USB,虚拟 USB):一个 USB 层,它将模拟的 USB 控制器与主机上的控制器和 USB 设备分离。此组件还支持远程 USB。

  • DBGF (Debug Facility,调试工具):一个内置的虚拟机调试器。

  • Oracle VM VirtualBox 模拟了许多设备,以提供各种客户机所需的硬件环境。其中大多数是许多兼容 PC 机器中常见的标准设备,并得到客户机操作系统的广泛支持。特别是对于网络和存储设备,模拟设备有多种选项来访问底层硬件。这些设备由 PDM 管理。

  • 适用于各种客户机操作系统的 Guest Additions。这是从虚拟机内部安装的代码。参见第 4 章,《增强功能》

  • “Main”组件很特殊。它将上述所有部分连接在一起,并且是 Oracle VM VirtualBox 提供的唯一公共 API。上述列出的所有客户端进程都只使用此 API,从不直接访问 Hypervisor 组件。因此,使用 Oracle VM VirtualBox Main API 的第三方应用程序可以信赖它始终经过充分测试,并且 Oracle VM VirtualBox 的所有功能都完全暴露。此 API 在 Oracle VM VirtualBox SDK 中进行了描述。参见第 11 章,《Oracle VM VirtualBox 编程接口》

10.3. 硬件虚拟化

Oracle VM VirtualBox 使得虚拟机中的软件可以直接在主机处理器上运行,但它采用了一系列复杂的技术来拦截会干扰主机的操作。每当客户机试图执行可能对您的计算机及其数据有害的操作时,Oracle VM VirtualBox 就会介入并采取行动。特别是,对于客户机认为正在访问的许多硬件,Oracle VM VirtualBox 会根据您配置虚拟机的方式模拟一个特定的虚拟环境。例如,当客户机试图访问硬盘时,Oracle VM VirtualBox 会将这些请求重定向到您配置为虚拟机虚拟硬盘的任何内容。这通常是主机上的一个镜像文件。

不幸的是,x86 平台在设计时从未考虑过虚拟化。如上所述,检测 Oracle VM VirtualBox 需要控制正在执行的客户机代码的情况是困难的。为了实现这一点,Oracle VM VirtualBox 使用硬件虚拟化

英特尔和 AMD 处理器支持硬件虚拟化。这意味着这些处理器可以帮助 Oracle VM VirtualBox 拦截客户机操作系统可能尝试的潜在危险操作,并且也使向虚拟机呈现虚拟硬件变得更容易。

这些硬件功能在英特尔和 AMD 处理器之间有所不同。英特尔将其技术命名为 VT-x,AMD 将其命名为 AMD-V。英特尔和 AMD 对虚拟化的支持在细节上差异很大,但在原理上差异不大。

注意

在许多系统上,硬件虚拟化功能需要首先在 BIOS 中启用,然后 Oracle VM VirtualBox 才能使用它们。

在以下场景中,需要启用硬件虚拟化:

  • 某些罕见的客户机操作系统,如 OS/2,使用了非常深奥的处理器指令。对于配置为使用此类操作系统的虚拟机,硬件虚拟化会自动启用。

  • Oracle VM VirtualBox 的 64 位客户机和多处理器 (SMP) 支持都要求启用硬件虚拟化。这算不上很大的限制,因为绝大多数 64 位和多核 CPU 都带有硬件虚拟化功能。此规则的例外是一些旧版英特尔和 AMD CPU。

警告

请勿将其他 Hypervisor(无论是开源还是商业虚拟化产品)与 Oracle VM VirtualBox 同时运行。虽然通常可以并行安装多个 Hypervisor,但请勿尝试同时运行来自不同 Hypervisor 的多个虚拟机。Oracle VM VirtualBox 无法跟踪另一个 Hypervisor 当前在同一主机上尝试做什么,特别是如果多个产品试图使用 VT-x 等硬件虚拟化功能时,这可能会导致整个主机崩溃。

有关硬件虚拟化的技术讨论,请参见第 10.4 节,“硬件虚拟化详情”

10.4. 硬件虚拟化详情

对于英特尔 VT-x,CPU 操作有两种不同的模式:VMX 根模式和非根模式。

  • 在根模式下,CPU 的操作与没有 VT-x 支持的旧一代处理器非常相似。有四个特权级别,称为环,并且支持相同的指令集,并增加了几个虚拟化专用指令。根模式是未进行虚拟化的主机操作系统使用的模式,当虚拟化处于活动状态时,Hypervisor 也使用它。

  • 在非根模式下,CPU 操作显著不同。仍然有四个特权环和相同的指令集,但现在一个名为 VMCS (Virtual Machine Control Structure,虚拟机控制结构) 的新结构控制着 CPU 操作并决定某些指令的行为方式。非根模式是客户机系统运行的地方。

从根模式切换到非根模式称为“VM 进入”,切换回来称为“VM 退出”。VMCS 包含一个客户机和主机状态区域,该区域在 VM 进入和退出时保存/恢复。最重要的是,VMCS 控制哪些客户机操作将导致 VM 退出。

VMCS 对客户机可以和不可以做什么提供了相当精细的控制。例如,Hypervisor 可以允许客户机写入影子控制寄存器中的某些位,但不能写入其他位。这使得在客户机可以写入控制位而不中断 Hypervisor 的情况下实现高效虚拟化,同时阻止它们更改 Hypervisor 需要完全控制的控制位。VMCS 还提供对中断传递和异常的控制。

每当指令或事件导致 VM 退出时,VMCS 都包含有关退出原因的信息,通常还附带详细信息。例如,如果对 CR0 寄存器的写入导致退出,则会记录违规指令,以及对控制寄存器进行写入访问导致退出的事实,以及有关源寄存器和目标寄存器的信息。因此,Hypervisor 可以有效地处理此情况,而无需上述的 CSAM 和 PATM 等高级技术。

VT-x 本身避免了软件虚拟化面临的几个问题。客户机拥有自己完全独立的地址空间,不与 Hypervisor 共享,从而消除了潜在的冲突。此外,客户机操作系统内核代码在 VMX 非根模式下以特权环 0 运行,从而通过在较低特权级别运行环 0 代码来避免了问题。例如,SYSENTER 指令可以转换到环 0 而不会导致问题。当然,即使在 VMX 非根模式的环 0,客户机代码的任何 I/O 访问仍会导致 VM 退出,从而实现设备模拟。

VT-x 和 AMD-V 之间最大的区别在于 AMD-V 提供了更完整的虚拟化环境。VT-x 要求 VMX 非根模式代码在启用分页的情况下运行,这排除了对实模式代码和非分页保护模式软件的硬件虚拟化。这通常只包括固件和操作系统加载程序,但 Nevertheless 使得 VT-x Hypervisor 的实现变得复杂。AMD-V 没有此限制。

当然,硬件虚拟化并非完美无缺。与软件虚拟化相比,VM 退出的开销相对较高。这对于其仿真需要大量陷阱的设备会造成问题。一个例子是 16 色模式下的 VGA 设备,不仅每个 I/O 端口访问,而且对帧缓冲区内存的每次访问都必须被捕获。

10.5. 半虚拟化提供者

Oracle VM VirtualBox 允许公开半虚拟化接口,以促进虚拟机内软件的准确高效执行。这些接口要求客户机操作系统识别它们的存在并利用它们,以便利用与 Oracle VM VirtualBox Hypervisor 通信的好处。

大多数现代主流客户机操作系统,包括 Windows 和 Linux,都自带一个或多个半虚拟化接口的支持。因此,通常无需在客户机中安装额外软件即可利用此功能。

将半虚拟化提供者公开给客户机操作系统不依赖于主机平台的选择。例如,Hyper-V 半虚拟化提供者可用于在 Oracle VM VirtualBox 支持的任何主机平台(而不仅仅是 Windows)上运行虚拟机。

Oracle VM VirtualBox 提供以下接口:

  • 最小:宣布虚拟化环境的存在。此外,向客户机操作系统报告 TSC 和 APIC 频率。此提供者是运行任何 Mac OS X 客户机的强制要求。

  • KVM:提供 Linux KVM Hypervisor 接口,Linux 内核版本 2.6.25 或更高版本可识别此接口。Oracle VM VirtualBox 的实现目前支持半虚拟化时钟和 SMP 自旋锁。建议 Linux 客户机使用此提供者。

  • Hyper-V:提供 Microsoft Hyper-V Hypervisor 接口,Windows 7 及更高版本操作系统可识别此接口。Oracle VM VirtualBox 的实现目前支持半虚拟化时钟、APIC 频率报告、客户机调试、客户机崩溃报告和宽松的计时器检查。建议 Windows 客户机使用此提供者。

10.6. 嵌套分页和 VPID

除了普通的硬件虚拟化之外,您的处理器还可能支持以下额外的复杂技术:

  • 嵌套分页在硬件中实现了一些内存管理,这可以大大加速硬件虚拟化,因为这些任务不再需要由虚拟化软件执行。

    通过嵌套分页,硬件在将线性地址转换为物理地址时提供了另一层间接。页表功能与以前一样,但线性地址现在首先转换为“客户机物理”地址,而不是直接转换为物理地址。现在,在传统分页机制下存在一组新的分页寄存器,它将客户机物理地址转换为主机物理地址,用于访问内存。

    嵌套分页消除了由 VM 退出和页表访问引起的开销。本质上,通过嵌套页表,客户机可以在没有 Hypervisor 干预的情况下处理分页。因此,嵌套分页显著提高了虚拟化性能。

    在 AMD 处理器上,嵌套分页从 Barcelona (K10) 架构开始可用。他们现在将其称为快速虚拟化索引 (RVI)。英特尔在其 Core i7 (Nehalem) 处理器中添加了对嵌套分页的支持,他们称之为扩展页表 (EPT)。

    如果启用了嵌套分页,Oracle VM VirtualBox Hypervisor 还可以使用大页面来减少 TLB 使用和开销。这可以带来高达 5% 的性能提升。要为虚拟机启用此功能,请使用 VBoxManage modifyvm --large-pages 命令。参见第 8.10 节,“VBoxManage modifyvm”

    如果您拥有支持 EPT 的英特尔 CPU,请参阅第 13.4.1 节,“CVE-2018-3646”以了解有关 EPT 的安全问题。

  • 在英特尔 CPU 上,一项名为虚拟处理器标识符 (VPID) 的硬件功能可以通过减少昂贵的处理器转换旁路缓冲器 (TLB) 刷新需求来大大加速上下文切换。

    要为虚拟机启用这些功能,请使用 VBoxManage modifyvm --vtx-vpidVBoxManage modifyvm --large-pages 命令。参见第 8.10 节,“VBoxManage modifyvm”