APP下载

基于i.MX8虚拟化Xen方案的Linux双系统设计

2021-04-24倪子豪何照丹耿杨张凯

汽车技术 2021年4期
关键词:内核分区虚拟化

倪子豪 何照丹, 耿杨 张凯,

(1.清华大学深圳国际研究生院,深圳 518055;2.深圳市阿丹能量信息技术有限公司,深圳 518126)

主题词:智能交通 i.MX8 嵌入式虚拟化 Xen Linux 双系统

1 前言

随着汽车多元化需求的增加,车载系统向着智能座舱方向发展,成为同时具有交通、娱乐、办公和通讯等多种功能的综合平台。现代化的智能座舱系统在保证车辆安全、稳定的前提下,对信息、娱乐和辅助驾驶的集成提出了新的要求。智能座舱需要集成度更高、感官效果更好的整体系统,因此需要将组合仪表、中控台等多个工作目的、性能要求不同的系统进行集成。

目前,汽车普遍将2套完全独立的系统分别安装于2 个处理器上,分别负责仪表的数据处理与显示,以及信息娱乐功能。该方法需2套硬件资源,成本较高,且2个系统需要通过总线或以太网协议进行信息交互,系统间交互较为复杂。另一种方法是使用虚拟化系统,即在1套硬件资源上通过虚拟化技术运行2个系统。若沿用类似VMWare的基于软件的虚拟化方案,会增加系统代码量,从而影响可靠性。因此,必须寻找新的基于硬件的虚拟化方案,通过采用多核方案实现硬件虚拟化,从而兼顾安全性与成本。

Xen是开源的虚拟化管理软件,其核心是虚拟机监视器,负责完成CPU 调度和内存资源分配[1],具有高性能和占用资源少的特点,且与操作平台的结合极为密切,并支持ARMv8 嵌入式架构。相比于其他虚拟化方案,Xen相对成熟,且其ARM架构支持相对前沿。在各种车载嵌入式系统的虚拟化中,Xen 的应用相对较少。在国外:Avanzini等人[2]提出了基于Xen的车载系统虚拟化方案,将Linux 系统和ERIKA 实时系统进行整合;Luca等人[3]的研究表明,Xen和KVM都可以作为实时管理程序,并提供了一些减少延迟的指导机制,有利于提高Xen在车载系统中的实时特性。在国内,主流的方案有:使用ARM和Windows Embedded CE设计车载系统[4];使用嵌入式Linux进行开发,例如结合图形界面QT设计车载虚拟仪表[5]等;王冲[6]提出了基于Xen的半虚拟化系统设计,讨论了Linux 与μC/OS-Ⅱ系统结合的性能,但由于μCOS-Ⅱ目前尚未开源,所以无法定制开发。

基于以上背景,本文使用NXP 公司开发的高配版i.MX8 系列处理器,基于i.MX8 系列ARMv8 架构处理器,使用Xen虚拟化方案实现Linux双系统的启动。

2 通用引导加载程序设计

2.1 通用引导加载程序

在嵌入式Linux 系统常用的引导加载程序(BootLoader)中,通用引导加载程序(Universal Boot Loader,U-Boot)使用频率最高。其“通用”有两层含义,一是支持多种不同的嵌入式操作系统,二是支持诸多常用系列的处理器。U-Boot 项目的开发目标与之契合,即支持尽可能多的嵌入式处理器和嵌入式操作系统。本文对U-Boot 进行一些定制化设计,将Xen 引导命令编译入U-Boot,使其能够正常启动虚拟机管理器。

U-Boot目录分为3类:与处理器架构和板极硬件相关的代码;通用函数和驱动、检测程序;参考文档和工具。修改代码时只需要修改/arch/arm、/board、/configs、/include目录下有关开发板和处理器架构等方面的配置文件。

2.2 U-Boot的修改与设计

