操作系统微内核架构研究
1 簡介
微內核是操作系統內核的一種,在工控系統、嵌入式系統、實時系統等領域發揮著重要作用。本文較為全面地研究了微內核技術的各個方面,包括微內核的定義、微內核的體系架構、微內核的發展歷史、微內核的特點、微內核的應用場景,以及作者所進行的部分研究工作。本文部分內容和圖來自網上,由于內容較多,有些沒有標注,如果原作者覺得不合適請聯系刪除。
2 微內核的定義
在計算機科學中,內核是操作系統的核心部分,它管理著系統的各種資源,譬如時鐘、中斷、存儲、進程、設備驅動、原語等。應用程序運行在內核之上,并通過系統調用訪問內核空間。
從內核架構來劃分,操作系統內核可分為微內核(Micro Kernel)和宏內核(Monolithic Kernel,也翻譯為單內核)。如下圖所示,微內核操作系統僅在內核中保留了調度、基礎IPC、虛擬內存管理等少數核心功能模塊,它們位于內核空間,而操作系統的其他功能模塊(譬如文件系統、驅動程序等)與用戶應用程序一起運行于用戶空間;宏內核操作系統在內核中包括了整個操作系統的大部分功能模塊(譬如文件系統、驅動程序等),并且這些系統模塊都運行在同一個內核地址空間,模塊之間通過簡單的系統調用進行協調工作。
微內核(通常縮寫為μ內核)由一群數量盡可能最少的軟件程序組成,它們負責提供實現一個操作系統所必須的各種機制。這些機制就是之前提到的線程/進程調度機制、基礎的進程間通信機制(IPC)、虛擬內存管理機制等;而包括文件系統、驅動程序在內的其他各種功能模塊都放到用戶空間。微內核的最小化也稱為Jochen Liedtke最小化原則。Jochen Liedtke是一名德國科學家。這里區分兩個術語,操作系統微內核即指微內核,微內核操作系統則指一種基于微內核架構的操作系統。
???????????????????????????????????????? 圖1?微內核與宏內核架構
從操作系統功能模塊來看,操作系統廠商依據自己的實際情況,可以將宏內核操作系統中的部分功能模塊從內核空間移到用戶空間,也可以將微內核操作系統中的部分功能模塊從用戶空間移到內核空間,由此就構成了微內核、小內核、大內核、宏內核等稱謂。對于介于微內核和宏內核之間的小內核、大內核來說,有時也把它們稱之為混合內核。對于操作系統廠商來說,沒有必要嚴格遵守微內核的最小化原則,非要做一個嚴格意義上的微內核,或者完全意義上的宏內核。本文在后面主要討論微內核和宏內核。
3 微內核的體系架構
3.1 分布式服務器架構
在圖1的微內核架構中,按照官方說法,位于用戶空間的各個功能模塊被設計成一個個功能獨立的服務器(Server),由微內核采用消息通信機制來調度各個服務器完成工作。為避免混淆,這里的服務器可以理解為一個服務器程序。微內核相當于客戶端程序(Client)。
從理論上來說,基于消息通信的兩個程序(Client和Server)可以位于同一臺機器,也可以位于不同機器。因而,微內核操作系統中的這些服務器可以是分布式的,它們可能位于同一臺機器,也可能位于其他機器。這里再次強調,只是理論上是這樣,真正這樣實現的操作系統還極少。
微內核的分布式架構是有意義的。從下面鏈接可知,鴻蒙操作系統聲稱自己具有兩個特點:微內核、分布式。采用分布式消息通信機制,可以實現鴻蒙操作系統與各類硬件設備(例如手機、平板、手表、PC等)的互聯。這種消息通信機制也被說成為分布式總線。
(參見:鴻蒙系統:微內核,分布式_華為)
????????????????????????????????????????圖2?基于分布式總線的鴻蒙操作系統的萬物互聯機制
3.2?插件架構
在圖1的微內核架構中,各個服務器程序相互獨立,也有個別人把這種架構稱之為“插件架構”。
如下圖所示(微內核架構 - 簡書),在軟件開發領域,插件化架構由一個中間的核心系統和若干插件模塊組成。該架構最大的優勢是允許第三方開發者遵循一定的開發規范添加額外的插件化應用。采用插件架構的軟件有很多,例如Eclipse、企業ERP軟件等,這類軟件自身具備豐富功能,同時支持第三方應用的即插即用;并且第三方插件化程序的安裝、運行、卸載以及故障不會對原有系統造成任何影響。
????????????????????????????????????????圖3?軟件插件架構
在插件架構中,核心系統的功能穩定,很少變更。它只擁有能使應用運行的最小功能邏輯(例如插件模塊的注冊、加載、卸載,以及插件模塊之間的相互通信等)不涉及任何特定業務;插件系統具備良好的擴展性,可根據特定業務需求而變更其業務邏輯。
插件架構本質上是將一個軟件系統中的變化部分封裝在插件中,從而實現不同業務之間的隔離性,達到系統快速靈活擴展的目的,同時所有特定業務相關邏輯的變更不會影響整體系統的穩定性。
另外,插件架構需要解決好三方面的問題:插件管理、插件鏈接和插件通信。
由上可知,理論上的微內核確實是一種基于插件架構的操作系統內核。
4 微內核的發展歷史
4.1 微內核起源(參見維基百科)
微內核的起源可以追溯到丹麥計算機先驅Per Brinch Hansen和他在丹麥計算機公司Regnecentralen任職期間的工作。當時,他領導了RC 4000計算機的軟件研發。1967年,Regnecentralen正在普瓦伊的一家波蘭化肥廠安裝RC 4000原型機。這臺計算機使用了一個小型的專門為工廠量身打造的實時操作系統。Brinch Hansen和他的團隊開始關注RC 4000操作系統缺乏通用性和可重用性。他們擔心每次在其他公司安裝一臺新機器都需要開發不同的操作系統,1969年,最終完成了RC 4000多道程序設計系統。它的內核提供了基于消息傳遞的進程間通信,最多可以為23個非特權進程提供進程間通信,其中每次有8個進程相互保護。
繼Brinch Hansen的工作之后,自20世紀70年代以來,人們開始開發微內核,但“微內核”這個術語大概在1981年之前才首次出現。最早的操作系統內核一直都是宏內核,不過早期的宏內核操作系統因為功能過于簡單而更像一個微內核操作系統。隨著計算機技術的發展,新的設備驅動程序、協議棧、文件系統和其他低級系統不斷出現導致宏內核一直處在開發過程中,因此需要為管理這些代碼花費大量的時間。由此,微內核提出了一個新理念:所有這些新出現的服務都要像其他程序一樣作為用戶空間程序來實現,允許它們像任何其他程序一樣單獨工作、啟動和停止。這不僅可以讓這些服務更容易操作,而且還可以分離內核代碼,使其能夠進行微調,而不必擔心意外的副作用。采用這種方式,操作系統的內核部分就不會頻繁修改,進而便于維護和管理。
在20世紀80年代,當第一個可用的局域網出現時,微內核是一個非常熱門的話題。AmigaOS Exec內核就是一個早期的例子,它于1986年引入,并在一臺在商業上相對成功的PC中得到了使用。
4.2 三代微內核
操作系統微內核技術起始于20世紀80年代,起初被設計用來解決傳統宏內核操作系統在可維護性、擴展性、可靠性和穩定性方面的諸多問題。但是伴隨著微內核思想的進一步發展,最終形成了一整套操作系統設計的核心理念,即操作系統微內核僅提供最簡單、基本的服務,如通信功能,而操作系統的普通服務,如文件管理、設備管理、網絡管理等則在微內核以外提供。
4.2.1 第一代微內核操作系統
以Mach為代表,Mach微內核操作系統試圖從架構上重構宏內核操作系統但是仍然能夠維持原有操作系統功能的一次嘗試。為此,Mach微內核研究出了一系列概念用來支撐該項目,其中較突出的有核外頁管理器和用戶空間設備驅動等。Mach采用的IPC(進程間通信)策略包括消息傳遞、RPC(遠程過程調用)、同步和通知等。
然而,包括Mach或IBM的Workplace的第一代微內核的性能都不佳。對于Mach3來說,比原來的宏內核UNIX運行慢了約50%。最終大部分人傾向于認為性能低的原因是因為IPC開銷過大引起的,也有提出其他原因的。
以用戶程序讀寫文件時所涉及到的文件操作的上下文切換為例:
4.2.2 第二代微內核操作系統
以L3、L4為代表,第一代微內核從概念上驗證了微內核技術的可行性,但是因為性能上的原因,并未在產業界引起大規模推廣,但相關學術研究不斷出現。鑒于第一代微內核在性能上的劣勢,Jochen Liedtke設計了高性能的第二代微內核L4。相對于第一代微內核,第二代微內核不再是傳統Unix操作系統的簡單重構,而是一種全新的設計,并具有較高的性能。
L4內核支持三種抽象概念:地址空間,線程和IPC。它只提供7 個系統調用,且僅有12K字節代碼。進程間通信的一個基本問題是數據需要跨越不同的地址空間。大多數操作系統的解決辦法是用兩次數據拷貝:用戶地址空間A->內核地址空間->用戶地址空間B。為了實現高性能的IPC,L4的解決辦法是通過暫時地址映射實現了1次拷貝:內核把數據的目的地址暫時映射到一個位于內核地址空間的通訊窗口,然后內核把數據從用戶A 地址空間拷貝到通訊窗口供用戶B 使用。L4還采用了許多新穎的技術來提高內核性能,例如直接地址轉換、懶惰調度(Lazy Scheduling)、使用寄存器傳送短消息、減少緩存及TLB Miss等。
4.2.3 第三代微內核操作系統
以seL4為代表,第三代微內核更強調安全性。seL4由澳大利亞人開發,是在第二代微內核L4基礎上發展起來的。L4作為第二代微內核,通過采用同步IPC技術以及使用寄存器而非內存拷貝的方式來傳遞消息,解決了第一代微內核的性能低、實時性差的問題;但是第二代微內核在設計時為了追求高性能,所使用的線程ID是一種全局共享靜態資源,任何任務中的線程都可以通過線程ID向其他服務器線程發起服務請求,由此形成了安全上的隱患。作為第三代微內核,seL4通過一種類似對象引用的機制即Capability進行調用,任何操作系統內核對象如線程、中斷、內存等都不能直接進行操作,由此解決了第二代微內核的安全隱患問題。seL4本身就是security L4的意思。
總之,微內核技術從第一代發展到了第三代。第一代微內核停留在概念層面,試圖從概念上印證微內核技術的可行性;第二代微內核更關心性能,在第一代微內核的基礎上印證微內核技術的可用性;第三代微內核則關注安全性。
5 微內核的特點
5.1 安全性、可靠性、可移植性、可維護性
在安全性方面,通常認為微內核操作系統比宏內核操作系統更安全。微內核之上的模塊之間相對獨立,單個模塊崩潰后可以重啟,通常不影響全局;宏內核的模塊之間因為都在內核內而糾纏在一起,一個模塊的崩潰容易導致整個系統的失敗。宏內核不安全的核心問題在于其不符合最低授權原則POLA(Principle Of Least Authority)。其中,最大的隱患在于宏內核可不斷擴張的內核模塊。例如,對Linux來說,一旦進入內核,所有的代碼都運行在CPU最高等級Ring 0,內核級的惡意軟件可以破壞中斷表、系統調用表等關鍵數據。然而,在微內核架構中,進程管理、文件系統、網絡服務等均運行在Ring 1并且沒有動態擴展,微內核的這種封閉性很好地保障了隔離性,當然這種隔離性也帶來了性能開銷。
另外,由于內核較小,微內核操作系統相比宏內核操作系統還具有可靠性好、可移植性好、可維護性好的特點。
5.2 可擴展性
從可擴展性來看,微內核操作系統只在內核部分包括功能幾乎不變的核心模塊,其他模塊位于內核之上,便于擴展新的模塊;宏內核操作系統則在內核部分包括了大部分操作系統功能模塊,添加新模塊會影響到其他模塊,因而不便于擴展。
5.3 可連續性
在工控領域,有些系統可以連續運行幾個月甚至幾年。可連續性是指長時間運行而不重啟;當然,如果失敗后應能很快恢復運行。相比宏內核,微內核因為功能少,安全性和可靠性高,因而具有更好的連續性。
5.4 性能
宏內核操作系統因為在內核部分包括了大部分操作系統功能模塊,這些模塊只需要通過函數調用的方式就可以完成相互間的調用。但是,微內核操作系統的大部分功能模塊在內核之外,需要通過上下文切換和地址空間(用戶空間和內核空間)切換才能夠完成。這樣,微內核的性能通常認為比宏內核差。但即便如此,也有觀點認為微內核因為其他各種優點而會在未來的PC、服務器等領域占有一席之地。
5.5 實時性
微內核與實時性沒有必然聯系。因為性能和實時性是兩個不同的概念,所以把實時性放在性能之后來討論。實時內核的對比對象是分時內核或非實時內核。實時內核要求系統響應的實時性,比如火箭、無人機等的操作系統就是實時的,要求對系統的各種狀態做立即處理;而分時系統則對任務做分時處理,平分處理器時間,所以不具備實時性。由于一些微內核操作系統在實時性方面做了處理,因而具有較好的實時性,但宏內核操作系統也可以在實時性方面進行優化處理。
6 微內核與宏內核架構之爭
Minix和Linux是兩個著名的開源操作系統,Minix于1987年發布,主要用于教學;Linux最早在1991年發布,而1.0正式版本則在1994年發布。
Minix采用微內核架構,Linux采用宏內核架構,那么這兩種架構到底誰更勝一籌呢?在1992年,Minix的發明者Andrew S. Tanenbaum和Linux的創始人Linus Benedict Torvalds為此有過一段著名的爭論。不過那時候,Linux才剛剛開始。看看兩位大佬的爭論,對我們會有所啟發。(參見:https://www.cnblogs.com/wickedboy237/archive/2013/05/12/3074009.html,郵件中是Andy Tanenbaum)
Andrew主要觀點:
(1)微內核架構優于宏內核架構。
(2)Linux采用宏內核架構過時了,那是一些老的操作系統采用的方法,譬如UNIX, MS-DOS, VMS, MVS, OS/360, MULTICS。這是從90年代退回到70年代的一種設計方法,就像把一個正在運行著的C程序用BASIC重寫了。在1991年還寫一個宏內核操作系統真是一個愚蠢的選擇。
(3)宏內核唯一可稱道的地方就是性能,但現在有足夠的證據表明微內核系統也能夠和宏內核系統跑得一樣快(比如Rick Rashid 發表的對 Mach 3.0 和宏內核系統對比的論文)。
(4)微內核架構的可移植性更好,沒有必要為所有的CPU都設計一個不同的宏內核。譬如不斷涌現的那些Intel CPUs: 8008、8080、8086、8088、80286、80386、80486,一直到子子孫孫無窮盡。
Linus主要觀點:
(1)Linux幾乎在所有的領域里面都能戰勝Minix。
(2)Minix并沒有把微內核的能力發揮出來,并且對于真正的在內核中的多任務處理還有問題。
(3)事實是Linux可移植性比Minix好。可移植性的存在是為了那些不會編程的人。可移植性是個好東西,但只在有意義的前提下。嘗試著把一個操作系統變得可移植沒有必要,其實只要附帶一個輕便的API就足夠了(例如POSIX標準)。一個操作系統的理念是利用硬件的特點,并且把他們隱藏在一層層的高級調用中。當然這也使得內核變得不大有移植性,但它也變得更容易設計。
從1992年到2020年,世間發生了太多變化:計算機性能變得越來越好,體積越來越小;Linux變得越來越流行;計算機用戶越來越年輕。由于Linux龐大的開發者和用戶群體,Linux也被開發者們移植到各類CPU架構中,并沒有因為可移植性而受到阻礙。
7 微內核的應用場景
在微內核的發展過程中,出現了很多的微內核操作系統,譬如:Mach、Fiasco.OC、Pistachio OKL4 Microvisor、seL4、NOVA、P4 Pike、Minix、μC/OS-ii、ADEOS、EPOC、EKA1、EROS、Mac OS、Windows NT、Micro Empix、TI-RTOS、WarpOS、嵌入式Linux、Windows Embedded、PSOS、VxWorks、Zircon等。
從理論上來講,一個操作系統既可以采用微內核架構,也可以采用宏內核架構,只要有開發人員愿意進行產品研發。譬如,早期的Windows NT、Mac OS等采用微內核架構,后面因為性能問題將用戶空間的一部分功能移到內核空間,構成一個混合內核。Linux則采用宏內核架構。
然而隨著計算機技術和操作系統的不斷發展,微內核和宏內核在不同應用場景中還是存在著實際差別。
7.1 嵌入式系統
嵌入式系統具有資源相對有限、專用性強、實時性高等特點,因此應用于嵌入式系統的操作系統必須滿足系統內核小、支持實時多任務、具有存儲區保護功能以及可裁剪等要求。嵌入式操作系統負責嵌入式系統的全部軟硬件資源的分配、任務調度,控制和協調并發活動。它必須體現其所在系統的特征,能夠通過裝卸某些模塊來達到系統所要求的功能。
嵌入式系統的這種需求與微內核操作系統的發展需求相吻合。現代微內核相關技術仍在繼續發展和不斷完善中,極小化和高IPC性能這兩個基本原則仍然是設計和實現決定的驅動力。
對于嵌入式系統領域,很多系統甚至沒有硬盤存儲,它們更多地使用微內核操作系統。
7.2 工控機、PC、服務器
對于工控機、PC、服務器來說,因為需要操作系統完成的功能很多,處理的任務非常復雜,因而更適合使用宏內核操作系統。
如果強調實時性,完成較簡單功能的工控機也可以采用微內核操作系統,譬如VxWorks等。
再次說明,從理論上講,微內核和宏內核操作系統都可以應用于各種場景,只是目前已經研制的各種操作系統所采取的架構導致了它們在具體應用場景中有所側重。譬如,微內核操作系統也可以運行于一些PC或服務器上。GNU HURD是一個從1990年就開始研制的微內核操作系統,運行于Mach或L4之上,目前從官網看到的最新版本為2019年開發的Debian版本。作為一個微內核操作系統,它不需要重新啟動機器就可以開發和測試新的Hurd內核組件,運行自己的內核組件不會干擾其他用戶,因此不需要特殊的系統特權。內核擴展的機制在設計上是安全的:不可能將一個用戶的更改強加給其他用戶,除非系統管理員或授權用戶這樣做。但是,由于開發人員很少,進展較慢,還沒有達到完全成熟好用階段。(參見GNU HURD: GNU Hurd)
7.3 移動/物聯網操作系統
在移動、物聯網操作系統領域,大家一般把相關的操作系統歸類為微內核操作系統,譬如應用在智能手機和平板電腦的Android、iOS等(也有人稱它們為混合內核操作系統);之前介紹的鴻蒙操作系統,采用Zircon內核的谷歌Fuchsia,這兩個微內核操作系統可能在未來萬物互聯的物聯網系統中發揮重要作用。(參見:鴻蒙系統的微內核是什么 _企業頭條 - 天眼查)
總之,對于一些專用系統,主要是實時系統、嵌入式系統、物聯網系統,微內核的思想更有吸引力。究其原因,主要是因為通常這些系統都不帶磁盤,整個系統都必須放在EPROM中,常常受到存儲空間的限制,而所需要的服務又比較單一和簡單。所以,幾乎所有的實時系統、嵌入式系統和物聯網系統都采用微內核。當然,微內核也有缺點,將這些服務的提供都放在進程層次上,再通過進程間通信(通常是報文的傳遞)提供服務,勢必增加系統的運行開銷,降低了效率。
與微內核相對應,其他通用式系統由于所需的服務面廣而量大,采用宏內核就更為合適。
8 基于seL4微內核的若干實驗研究
8.1 第三代微內核seL4
seL4是一個通過形式化驗證的、代碼被證明是完全正確的操作系統微內核。其實,seL4不僅是一個微內核,它還是一個類似KVM的虛擬化管理程序(hypervisor),可以在它上面運行一個虛擬機。如下圖所示,seL4支持在虛擬機中運行其他Linux操作系統。
????????????????????????????????????????圖4?基于seL4的虛擬化技術
8.2 實驗1:基于中標麒麟操作系統V7.0搭建seL4編譯和測試環境
實驗目的:本實驗是為研究如何搭建和使用seL4系統。
實驗環境:在搭建seL4編譯和測試環境時,選取裝有《中標麒麟操作系統V7.0》操作系統的x86機器兩臺,一臺用于編譯seL4,另一臺用于測試seL4。
實驗步驟:
編譯環境搭建步驟如下:
(a)搭建編譯依賴
yum install protobuf-compiler protobuf python2-protobuf
yum install qemu-kvm libvirt libvirt-client virt-install virt-viewer
yum install centos-release-scl scl-utils-build -y
yum install devtoolset-8-toolchain -y
yum install make automake gcc gcc-c++ kernel-devel
yum install python3-devel
pip3 install --user setuptools
pip3 install --user sel4-deps
pip3 install --user camkes-deps
yum install ghc cabal-install
yum install openssl-devel
yum install qemu-system-x86
yum install?nanopb
yum install -y gcc gcc-c++ make automake
yum install ninja-build
yum install python3
yum install python2
pip3 install future
pip3 install Jinja2
pip3 install tempita
pip3 install future
pip3 install templating
pip3 install six
pip3 install ply
pip3 install protobuf grpcio-tools
(b)升級cmake版本
wget https://cmake.org/files/v3.17/cmake-3.17.0.tar.gz
tar -zxvf cmake-3.17.0.tar.gz
cd cmake-3.17.0
./bootstrap --parallel=16
gmake -j 16
gmake install
(c)編譯sel4源碼
mkdir sel4-tutorials-manifest
cd sel4-tutorials-manifest
repo init -u https://github.com/SEL4PROJ/sel4-tutorials-manifest
repo sync
./init --plat pc99 --tut hello-world ?--solution
cd hello-world_build
ninja -j 8
測試環境搭建步驟如下:
(d)修改啟動項
menuentry 'sel4-hello-world' --class fedora --class gnu-linux --class gnu --class os {
????load_video
????insmod gzio
????insmod part_msdos
????insmod xfs
????set root='hd0,msdos1'
????search --no-floppy --fs-uuid --set=root b83f90f1-65b3-4db3-b19b-ef30ca140513
????echo ???'Loading seL4 kernel'
????multiboot /?kernel-x86_64-pc99
????echo ???'Loading initial module ...'
????module ?/hello-world-image-x86_64-pc99
}
(e)準備seL4內核和應用鏡像
從編譯環境中復制images文件夾中的kernel-x86_64-pc99和hello-world-image-x86_64-pc99文件到測試環境的/boot文件夾下
(f)重啟并選擇seL4啟動項
重啟,選擇“sel4-hello-world”啟動項,在串口中出現下圖畫面
????????????????????????????????????????圖5?Hello World測試程序輸出
至此,seL4的編譯環境和測試環境搭建完畢。為了進一步研究如何修改helloworld程序,可以在編譯環境中對/root/sel4-tutorials-manifest/ hello-world/src/main.c文件進行修改,如下圖所示:
????????????????????????????????????????圖6?新Hello World測試源碼
重新回到測試環境中的/root/sel4-tutorials-manifest/hello-world_ build目錄,執行ninja clean && ninja -j 8命令,命令執行成功后,把kernel-x86_64-pc99和hello-world-image-x86_64-pc99兩個文件復制到測試環境中/boot目錄下,重啟測試機器,選擇“sel4-hello-world”啟動項,可以看到修改后的源碼輸出,如下圖所示:
?????????????????????????????????????? 圖7?新Hello World測試效果
8.3 實驗2:基于seL4進行進程間通訊
實驗目的:為進一步研究seL4如何使用,需要研究如何在seL4系統下進行進程間通訊。
實驗環境:與實驗1相同。
實驗步驟:
我們寫了一個server端和兩個client端和CMakeLists.txt文件。
server.c代碼如下圖所示:
????????????????????????????????????????圖8?進程間通訊server源碼
client1端代碼如下圖所示:
????????????????????????????????????????圖9?進程間通訊client1源碼
client2端源碼如下圖所示:
????????????????????????????????????????圖10?進程間通訊client2源碼
CMakeLists.txt代碼如下:
????????????????????????????????????????圖11?進程間通訊CMake文件
對上述文件執行cmake . && ninja 命令后,在把images文件夾中的kernel-x86_64-pc99和capdl-loader-image-x86_64-pc99兩個文件復制到測試環境中/boot目錄下,增加啟動項,重啟后選擇新建啟動項,則會在串口中發現如下圖所示輸出:
????????????????????????????????????????圖12?進程間測試效果
8.4 實驗3:seL4性能測試實驗
實驗目的:為了測試seL4的性能,需要對ipc、irq、schedule、signal、fault、hardware、sync、page_mapping等方面進行性能測試。
實驗環境:與實驗1相同。
實驗步驟:
使用google-benchmark測試工具庫,對每一個測試項編寫一個測試程序,如下圖所示:
????????????????????????????????????????圖13?性能測試工程樹
針對上述源碼,為每一個測試源碼編寫CMakeLists.txt文件,執行ninja命令成功后,把images文件夾中的kernel-x86_64-pc99和sel4benchapp-image-x86_64-pc99文件復制到測試環境的/boot目錄下,增加啟動項,重啟后選擇新增加的啟動項。觀察串口輸出,抓取輸出數據起始信息如下圖所示:
????????????????????????????????????????圖14?性能測試原始數據
對原始數據進行格式化處理后,顯示信息如下所示:
????????????????????????????????????????圖15?性能測試結構化數據
8.5 實驗4:seL4虛擬化實驗
實驗目的:為研究如何在sel4上運行Linux。
實驗環境:與實驗1 相同。
實驗步驟:
(a)準備內核
使用中標麒麟安全操作系統V7.0系統中自帶內核源碼,對內核進行如下修改:
CONFIG_X86_32=y
CONFIG_X86=y
CONFIG_X86_32_SMP=n
CONFIG_SMP=n
CONFIG_NOHIGHMEM=y
CONFIG_PCI_MSI=n
CONFIG_X86_UP_APIC=n
CONFIG_SUSPEND=n
CONFIG_HIBERNATION=n
CONFIG_PM=n
CONFIG_ACPI=n
CONFIG_VIRTIO=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_NET=y
(b)準備initrd
使用中標麒麟安全操作系統V7.0系統中自帶initrd
(c)編寫camkes文件生成虛擬機
import <VM/vm.camkes>;
#include <configurations/vm.h>
#define VM_GUEST_CMDLINE "earlyprintk=ttyS0,115200 console=tty0 console=ttyS0,115200 i8042.nokbd=y i8042.nomux=y \
i8042.noaux=y io_delay=udelay noisapnp pci=nomsi debug root=/dev/mem"
component Init0 {
????VM_INIT_DEF()
}
assembly {
????composition {
????????VM_COMPOSITION_DEF()
????????VM_PER_VM_COMP_DEF(0)
????}
????configuration {
????????VM_CONFIGURATION_DEF()
????????VM_PER_VM_CONFIG_DEF(0)
????????vm0.simple_untyped23_pool = 20;
????????vm0.heap_size = 0x2000000;
????????vm0.guest_ram_mb = 128;
????????vm0.kernel_cmdline = VM_GUEST_CMDLINE;
????????vm0.kernel_image = "bzimage";
????????vm0.kernel_relocs = "bzimage";
????????vm0.initrd_image = "rootfs.cpio";
????????vm0.iospace_domain = 0x0f;
????}
}
(d)編寫CMake文件生成sel4鏡像
include(${SEL4_TUTORIALS_DIR}/settings.cmake)
sel4_tutorials_regenerate_tutorial(${CMAKE_CURRENT_SOURCE_DIR})
cmake_minimum_required(VERSION 3.8.2)
project(vm-app C ASM)
include(ExternalProject)
find_package(camkes-vm REQUIRED)
include(${CAMKES_VM_SETTINGS_PATH})
camkes_x86_vm_setup_x86_vm_environment()
include(${CAMKES_VM_HELPERS_PATH})
find_package(camkes-vm-linux REQUIRED)
include(${CAMKES_VM_LINUX_HELPERS_PATH})
include(simulation)
GenerateSimulateScript()
DeclareCAmkESVM(Init0)
GetDefaultLinuxKernelFile(default_kernel_file)
GetDefaultLinuxRootfsFile(default_rootfs_file)
DecompressLinuxKernel(extract_linux_kernel decompressed_kernel ${default_kernel _file})
AddToFileServer("bzimage" ${decompressed_kernel} DEPENDS extract_linux_kernel)
AddToFileServer("rootfs.cpio" ${default_rootfs_file})
DeclareCAmkESVMRootServer(vm_tutorial.camkes)
GenerateCAmkESRootserver()
(e)測試與驗證
執行ninja命令成功后,把images文件夾中的kernel-x86_64-pc99和capdl-loader-image-x86_64-pc99文件復制到測試環境的/boot目錄下,增加啟動項,重啟后選擇新增加的啟動項。觀察串口輸出,可看到如下圖所示信息:
????????????????????????????????????????圖16 虛擬機啟動界面
8.6 實驗5:seL4與Linux性能對比測試
seL4官方提供了一個性能測試工具sel4bench,直接編譯運行就可以得到測試結果。我們仔細研究了sel4bench,然后花時間將每個測試用例移植到了Linux平臺下,從而得出了Linux環境下的測試結果。
seL4內核版本:?11.0.0-dev
Linux發行版本CentOS Linux release 8.2.2004 (Core),Linux內核版本4.18.0-193.19.1.el8_2.x86_64
seL4微內核環境:使用seL4官方提供的測試工具sel4bench
Linux環境:將seL4官方提供的測試工具sel4bench移植到Linux內核環境
|
| 最小時間 | 平均時間 | 最大時間 | |||
|
| Sel4 | Linux | Sel4 | linux | Sel4 | linux |
| ipc | 128 | 2102 | 131 | 2282 | 134 | 3121 |
| irquser | 113869 | 15605 | 380496 | 22724 | 646754 | 48663 |
| scheduler | 340 | 519 | 354 | 628 | 672 | 849 |
| signal | 187 | 5 | 214 | 48 | 337 | 126 |
| fault | 279 | 1718 | 284 | 1734 | 291 | 1754 |
| hardware | 167 | 58 | 180 | 205 | 390 | 7718 |
| sync | 1763 | 1752 | 1778 | 1966 | 1836 | 2181 |
表1 seL4與Linux性能測試結果
?????????????????????????????????????????圖17 seL4與Linux性能對比測試
通過以上對比測試,可以看出seL4內核與Linux內核綜合性能持平。
d)測試基準單位
TSC(Time Stamp Counter)時間戳計數器的值:從pentium開始,很多80x86微處理器都引入TSC,一個用于時間戳計數器的64位的寄存器,它在每個時鐘信號到來時加一。當前使用的CPU主頻為2.90GHz(2903.998MHz),所以計數器的單位大約是0.34ns
e)測試原理:
seL4微內核和Linux內核之間主要做了以下對比測試:
ipc Benchmarks:進程間通信機制( Inter-Process Communication,IPC)是一項影響內核操作系統整體性能的關鍵因素。為了評估IPC通信的實時性能, ipc Benchmarks測試用例中通過統計內核IPC通信機制下消息在內核中的時間消耗,用以測試高實時優先級進程的通信延時。
irquser Benchmarks:中斷處理是整個系統中優先級最高的代碼,在系統運行過程中,中斷程序可以搶占到任意任務級別的代碼運行,而且中斷也分等級,高級別中斷搶占低級別中斷。系統實時性是依靠中斷機制來保證的,多任務的環境運行基礎也是中斷機制。所以對于衡量內核性能,最重要的指標就是中斷延遲。irquser Benchmarks測試用例用來測試內核的中斷延遲。
scheduler Benchmarks:主要用于統計任務切換時間(task switching time),即系統在兩個獨立的、處于就緒態并且具有相同或不同優先級的任務之間切換所需要的時間。切換所需的時間主要取決于保存任務上下文所用的數據結構以及操作系統采用的調度算法的效率。產生任務切換的原因可以是資源可得,信號量的獲取等。任務切換過程增加了應用程序的額外負荷。CPU的內部寄存器越多,額外負荷就越重。任務切換所需要的時間取決于CPU有多少寄存器要入棧。
signal Benchmarks:信號量混洗時間是指從一個任務釋放信號量到另一個等待該信號量的任務被激活的時間延遲。在操作系統中,通常有許多任務同時競爭某一共享資源,基于信號量的互斥訪問保證了任一時刻只有一個任務能夠訪問公共資源。信號量混洗時間反映了與互斥有關的時間開銷,因此也是衡量內核實時性能的一個重要指標。
fault Benchmarks:異常是可以打斷CPU正在運行流程的一些事情,比如外部中斷、未定義指令、試圖修改只讀數據、執行swi指令(中斷指令)等。當這些事情發生時,CPU暫停當前的程序,先處理異常事件,然后再繼續執行被中斷的程序。中斷也是異常的一種。fault Benchmarks測試用例用于統計內核處理異常時間消耗。
hardware Benchmarks:用于統計內核執行空系統調用的時間消耗。
sync Benchmarks:互斥鎖是使用簡單的加鎖的方法來控制對共享資源的存取。互斥鎖只有兩種狀態,也就是上鎖和解鎖。可以把互斥鎖看作某種意義上的全局變量。在同一時刻只能有一個線程掌握某個互斥上的鎖,擁有上鎖狀態的線程能夠對共享資源進行操作。若其他線程希望上鎖一個已經上鎖了的互斥鎖,則該線程就會掛起,直到上鎖的線程釋放掉互斥鎖為止。互斥鎖使得共享資源按序在各個線程中操作。sync Benchmarks使用互斥鎖和信號量實現多線程間的同步,統計同步信號發出到所有等待線程接收到同步信號的時間消耗。
總結
以上是生活随笔為你收集整理的操作系统微内核架构研究的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js ejs for语句的第二种遍历
- 下一篇: 基于java SSM的房屋租赁系统设计和