倪子豪 何照丹, 耿楊 張凱,
(1.清華大學(xué)深圳國(guó)際研究生院,深圳 518055;2.深圳市阿丹能量信息技術(shù)有限公司,深圳 518126)
主題詞:智能交通 i.MX8 嵌入式虛擬化 Xen Linux 雙系統(tǒng)
隨著汽車多元化需求的增加,車載系統(tǒng)向著智能座艙方向發(fā)展,成為同時(shí)具有交通、娛樂、辦公和通訊等多種功能的綜合平臺(tái)。現(xiàn)代化的智能座艙系統(tǒng)在保證車輛安全、穩(wěn)定的前提下,對(duì)信息、娛樂和輔助駕駛的集成提出了新的要求。智能座艙需要集成度更高、感官效果更好的整體系統(tǒng),因此需要將組合儀表、中控臺(tái)等多個(gè)工作目的、性能要求不同的系統(tǒng)進(jìn)行集成。
目前,汽車普遍將2套完全獨(dú)立的系統(tǒng)分別安裝于2 個(gè)處理器上,分別負(fù)責(zé)儀表的數(shù)據(jù)處理與顯示,以及信息娛樂功能。該方法需2套硬件資源,成本較高,且2個(gè)系統(tǒng)需要通過總線或以太網(wǎng)協(xié)議進(jìn)行信息交互,系統(tǒng)間交互較為復(fù)雜。另一種方法是使用虛擬化系統(tǒng),即在1套硬件資源上通過虛擬化技術(shù)運(yùn)行2個(gè)系統(tǒng)。若沿用類似VMWare的基于軟件的虛擬化方案,會(huì)增加系統(tǒng)代碼量,從而影響可靠性。因此,必須尋找新的基于硬件的虛擬化方案,通過采用多核方案實(shí)現(xiàn)硬件虛擬化,從而兼顧安全性與成本。
Xen是開源的虛擬化管理軟件,其核心是虛擬機(jī)監(jiān)視器,負(fù)責(zé)完成CPU 調(diào)度和內(nèi)存資源分配[1],具有高性能和占用資源少的特點(diǎn),且與操作平臺(tái)的結(jié)合極為密切,并支持ARMv8 嵌入式架構(gòu)。相比于其他虛擬化方案,Xen相對(duì)成熟,且其ARM架構(gòu)支持相對(duì)前沿。在各種車載嵌入式系統(tǒng)的虛擬化中,Xen 的應(yīng)用相對(duì)較少。在國(guó)外:Avanzini等人[2]提出了基于Xen的車載系統(tǒng)虛擬化方案,將Linux 系統(tǒng)和ERIKA 實(shí)時(shí)系統(tǒng)進(jìn)行整合;Luca等人[3]的研究表明,Xen和KVM都可以作為實(shí)時(shí)管理程序,并提供了一些減少延遲的指導(dǎo)機(jī)制,有利于提高Xen在車載系統(tǒng)中的實(shí)時(shí)特性。在國(guó)內(nèi),主流的方案有:使用ARM和Windows Embedded CE設(shè)計(jì)車載系統(tǒng)[4];使用嵌入式Linux進(jìn)行開發(fā),例如結(jié)合圖形界面QT設(shè)計(jì)車載虛擬儀表[5]等;王沖[6]提出了基于Xen的半虛擬化系統(tǒng)設(shè)計(jì),討論了Linux 與μC/OS-Ⅱ系統(tǒng)結(jié)合的性能,但由于μCOS-Ⅱ目前尚未開源,所以無(wú)法定制開發(fā)。
基于以上背景,本文使用NXP 公司開發(fā)的高配版i.MX8 系列處理器,基于i.MX8 系列ARMv8 架構(gòu)處理器,使用Xen虛擬化方案實(shí)現(xiàn)Linux雙系統(tǒng)的啟動(dòng)。
在嵌入式Linux 系統(tǒng)常用的引導(dǎo)加載程序(BootLoader)中,通用引導(dǎo)加載程序(Universal Boot Loader,U-Boot)使用頻率最高。其“通用”有兩層含義,一是支持多種不同的嵌入式操作系統(tǒng),二是支持諸多常用系列的處理器。U-Boot 項(xiàng)目的開發(fā)目標(biāo)與之契合,即支持盡可能多的嵌入式處理器和嵌入式操作系統(tǒng)。本文對(duì)U-Boot 進(jìn)行一些定制化設(shè)計(jì),將Xen 引導(dǎo)命令編譯入U(xiǎn)-Boot,使其能夠正常啟動(dòng)虛擬機(jī)管理器。
U-Boot目錄分為3類:與處理器架構(gòu)和板極硬件相關(guān)的代碼;通用函數(shù)和驅(qū)動(dòng)、檢測(cè)程序;參考文檔和工具。修改代碼時(shí)只需要修改/arch/arm、/board、/configs、/include目錄下有關(guān)開發(fā)板和處理器架構(gòu)等方面的配置文件。
U-Boot啟動(dòng)過程分為3個(gè)階段,其中第3個(gè)階段主要任務(wù)是加載內(nèi)核并跳轉(zhuǎn)到內(nèi)核啟動(dòng)。而Xen Hypervisor是類似內(nèi)核的模塊,因此U-Boot設(shè)計(jì)與修改的重點(diǎn)在于了解第3個(gè)階段如何調(diào)用內(nèi)核并傳遞必要參數(shù)。
按照正常的單系統(tǒng)啟動(dòng)流程,應(yīng)在內(nèi)存中將U-Boot、Linux系統(tǒng)內(nèi)核、根文件系統(tǒng)等啟動(dòng)相關(guān)的鏡像按照?qǐng)D1的順序加載。
圖1 Linux單系統(tǒng)啟動(dòng)流程
Xen是一個(gè)微內(nèi)核,作為L(zhǎng)inux虛擬機(jī)的管理者,需要先于Linux 系統(tǒng)啟動(dòng),在Xen 虛擬化方案下的啟動(dòng)鏡像應(yīng)按照?qǐng)D2的順序加載。
圖2 Xen虛擬化方案下Linux雙系統(tǒng)啟動(dòng)流程
比較圖1和圖2可以明確需對(duì)U-Boot進(jìn)行的修改:將傳遞給Linux 和Xen 的參數(shù)全部傳遞給Xen 內(nèi)核,并加載Xen內(nèi)核到內(nèi)存中,最后啟動(dòng)Xen Hypervisor。
基于上述分析,本文對(duì)U-Boot進(jìn)行了如下修改:
a.在定義環(huán)境變量中加入有關(guān)Xen啟動(dòng)的變量:
b.對(duì)Xen Hypervisor 使用參數(shù)進(jìn)行定義,包括命令行為串口1、加載地址為0x80280000、啟動(dòng)介質(zhì)為SD卡,在此基礎(chǔ)上傳遞Linux 系統(tǒng)Domain-0 啟動(dòng)所需參數(shù),包括加載地址為0x85000000、分配內(nèi)存2 048 M 和分配4個(gè)虛擬CPU。最后定義指令run xenmmcboot作為U-Boot命令行調(diào)用這些代碼加載Xen內(nèi)核的入口:
通過以上操作,完成了U-Boot的設(shè)計(jì)與修改,設(shè)置了啟動(dòng)方式和命令,使U-Boot從SD卡啟動(dòng),使得U-Boot啟動(dòng)目標(biāo)為復(fù)制Xen內(nèi)核到內(nèi)存中,最后啟動(dòng)Xen內(nèi)核,并將控制權(quán)交給Xen Hypervisor。經(jīng)過上述修改,對(duì)Xen加入內(nèi)存前、后的內(nèi)存空間進(jìn)行比較,如圖3所示。
圖3 Linux系統(tǒng)和Xen虛擬化方案Linux雙系統(tǒng)內(nèi)存空間分布
從Linux 3.0 開始,Linux 內(nèi)核添加了Xen 相關(guān)的支持,可以選擇是否作為Domain-0內(nèi)核使用,給內(nèi)核編譯帶來(lái)不少方便。Domain-0內(nèi)核修改過程如圖4所示。
圖4 Domain-0內(nèi)核修改過程
由于i.MX8 系列處理器使用ARMv8 架構(gòu),屬于64位處理器,所以需要在內(nèi)核配置前執(zhí)行:
上述代碼將架構(gòu)改為ARM64,并在內(nèi)核根目錄的/arch/arm64/configs 下對(duì)默認(rèn)配置文件defconfig 進(jìn)行修改,調(diào)整是否為Domain-0的配置,將修改后的配置文件重命名為Dom0_defconfig、DomU_defconfig 并保存,如是便可以在后續(xù)修改2 個(gè)系統(tǒng)的內(nèi)核時(shí)分別擁有對(duì)應(yīng)的默認(rèn)配置文件。進(jìn)而執(zhí)行:
則make 腳本會(huì)讀取Dom0_defconfig 中的代碼,對(duì)內(nèi)核進(jìn)行配置,并保存文件.config。該文件即內(nèi)核在進(jìn)行編譯時(shí)參考的最終配置文件。
其中,關(guān)于Xen和Domain-0的部分重要配置如下:
以上即以Domain-0 作為特權(quán)域必須的配置,能使Domain-0 在啟動(dòng)時(shí)加載特權(quán)域相關(guān)組件,及組成Xen Hypervisor中分離驅(qū)動(dòng)架構(gòu)的必要部分——backend驅(qū)動(dòng)。
配置結(jié)束后保存,然后對(duì)內(nèi)核進(jìn)行編譯。本文使用的Linux 內(nèi)核加入了Yocto Project 的支持,可以使用bitbake linux-imx-C compile 指令一步完成內(nèi)核編譯和部署,之后會(huì)直接將編譯生成的鏡像文件Image 和設(shè)備樹.dtb 文件保存于deploy 目錄下,方便查找和使用。
一個(gè)Linux 系統(tǒng)的運(yùn)行包含4 個(gè)必需部分:Linux系統(tǒng)內(nèi)核Image、設(shè)備樹.dtb 文件、BootLoader、根文件系統(tǒng)。通過Yocto Project 提供的bibake 編譯指令可在/tmp/deploy 目錄下生成單獨(dú)的內(nèi)核、文件系統(tǒng)等,也有將上述4個(gè)部分全部打包的鏡像.sdcard文件,供開發(fā)人員制作啟動(dòng)介質(zhì),可以直接使用dd 指令將打包好的完整系統(tǒng)鏡像.sdcard文件燒錄到SD卡中。但是使用這種固定的燒錄鏡像方法時(shí),無(wú)論SD卡的存儲(chǔ)空間多大,都會(huì)對(duì)SD 卡進(jìn)行固定大小的分區(qū),且僅有2 個(gè)分區(qū)。這會(huì)造成SD卡存儲(chǔ)資源的浪費(fèi),且空間大小不可調(diào)節(jié),若文件系統(tǒng)中放入大量應(yīng)用程序,則會(huì)造成分區(qū)空間不足,但空余空間無(wú)法利用的后果。另外,由于使用Xen虛擬化方案啟動(dòng)2個(gè)系統(tǒng),則需要在一張SD卡上燒錄2個(gè)系統(tǒng),以上方法便不能適應(yīng)此需求。
對(duì)上述結(jié)果進(jìn)行分析,并結(jié)合Linux系統(tǒng)啟動(dòng)過程,本文手動(dòng)對(duì)SD卡進(jìn)行分區(qū)并格式化,根據(jù)需求自定義分區(qū)大小。此后,按地址前后順序在SD卡上燒錄U-Boot、在第1個(gè)分區(qū)放置設(shè)備樹.dtb文件和系統(tǒng)鏡像,在第2個(gè)分區(qū)放入根文件系統(tǒng)。后續(xù)空間為未分區(qū)或格式化的raw存儲(chǔ)空間,仍可在后期增加分區(qū)和放置系統(tǒng)文件。
考慮到目前本課題實(shí)際需要,暫不涉及多系統(tǒng)的試驗(yàn),因此對(duì)SD卡分為3個(gè)分區(qū),如表1所示。
表1 自定義SD卡分區(qū)情況
分區(qū)完成后需要進(jìn)行格式化,第1 個(gè)分區(qū)格式為vfat,用于存放設(shè)備樹文件和內(nèi)核鏡像,第2、第3個(gè)分區(qū)格式為ext4,用于存放根文件系統(tǒng)。接下來(lái)分別完成單獨(dú)燒錄BootLoader、復(fù)制根文件系統(tǒng)等操作,即完成了啟動(dòng)介質(zhì)的自定義制作。
經(jīng)試驗(yàn)驗(yàn)證,該方法具有可行性,同時(shí)解決了無(wú)法燒錄多個(gè)系統(tǒng)、SD卡空間浪費(fèi)的問題。為提高SD卡內(nèi)存使用率,在后續(xù)研究中將全部使用該方法。
完成SD卡啟動(dòng)介質(zhì)制作后,將SD卡插入開發(fā)板卡槽,輸入run xenmmcboot,即從SD卡中啟動(dòng)Xen Hypervisor。初始化Xen的一些資源后,內(nèi)核開始啟動(dòng)Domain-0。
Domain-U內(nèi)核的配置過程與Domain-0類似,但在設(shè)備分配上有所不同。Domain-U的配置主要是內(nèi)核模塊與硬件設(shè)備的分配。Linux 內(nèi)核從3.x 版本開始引入設(shè)備樹的概念,用于實(shí)現(xiàn)驅(qū)動(dòng)代碼與設(shè)備信息的分離。對(duì)于Linux 雙系統(tǒng),需要編寫2 個(gè)系統(tǒng)分別對(duì)應(yīng)的設(shè)備樹.dts文件。而NXP公司對(duì)于單Linux系統(tǒng)已經(jīng)編寫了針對(duì)該開發(fā)板的設(shè)備樹文件fsl-imx8qm-mek.dtsi,因此可以在此基礎(chǔ)上進(jìn)行修改。
設(shè)備樹文件的修改原理如圖5 所示。根據(jù)Xen Hypervisor 虛擬化方案的原理,Domain-0作為特權(quán)域擁有所有硬件資源的訪問權(quán),因此在Domain-0 的設(shè)備樹中理應(yīng)包括所有的設(shè)備,但有些需要設(shè)置為“xen,passthrough”屬性,傳遞給Domain-U 供其重寫屬性并使用。本文完成了fsl-imx8qm-mek-dom0.dts 和fsl-imx8qm-mek-domu.dts 2個(gè)文件的編寫,并在調(diào)試中進(jìn)一步修正。
圖5 Xen資源分配方法
根據(jù)Domain-U 的配置要求,對(duì)其內(nèi)核配置make menuconfig時(shí),將XEN_BACKEND設(shè)為n,即將與Xen有關(guān)的backend 驅(qū)動(dòng)全部關(guān)閉。此外,在啟動(dòng)過程中經(jīng)常遇到啟動(dòng)Domain-U時(shí)部分模塊啟動(dòng)異常而出現(xiàn)致命錯(cuò)誤,導(dǎo)致內(nèi)核錯(cuò)誤(kernel panic)的問題。以加密算法模塊(Cryptographic Accelerator and Assurance Module,CAAM)為例,由于其需要直接與硬件通訊,而根據(jù)Xen虛擬化方案,只有Xen Hypervisor工作在ring 0時(shí)可以直接訪問硬件,其他域的特權(quán)級(jí)均低于它。非特權(quán)域中的操作系統(tǒng)不能直接與硬件通訊,因此,在啟動(dòng)過程中CAAM模塊會(huì)因找不到硬件地址而出現(xiàn)野指針,從而導(dǎo)致內(nèi)核出現(xiàn)錯(cuò)誤,無(wú)法正常啟動(dòng)。
根據(jù)以上原因,需要把Domain-U中與硬件資源直接相關(guān)的配置刪除,重新編譯內(nèi)核作為Domain-U的Image,以上便完成了Domain-U的內(nèi)核配置。隨后使用與編譯Domain-0內(nèi)核相同的方法完成Domain-U內(nèi)核的編譯。
Xen Hypervisor將策略的制定和實(shí)施分離,將管理和配置工作交給Domain-0 進(jìn)行,而并非給Hypervisor 實(shí)施。亦即若將虛擬機(jī)的管理工作分為2類,即確定如何管理和實(shí)施,則Domain-0 負(fù)責(zé)第1 類工作,Xen Hypervisor 負(fù)責(zé)第2類。之后,Domain-U 創(chuàng)建的過程即在Domain-0中對(duì)其配置進(jìn)行設(shè)置,繼而通過xl create、xl console等命令行指令進(jìn)行創(chuàng)建。同理,用戶在Domain-0中可以設(shè)置虛擬機(jī)的管理參數(shù),而Xen Hypervisor 按照在Domain-0中設(shè)置的參數(shù)設(shè)置并啟動(dòng)客戶虛擬機(jī)。
根據(jù)以上分析,對(duì)于從Domain-0到Domain-U的啟動(dòng),需要經(jīng)過如圖6所示的操作過程。
圖6 Domain-U的啟動(dòng)過程
其中重點(diǎn)在于需要編寫/etc/xen/domu-im8qm-mek.cfg 配置文件,對(duì)Domain-U 進(jìn)行配置。domu-im8qmmek.cfg文件的主要內(nèi)容包括:
該.cfg文件中對(duì)Domain-U的內(nèi)存進(jìn)行了設(shè)置,同時(shí)在U-Boot 中也對(duì)內(nèi)存資源進(jìn)行了預(yù)分配。其中.cfg 文件中指定最大內(nèi)存容量,U-Boot中通過宏分配實(shí)際的內(nèi)存地址空間大小。若U-Boot 中分配的內(nèi)存大于.cfg 文件中配置的最大內(nèi)存,則在創(chuàng)建過程中Domain-U 正在使用的內(nèi)存會(huì)超出最大允許范圍,出現(xiàn)野指針導(dǎo)致系統(tǒng)跑飛,進(jìn)而被Xen Hypervisor強(qiáng)制關(guān)閉。根據(jù)以上情況,對(duì)2處內(nèi)存設(shè)置進(jìn)行協(xié)調(diào),完成Domain-U的創(chuàng)建。
本文使用xl create/etc/xen/domu-im8qm-mek.cfg 的方法將配置要求傳遞給Xen Hypervisor,隨后Xen Hypervisor 進(jìn)行資源分配,并創(chuàng)建Domain-U。xl create方法流程圖如圖7所示。
將修改好的Domain-U 內(nèi)核鏡像Image、Domain-U設(shè)備樹文件復(fù)制到SD 卡中的第1 個(gè)分區(qū)。隨后在SD卡中的第3 個(gè)分區(qū)中裝入Domain-U 的根文件系統(tǒng),將寫好的Domain-U系統(tǒng)配置文件放在/etc/xen目錄下。
Domain-0 系統(tǒng)啟動(dòng)后,進(jìn)入到/etc/xen,然后執(zhí)行xl create domu-imx8qm-mek.cfg,成功創(chuàng)建Domain-U 系統(tǒng)。隨后執(zhí)行xl console DomU 接入Domain-U 的控制,完成雙系統(tǒng)啟動(dòng)。
圖7 xl create*.cfg創(chuàng)建客戶虛擬機(jī)流程
為了方便區(qū)分2 個(gè)系統(tǒng),在用戶名中把Domain-U的root 用戶名設(shè)置為guest。登錄Domain-U 后,可以回到特權(quán)域Domain-0,通過xl list命令可以看到正在運(yùn)行的2個(gè)虛擬機(jī)系統(tǒng)及其相關(guān)信息。
雙屏顯示驅(qū)動(dòng)程序的開發(fā)過程中需要根據(jù)Xen Hypervisor 的驅(qū)動(dòng)結(jié)構(gòu)對(duì)一般的顯示驅(qū)動(dòng)進(jìn)行前、后端分離。Xen的虛擬設(shè)備架構(gòu)采用前、后端分離的設(shè)備驅(qū)動(dòng)結(jié)構(gòu)。虛擬設(shè)備驅(qū)動(dòng)包含Domain-U中前端設(shè)備驅(qū)動(dòng)和Domain-0中后端設(shè)備驅(qū)動(dòng)。后端設(shè)備驅(qū)動(dòng)可以通過原生設(shè)備驅(qū)動(dòng)訪問真實(shí)的硬件設(shè)備,其架構(gòu)如圖8所示。
圖8 Xen設(shè)備驅(qū)動(dòng)架構(gòu)
基于Xen的虛擬驅(qū)動(dòng)架構(gòu),本文完成了雙屏顯示所需的原生驅(qū)動(dòng)程序、資源配置、設(shè)備節(jié)點(diǎn)分配、前后端驅(qū)動(dòng)的所有設(shè)計(jì)與開發(fā),最終完成了雙屏顯示的驅(qū)動(dòng)程序設(shè)計(jì),顯示效果如圖9所示。
圖9 雙系統(tǒng)雙屏顯示
本文在NXP 公司開發(fā)的基于i.MX8 處理器的i.MX8QuadMax Mek 開發(fā)板上完成了虛擬化Xen方案下的Linux雙系統(tǒng)設(shè)計(jì),在i.MX8系列處理器上實(shí)現(xiàn)了Xen虛擬化方案,驗(yàn)證了虛擬化方案在車載智能座艙系統(tǒng)上的可行性,是嵌入式虛擬化技術(shù)在車載智能座艙系統(tǒng)上使用的新嘗試。在本文研究成果的基礎(chǔ)上,未來(lái)可以進(jìn)行進(jìn)一步探索,如:開發(fā)系統(tǒng)間通訊機(jī)制,在2個(gè)系統(tǒng)之間提高數(shù)據(jù)傳遞速度;將Linux 系統(tǒng)升級(jí)為Android 系統(tǒng),并在Android系統(tǒng)中開發(fā)更加豐富的中控系統(tǒng)應(yīng)用,最終真正應(yīng)用于實(shí)際的車載智能座艙系統(tǒng)。