VirtualizationService
主要通过管理 crosvm 实例来管理在 Android 系统上运行的所有受保护或其他方式的来宾 VM。 VirtualizationService
公开了一个 AIDL API,系统服务或应用程序可以使用该 API 来启动、监视和停止 VM。
AIDL API
VirtualizationService
公开了一个 AIDL API,客户端可以使用该 API 来提供映像并启动 VM。此描述可以是原始 VM 配置,其中包含引导加载程序或内核的文件描述符以及要包含在 VM 中的各种磁盘映像,也可以是 Microdroid 配置,其中客户端仅提供有效负载,并且 VM 使用标准 Microdroid 内核和基础架构启动。然后, VirtualizationService
返回代表 VM 的IVirtualMachine
Binder 对象。启动VM的客户端可以选择使用通常的Binder机制与其他进程共享Binder对象。
IVirtualMachine
具有 AIDL 方法来获取有关 VM 的信息,例如 CID,可用于通过 vsock 与其进行通信,并且还允许注册回调以在 VM 停止时调用。对于 Microdroid VM, IVirtualMachine
对象也可用于设置与 VM 的 Binder 连接。
虚拟机生命周期
对 VM 的访问由IVirtualMachine
对象跟踪。只要至少有一个对IVirtualMachine
对象的引用,VM 就会继续运行(除非它自行崩溃或关闭)。如果在 VM 关闭之前删除对IVirtualMachine
对象的所有引用,则VirtualizationService
会自动关闭 VM。这个过程意味着,如果启动VM的客户端被低内存杀手关闭,那么VM也会被关闭,从而防止资源泄漏。
每个虚拟机都由其自己的 crosvm 实例进行管理,而VirtualizationService
又代表客户端进行管理。 VirtualizationService
根据需要启动这些 crosvm 子进程,并向它们传递 VM 所需映像的文件描述符。然后, VirtualizationService
会监视子进程何时终止,以便相应地通知任何剩余的客户端。
虚拟机包装
crosvm 支持两种不同的虚拟机启动方式:提供内核和 initrd 或提供引导加载程序。在任何一种情况下,都可以提供任意数量的磁盘映像,这些映像可以是原始映像,也可以是多个分区的组合。各种图像由客户端作为文件描述符提供。
VirtualizationService
根据需要构建复合磁盘映像。这个过程是必要的,因为复合磁盘文件在内部指的是组成磁盘的各个分区映像文件,这些文件是由客户端传递的,并且可能无法被 crosvm 直接访问。为了解决这个问题, VirtualizationService
确保 crosvm 继承的文件描述符编号与 VirtualizationService 在创建复合映像时使用的文件描述符编号相同。复合磁盘映像使用/proc/self/fd/N
形式的文件名来表示每个分区文件。
对于 Microdroid pVM,AVF 包含一个引导加载程序,它按照标准 Android 验证引导流程从复合磁盘映像的分区加载内核。
虚拟机套接字 (vsock)
pVM 之间通信的主要接口是 vsock,一个标准 virtio 套接字接口。每个虚拟机都由 32 位上下文标识符 (CID) 进行标识,该标识符类似于 IP 地址, VirtualizationService
在创建虚拟机时将其分配给虚拟机,并且可以在虚拟机选择的任何端口号上公开服务。当VM运行时,CID是唯一的,但是当VM终止并且VM的所有IVirtualMachine
Binder句柄都已被删除时,CID值可以被回收。
调试接口
提供vm
命令用于调试目的。此命令允许开发人员从 shell 启动 VM、查看其日志以及终止 VM。有关 AVF 提供的命令行工具和其他调试接口的更多信息,请访问https://android.googlesource.com/platform/packages/modules/Virtualization/+/refs/heads/main/docs/debug 。