JasonWang's Blog

虚拟化之二QNX虚拟化平台简介

字数统计: 2.4k阅读时长: 8 min
2023/08/09

QNX最初是Gordon BellDan Dodge两人在1980年代初期创建的一个实时微内核操作系统(RTOS(Real-Time Operating System), 后来被黑莓(BlackBerry)公司收购,因此也叫做Blackberry QNX系统。QNX被世人熟知还是因为其高安全性、QNX hypervisor等特性在汽车领域的广泛应用。

这篇文章,我们就来看看QNX虚拟化平台的基本架构与实现原理,着重会介绍虚拟化方案:

  • 介绍QNX以及虚拟化平台的基本概念与架构
  • 介绍QNX虚拟化的实现方法,包括CPU虚拟化,内存虚拟化,设备虚拟化等

QNX虚拟化平台的架构组成

QNX系统是一个微内核(microkernel)的类UNIX的实时操作系统,支持x86/ARM/PowerPC/MIPS等多个芯片架构,可以应用到从小型的嵌入式硬件到大型的分布式系统中。总结来说,主要有如下几个特点:

  • 微内核的实时操作系统: 与Linux这样的宏内核(Monolithic)操作系统不同的是,QNX采用的微内核的实现。内核只实现了很少一部分功能,比如进程管理与进程通讯,进程同步与调度等,其他的如文件系统,设备驱动以及网络协议栈都在用户空间中实现。这么做一个明显的好处是,内核不会设备驱动或者网络协议栈等异常崩溃而卡死,从而提升了系统的稳定性与可用性;进程的上下文切换效率更高,因而实时性更好。
  • 支持POSIX接口: 与大部分UNIX的操作系统类似,QNX支持POSIX标准接口,这样其他很多比如在Linux上写的程序就可以直接移植到QNX上,减少了开发成本。
  • 系统级别的HA(High Availability)框架: QNX专门提供了一套高可用的开发框架,可以用于进程的快速恢复,确保系统业务功能的高可用性。
  • 多个行业安全认证: QNX代码经过多个行业安全标准,如通信行业的FIPS 140-2, 工控行业的IEC 61508, 汽车电子领域的ISO 26262等等,从代码级别上提升了系统的安全性。
  • 支持多个硬件平台:支持市面上大部分SoC供应商如AMDIntelNvidiaNXPQualcomm的芯片

QNX RTOS

如上图所示,是QNX系统的一个架构简图,可以看到,内核为所有进程通讯提供了一个软总线(software bus),进程之间的通讯都是通过这条软总线传递消息。内核只是实现了诸如线程管理、消息传递、发送信号、中断处理、并发同步等功能,其他的如显示驱动,文件系统,网络协议栈、字符设备等统一在用户空间实现。

QNX在原有系统上进行了虚拟化扩展,支持了hypervisor功能;在hypervisor的基础上,QVM(QNX Virtual Machine)支持运行如LinuxAndroidQNXGuest操作系统。目前常见的汽车座舱芯片如Renesas R-Car H3, 高通820A8155以及NXP i.MX 8等都支持QNX虚拟化方案。

下图是QNX虚拟化平台的一个框架简图,每个运行的客户操作系统(Guest OS)都对应个QVM进程;客户操作系统可以通过虚拟设备或者pass-through的方式访问控制硬件。实际上,对QNX来说,客户操作系统并不一定运行在虚拟的环境,而是大部分时候都直接在物理CPU上执行指令,只有当需要访问一些特权指令或者无法访问的内存时,hypervisor才会介入,执行虚拟化相关的指令,让虚拟机退出。

QNX hypervisor architecture

以单个CPU的执行流程为例,当hypervisor陷入到虚拟化相关的指令后,首先会尝试保存当前虚拟机的上下文信息,此时虚拟机退出,由hypervisor完成必要的工作后再恢复虚拟机的上下文,重新执行虚拟机被打断的流程(具体路程参考下图):

The lahav line

接下来我们就具体来看看QNX是如何实现CPU、内存、I/O设备以及中断是如何处理的。

QNX虚拟化实现

CPU的虚拟化

虚拟机上的进程的调度实际是以虚拟CPU(vCPU)为基础进行的,每个虚拟机在启动时,可以配置vCPU的数量;vCPU的调度是由在hypervisor中的调度线程负责执行的。一个物理CPU可能对应着多个vCPU;类似的,一个vCPU也可以选择在多个物理CPU上电调度执行。需要注意的是,虚拟机中的线程优先级与宿主机中QNX的线程优先级没有关系,具体何时执行哪个vCPU完全是由hypervisor中的调度线程的优先级决定的: 两个vCPU竞争物理CPU时,对应的hypervisor调度线程的优先级更高的任务获得对应的物理CPU执行权。

QNX虚拟化中进程的调度

虚拟机的线程调度到物理CPU的过程类似与普通操作系统中进程上下文切换的过程: 在虚拟机上需要保存当前线程的上下文信息,接着通过一个虚拟指令陷入(trap, 这个跟Linux下的系统调用从用户空间切换到内核空间的过程很类似)到hypervisor中,然后由hypervisor最终完成整个调度上下文的状态保存与切换。当一个客户虚拟机中发生如QNX的中断,虚拟设备访问(不一定放弃CPU的控制权),虚拟时钟到期等事件时,虚拟机就会让出当前CPU的控制权。

内存虚拟化

QNX中使用stage 2 translation(二阶转换)来完成内存的虚拟化,虚拟机看到的物理内存实际上是QNX宿主系统管理的非连续虚拟内存而已:二阶内存转换就是在正常的VA->PA之间增加一个地址转换过程IPA(Intermediate Physical Address),于是虚拟机的内存访问就变成了VA->IPA->PA这样一个二阶段的过程。

  • 阶段1的内存地址转换VA->IPA由虚拟机来控制完成
  • 阶段2的内存地址转换IPA->PAQNX宿主机系统来完成

QNX内存虚拟化

由于增加了中间地址的转换层IPA,这样虚拟机与QNX宿主机之间的内存空间就完全隔离了,虚拟机只能看到QNX宿主机分配好的内存,无法访问其他虚拟机或者宿主机的内存空间。除此之外,QNX还提供了额外的内存访问方式:

  • Pass-through memory:直通内存允许虚拟机将某些设备直接映射到某个内存区域,然后直接访问这个物理设备;直通模式下的设备只有该虚拟机才能访问,在性能上比虚拟的设备会更高。有关直通设备的详细信息可以参考直通设备
  • Shared Memory: 共享内存允许不同虚拟机共享同一块物理内存,通过该内存区域进行数据交互

I/O设备虚拟化

QNX中,物理设备可以由宿主机或者虚拟机独占,也可以由虚拟机与宿主机之间共享。虚拟机要访问物理设备,可以通过直通或者虚拟化的方式实现:

  • Pass-through device: 直通设备的访问完全由虚拟机控制,驱动也在虚拟机中实现, 而hypervisor只是负责识别、传递来自设备的中断,传递来自虚拟机发送过来的信号。

pass-through device

  • Virtual Devices: 虚拟设备vdev可以是一个物理设备的模拟,也可以只是提供了一个类似物理设备功能的模拟设备。与直通设备类似,虚拟机要使用虚拟设备也需要提供驱动。目前QNX hypervisor提供了两种形式的虚拟设备-一个是模拟(Emulation)设备,一个是半虚拟化设备(para-virtualized, 见下图)。QNX中很多设备都是通过半虚拟化提供给虚拟机的,如输入设备、虚拟网卡都是通过半虚拟化方式virtio实现的,后面我们会专门用一篇文章来分析下virtio的虚拟化设备怎样的工作原理。

Para-virtualized devices

更多有关QNX支持的虚拟设备的可以参考vdev references

虚拟机的中断处理流程

每个中断都有一个中断号,如果设备需要处理中断,需要通过vdev或者pass直通的方式传递给虚拟机:

1
2
3
4
5
6
7

//vdev
vdev vdev-virtio-i2c.so loc 0x1cd00000 intr gic:104 verbose 3 device i2c5

// pass through
pass intr gic:183=183

当一个中断发生时,如下图所示一般分为两种情况:

  • 如果当前中断发生的CPU执行是虚拟机线程,则首先虚拟机的线程退出,将中断丢给hypervisor处理,并切换到宿主机,由QNX判断该中断属于虚拟机还是宿主机:如果中断属于宿主机QNX,则由其处理中断即可;如果是属于虚拟机的中断,则需要通过hypervisor发送一个中断信号给虚拟机,然后交由虚拟机处理
  • 如果当前中断发生的CPU执行的是宿主机QNX线程,QNX判断是虚拟机的线程则按照前述的步骤交由虚拟机处理。

GIC handling process

参考资料

原文作者:Jason Wang

更新日期:2023-08-10, 12:34:45

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG
  1. 1. QNX虚拟化平台的架构组成
  2. 2. QNX虚拟化实现
    1. 2.1. CPU的虚拟化
    2. 2.2. 内存虚拟化
    3. 2.3. I/O设备虚拟化
    4. 2.4. 虚拟机的中断处理流程
  3. 3. 参考资料