《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 嵌入式技術(shù) > 業(yè)界動態(tài) > 多線程ARM虛擬機的設(shè)計與實現(xiàn)

多線程ARM虛擬機的設(shè)計與實現(xiàn)

2009-07-16
作者:胡小龍,周艷科

  摘 要: 虛擬機技術(shù)廣泛應(yīng)用于代碼移植、跨平臺計算和模擬硬件機器、嵌入式系統(tǒng)模擬等領(lǐng)域。該技術(shù)以軟件的方式構(gòu)建通用機器的硬件的仿真環(huán)境,實現(xiàn)機器指令在處理器中的運算過程。在介紹了虛擬機原理的基礎(chǔ)上,設(shè)計并實現(xiàn)了基于多線程的ARM虛擬機,初步模擬了ARM9的指令執(zhí)行過程。
??? 關(guān)鍵詞: 虛擬機;多線程;ARM

?

  所謂虛擬化就是把計算機的資源,如運算能力,存儲空間以及IO設(shè)備抽離出來,讓資源的使用方式更具效率。虛擬化技術(shù)可以提高硬件的處理能力,簡化軟件的重新配置過程。其主要作用體現(xiàn)在服務(wù)器整合、動態(tài)負載均衡、快速應(yīng)用部署、災(zāi)難恢復(fù)、處理器的前期開發(fā)的軟件模擬、代碼移植、反病毒等領(lǐng)域。
  虛擬化技術(shù)最早產(chǎn)生于上世紀60年代[1],但是被廣泛地應(yīng)用卻是近兩年的事情。虛擬化技術(shù)成為研究熱點的主要原因有兩個:首先是服務(wù)的細分,為了提高應(yīng)用的靈活性,很多技術(shù)都將IT應(yīng)用從大型系統(tǒng)轉(zhuǎn)向“模塊化”,這就需要一個個應(yīng)用獨立出來,這種需求也正符合如今人們所熟知的SOA思想;同時硬件發(fā)展為這種細分需求提供了一個平臺,硬件發(fā)展速度越來越快,如雙核、四核CPU的推動,服務(wù)器內(nèi)存擴展能力越來越大。也就是說,僅僅一個簡單的應(yīng)用已經(jīng)無法充分利用服務(wù)器的資源,很多資源被浪費,虛擬化技術(shù)可以幫助用戶大大地提高服務(wù)器資源的利用率,降低成本,并且能夠迎合細分的服務(wù)。
  實現(xiàn)虛擬化,主要有三種方法:完全虛擬化,如圖1所示;準虛擬化,如圖2所示;操作系統(tǒng)虛擬化,如圖3所示[2]。

?


1 虛擬機原理
??? 虛擬機用軟件模擬指令在硬件機器中執(zhí)行的全過程,即先從磁盤中讀取字節(jié)碼文件,存儲到虛擬機開辟的內(nèi)存段中,再將指令加載到虛擬機寄存器并予以執(zhí)行。它并不是指某個特定的軟件,而是一整套完整的規(guī)范,可以用不同的程序設(shè)計語言在不同的硬件平臺上實現(xiàn)[3]。不論是硬件機器還是虛擬機系統(tǒng),只要遵循相同的規(guī)范,即可運行遵循該規(guī)范的可執(zhí)行代碼。下面將從處理器引擎、內(nèi)存管理、任務(wù)管理和輸入輸出4個方面分別討論ARM虛擬機的實現(xiàn)規(guī)范。
1.1 處理器引擎
  ? 根據(jù)運算數(shù)據(jù)交換平臺的不同,主要有基于堆棧的處理器和基于寄存器的處理器兩種引擎。前者在運行時對系統(tǒng)資源的消耗要遠小于后者,但堆棧將會延伸到內(nèi)存;后者的計算處理則全部在芯片內(nèi)部的寄存器上完成,因此后者的處理速度要遠遠高于前者。由于基于堆棧的處理器已經(jīng)退出主流的行列,ARM虛擬機將采用基于寄存器的執(zhí)行引擎來模擬具體硬件實現(xiàn),并在ARM虛擬機中構(gòu)建堆棧,從而繼承堆棧在處理函數(shù)調(diào)用和遞歸等問題上的優(yōu)勢。虛擬寄存器是系統(tǒng)的核心,ARM虛擬機通過寄存器之間的運算來執(zhí)行字節(jié)碼指令。作為處理器中的數(shù)據(jù)存儲單元,各類寄存器均有不同用途,例如通用寄存器用來存儲和轉(zhuǎn)換數(shù)據(jù)和地址,指針寄存器指向堆棧段的棧頂位置,段寄存器則標識出代碼段、數(shù)據(jù)段和堆棧段之間的界限。
