技术背景

本章为熟悉计算机架构和技术的读者提供了额外信息,帮助他们深入了解 Oracle VirtualBox内部工作原理。本章内容并非成功使用 Oracle VirtualBox 的必读项。

Oracle VirtualBox 存储其文件位置

Oracle VirtualBox 中,虚拟机及其设置以 XML 格式的虚拟机设置文件描述。此外,大多数虚拟机都带有一个或多个虚拟硬盘。这些通常由磁盘映像表示,例如 VDI 格式的磁盘映像。这些文件的位置可能因主机操作系统而异。请参阅机器文件夹

Oracle VirtualBox 的全局配置数据维护在主机上的另一个位置。请参阅全局设置

虚拟机文件夹

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

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

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

  • 在 Linux、macOS 和 Oracle Solaris 上,这通常取自环境变量 $HOME,但 root 用户除外,其位置取自账户数据库。这是为了解决用户在使用 Oracle VirtualBoxsudo 工具结合时经常遇到的问题,sudo 默认情况下不会重置环境变量 $HOME

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

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

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

  • 一个机器文件夹:$HOME/VirtualBox VMs/Example VM/

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

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

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

您可以通过在 Oracle VirtualBox 主窗口的文件菜单中选择首选项来更改默认机器文件夹。然后,在显示的窗口中,单击常规选项卡。或者,使用 VBoxManage setproperty machinefolder 命令。请参阅VBoxManage setproperty

全局设置

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

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

  • Windows:$HOME/.VirtualBox

  • macOS:$HOME/Library/VirtualBox

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

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

配置数据位置摘要

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

表 1. 配置文件位置。 配置文件位置

设置

位置

默认虚拟机文件夹

$HOME/VirtualBox VMs

默认磁盘镜像位置

在每个虚拟机的文件夹中

虚拟机设置文件扩展名

.vbox

媒体注册表

每个虚拟机设置文件

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

Oracle VirtualBox XML 文件

Oracle VirtualBox 将 XML 用于机器设置文件和全局配置文件 VirtualBox.xml

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

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

我们有意不记录 Oracle VirtualBox XML 文件的规范,因为我们必须保留将来修改它们的权利。因此,我们强烈建议您不要手动编辑这些文件。Oracle VirtualBox 通过其 VBoxManage 命令行工具(请参阅VBoxManage)及其 API(请参阅Oracle VirtualBox 编程接口)提供对其配置数据的完全访问。

Oracle VirtualBox 可执行文件和组件

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

  • VBoxSVCOracle VirtualBox 服务进程,它始终在后台运行。此进程由第一个 Oracle VirtualBox 客户端进程自动启动,并在最后一个客户端退出后不久退出。第一个 Oracle VirtualBox 服务可以是 VirtualBox ManagerVBoxManageVBoxHeadless、Web 服务等。该服务负责记账、维护所有虚拟机的状态,并提供 Oracle VirtualBox 组件之间的通信。这种通信是使用 COM/XPCOM 实现的。

    注意

    当我们此处提及“客户端”时,我们指的是特定 VBoxSVC 服务器进程的本地客户端,而非网络中的客户端。Oracle VirtualBox 采用自己的客户端/服务器设计以允许其进程协作,但所有这些进程都在主机操作系统上的同一用户帐户下运行,并且这对于用户而言是完全透明的。

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

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

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

