Skip to content

2. RVM 整体架构

equation314 edited this page Aug 6, 2020 · 1 revision

RVM 整体架构

如上图所示,RVM 是一个 Type-2 的 hypervisor。类似于 Linux + KVM + QEMU 的架构,一个基于 RVM 的 Type-2 hypervisor 的正常运行离不开下列组件:

  1. Host OS:目前支持 zCore 或 rCore。类比于 Linux。
  2. RVM:Host OS 中的一个模块。类比于 Linux 的 KVM。
  3. VMM 用户程序:一个用户态程序,通过系统调用访问 RVM API,构建完整的能运行 Guest OS 的应用。类比于 QEMU。
  4. Guest OS:在虚拟机上运行的 OS,目前已能运行 μCore。类比于 QEMU 上运行的 Guest OS。

RVM API

RVM 主要提供了两个结构体:GuestVcpu,分别是对一个 Guest 和 vCPU 的抽象。使用 RVM 的 Host OS 通过调用这两个结构体提供的函数,来实现 hyervisor 的功能。Host OS 也可通过系统调用的方式将这些函数提供给用户程序,以实现 Type-2 的 hypervisor。由于 rCore 和 zCore 分别兼容的是 Zircon 和 Linux 的系统调用,因此用户程序调用的方式有所不同:

  • zCore:每一个 RVM API 对应一个 zCore 的 syscall,并以 sys_guestsys_vcpu 开头,除了向 Guest 添加物理内存段的 API,它使用的是 VMO 和 VMAR 相关的 syscall,不需要专门提供 syscall。

  • rCore:与 Linux KVM 一样,RVM 被抽象为一个虚拟设备文件,用户程序首先通过 open("/dev/rvm", O_RDWR) 打开该文件,然后通过 ioctl 系统调用访问 RVM;每个 RVM API 对应不同的 ioctl 编号,编号起始值与 KVM 一样都是 0xAE00

除了形式上的不同,在功能上它们可以一一对应。下表给出了 RVM API、zCore syscall 和 rCore ioctl 编号的对应关系:

API 原语/rCore ioctl zCore syscall RVM API 说明
RVM_GUEST_CREATE sys_guest_create Guest::new() 创建一个 Guest
RVM_GUEST_ADD_MEMORY _REGION sys_vmo_create sys_vmar_map guest.add_memory_region() 添加 Guest 的物理内存段
RVM_GUEST_SET_TRAP sys_guest_set_trap guest.set_trap() 设置捕获哪些 I/O 操作
RVM_VCPU_CREATE sys_vcpu_create Vcpu::new() 创建一个 vCPU
RVM_VCPU_RESUME sys_vcpu_resume vcpu.resume() (恢复)运行 vCPU,阻塞当前线程,直到需要用户态模拟
RVM_VCPU_READ_STATE sys_vcpu_read_state vcpu.read_state() 读 vCPU 状态(寄存器)
RVM_VCPU_WRITE_STATE sys_vcpu_write_state vcpu.write_state() vcpu.write_io_state() 写 vCPU 状态(寄存器和 I/O 指令结果)
RVM_VCPU_INTERRUPT sys_vcpu_interrupt vcpu.virtual_interrupt() 让 vCPU 产生一个中断

用户程序使用 RVM

可利用以上 API,构建完整的可运行 Guest OS 的用户程序,步骤如下:

  1. 创建一个 guest;
  2. 向 Guest 添加物理内存段,写入必要的数据(如 Guest OS 镜像);
  3. 创建和设置相关虚拟设备,通过 RVM_GUEST_SET_TRAP 设置哪些 I/O 操作由用户程序模拟;
  4. 创建 vCPU;
  5. 轮询调用 RVM_VCPU_RESUME,阻塞直到需要模拟 I/O 操作;
  6. 模拟 I/O 操作,然后返回 5。

由于 vCPU 运行时会阻塞当前线程,因此当一个 Guest 中有多个 vCPU 时,需要将它们放在不同的线程中执行。

用户程序使用 RVM

Clone this wiki locally