1.2 內(nèi)存管理
??? 程序指令和數(shù)據(jù)在內(nèi)存中的存儲方式有兩種:降序(big-endian)和升序(little-endian)。降序是指數(shù)據(jù)的高位字節(jié)存放在內(nèi)存中的低位地址中;升序則相反,是指數(shù)據(jù)的低位字節(jié)存放在內(nèi)存中的低位地址中。內(nèi)存管理負責內(nèi)存的分配和回收問題,主要有顯式內(nèi)存管理法 EMM(Explicit Memory Management)和自動內(nèi)存管理法AMM(Automatic Memory Management)兩種方法[4]。其中,前者由程序員人工完成內(nèi)存的分配和回收工作,例如C語言用malloc()調(diào)用來實現(xiàn)分配一段內(nèi)存空間,用free()函數(shù)來釋放不再使用的內(nèi)存。后者則由程序員完成內(nèi)存的分配,由系統(tǒng)負責自動回收,例如Java語言對于已分配的內(nèi)存,由內(nèi)存管理根據(jù)其作用域完成與否決定是否收回該段內(nèi)存。一般來說,顯示內(nèi)存管理法要比自動內(nèi)存管理法的速度要快,內(nèi)存分配算法相對簡單。
1.3 任務(wù)管理
  現(xiàn)代計算機使用多任務(wù)技術(shù)[5],即多個任務(wù)共享同一處理器。該技術(shù)主要依靠隊列和堆棧,為排隊等候的每個任務(wù)分配一段時間,并在系統(tǒng)中建立一張進程表,記錄每一個進程的狀態(tài)。相應(yīng)的狀態(tài)有3種:正在執(zhí)行、被掛起和阻塞。通常采用搶占式多任務(wù)技術(shù),即由操作系統(tǒng)決定進程間的切換。例如在著名的時間片輪轉(zhuǎn)(round-robin)算法里,每個進程所分配的執(zhí)行時間的長度是固定的,進程調(diào)度不停地依次遍歷整個進程表,讓每個進程都有機會占用同樣長度的處理器時間。
1.4 輸入/輸出
  虛擬機依托于宿主平臺,因此輸入/輸出功能的實現(xiàn)相對較簡單,在系統(tǒng)調(diào)用層基礎(chǔ)上的標準輸入/輸出函數(shù)即可勝任。運算速度有所限制,但無須接觸機器級的中斷調(diào)用和輸入/輸出操作。
2 32位ARM虛擬機的設(shè)計
  32位處理器的地址空間僅能支持4 GB,ARM虛擬機采用32位地址空間技術(shù),在Win32位平臺上開辟一個4 B的空間來表示32位整型,并涉及一組虛擬寄存器、一段虛擬內(nèi)存空間和一個類ARM9的指令集,分別對應(yīng)于需要仿真的機器部件。在32位地址空間的基礎(chǔ)上,采用寄存器引擎、顯示內(nèi)存管理法、搶占式多任務(wù)技術(shù)等基本工作機制,構(gòu)建虛擬機軟件的基本結(jié)構(gòu)。


2.1 虛擬寄存器
 ?  ARM虛擬機共有37個寄存器,包括31個32位的通用寄存器(包括程序計數(shù)器PC在內(nèi)),6個32位的狀態(tài)寄存器[6]。ARM處理器共有7種不同的處理模式,在每一處理器模式中有一組相應(yīng)的寄存器組。在任意的處理器模式下,可見的寄存器包括15個通用寄存器(R0~R14),一個或兩個狀態(tài)寄存器及程序計數(shù)器(PC)。在所有的寄存器中,有些是各模式共用同一個物理寄存器,有一些寄存器是各模式自己擁有的獨立的物理寄存器。表1列出了各處理器模式下可見的寄存器情況。
2.2 虛擬的MMU的設(shè)計和管理
  在ARM虛擬機設(shè)計中,通過C++的vector來開辟一塊連續(xù)的內(nèi)存地址作為虛擬內(nèi)存空間,存儲程序的字節(jié)碼指令。由于在32位機器上無法提供這么多的物理內(nèi)存,因此ARM虛擬機采用先預(yù)讀后分配的原則來開辟虛擬內(nèi)存,即先對字節(jié)碼文件的大小進行預(yù)讀,根據(jù)其大小再從物理內(nèi)存中分配足夠的內(nèi)存作為虛擬內(nèi)存,如果剩余的物理內(nèi)存無法滿足需要,則退出該次分配。由于當前主流硬件平臺(如Intel公司的系列處理器)均采用降序方式,在ELF文件的加載過程中無須改變數(shù)據(jù)存儲方式,因此在ARM虛擬機的設(shè)計中使用降序方式,提高了虛擬機的執(zhí)行效率,同時保證了設(shè)計的通用性和簡單性。另外,在內(nèi)存的管理和回收方面,采用顯式內(nèi)存管理法,從而確保虛擬機的運行速度、內(nèi)存分配的靈活性和對程序的控制權(quán)。