U-Boot启动过程分为3个阶段,其中第3个阶段主要任务是加载内核并跳转到内核启动。而Xen Hypervisor是类似内核的模块,因此U-Boot设计与修改的重点在于了解第3个阶段如何调用内核并传递必要参数。

按照正常的单系统启动流程,应在内存中将U-Boot、Linux系统内核、根文件系统等启动相关的镜像按照图1的顺序加载。

图1 Linux单系统启动流程

Xen是一个微内核,作为Linux虚拟机的管理者,需要先于Linux 系统启动,在Xen 虚拟化方案下的启动镜像应按照图2的顺序加载。

图2 Xen虚拟化方案下Linux双系统启动流程

比较图1和图2可以明确需对U-Boot进行的修改:将传递给Linux 和Xen 的参数全部传递给Xen 内核,并加载Xen内核到内存中,最后启动Xen Hypervisor。

基于上述分析,本文对U-Boot进行了如下修改:

a.在定义环境变量中加入有关Xen启动的变量:

b.对Xen Hypervisor 使用参数进行定义,包括命令行为串口1、加载地址为0x80280000、启动介质为SD卡,在此基础上传递Linux 系统Domain-0 启动所需参数,包括加载地址为0x85000000、分配内存2 048 M 和分配4个虚拟CPU。最后定义指令run xenmmcboot作为U-Boot命令行调用这些代码加载Xen内核的入口:

通过以上操作,完成了U-Boot的设计与修改,设置了启动方式和命令,使U-Boot从SD卡启动,使得U-Boot启动目标为复制Xen内核到内存中,最后启动Xen内核,并将控制权交给Xen Hypervisor。经过上述修改,对Xen加入内存前、后的内存空间进行比较,如图3所示。

图3 Linux系统和Xen虚拟化方案Linux双系统内存空间分布

3 特权域Domain-0设计与启动

3.1 Domain-0内核配置与编译

从Linux 3.0 开始,Linux 内核添加了Xen 相关的支持,可以选择是否作为Domain-0内核使用,给内核编译带来不少方便。Domain-0内核修改过程如图4所示。

图4 Domain-0内核修改过程

由于i.MX8 系列处理器使用ARMv8 架构,属于64位处理器,所以需要在内核配置前执行:

上述代码将架构改为ARM64,并在内核根目录的/arch/arm64/configs 下对默认配置文件defconfig 进行修改,调整是否为Domain-0的配置,将修改后的配置文件重命名为Dom0_defconfig、DomU_defconfig 并保存,如是便可以在后续修改2 个系统的内核时分别拥有对应的默认配置文件。进而执行:

则make 脚本会读取Dom0_defconfig 中的代码,对内核进行配置,并保存文件.config。该文件即内核在进行编译时参考的最终配置文件。

其中,关于Xen和Domain-0的部分重要配置如下:

以上即以Domain-0 作为特权域必须的配置,能使Domain-0 在启动时加载特权域相关组件,及组成Xen Hypervisor中分离驱动架构的必要部分——backend驱动。

配置结束后保存,然后对内核进行编译。本文使用的Linux 内核加入了Yocto Project 的支持,可以使用bitbake linux-imx-C compile 指令一步完成内核编译和部署,之后会直接将编译生成的镜像文件Image 和设备树.dtb 文件保存于deploy 目录下,方便查找和使用。

3.2 系统启动介质的制作

一个Linux 系统的运行包含4 个必需部分:Linux系统内核Image、设备树.dtb 文件、BootLoader、根文件系统。通过Yocto Project 提供的bibake 编译指令可在/tmp/deploy 目录下生成单独的内核、文件系统等,也有将上述4个部分全部打包的镜像.sdcard文件,供开发人员制作启动介质,可以直接使用dd 指令将打包好的完整系统镜像.sdcard文件烧录到SD卡中。但是使用这种固定的烧录镜像方法时,无论SD卡的存储空间多大,都会对SD 卡进行固定大小的分区,且仅有2 个分区。这会造成SD卡存储资源的浪费,且空间大小不可调节,若文件系统中放入大量应用程序,则会造成分区空间不足,但空余空间无法利用的后果。另外,由于使用Xen虚拟化方案启动2个系统,则需要在一张SD卡上烧录2个系统,以上方法便不能适应此需求。

