如何利用虛擬化技術(shù)解決物聯(lián)網(wǎng)開發(fā)難題?從了解ACRN開始
物聯(lián)網(wǎng)市場的應(yīng)用場景日益復(fù)雜,越來越多的上網(wǎng)設(shè)備需要支持更多的硬件資源、操作系統(tǒng)、軟件工具及應(yīng)用程序,現(xiàn)有的解決方案顯然無法為數(shù)量龐大的物聯(lián)網(wǎng)設(shè)備提供相應(yīng)的靈活性,這使開發(fā)者們面臨巨大的設(shè)計壓力。虛擬化技術(shù)是解決這些問題的關(guān)鍵。不過,現(xiàn)有的虛擬化解決方案并不能滿足物聯(lián)網(wǎng)開發(fā)的輕量級和靈活性的特殊要求。為了滿足當前物聯(lián)網(wǎng)市場的發(fā)展趨勢,Linux 基金會推出了開源項目 —— ACRN。
ACRN 到底具有哪些強大的功能,它又是怎么實現(xiàn)的?今天我們就從架構(gòu)到應(yīng)用對 ACRN 進行詳細分析,讓開發(fā)者們快速上手使用ACRN進行產(chǎn)品設(shè)計。
ACRN 是一個專為嵌入式設(shè)備設(shè)計的 hypervisor,包括如下兩部分:一套 hypervisor 的參考軟件和架構(gòu),通過虛擬機監(jiān)視器可以在同一個物理硬件上安全地同時運行多個操作系統(tǒng)。另外,它還為設(shè)備虛擬化模擬定義了一套參考設(shè)計框架,稱為“ACRN 設(shè)備模型”。
ACRN hypervisor 是一個 Type-I 的 hypervisor,可以直接運行在物理硬件上,適用于各種物聯(lián)網(wǎng)和嵌入式設(shè)備解決方案。ACRN hypervisor 解決了當前數(shù)據(jù)中心 hypervisor 和 partitioning hypervisor 之間存在的差距。ACRN hypervisor 設(shè)計時把系統(tǒng)分為不同的功能域,并為物聯(lián)網(wǎng)和嵌入式設(shè)備精心挑選的用戶操作系統(tǒng)進行共享優(yōu)化。
汽車應(yīng)用案例
ACRN hypervisor 的一個有趣的案例是用于汽車場景。ACRN hypervisor 可以用于構(gòu)建軟件定義駕駛艙(SDC)或者車載娛樂系統(tǒng)(IVE)。作為參考實現(xiàn),ACRN 可以為嵌入式 hypervisor 廠商的解決方案提供一個很好的基礎(chǔ),以及一套 I/O 設(shè)備虛擬化的參考設(shè)計。
在這種場景下,汽車 SDC 系統(tǒng)由儀表盤(IC)系統(tǒng)、車載信息娛樂系統(tǒng)(IVI)和一個或多個后座娛樂系統(tǒng)(RSE)組成。為了整體系統(tǒng)安全性考慮,每個系統(tǒng)都作為獨立的虛擬機運行。
儀表盤系統(tǒng)(IC)用于顯示和駕駛員相關(guān)的車輛的駕駛操作信息,如:
- 汽車的速度、燃油、行駛里程和其它駕駛信息;
- 投影在擋風玻璃上的抬頭顯示,用以警告缺油或胎壓報警;
- 顯示后視攝像頭影像和車身的周邊攝像頭信息,用于輔助停車;
車載娛樂系統(tǒng)(IVI)的功能包括:
- 導(dǎo)航系統(tǒng)、收音機和其它娛樂系統(tǒng);
- 連接到移動設(shè)備,可以打電話,播放音樂或者通過語音識別來控制應(yīng)用程序;
- 通過手勢識別或觸控進行交互;
后座娛樂系統(tǒng)(RSE)可以運行:
- 娛樂系統(tǒng);
- 虛擬辦公;
- 連接到前排座椅的IVI系統(tǒng)和移動設(shè)備(云連接);
- 連接到移動設(shè)備,可以打電話,播放音樂或者通過語音識別來控制應(yīng)用程序;
- 通過手勢識別或觸控進行交互;
ACRN hypervisor 可以支持 Linux 和 Android 虛擬機作為用戶操作系統(tǒng)(UOS),UOS 由 ACRN hypervisor 進行管理。開發(fā)者和 OEM 廠商可以在 ACRN hypervisor 之上運行自己的虛擬機,以及 IC、IVI 和 RSE VM。Service OS 是作為 VM0 運行(在Xen hypervisor 中被稱為 Dom0,在 KVM hypervisor 中被稱為 Host OS),User OS 用戶操作系統(tǒng)作為 VM1 運行(也被稱為 DomU)。
注:Android 虛擬機的支持將在未來版本發(fā)布。
圖 1 顯示了一個使用 ACRN hypervisor 的實例框圖。
圖 1:SOS 和 UOS 運行在 ACRN hypervisor 之上
從 ACRN hypervisor 的架構(gòu)圖中可以看到:
- ACRN hypervisor 直接位于 bootloader 之上,因而具備快速啟動的能力;
- 部分資源進行 partitioning,以確保安全關(guān)鍵性應(yīng)用和非安全關(guān)鍵業(yè)務(wù)可以共存在同一平臺上;
- 豐富的 I/O 設(shè)備虛擬化提供在多個 VM 之間的 I/O 設(shè)備共享,從而提供全面的用戶體驗;
- 通過高效的虛擬化,一個 SoC 可以支持多個操作系統(tǒng)同時運行;
圖 1 中的黃色部分是 ACRN 項目的軟件棧。該架構(gòu)框圖中列出的某些功能還沒有完全實現(xiàn),歡迎社區(qū)共同參與開發(fā)實現(xiàn)。另外,圖中的其他模塊來自于別的開源項目,這里僅供參考。
例如,Service OS 和 Guest Linux 來源于 https://clearlinux.org 上的 Clear Linux 項目,而未來 Guest Android 的支持將會來自 https://01.org/android-ia 項目。
當前ACRN所支持的功能列表,請參照發(fā)布說明。
許可證
ACRN hypervisor和ACRN Device Model軟件采用的都是自由許可證的BSD-3-Clause,它允許以“源代碼和二進制再次發(fā)布和使用,無論是否進行了修改”, 許可證中也注明了完整版權(quán)聲明和免責聲明。
ACRN Device Model,Service OS 和 User OS
為了使 ACRN hypervisor 代碼盡可能精悍且高效,用于實現(xiàn) I/O 設(shè)備共享的 device model 代碼運行在 Service OS 中而非 ACRN Hypervisor。哪些 I/O 設(shè)備被共享以及其實現(xiàn)細節(jié)將在下面的 pass-through 章節(jié)具體介紹。
Service OS 在所有虛擬機里,以最高優(yōu)先權(quán)運行,以滿足那些對時間響應(yīng)要求很高的需求和系統(tǒng)服務(wù)質(zhì)量的需求(QoS)。具體到 Service OS 中的任務(wù),他們的優(yōu)先級則有高有低。例如響應(yīng) User OS 請求的回調(diào)函數(shù),其運行在 Service OS 的軟件(或者 mediator)就會繼承 User OS 的優(yōu)先級。另外,在 Service OS 中還有一些在后臺運行的任務(wù)也是低優(yōu)先級。
在上述的車載系統(tǒng)示例中,User OS 是駕駛控制和車內(nèi)娛樂的中心樞紐。它能提供收音機和各種娛樂選項、車內(nèi)空調(diào)和通風控制、車輛導(dǎo)航顯示等支持。它可以讓第三方設(shè)備使用 USB、藍牙或者 WiFi 等連接技術(shù)與車載系統(tǒng)進行交互,例如:Android Auto 或者 Apple CarPlay, 還能提供許多其它功能。
啟動步驟
在圖 2 中,我們展示了在一個采用英特爾架構(gòu)平臺的NUC上使用UEFI驗證啟動的步驟。
圖 2: ACRN Hypervisor 啟動步驟
啟動引導(dǎo)順序執(zhí)行如下:
- UEFI 驗證和啟動 ACRN hypervisor 和 Service OS 的引導(dǎo)加載程序;
- UFEI(或 Service OS 的引導(dǎo)加載程序)驗證并啟動 Service OS 內(nèi)核;
- Service OS 的內(nèi)核通過 dm-verity 驗證并且加載 ACRN Device Model 和虛擬引導(dǎo)加載程序;
- 虛擬引導(dǎo)加載程序啟動用戶端的驗證啟動進程;
ACRN Hypervisor 架構(gòu)
ACRN hypervisor 是 Type 1 的虛擬機管理程序,能夠直接運行在硬件系統(tǒng)上。它是一個混合的 VMM 架構(gòu),采用一個運行在特權(quán)級的 Service OS 來管理和協(xié)調(diào) I/O 設(shè)備的使用。它能支持多個用戶虛擬機,其中每個虛擬機都可以運行 Linux 或者安卓操作系統(tǒng)作為用戶操作系統(tǒng)。
在虛擬機內(nèi)運行的操作系統(tǒng)是與其它虛擬機內(nèi)的系統(tǒng)或應(yīng)用程序相互隔離的,從而縮小了潛在的被攻擊可能性,最大限度地減小安全隱患。當然由于系統(tǒng)運行在虛擬機內(nèi)也可能會給其應(yīng)用程序的運行帶來額外的延遲。
圖3顯示了 ACRN hypervisor、車載系統(tǒng)中的 Instrumental Cluster (IC) VM 和 Service VM 一起協(xié)同工作的架構(gòu)圖。Service OS(SOS)負責包括平臺設(shè)備在內(nèi)的大部分設(shè)備的管理,并提供 I/O 的協(xié)調(diào)功能。某些PCIe設(shè)備可以通過VM配置直通給 User OS 使用。IC 應(yīng)用程序和虛擬機特定的應(yīng)用程序都運行在 SOS 中,例如:ACRN device model 和 ACRN VM 管理器。
ACRN hypervisor 內(nèi)還有 ACRN 虛機管理器,用來收集 User OS 的運行信息,并控制用戶虛擬機的開始、停止和暫停,還能暫停或者恢復(fù)執(zhí)行單個虛擬 CPU。
圖 3: ACRN Hypervisor 架構(gòu)圖
ACRN hypervisor 采用了英特爾虛擬化技術(shù)(Intel VT),其運行在虛擬機擴展模式(VMX)的 root 模式下,也稱為主機模式或 VMM 模式。其他所有的用戶虛擬機包括 UOS 和 SOS 都運行在 VMX non-root 模式或 guest 模式下。(以下為了簡略,我們將繼續(xù)使用術(shù)語 VMM 模式和 guest 模式)。
VMM 模式下有 4 種權(quán)限的 ring 模式,但 ACRN hypervisor 僅在 ring 0 的特權(quán)模式下運行,其余 ring 1-3 并未使用。運行在 guest 模式下的用戶系統(tǒng)(包括 SOS 和 UOS)也有自己的 4 個 ring 模式(ring 0-3)。用戶系統(tǒng)的內(nèi)核運行在 guest 模式下的 ring 0,而用戶系統(tǒng)的應(yīng)用程序則在 guest 模式下運行于 ring 3(ring 1 和 ring 2 一般不被商業(yè)操作系統(tǒng)所使用)。
圖 4: VMX 簡介
如圖 4 所示,VMM 模式和 guest 模式通過 VM Exit 和 VM Entry 進行切換。當引導(dǎo)加載程序?qū)⒖刂茩?quán)交給 ACRN hypervisor 時,處理器還未啟動 VMX 模式。ACRN hypervisor 首先需要通過 VMXON 指令啟用 VMX 模式。啟用 VMX 后,處理器處于 VMM 模式,它可以通過 VM resume 指令進入 guest 模式(或者通過第一次 VM launch 指令),然后可以通過處理器的 VM exit 事件回到 VMM 模式。一般處理器會在響應(yīng)某些指令和事件時發(fā)生 VM exit。
在 guest 模式下,處理器的執(zhí)行是由一個虛擬機控制結(jié)構(gòu)(VMCS)所控制的。VMCS 包含了虛機狀態(tài)(在 VM Entry 時加載并在 VM Exit 時保存),主機狀態(tài)(在 VM exit 時加載),以及虛機的控制執(zhí)行。ACRN hypervisor 為每個虛擬 CPU 創(chuàng)建了一個 VMCS 數(shù)據(jù)結(jié)構(gòu),并使用該 VMCS 來控制運行在 guest 模式下處理器的行為。
當虛機執(zhí)行到一個敏感指令時,就會觸發(fā)一次定義在 VMCS 配置中的 VM exit 事件。當 VM exit 發(fā)生后,系統(tǒng)的控制權(quán)就交給了 ACRN hypervisor。ACRN hypervisor 會模擬虛機的指令(如果 VM exit 的原因是由于指令權(quán)限問題),然后恢復(fù)虛機繼續(xù)執(zhí)行它的下一條指令,或者根據(jù) VM exit 的原因進行相關(guān)處理(例如,一個虛機的存儲頁面需要建立映射關(guān)系),然后恢復(fù)虛機重新執(zhí)行該條指令。
需要注意的是用于VMM模式的地址空間和用于 guest 模式的地址空間是不同的。guest 模式和 VMM 模式下使用不同的內(nèi)存映射表,因此虛機是無法訪問 ACRN hypervisor 的。ACRN hypervisor 使用 EPT 來映射虛機地址,虛機頁表會將虛機的線性地址映射到虛機的物理地址, EPT 表則將虛機的物理地址映射到機器物理地址或主機物理地址(HPA)。
ACRN 設(shè)備模式架構(gòu)
因為系統(tǒng)設(shè)備可能需要在不同的虛機之間被共享,虛機內(nèi)應(yīng)用程序(和操作系統(tǒng))要對這些共享設(shè)備進行訪問就需要借助設(shè)備模擬。一般來說,設(shè)備模擬有三種架構(gòu):
- 第一種架構(gòu)被稱為 hypervisor中 的設(shè)備模擬,這是在 VMware 工作站產(chǎn)品(一個基于操作系統(tǒng)的 hypervisor)中實現(xiàn)的設(shè)備模擬方式。在這種方式中,hypervisor 負責模擬需要在各個虛機操作系統(tǒng)之間共享的常見設(shè)備,其中包括:虛擬磁盤、虛擬網(wǎng)絡(luò)適配器和其它必要的平臺資源。
- 第二種架構(gòu)稱為用戶空間的設(shè)備模擬。顧名思義,不是將設(shè)備模擬的實現(xiàn)嵌入到 hypervisor 中,而是將其放在一個用戶空間的應(yīng)用程序中實現(xiàn)。比如被各種獨立的 hypervisor 所使用的 QEMU 就提供了此類的設(shè)備模擬方式。這種架構(gòu)的優(yōu)勢在于設(shè)備模擬的實現(xiàn)不依賴于 hypervisor,所以其它 hypervisor 可以重用改實現(xiàn)。甚至它還可以做任意設(shè)備的模擬,而不必擔心其功能的實現(xiàn)會影響 hypervisor(其在特權(quán)模式下運行)。
- 第三種架構(gòu)則是從基于 hypervisor 的設(shè)備模擬改變而來的半虛擬化驅(qū)動程序。該架構(gòu)一開始是在XEN項目中引入的,其中 hypervisor 提供物理設(shè)備驅(qū)動,每個虛機操作系統(tǒng)則需要安裝一個與能與物理驅(qū)動配合使用的 hypervisor 感知的驅(qū)動程序。
在以上討論的設(shè)備模擬架構(gòu)中,共享設(shè)備都需要付出代價。因為不管設(shè)備模擬是在 hypervisor 中,還是在每個虛機內(nèi)的用戶空間中,都存在相應(yīng)的系統(tǒng)開銷。不過只要系統(tǒng)設(shè)備需要被多個虛機操作系統(tǒng)共享,這種開銷就是值得的。反之如果設(shè)備不需要被共享,那么就可以使用更有效的方法來訪問設(shè)備,例如使用“直通”。
看完以上的分析,你是否對 ACRN 有了更深入的了解?也是否有更多問題急需解答? 不用著急,我們將在下期中繼續(xù)講解各種技術(shù)細節(jié),例如 ACRN 設(shè)備模塊架構(gòu)、設(shè)備 pass through, ACRN I/O mediator,Virtio 框架結(jié)構(gòu)等一一為你展示。
ACRN 的設(shè)備模塊
在 ACRN 中,每個 User OS(簡稱 UOS)都需要有一個 ACRN 設(shè)備模型與之對應(yīng)。ACRN 設(shè)備模型首先為 UOS 初始化虛擬硬件平臺(包括初始化 VCPU 狀態(tài)、分配并初始化內(nèi)存、初始化 UOS 啟動腳本中所指定的虛擬設(shè)備)、加載 guest 平臺固件文件或 guest 操作系統(tǒng)內(nèi)核文件等,并最終通過調(diào)用 ACRN hypervisor 提供的服務(wù)去執(zhí)行g(shù)uest指令。
ACRN 設(shè)備模型是運行在 Service OS(簡稱 SOS)上的應(yīng)用程序,其架構(gòu)如圖5所示。
圖 5: ACRN 設(shè)備模塊
在 ACRN 中, I/O 虛擬化主要依賴于以下三部分的協(xié)同工作:
- 設(shè)備仿真
- I/O 請求處理
- VHM(Virtio 和 Hypervisor 服務(wù)模塊)
設(shè)備仿真
設(shè)備仿真指的是一系列 I/O 設(shè)備仿真例程,用來模擬不同種類的設(shè)備,比如 PCI 總線設(shè)備、ACPI 設(shè)備等。這些設(shè)備仿真例程均會被注冊到 ACRN 設(shè)備模型中,由 ACRN 設(shè)備模型中的 I/O 調(diào)度器進行調(diào)度和分發(fā)。當 UOS 產(chǎn)生 I/O 設(shè)備訪問請求時,I/O 調(diào)度器會根據(jù)請求的 I/O 地址,PIO 或者 MMIO,進一步調(diào)用具體設(shè)備的仿真例程。
I/O 請求(簡稱 IOREQ)處理
參照以下 ACRN-I/O-mediator 。
VHM
VHM(Virtio 和 Hypervisor 服務(wù)模塊)作為 ACRN hypervisor 和設(shè)備模型之間的橋梁,為設(shè)備模型提供必要的服務(wù)。VHM 運行在 Service OS 中,以內(nèi)核模塊的形式存在,其具體的服務(wù)流程,如下所述:
- ACRN hypervisor 通過中斷的方式通知 VHM 新的 IOREQ 到來;
- VHM 首先將 IOREQ 標記為“正在處理”,同時將其發(fā)送給 VHM 的用戶(如設(shè)備模型、gvt-g、VBS-K 等)做進一步處理。之后,VHM 可以處理新的 IOREQ;
- 實際對 IOREQ 進行處理的可以是運行在 SOS 用戶態(tài)的ACRN設(shè)備模型,也可以是運行在 SOS 內(nèi)核態(tài)中的其他設(shè)備模型,如 gvt-g 和 VBS-K。一旦 IOREQ 被處理完成,VHM 將被通知(內(nèi)核態(tài)直接通過函數(shù)調(diào)用方式通知,而用戶態(tài)則通過 IOCTL 的方式通知),之后 VHM 通過 hypercall 的方式,進一步通知 ACRN hypervisor 該 IOREQ 已經(jīng)處理完成。
用戶態(tài)程序:ACRN 設(shè)備模型;
內(nèi)核態(tài)模塊:VHM、VBS-K、gvt-g 等;
設(shè)備直通
總體上講,設(shè)備直通是為了將指定設(shè)備排他性提供給某個客戶操作系統(tǒng)獨立使用。
圖 6: 設(shè)備直通
通過設(shè)備直通可以實現(xiàn)幾乎原生的性能。在不需要在多個虛擬機中共享同一個設(shè)備的情況下,如系統(tǒng)中有多塊物理設(shè)備,設(shè)備直通對于某些高 I/O 需求的設(shè)備來說是最佳選擇,因為通過 hypervisor(無論是在 hypervisor 中還是在用戶空間中)虛擬設(shè)備會產(chǎn)生額外的性能下降。
除了性能角度考量外,有些設(shè)備先天不能被用在多個虛擬共享環(huán)境中,如 USB device 模式的 xDCI 端口。對于這類設(shè)備,ACRN 中則直接采用設(shè)備直通的方式供客戶操作系統(tǒng)使用。
設(shè)備直通的硬件支持
英特爾目前的處理器架構(gòu)使用 VT-d 為設(shè)備直通提供支持。VT-d 將客戶平臺物理地址映射到本地平臺機器物理地址,從而客戶操作系統(tǒng)能夠通過訪問客戶平臺物理地址進而訪問到本地平臺的物理硬件。在這個過程中,VT-d 負責設(shè)備的發(fā)訪問和保護,而客戶平臺操作系統(tǒng)只需像非虛擬化環(huán)境中一樣,直接訪問設(shè)備。除此之外,VT-d 還能防止物理設(shè)備惡意訪問屬于其他 VM 或者 hypervisor 的內(nèi)存,從而能夠提高安全性。
此外,在 ACRN 項目中,設(shè)備主要使用 MSIx/MSI 中斷,而不是傳統(tǒng)的基于中斷 pin 的方式通知 guest。從而帶來的好處在于不僅能夠很好地處理來自于多個 VM 多個中斷的情況,而且能夠保證中斷源的隔離。
設(shè)備直通的 hypervisor 支持
較新的英特爾處理器架構(gòu)均支持 VT-d,因此各主流 hypervisor(Xen 和 KVM)均可以基于 VT-d 實現(xiàn)設(shè)備直通的功能。ACRN 同樣基于 VT-d 實現(xiàn)設(shè)備直通的功能。
ACRN 虛擬 I/O 設(shè)備
圖 7 展示了ACRN 中訪問一個虛擬 I/O 所經(jīng)歷的流程。
圖 7 I/O 虛擬流程(Port IO)
以下是圖 7 中的編號項目:
- 當 guest 操作系統(tǒng)執(zhí)行 I/O 指令(PIO 或 MMIO)時,VM-Exit 發(fā)生,ACRN hypervisor 獲得處理器控制權(quán),首先會判斷虛擬機執(zhí)行退出的原因。在我們的例子中,VM-Exit 是因為 guest 中發(fā)生了 PIO 訪問,退出原因的號碼為VMX_EXIT_REASON_IO_INSTRUCTION。
- 除了根據(jù) VM-Exit 的原因號碼,ACRN hypervisor 還會對產(chǎn)生 VM-Exit 的指令進行譯碼。在我們的例子中,hypervisor會注意到是 PIO 指令(例如:in AL, 20h)。接下來,hypervisor 將譯碼得到的相關(guān)信息(包括 PIO 訪問、訪問字節(jié)數(shù)、讀/寫方式、目標寄存器等)放到與 ACRN VHM、ACRN 設(shè)備模型共享的物理頁面之中,然后以中斷的方式通知 SOS/VHM 去做進一步處理。
- SOS 中的 VHM 接收到中斷后,查詢該 IOREQ 有關(guān)的所有信息。
- VHM 首先會檢查是否應(yīng)該由內(nèi)核態(tài)的設(shè)備模型來處理該 IOREQ,如果是,那么相應(yīng)的內(nèi)核模塊之前注冊的callback函數(shù)會被 VHM 調(diào)用。否則,如果沒有內(nèi)核態(tài)設(shè)備模型來處理 IOREQ,那么 VHM 則會將該 IOREQ 保留在共享頁面中,并喚醒 ACRN 設(shè)備模型對該 IOREQ 進行處理。
- ACRN 設(shè)備模型采用與 VHM 相同的機制對 IOREQ 進行處理。設(shè)備模型的 I/O 執(zhí)行線程會首先查詢 IOREQ 具體的信息,同時檢查是否有設(shè)備仿真模塊實現(xiàn)了該 IOREQ 對應(yīng)的邏輯。如果有相應(yīng)的模塊,那么該模塊對應(yīng)的 callback 函數(shù)將會被調(diào)用。
- ACRN 設(shè)備模型完成設(shè)備模擬仿真后(本示例中是對端口 IO 20h 的訪問),uDev1 將結(jié)果保存到共享頁面(示例中保存在 AL 寄存器)。
- 完成相應(yīng) IOREQ 的模擬和仿真后,ACRN 設(shè)備模型通過 VHM 的 API 將控制權(quán)返回給 ACRN hypervisor。
- ACRN hypervisor 得知 IOREQ 已經(jīng)處理完成,則會結(jié)果保存到 VCPU 的相應(yīng)寄存器中。
- ACRN hypervisor 更新完 VCPU 寄存器后,進一步更新IP地址寄存器指向下一條 guest 指令,同時重啟 guest 的執(zhí)行。
針對 guest 中 MMIO 訪問的處理,與上面例子中的 PIO 訪問處理類似,除了 VM-Exit 的原因不同:MMIO 對應(yīng)的 VM-Exit 原因代碼是 VMX_EXIT_REASON_EPT_VIOLATION。
Virtio 框架架構(gòu)
Virtio 是一種通用的面向虛擬設(shè)備的抽象,可以應(yīng)用在任何 hypervisor 中。在 ACRN 參考設(shè)計中,我們的 Virtio 實現(xiàn)兼容 Virtio 標準規(guī)范 0.9 和 1.0。帶來的好處是,對于虛擬設(shè)備的實現(xiàn),虛擬環(huán)境和客戶平臺可以復(fù)用一套直觀、高效、標準和可擴展的機制,而無需根據(jù)每個環(huán)境或者操作系統(tǒng)進行定制。
Virtio 提供一個通用的前端/后端驅(qū)動程序框架,它不僅標準化 virtio 設(shè)備的訪問接口,而且還增加了不同的虛擬化平臺上的代碼重用。
圖 8: Virtio 架構(gòu)
為了更好地理解 Virtio,尤其是它在 ACRN 項目中的使用,下面列舉幾個 Virtio 的關(guān)鍵概念:
Virtio 前端驅(qū)動程序
Virtio 采用了前端-后端架構(gòu),分別為前端和后端 Virtio 驅(qū)動程序提供一個簡單又靈活的框架。Virtio 前端驅(qū)動框架提供了前端Virtio API 來配置硬件、傳遞消息、提交請求、通知后端 Virtio 驅(qū)動程序等。因此,Virtio 前端驅(qū)動程序很容易實現(xiàn),并且性能與設(shè)備模擬仿真相比有較大提升。
后端 Virtio 驅(qū)動程序
與 Virtio 前端驅(qū)動程序類似,Virtio 后端驅(qū)動程序運行在宿主平臺(內(nèi)核態(tài)或者用戶態(tài))。Virtio 后端驅(qū)動程序處理來自于前端驅(qū)動程序的請求,并按需將請求進一步發(fā)送到本地設(shè)備驅(qū)動程序。一旦請求被 Virtio 后端驅(qū)動程序處理完成,后端驅(qū)動程序就會通知前端驅(qū)動程序“請求已完成”。
直觀:Virtio 設(shè)備復(fù)用已有設(shè)備總線
Virtio 復(fù)用已有設(shè)備總線,而不是創(chuàng)建全新類型的設(shè)備總線,帶來的好處是 Virtio 前端和后端驅(qū)動可以直接利用已有的代碼進行交互。例如,Virtio 前端驅(qū)動程序可以直接讀/寫虛擬設(shè)備(由 Virtio 后端驅(qū)動程序虛擬)的寄存器,同時虛擬設(shè)備(由 Virtio 后端驅(qū)動程序虛擬)可以直接以中斷的方式通知前端驅(qū)動程序事件的發(fā)生。目前,Virtio 標準規(guī)范定義了幾種總線結(jié)果,如PCI/PCIe 總線、MMIO 總線、CCW 總線等。目前 ACRN 項目只支持 PCI/PCIe 總線。
高效:鼓勵批處理操作
批處理操作和延遲通知對于實現(xiàn)高性能 I/O 非常重要,因為Virtio前端和后端驅(qū)動程序之間的通知會導(dǎo)致代價高昂的VM-Exit等。因此應(yīng)當盡可能批量處理數(shù)據(jù),同時減少事件的通知。
標準:virtqueue
所有 Virtio 設(shè)備使用同一套稱為 virtqueue 的機制,其內(nèi)部實現(xiàn)是兩個標準環(huán)形緩沖區(qū)和一個描述符列表,如圖 6 所示。Virtqueue 是一個分散-聚集緩沖區(qū)隊列,主要有以下三種操作方式:
- add_buf 在 virtqueue 中添加請求/響應(yīng);
- get_buf 在 virtqueue 中獲得響應(yīng)/請求;
- kick 通知對方 virtqueue 已經(jīng)被更新;
virtqueue 由 Virtio 前端驅(qū)動程序在 guest 物理內(nèi)存中創(chuàng)建。Virtio 后端驅(qū)動程序只需要調(diào)用 Virtio API 解析 virtqueue 的結(jié)構(gòu)即可獲得請求或響應(yīng)。如何構(gòu)建 virtqueue 則取決于 guest 操作系統(tǒng)。在 Linux 中實現(xiàn) Virtio 時,virtqueue 被實現(xiàn)為一個稱為 vring 的環(huán)形緩沖結(jié)構(gòu)。
在 ACRN 的 Virtio 前端驅(qū)動程序開發(fā)過程中,virtqueue API 可被直接利用,從而用戶無需關(guān)心 virtqueue 的具體內(nèi)部細節(jié)。關(guān)于 virtqueue 實現(xiàn)的更多細節(jié),請參考您所使用的 guest 操作系統(tǒng)。
可擴展:特征 bit
每個 Virtio 設(shè)備和其 Virtio 前端驅(qū)動程序之間都存在一個簡單可擴展的特征協(xié)商機制。每個Virtio設(shè)備都可以聲明其設(shè)備特定的功能,而相應(yīng)地 Virtio 前端驅(qū)動程序可以表示自己能夠理解哪些硬件特征。這種特征協(xié)商的機制能夠保證驅(qū)動程序向前和向后兼容。
在 ACRN 參考實現(xiàn)中,Virtio 前端驅(qū)動程序存在于 guest 操作系統(tǒng)的內(nèi)核態(tài)空間,而 Virtio 后端驅(qū)動程序則存在兩種可能:用戶態(tài)和內(nèi)核態(tài)。圖 9 顯示了 ACRN 中用戶態(tài)的 Virtio 后端驅(qū)動程序架構(gòu)。
圖 9: Virtio 框架 – 用戶態(tài)程序
在 ACRN virtio 后端驅(qū)動框架中,該實現(xiàn)兼容 virtio 標準規(guī)范 0.9 和 1.0 版本。VBS-U 與設(shè)備模型靜態(tài)鏈接,并通過 PCIe/PCI 虛擬設(shè)備接口(PIO/MMIO 或 MSI/MSIx)與設(shè)備模型通信。VBS-U 通過用戶態(tài) virtqueue API 來訪問 Virtio 前端驅(qū)動程序在共享內(nèi)存中放置的數(shù)據(jù)。SOS 訪問 UOS 物理內(nèi)存則是基于 ACRN hypervisor 的幫助。
圖 10: Virtio 框架- 內(nèi)核態(tài)程序
從性能角度出發(fā),為了支持一些性能要求較高的設(shè)備,數(shù)據(jù)平面的處理可以從用戶態(tài)挪到內(nèi)核態(tài),從而避免 Virtio 后端驅(qū)動在用戶態(tài)和內(nèi)核態(tài)切換時產(chǎn)生額外的數(shù)據(jù)搬運;而控制平面的處理,仍然保留在用戶空間,即 VBS-U 中。VBS-U需要選擇在正確的時間初始化 VBS-K,例如,Virtio 前端驅(qū)動設(shè)置 VIRTIO_CONFIG_S_DRIVER_OK 時就是一個不錯的時機。運行在內(nèi)核態(tài)的 Virtio 后端驅(qū)動可以使用 VBS-K virtqueue API 前端驅(qū)動共享的數(shù)據(jù)。考慮到易用性,VBS-K virtqueue API 與 VBS-U virqueue API 設(shè)計得極為相似。此外,VBS-K 依賴于 VHM,即 VHM 負責分發(fā) IOREQ 給 VBS-K 模塊。每個 VBS-K 需要處理一類或者多類 IOREQ 請求,具體多少取決于特定的VBS-K需要監(jiān)聽多少段連續(xù)的寄存器空間。最后,VBS-K 借助于 VHM 的 API 來通過中斷的方式通知 Virtio 前端驅(qū)動程序。
看到這里,開發(fā)者們是不是有興趣親自動手實踐了,如果您在項目設(shè)計中遇到關(guān)于ACRN的技術(shù)問題,歡迎訪問ACRN社區(qū)進行討論,社區(qū)地