2.3 虛擬機基本結(jié)構(gòu)
??? 圖4是ARM虛擬機的總體結(jié)構(gòu),由以下模塊組成:


  指令集功能仿真模塊和系統(tǒng)調(diào)用仿真模塊都屬于功能仿真模塊,前者按序仿真每條指令(現(xiàn)在不包含時序模擬),其主要用于性能模擬器執(zhí)行結(jié)果正確性驗證;后者采用宿主機代理方式仿真系統(tǒng)調(diào)用處理過程[7]。
  ? 流水線模塊、功能部件模塊、寄存器模塊和分支預(yù)測模塊共同組成了性能模擬器內(nèi)核,為ARM虛擬機的主要組成部分。其中,流水線模塊包含所有和流水線相關(guān)的數(shù)據(jù)結(jié)構(gòu)和處理函數(shù);功能部件和寄存器模塊用于建模功能部件和ARM寄存器組;分支預(yù)測模塊用于建模分支預(yù)測器。
  ? Cache模塊、TLB模塊、總線邏輯和MMU模塊共同組成了存儲器層次模塊組,其模擬了一個ARM存儲器的行為過程。
?   ELF文件加載器模塊、數(shù)據(jù)收集統(tǒng)計模塊、參數(shù)處理模塊和調(diào)試器模塊為ARM虛擬機的輔助模塊,ELF文件加載器模塊用于將可執(zhí)行文件加載到模擬器內(nèi)存中;數(shù)據(jù)收集統(tǒng)計模塊用于收集統(tǒng)計模擬器各項狀態(tài)數(shù)據(jù),如指令執(zhí)行條數(shù);參數(shù)處理模塊用于處理命令行參數(shù);調(diào)試器模塊用于調(diào)試用戶程序。
??? 檢驗?zāi)K用于驗證性能模擬器的正確性,它通過將每條指令的性能模擬結(jié)果并與其功能仿真結(jié)果進行比較,就可以判斷出指令是否被正確執(zhí)行,然后可以根據(jù)用戶要求采取不同的操作。
3 ARM虛擬機的工作流程
3.1 基本流程
  ARM虛擬機從讀入ELF文件到執(zhí)行完畢的全過程,算是一個生命周期。該周期按功能不同,可分為5個階段:(1)啟動虛擬機,并處理命令行輸入;(2)初始化虛擬機運行環(huán)境;(3)調(diào)入并加載文件;(4)格式化內(nèi)存存儲方式;(5)執(zhí)行指令。其中,第(2)和(5)階段是整個程序運行的核心,完成了虛擬機的初始化和執(zhí)行ELF文件中分析出的代碼段指令的主要工作。
3.2 初始化虛擬機
  階段(1)通過對命令行的處理,獲取字ELF文件的信息。該信息通過ELF文件加載器得到程序代碼段、數(shù)據(jù)段、堆棧段的信息傳遞到階段(2)初始化虛擬機的InitVM函數(shù)中。其中數(shù)據(jù)段和堆棧段的缺省長度均為64 KB,而代碼段的長度為ELF文件中代碼指令所占用的實際長度。
  InitVM函數(shù)的執(zhí)行流程是:(1)函數(shù)從文件頭中提取必要的信息后,立即檢查字節(jié)碼長度,將其與數(shù)據(jù)段和堆棧段的長度之和與宿主機的可用內(nèi)存比較。如果可用內(nèi)存不夠,則報錯并退出虛擬機;否則宿主機將分配一段大小為三者之和的內(nèi)存給虛擬機。(2)將段寄存器分別設(shè)置成為相應(yīng)段的值。(3)將ELF代碼加載到內(nèi)存空間的代碼段。具體算法如下:
??? If (ELF文件大小為零或文件打開錯誤)
????   {記錄并打印錯誤,并直接返回 }
??? If (代碼段、數(shù)據(jù)段和堆棧段的長度之和 > 宿主機的可用內(nèi)存)
?   ?? {記錄并打印錯誤,并直接返回 }
??? 分配內(nèi)存 R=malloc(代碼段、數(shù)據(jù)段和堆棧段的長度之和);
????   初始化寄存器;
??   ? 重新返回ELF文件的代碼段部分,調(diào)用fseek()定位代碼段部分的位置;
??? 讀取代碼段部分,并將其加載入所開辟的內(nèi)存代碼段中。
  如果上述過程順利執(zhí)行,所獲取的虛擬機內(nèi)存地址空間如圖5所示。