对上述结果进行分析,并结合Linux系统启动过程,本文手动对SD卡进行分区并格式化,根据需求自定义分区大小。此后,按地址前后顺序在SD卡上烧录U-Boot、在第1个分区放置设备树.dtb文件和系统镜像,在第2个分区放入根文件系统。后续空间为未分区或格式化的raw存储空间,仍可在后期增加分区和放置系统文件。

考虑到目前本课题实际需要,暂不涉及多系统的试验,因此对SD卡分为3个分区,如表1所示。

表1 自定义SD卡分区情况

分区完成后需要进行格式化,第1 个分区格式为vfat,用于存放设备树文件和内核镜像,第2、第3个分区格式为ext4,用于存放根文件系统。接下来分别完成单独烧录BootLoader、复制根文件系统等操作,即完成了启动介质的自定义制作。

经试验验证,该方法具有可行性,同时解决了无法烧录多个系统、SD卡空间浪费的问题。为提高SD卡内存使用率,在后续研究中将全部使用该方法。

完成SD卡启动介质制作后,将SD卡插入开发板卡槽,输入run xenmmcboot,即从SD卡中启动Xen Hypervisor。初始化Xen的一些资源后,内核开始启动Domain-0。

4 非特权域Domain-U设计与启动

4.1 Domain-U内核配置与编译

Domain-U内核的配置过程与Domain-0类似,但在设备分配上有所不同。Domain-U的配置主要是内核模块与硬件设备的分配。Linux 内核从3.x 版本开始引入设备树的概念,用于实现驱动代码与设备信息的分离。对于Linux 双系统,需要编写2 个系统分别对应的设备树.dts文件。而NXP公司对于单Linux系统已经编写了针对该开发板的设备树文件fsl-imx8qm-mek.dtsi,因此可以在此基础上进行修改。

设备树文件的修改原理如图5 所示。根据Xen Hypervisor 虚拟化方案的原理,Domain-0作为特权域拥有所有硬件资源的访问权,因此在Domain-0 的设备树中理应包括所有的设备,但有些需要设置为“xen,passthrough”属性,传递给Domain-U 供其重写属性并使用。本文完成了fsl-imx8qm-mek-dom0.dts 和fsl-imx8qm-mek-domu.dts 2个文件的编写,并在调试中进一步修正。

图5 Xen资源分配方法

根据Domain-U 的配置要求,对其内核配置make menuconfig时,将XEN_BACKEND设为n,即将与Xen有关的backend 驱动全部关闭。此外,在启动过程中经常遇到启动Domain-U时部分模块启动异常而出现致命错误,导致内核错误(kernel panic)的问题。以加密算法模块(Cryptographic Accelerator and Assurance Module,CAAM)为例,由于其需要直接与硬件通讯,而根据Xen虚拟化方案,只有Xen Hypervisor工作在ring 0时可以直接访问硬件,其他域的特权级均低于它。非特权域中的操作系统不能直接与硬件通讯,因此,在启动过程中CAAM模块会因找不到硬件地址而出现野指针,从而导致内核出现错误,无法正常启动。

根据以上原因,需要把Domain-U中与硬件资源直接相关的配置删除,重新编译内核作为Domain-U的Image,以上便完成了Domain-U的内核配置。随后使用与编译Domain-0内核相同的方法完成Domain-U内核的编译。

4.2 创建并启动Linux双系统

Xen Hypervisor将策略的制定和实施分离,将管理和配置工作交给Domain-0 进行,而并非给Hypervisor 实施。亦即若将虚拟机的管理工作分为2类,即确定如何管理和实施,则Domain-0 负责第1 类工作,Xen Hypervisor 负责第2类。之后,Domain-U 创建的过程即在Domain-0中对其配置进行设置,继而通过xl create、xl console等命令行指令进行创建。同理,用户在Domain-0中可以设置虚拟机的管理参数,而Xen Hypervisor 按照在Domain-0中设置的参数设置并启动客户虚拟机。

