车载操作系统(七):虚拟化(Hypervisor)
在电子电气系统架构从分布式向域集中式演进的大背景下,各种功能模块都集中到少数几个域控制器中,以前需要N个ECU(Electronic Control Unit,电子控制单元)实现各种功能,现在只需要一个DCU(Domain Control Unit,域控制器),节省了大量的线束和接插件,减轻了车身整体重量。
但是,在汽车电子电气系统中,不同的ECU提供不同的服务,具有不同的优先级,对底层操作系统的要求也不一样。例如,根据ISO 26262标准,汽车仪表系统与娱乐信息系统属于不同的安全等级,具有不同的处理优先级。汽车仪表系统与动力系统密切相关,要求具有高实时性、高可靠性和强安全性,以QNX操作系统为主,而信息娱乐系统主要为车内人机交互提供控制平台,追求多样化的应用与服务,以Linux和Android为主。
要使不同类型的操作系统运行在同一个计算平台,最直接的技术路径就是虚拟化。虚拟化作为一项底层IT核心技术一直被广泛应用于云计算领域,它的作用是通过Hypervisor软件模拟出一个具有完整硬件系统功能、运行在一个完全隔离环境中的计算机系统。
虚拟化的概念被引入到车载操作系统之后,供应商不再需要设计多个硬件来实现不同的功能需求,而只需要在车载主芯片上进行虚拟化的软件配置,形成多个虚拟机,在每个虚拟机上运行相应的软件即可满足需求。
虚拟化(Hypervisor)解决方案提供了在同一硬件平台上承载异构操作系统的灵活性,同时实现了良好的高可靠性和故障控制机制, 以保证关键任务、硬实时应用程序和一般用途、不受信任的应用程序之间的安全隔离,实现了车载计算单元整合与算力共享。
云虚拟化 vs 物虚拟化
如果说“云“虚拟化是过去20年的技术风口,那么”物“虚拟化将会是下一个20年不容错过的技术风口。虽然两种技术同根同源,但是,基于嵌入式的物虚拟化与传统的云计算虚拟化还是有其不同的地方。
**定位目标不同:**云虚拟化关注虚拟机的热迁移、资源弹性按需分配、灵活管理,而嵌入式虚拟化关注实时性、可确定性、功能安全(Functional Safety) 及小身材(Footprint)等。
**可用的资源多寡不同:**云服务器的计算能力和内存资源远多于嵌入式系统,后者对资源的使用几乎达到“斤斤计较”的地步。
软件发布模式不同。云虚拟化软件是同一套二进制代码部署在所有服务器上运行,而嵌入式虚拟化软件和嵌入式硬件往往是绑定的,大多数情况下是一物一系统。
车载虚拟化的技术要求
车载虚拟化操作系统首先是一个稳定可靠、性能良好、具备实时响应能力的微内核,承载在虚拟机上的应用程序按照预先设定的优先级运行,确保在高优先级虚拟机中运行的实时进程能够及时获得对计算资源的必要访问,无论低优先级虚拟机执行的繁忙程度如何,同时,强制性地将关键应用程序和实时操作系统与非关键应用程序和普通操作系统安全隔离。
小知识
所谓微内核(Microkernel),是指内核进程仅提供最基本的服务,例如进程调度、进程间通信、信号、时钟、中断等,而其它的服务(例如文件系统、内存管理、设备驱动、网络协议栈等)都独立于内核以单独的进程运行,它们与内核进程和其它进程之间通过内核提供的消息传递机制进行通信。
微内核是相对于宏内核而言的,Linux是典型的宏内核,除了时钟、中断、进程调度、进程间通信外,文件系统、内存管理、设备驱动管理等都由内核完成。
一般而言,车载虚拟化操作系统要求具备三点技术要求:
使用资源分区技术严格隔离和分配资源。
灵活高效的实时和非实时任务调度机制。
进程间通信,实现消息在虚拟机之间通信。
1、资源分区
微内核将全局内存空间划分为静态可配置的资源池,虚拟机启动时,将相应的内存页地址空间分配给它,虚拟机中的任务线程总是连接到这部分地址空间,并且它只能访问和管理这部分地址空间,此机制确保了虚拟机之间的严格隔离。当一个虚拟机中的应用程序出现故障时,只会影响分配给它的内存,而不会影响其它虚拟机的内存池。这是一个简单的解决方案,因为它维护了一个最小的受信任的代码库,唯一的挑战是开发人员应该预先预测Guest OS的内存需求。
2、任务调度机制
常见的操作系统任务调度机制有两种:
基于优先级:一旦内核把资源分配给某进程,该进程便会一直执行下去,直到该进程结束或发生某事件被阻塞(例如主动调用延时),才把资源分配给其它进程。在这种情况下,如果某个高优先级的任务运行时间过长,最好有阻塞机制,让出CPU使其它低优先级的任务也有机会运行。
基于时间片:所有任务的执行优先级相同,当内核分配给该进程的时间片结束,内核会立即停止执行该进程,将时间片分配给其它进程执行,即便这个任务还没有执行完。
车载虚拟化系统同时承载实时车控系统和非实时娱乐系统,这两种系统对于任务的时间响应要求有着本质的不同:
实时系统:一般要求基于优先级的调度方式,对于不同优先级的任务,完全基于优先权原则来运行,一旦高优先级的任务就绪,它可以无条件地抢占任何正在执行的、低于自己优先级的进程,无论正在运行的进程是否已经进入内核调度阶段。在一些实时操作系统的实现中,同时支持基于时间片的调度方式,当几个任务的优先级相同时,会按照时间片来管理,在优先级相同的任务间切换运行。
非实时系统:一般情况下没有任务优先级的概念,所有任务默认优先级相同,任务调度采用时间片调度方式。
车载虚拟化内核应该具备灵活的时间调度机制,既支持基于优先级的任务调度方式,又支持基于时间片的任务调度方式。
3、进程间通信
Hypervisor在对虚拟机进行严格安全隔离的同时,也需要支持不同虚拟机进程之间以受控方式相互通信。最基本的进程间通信包括同步消息传递和共享内存两种方式。
同步消息传递:采用客户端/服务器(Client/Server)模式,它实现了两个进程之间的点对点通信。
共享内存:一种相对高效的进程间通信方式,对于效率要求较高、数据量较大的场景,通常采用这种方式。共享内存段被视为共享文件系统,为每个虚拟机进程配置对共享内存的读写访问。
在车载虚拟化领域,主流的虚拟机技术提供商包括BlackBerry QNX Hypervisor(闭源)及Intel与Linux基金会主导的ACRN(开源)。但截至目前,只有QNX Hypervisor应用到量产车型,它也是目前市场上唯一被认可功能安全等级达到ASIL D级的虚拟化操作系统。
BlackBerry:QNX Hypervisor
QNX是由加拿大QSSL公司(QNX Software System Ltd.)开发的实时操作系统,既能运行于以Intel x86、Pentium等CPU为核心的硬件环境,也能运行于以PowerPC、MIPS等CPU为核心的硬件环境。
小知识
2004年,全球领先的音响产品制造商哈曼国际工业集团(Harman International Industries)收购QNX,2010年4月,BlackBerry母公司RIM以2亿美元从哈曼国际手中收购QNX。
QNX操作系统的应用范围极广,包括控制保时捷跑车的音乐和媒体功能、核电站、美国陆军无人驾驶坦克的控制系统、BlackBerry PlayBook平板电脑等。
2021年2月,BlackBerry正式发布QNX Hypervisor 2.2版本,该版本基于QNX Neutrino实时操作系统(RTOS)7.1。
QNX Hypervisor是基于Type-1(直接运行于裸机)、实时优先级的微内核管理程序,符合IEC 61508 SIL-3(用于工业安全),IEC 62304(用于医疗设备软件)和ISO 26262 ASIL-D(用于汽车安全)等标准。
整个QNX操作系统是由微内核调度管理的一组进程的集合,与硬件总线结构非常相似,称之为“软件总线”。
QNX是一个基于优先级抢占的操作系统,线程优先级用0\~255的数字表示,数字越大,优先级越高。优先级0是内核中的IDLE线程。同时,优先级64是一个分界岭,优先级1\~63是非特权优先级,一般用户都可以用,而64\~255必须是有Root权限的线程才可以设置。调度程序在选择下一个运行的线程时,将检查每个处于就绪状态的线程的优先级,具有高优先级的线程将被优先执行。
QNX基本的任务调度算法使用的是按优先级抢占的调度方法。这种方法保证在任何时刻都是优先级最高的任务占用CPU时间。优先级最高的任务可以中断当前运行的任务。这种方法适用于工业实时性要求较高的场合。
在基本调度算法的基础上,当两个或更多具有相同优先级的线程同时处于就绪状态,并且都是当前就绪队列中最高优先级的任务时,QNX提供了四种调度方法来解决问题:
先进先出(First In First Out,FIFO):先进入任务队列的线程被选择执行,直到它自动放弃,或者被一个级别更高的线程打断运行。
轮询(Round Robin):先进入任务队列的线程被选择执行,直到它自动放弃,或者被一个级别更高的线程打断运行,或者它消耗完了自己的时间片(时间片为50ms,是系统分配给每个线程用于运行的时间单位)。
自适应调度(Adaptive Scheduling):如果一个线程消耗完自己的时间片时仍未被阻塞,线程优先级将被减1,称为优先级衰减。一个线程只能降低一次优先级。如果该线程被阻塞,则将立即恢复为原来的优先级。这种算法不适用于实时控制系统,主要应用于后台有计算密集的任务,且同时需要响应用户的交互信息,此时,计算线程可以拥有足够的CPU资源,同时对用户请求又有很快的响应。
零星调度(Sporadic Scheduling):引入Initial Budget、Replenishment Period、Max Number of Pending Replenishments三个参数,使一个线程可动态执行于Normal Priority和Low Priority两个优先级。
Initial Budget(C):线程在Normal Priority下允许执行的时间。
Low Priority:由于某种原因,线程不再以Normal Priority运行,就将该线程的优先级降至此优先级。
Replenishment Period(T):只有在这个时间段内,线程才被允许消耗完它的Initial Budget。
Max Number of Pending Replenishments:限制Replenishment Period的发生次数。
当线程的优先级降低到Low Priority时,它可能会被执行,也可能不被执行,取决于系统当时其它线程的优先级。一旦一个Replenishment Period(T)到来,该线程的优先级立即升至Normal Priority,这样,只要适当配置系统中各线程的C和T,就可以使每个线程都可以在每个T内被执行C时间值。
零星调度将一个线程需要执行的时间分拆成若干段进行执行(这也是“零星调度”名称的由来),这种算法适用于一个周期内具有执行时间上限的线程,可以使一个线程对非周期事件进行服务,而不用担心影响其它硬实时线程的执行期限。
Intel & Linux基金会:ACRN
ACRN由Linux基金会于2018年3月在“Linux嵌入式大会”上发布,是一款灵活、开源的(BSD-3-Clause License)、轻量级Hypervisor参考软件。Intel开源技术中心为ACRN项目的发布贡献了源代码,早期支持者包括Intel、ADLink(凌华科技)、Aptiv、LG和东软等。
2020年6月,ACRN v2.0正式发布,采用**“Partition Mode”+“Sharing Mode”的“**Hybrid Mode”架构设计。
Partition Mode(左侧)的VM独享CPU、内存、I/O外设等资源,在运行时没有ACRN Hypervisor的性能开销,可以达到最大****的隔离性和更高的实时性。这个VM既可以作为Safety VM监控整个物理平台的健康状态,在系统发生严重故障时采取紧急措施,又可以作为实时VM获得更好的实时性。
Sharing Mode(右侧)有一个Service VM,它的作用类似于Xen虚拟化架构中的Dom0,通过Device Model模块在User VM(类似于Xen虚拟化架构中的DomU)之间共享外设,同时管理各个VM的生命周期,并调用Libvirt接口对外提供远程调用和编排的标准接口。需要特别说明的是,为了使RTVM(右侧黄色VM)能够运行硬实时OS(例如VxWorks、Zephyr、Xenomai等),ACRN进行了特别的设计与代码优化,例如Local APIC直通等,使RTVM达到接近裸金属的实时性能。
Hybrid Mode架构具有两个特点:
利用Partition Mode的VM运行Safety VM监控物理平台状态,同时利用Sharing Mode中的RTVM运行RTOS实现实时控制,满足复杂工业场景的需求。
通过ACRN Hypervisor实现了异构负载的整合,例如,实时和非实时负载、安全功能和非安全功能的隔离等。
为了保持ACRN Hypervisor代码库尽可能精简且高效,大部分设备模块的实现都驻留在Service VM,Service VM可以运行Clear Linux(Intel基于GPL协议的开源项目),也支持其它Linux发行版或者专有RTOS作为Service OS。如果没有Partition Mode中的Pre-launched VM,Service VM是ACRN Hypervisor创建的第一个虚拟环境,以系统最高优先级的虚拟机形式存在,通过Device Model模块向Guest OS提供I/O模拟操作。
ACRN Hypervisor基于Intel IA-32处理器的硬件辅助虚拟化技术(Intel VT-x)。
Intel VT-x引入了一种新的CPU操作,称为VMX(Virtual Machine eXtensions),以及两种新的CPU工作模式和10条新的虚拟专用指令(VMPTRLD、VMPTRST、VMCLEAR、VMREAD、VMWRITE、VMCALL、VMLAUNCH、VMRESUME、VMXOFF和VMXON)。两种工作模式分别为VMX root operation(根虚拟化操作)和VMX non-root operation(非根虚拟化操作),其中,VMX root operation被设计用于给Hypervisor使用,VMX non-root operation则由Guest OS使用。两种工作模式都支持Ring 0~Ring 3,因此,Hypervisor和Guest OS可以自由选择它们所期望的运行级别。
硬件辅助虚拟化技术就是通过在VMX root operation和VMX non-root operation两种工作模式之间相互切换实现的。
运行在VMX root operation模式下的Hypervisor通过显式调用VMLAUNCH或VMRESUME指令切换到VMX non-root operation模式,硬件自动加载Guest OS的上下文,于是Guest OS获得运行,这种转换称为VM entry。Guest OS运行过程中遇到需要Hypervisor处理的事件,例如外部中断或缺页异常,或者主动调用VMCALL指令请求Hypervisor的服务的时候(与系统调用类似),硬件自动挂起Guest OS,切换到VMX root operation模式,恢复Hypervisor的运行,这种转换称为VM exit。VMX root operation模式下,软件的行为与在没有VT-x技术的处理器上的行为基本一致;而VMX non-root operation模式则有很大不同,最主要的区别是此时运行某些指令或遇到某些事件时,发生VM exit。
ACRN Device Model是一个类似QEMU的硬件设备模拟软件,依赖以下三个子系统协同工作:
1、设备仿真(Device Emulation)
Device Model为User VM中的设备驱动提供设备仿真例程(Routines),用来模拟各种不同种类的硬件设备,这些设备仿真例程将各自的I/O处理程序注册到I/O调度器(Dispatcher)。当User VM产生I/O设备访问请求时,I/O调度器将这些请求分发到相应的设备仿真例程,实现硬件模拟。
2、VHM(Virtio and Hypervisor Service Module)
以Service OS的内核模块形式存在,作为ACRN Hypervisor与Device Model之间的桥梁,为设备模拟提供必要的服务,具体的服务流程如下:
ACRN Hypervisor通过中断通知VHM新的IOREQ到来。
VHM将IOREQ标记为“正在处理”,同时将其发送给设备模拟、GVT-g(Intel开源的GPU虚拟化解决方案)、VBS-K(Virtio Backend Service Kernel-land)等做进一步处理。之后,VHM可以处理新的IOREQ。
一旦IOREQ被处理完成,VHM将被通知(内核态通过函数调用方式通知,用户态通过IOCTL的方式通知),之后,VHM通过Hypercall方式进一步通知ACRN Hypervisor该IOREQ处理完成。
3、I/O请求(I/O Path)
下图展示了ACRN中访问一个虚拟I/O的流程。
当Guest OS执行I/O指令时,VM exit发生,ACRN Hypervisor获得CPU控制权,首先判断VM执行退出的原因,例如PIO或MMIO等。
ACRN Hypervisor对产生VM exit的指令进行译码,将译码得到的信息(包括PIO访问、访问字节数、读/写方式、目标寄存器等)放到与ACRN VHM、ACRN Device Model共享的物理页面中,然后以中断的方式通知Service OS中的VHM做进一步处理。
Service OS中的VHM接收到中断后,查询与该IOREQ相关的所有信息。
VHM首先会检查是否应该由内核态的Device Model来处理该IOREQ。如果是,相应的内核模块之前注册的Callback函数会被VHM调用;否则,如果没有内核态的Device Model来处理IOREQ,VHM则会将该IOREQ保留在共享页面中,并唤醒ACRN Device Model对该IOREQ进行处理。
ACRN Device Model采用与VHM相同的机制对IOREQ进行处理。Device Model的I/O执行线程会首先查询IOREQ具体的信息,同时检查是否有设备仿真模块实现了该IOREQ对应的逻辑。如果有相应的模块,那么该模块对应的Callback函数将会被调用。
ACRN Device Model完成设备模拟仿真后,将结果保存到共享页面。
完成IOREQ的模拟和仿真后,ACRN Device Model通过VHM的API将控制权返回给ACRN Hypervisor。
ACRN Hypervisor得知IOREQ处理完成,将结果保存到vCPU的相应寄存器中。
ACRN Hypervisor更新完vCPU寄存器后,进一步更新IP地址寄存器指向下一条Guest OS指令,同时恢复Guest OS的执行。
VirtIO标准
Hypervisor介乎于底层DCU硬件和上层OS软件之间,与标准化服务器(x86)+标准化OS(Windows和Linux)的云虚拟化应用场景不同,汽车嵌入式环境中的虚拟化技术面临的挑战是Hypervisor往往需要定制适配底层DCU硬件和上层OS软件,这一点对于Hypervisor的大规模商用与普及是一个非常大的技术障碍。
2016年3月,OASIS(Organization for the Advancement of Structured Information Standards,结构化信息标准促进组织)正式标准化VirtIO项目,旨在提供一种通用的框架和标准接口,减少Hypervisor对底层不同硬件和上层不同软件的适配开发工作量。
目前,VirtIO标准得到了众多科技巨头的支持,包括Apple、Google、ARM、Intel、Red Hat、华为等。Google也计划在Android Automotive OS中集成对VirtIO的支持。
VirtIO是一套易维护和易扩展的通用设备仿真接口,由前端驱动程序(Front-End Driver)、后端驱动程序(Back-End Driver)和VirtIO虚拟队列(Virtual Queue)构成。
前端驱动程序由Guest OS实现,后端驱动程序由Hypervisor实现,虚拟队列通常使用环形缓冲,在Hypervisor和Guest OS之间传输数据,每个驱动可以有0个或多个队列,取决于实际需要。例如,网络驱动(virtio-net)可能使用了两个虚拟队列(分别用于接收和发送),而块存储驱动(virtio-blk)可能只需要一个。
除了网卡、PCI、块存储、控制台、输入等常用设备之外,传感器、CAN网络、媒体编解码设备等汽车领域的一些特殊类型硬件,可能是未来VirtIO标准完善的方向。
结束语
汽车电子电气架构从分布式向域集中式发展的趋势已成定局,越来越多的功能被整合到少数几个域控制器中,从而出现了多种不同的功能复用同一个硬件平台的需求。
Hypervisor虚拟化为同一个硬件平台承载多种不同类型的操作系统、不同时间响应要求的业务应用提供了关键的技术支撑。借助Hypervisor虚拟化技术,既消除了硬件冗余,简化了总体设计,降低了整车重量,又满足了资源复用、算力共享、安全隔离的需求。
当前,大多数的Hypervisor都需要与指定的底层硬件和上层Guest OS配合使用,随着越来越多的Hypervisor提供商和Guest OS供应商遵循VirtIO标准,以及VirtIO标准对特定汽车硬件的虚拟化支持,Hypervisor将进一步解耦车载软硬件,车载系统供应商将更容易在不同的DCU硬件平台上支撑不同的Guest OS和应用程序,从而真正实现软件定义汽车。
作者:欧珊瑚
来源:https://mp.weixin.qq.com/s/Ilv9nn0Fy5o6p3p2\_oiacw