3.3 執(zhí)行代碼段
  ? run()函數(shù)是ARM虛擬機的指令執(zhí)行引擎,負責完成代碼段指令的執(zhí)行工作。該函數(shù)將字節(jié)碼指令從虛擬地址0處開始逐條執(zhí)行,當遇到HALT指令或發(fā)生錯誤時停止。指針寄存器IP始終指向下一條所需執(zhí)行的指令。參照基于寄存器的處理器的設(shè)計方法,第(5)階段指令執(zhí)行過程的算法如下(其中,CPSR表示指令指針寄存器值;CPSR中表示內(nèi)存地址為CPSR所存值的地址處的指令):
??? void run()
???? {
?????? while(內(nèi)存地址為CPSR不等于中止指令HALT)
?????? {
???    switch(內(nèi)存地址為CPSR的指令)
???    {
    ??? case MOV:{…;}break;
???????????? …各種指令的具體執(zhí)行;
    ???????? default:{ERROR;}break;
?????????? }
???????? 將指令指針CPSR指向下一條指令;
???  }
??? }
??? ARM指令按照指令功能的不同來分,包括數(shù)據(jù)處理指令(如MOV、MVN、CMP)、內(nèi)存訪問指令(如LDR、STR)、內(nèi)存批訪問指令、跳轉(zhuǎn)指令(如B、BL)、訪問狀態(tài)寄存器指令(如MRS)、軟中斷指令等。
??? 指令模擬執(zhí)行過程如圖6所示。


3.4 流水線的實現(xiàn)
  ARM9采用哈佛結(jié)構(gòu)的設(shè)計[8],采用5級流水線,其功能分別描述如下:
??? (1)取指。從存儲器(CACHE/Memory)取出指令,并將其放入指令流水線。
??? (2)譯碼。指令譯碼,從寄存器堆中讀取寄存器操作數(shù)。在寄存器堆中有3個操作數(shù)讀端口,大多數(shù)ARM指令能在一個周期內(nèi)讀取其操作數(shù)。
??? (3)執(zhí)行。一個操作數(shù)移位,產(chǎn)生ALU的結(jié)果,如果指令是LOAD或STORE,則在ALU中計算存儲地址。
??? (4)緩沖/數(shù)據(jù)訪存。如果需要,則訪問數(shù)據(jù)存儲器;否則,ALU只是簡單的緩沖一個時鐘周期,以便所有的指令具有同樣的流水線流程。
??? (5)回寫。將指令產(chǎn)生的結(jié)果回寫(Write back)至寄存器堆,包括任何從存儲器中讀取的數(shù)據(jù)。
??? 采用多線程模擬5級流水線的執(zhí)行過程如圖7所示。


??? ARM指令的實現(xiàn)方式(單線程和多線程),如表2所示,在ARM虛擬機運行ARMlinux,記錄了10次兩種方式的起始時間,計算平均值。


??? 從表2中可以看出,多線程的方法對指令流水線模擬的性能有很大改進。
  本文主要采用顯式內(nèi)存管理、代碼段的解析、基于寄存器的機器引擎,多線程等關(guān)鍵技術(shù),在以Win32為宿主平臺的基礎(chǔ)上,設(shè)計并實現(xiàn)了基于多線程的ARM虛擬機系統(tǒng),能夠在32位的內(nèi)存地址空間和虛擬寄存器上執(zhí)行指令,為模擬ARM處理器的仿真環(huán)境做出了有益的嘗試。今后將進一步完善ARM嵌入式系統(tǒng)模擬的設(shè)計,充分發(fā)揮虛擬機在嵌入式開發(fā)方面的優(yōu)勢。


參考文獻
[1] 李林華,盛浩,馬世龍.基于寄存器引擎的64位虛擬機的實現(xiàn)[J].計算機工程,2005,31(2):91-93.
[2] 劉洪浩.虛擬化,熱潮不等于機會[J].程序員2007年精華本,2007.
[3] BLUNDEN B. Virtual Machine Design and Implementation in C/C++[M]. Wordware Publishing, 2002.
[4] JONES R, LINES R. Garbage Collection: Algorithms for Automatic Dynamic Memory Management[M]. John Wiley & Sons,1996.
[5] TANENBAUM A S, WOODHULL A S. Operating System: Design and Implementation[M]. Prentice Hall, 1997.
[6] 杜春雷.ARM體系結(jié)構(gòu)與編程[M].北京:清華大學出版社,2003.
[7] 萬寒,高小鵬. Design and Implementation of a Simulation Framework for the ARM Embedded System. IEEE Computer Society,北京:北京大學,2008.
[8] 譚華.嵌入式系統(tǒng)軟件仿真器的研究與實現(xiàn)[D].西安:電子科技大學,2006.

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請及時通過電子郵件或電話通知我們,以便迅速采取適當措施,避免給雙方造成不必要的經(jīng)濟損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。