Oracle VirtualBox GUI 应用程序(称为 VirtualBox Manager)只是几个可用前端或客户端之一。Oracle VirtualBox 随附的完整列表如下:

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

  • VBoxManage:一个不那么用户友好但功能更强大的替代方案。请参阅VBoxManage

  • VBoxHeadless:一个不直接提供任何视频输出以及键盘或鼠标输入的虚拟机前端,但通过 VirtualBox 远程桌面扩展实现重定向。请参阅VBoxHeadless,远程桌面服务器

  • vboxwebsrvOracle VirtualBox Web 服务进程,它允许远程控制 Oracle VirtualBox 主机。这在 Oracle VirtualBox 软件开发工具包 (SDK) 参考中详细描述。请参阅Oracle VirtualBox 编程接口

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

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

  • IPRT:一个可移植运行时库,它抽象了文件访问、线程处理和字符串操作。无论何时 Oracle 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(可插拔设备管理器):VMM 和仿真设备之间的一个抽象接口,它将设备实现与 VMM 内部结构分离,并使添加新的仿真设备变得容易。通过 PDM,第三方开发人员可以向 Oracle VirtualBox 添加新的虚拟设备,而无需更改 Oracle 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 VirtualBox 仿真了许多设备,以提供各种客户机所需的硬件环境。其中大多数是许多 PC 兼容机器中常见的标准设备,并得到客户操作系统的广泛支持。特别是对于网络和存储设备,仿真设备有多种选项可以访问底层硬件。这些设备由 PDM 管理。

  • 针对各种客户操作系统的 Guest Additions。这是从虚拟机内部安装的代码。请参阅Guest Additions

  • “Main”组件是特殊的。它将上述所有组件连接在一起,并且是 Oracle VirtualBox 提供的唯一公共 API。上述所有客户端进程都只使用此 API,从不直接访问 hypervisor 组件。因此,使用 Oracle VirtualBox Main API 的第三方应用程序可以依赖于以下事实:它始终经过良好测试,并且 Oracle VirtualBox 的所有功能都完全公开。Oracle VirtualBox SDK 中描述的正是此 API。请参阅Oracle VirtualBox 编程接口

硬件虚拟化

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

遗憾的是,x86 平台从未被设计用于虚拟化。如上所述,检测 Oracle VirtualBox 需要控制正在执行的客户机代码的情况是很困难的。为此,Oracle VirtualBox 使用硬件虚拟化

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

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

注意

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

在以下情况下,必须启用硬件虚拟化:

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

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

注意

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

有关硬件虚拟化的技术讨论,请参阅关于硬件虚拟化的详细信息

关于硬件虚拟化的详细信息

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

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

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

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

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

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

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

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

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

半虚拟化提供程序

Oracle VirtualBox 支持暴露准虚拟化接口,以促进虚拟机内软件的准确高效执行。这些接口要求客户操作系统识别它们的存在并加以利用,以便利用与 Oracle VirtualBox hypervisor 通信的优势。

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

向客户操作系统暴露准虚拟化提供程序不依赖于主机平台的选择。例如,Hyper-V 准虚拟化提供程序可用于虚拟机在 Oracle VirtualBox 支持的任何主机平台上运行,而不仅仅是 Windows。

Oracle VirtualBox 提供以下接口:

  • Minimal:宣告虚拟化环境的存在。此外,还会向客户操作系统报告 TSC 和 APIC 频率。运行任何 Mac OS X 客户机都需要此提供程序。

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

  • Hyper-V:提供一个 Microsoft Hyper-V hypervisor 接口,该接口可被 Windows 7 及更新的操作系统识别。Oracle VirtualBox 的实现目前支持准虚拟化时钟、APIC 频率报告、客户机调试、客户机崩溃报告和宽松计时器检查。建议 Windows 客户机使用此提供程序。

嵌套分页和 VPID

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

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

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

    嵌套分页消除了虚拟机退出和页表访问造成的开销。实质上,借助嵌套页表,客户机可以在不经 hypervisor 干预的情况下处理分页。因此,嵌套分页显著提高了虚拟化性能。

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

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

    如果您使用的是带 EPT 的 Intel CPU,请查阅CVE-2018-3646 以了解有关 EPT 的安全问题。

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

    要为虚拟机启用这些功能,请使用 VBoxManage modifyvm --vtx-vpidVBoxManage modifyvm --large-pages 命令。请参阅VBoxManage modifyvm