1.1 Hypercall
系統調用是通用操作系統提供的一種重要機制,系統調用將操作系統分爲兩個部分:內核空間和用戶空間。用戶程序可以通過系統調用接口從用戶空間陷入內核空間,這種機制有助於虛擬內存的實現,並且還可以提高系統的可靠性、安全性、健壯性。在XtratuM系統中,Hypercall是一種類似於系統調用的機制,它是上層域從用戶空間陷入Hypervisor Kernel的接口。在XtratuM系統中,XtratuM模塊通過Linux提供的指令將其加載,並且讓XtratuM內核與Linux內核運行於同一地址空間。爲了將實時域與Linux內核空間相分離,在XtratuM內核與實時域之間建立一層Hypercall,實時域就是通過這層Hypercall訪問底層資源。在Linux系統中,系統調用對應的陷阱號是0x80,由於要保留Linux這一特性,XtratuM Hypercall 對應的陷阱號是0x82。當前,XtratuM共支持11個Hypercall。在XtratuM系統中,所有的Hypercalls被保存在一個Hypercall表中,如下段代碼所示。
hypercall_handler_t
syscall_table [HYPERCALL_ENTRIES] = {
exit_domain_sys,
load_domain_sys,
unload_domain_sys,
suspend_domain_sys,
sync_events_sys,
pass_event_sys,
get_time_sys,
set_timer_sys,
get_cpu_khz_sys,
write_scr_sys,
enable_hwirq_sys
};
用戶新定義的Hypercall函數指針就可以添加到該表中中,但是要注意HYPERCALL_ENTRIES的數值以及對應Hypercall的調用號。HYPERCALL_ENTRIES應該大於等於Hypercall的個數,而Hypercall的調用號是給應用域使用。__syscall1就是客戶域定義的能夠實現具有一個參數的Hypercall的宏,其中包含參數值(arg1),Hypercall號(name_nr),和返回值(__res),“int $0x82”指令將會觸發Hypercall陷阱,使系統由域空間進入XtratuM內核空間。__syscall1宏的代碼如下。
#define __syscall1(arg1, name_nr, __res) /
__asm__ __volatile__ ("int $0x82/n/t" /
: "=a" (__res) /
: "0" (name_nr),"b" ((long)(arg1)))
在XtratuM系統中,存在六個類似__syscall1的宏,分別用來創建無參數、一個至五個參數的Hypercall。圖2-5給出了PaRTiKle系統調用write_scr()的函數調用圖。
圖2-1. write_scr() 調用函數樹
1.2 任務管理
在XtratuM系統,域是基本的調度單位,那麼與通用操作系統中的進程或線程相比,有什麼區別呢?本節中從域的定義、實現、以及XtratuM系統中的調度器和任務切換等方面介紹這一XtratuM系統中的基本運行單位。
1.2.1 域任務
域(Domain)類似於進程或線程,是一種調度單位,但是與進程和線程相比,域具有更廣泛的概念。域具有自己獨立的物理資源,例如內存、並口等物理設備,以及其它的虛擬設備等。一個域中可以包含多個進程或線程,並且域具有內部調度器,可以根據需要調度域內任務。概括來說,域是一個具有私有軟件和硬件資源的可調度單位,對資源有着更強更多的私有化,尤其是硬件資源,甚至可以將一個域對應爲一個操作系統。
在XtratuM系統,一個域由一個域結構體表示,主要包含私有物理內存、虛擬中斷、虛擬時鐘、虛擬內存、優先級等私有資源。其中私有物理內存構成私有棧,作爲內存池爲域內任務分配內存。每一個域中有32個虛擬中斷,可以對其進行屏蔽、打開操作,具有已發生、已處理等狀態。虛擬時鐘可以用來模擬時鐘週期和當前時刻。每一個域不僅具有物理內存,還具有私有虛擬內存空間。這種採用虛擬內存地址空間的策略,有助於實現XtratuM Hypervisor系統的Hypercalls。XtratuM系統可以爲域分配1024個不同的優先級,Linux系統具有最低優先級(1023)。優先級作爲域的重要資源,是任務調度器選擇將要被調度任務的重要判斷依據。圖2-6給出了XtratuM系統中域的基本結構。
圖2-2. 域的結構模型
1.2.2 調度器
上面一節已經介紹了優先級的概念,從理論的角度來說,它是域系統重要的表現方式,從實踐的情況說,它是調度器選擇可運行域和分配CPU資源的依據。XtratuM系統中,域具有四個狀態:睡眠,就緒、運行、阻塞,其中阻塞的原因可能是被搶佔或缺乏資源。圖2-7給出了域的狀態轉換模型。
圖2-3. 域狀態轉換模型
XtratuM的具有簡單的基於優先級的可搶佔實時調度策略,支持週期性和非週期性任務。通常,調度器由時鐘中斷和任務狀態切換函數觸發,調度器被觸發後,主要完成:
1) 將中斷向低優先級域傳遞。在XtratuM系統中,中斷採用I-PIPE策略,這種管理方式類似管道,中斷首先設置最高優先級的域,等高優先級域被調度和執行後,次優先級的域會將中斷傳遞給更低優先級的域,然後執行次優先級任務,依次遞歸,直到所有的域對中斷做出響應。這種管理方式可以保證低優先級的域即使中斷服務也不會阻礙高優先級任務的執行,並且可以降低中斷延遲,保證高優先級的域對中斷進行最快服務。
2) 根據優先級大小,選擇具有最高優先級的可運行域。在系統中,每一個域對應唯一的一個域結構體,它們在一個由優先級決定的鏈表中,優先級越高,對應的數值越小,越接近鏈表頭。當域處於可運行狀態或者是該域支持的中斷髮生時,該域就會被選中,獲得CPU的使用權。
3) 任務切換,進入新任務。所爲任務切換,實際上就是任務運行任務上下文的切換,主要包含代碼段、數據段、和棧的切換,而這些內容的標記都保存在寄存器中,因此,任務切換的底層分析就是寄存器內容的轉變。域任務切換的算法如下:
FUNCTION INT Domain_Context_Switch(old_domain, new_domain)
BEGINE
將通用寄存器壓入棧(old_domain);
將浮點運算相關寄存器壓入棧(old_domain);
切換地址空間(改變CR3寄存器的數值) (old_domain->new_domain);
將浮點寄存器彈出棧(new_domain);
將通用寄存器彈出棧(new_domain);
Return 0;
END {FUNCTION}
4) 中斷服務。恐怕很多讀者都很奇怪,爲什麼會將中斷服務程序的相應放到任務切換模塊中。主要有兩個方面,首先,由於這裏的中斷是域系統的一個虛擬中斷,系統剛剛切換到一個新域,對應於操作系統,中斷應該在域中具有最高優先級,因此,在系統退出中斷模式、進入域線程或進程時,中斷應首先被調用;另外實現簡單,不需要將域虛擬中斷服務程序單獨處理,避免了域內空間切換。