根据以上分析,对于从Domain-0到Domain-U的启动,需要经过如图6所示的操作过程。

图6 Domain-U的启动过程

其中重点在于需要编写/etc/xen/domu-im8qm-mek.cfg 配置文件,对Domain-U 进行配置。domu-im8qmmek.cfg文件的主要内容包括:

该.cfg文件中对Domain-U的内存进行了设置,同时在U-Boot 中也对内存资源进行了预分配。其中.cfg 文件中指定最大内存容量,U-Boot中通过宏分配实际的内存地址空间大小。若U-Boot 中分配的内存大于.cfg 文件中配置的最大内存,则在创建过程中Domain-U 正在使用的内存会超出最大允许范围,出现野指针导致系统跑飞,进而被Xen Hypervisor强制关闭。根据以上情况,对2处内存设置进行协调,完成Domain-U的创建。

本文使用xl create/etc/xen/domu-im8qm-mek.cfg 的方法将配置要求传递给Xen Hypervisor,随后Xen Hypervisor 进行资源分配,并创建Domain-U。xl create方法流程图如图7所示。

将修改好的Domain-U 内核镜像Image、Domain-U设备树文件复制到SD 卡中的第1 个分区。随后在SD卡中的第3 个分区中装入Domain-U 的根文件系统,将写好的Domain-U系统配置文件放在/etc/xen目录下。

Domain-0 系统启动后,进入到/etc/xen,然后执行xl create domu-imx8qm-mek.cfg,成功创建Domain-U 系统。随后执行xl console DomU 接入Domain-U 的控制,完成双系统启动。

图7 xl create*.cfg创建客户虚拟机流程

为了方便区分2 个系统,在用户名中把Domain-U的root 用户名设置为guest。登录Domain-U 后,可以回到特权域Domain-0,通过xl list命令可以看到正在运行的2个虚拟机系统及其相关信息。

5 双屏显示驱动设计

双屏显示驱动程序的开发过程中需要根据Xen Hypervisor 的驱动结构对一般的显示驱动进行前、后端分离。Xen的虚拟设备架构采用前、后端分离的设备驱动结构。虚拟设备驱动包含Domain-U中前端设备驱动和Domain-0中后端设备驱动。后端设备驱动可以通过原生设备驱动访问真实的硬件设备,其架构如图8所示。

图8 Xen设备驱动架构

基于Xen的虚拟驱动架构,本文完成了双屏显示所需的原生驱动程序、资源配置、设备节点分配、前后端驱动的所有设计与开发,最终完成了双屏显示的驱动程序设计,显示效果如图9所示。

图9 双系统双屏显示

6 结束语

本文在NXP 公司开发的基于i.MX8 处理器的i.MX8QuadMax Mek 开发板上完成了虚拟化Xen方案下的Linux双系统设计,在i.MX8系列处理器上实现了Xen虚拟化方案,验证了虚拟化方案在车载智能座舱系统上的可行性,是嵌入式虚拟化技术在车载智能座舱系统上使用的新尝试。在本文研究成果的基础上,未来可以进行进一步探索,如:开发系统间通讯机制,在2个系统之间提高数据传递速度;将Linux 系统升级为Android 系统,并在Android系统中开发更加丰富的中控系统应用,最终真正应用于实际的车载智能座舱系统。

猜你喜欢

内核分区虚拟化
贵州省地质灾害易发分区图
上海实施“分区封控”
人民情怀:柳青为文为人的内核(评论)
初春
微软发布新Edge浏览器预览版下载换装Chrome内核
大型数据库分区表研究
浅谈虚拟化工作原理
用户怎样选择虚拟化解决方案
神探出手,巧破分区离奇失踪案
虚拟化整合之势凸显