操作系统微内核架构研究
1 簡介
微內(nèi)核是操作系統(tǒng)內(nèi)核的一種,在工控系統(tǒng)、嵌入式系統(tǒng)、實時系統(tǒng)等領(lǐng)域發(fā)揮著重要作用。本文較為全面地研究了微內(nèi)核技術(shù)的各個方面,包括微內(nèi)核的定義、微內(nèi)核的體系架構(gòu)、微內(nèi)核的發(fā)展歷史、微內(nèi)核的特點、微內(nèi)核的應(yīng)用場景,以及作者所進行的部分研究工作。本文部分內(nèi)容和圖來自網(wǎng)上,由于內(nèi)容較多,有些沒有標(biāo)注,如果原作者覺得不合適請聯(lián)系刪除。
2 微內(nèi)核的定義
在計算機科學(xué)中,內(nèi)核是操作系統(tǒng)的核心部分,它管理著系統(tǒng)的各種資源,譬如時鐘、中斷、存儲、進程、設(shè)備驅(qū)動、原語等。應(yīng)用程序運行在內(nèi)核之上,并通過系統(tǒng)調(diào)用訪問內(nèi)核空間。
從內(nèi)核架構(gòu)來劃分,操作系統(tǒng)內(nèi)核可分為微內(nèi)核(Micro Kernel)和宏內(nèi)核(Monolithic Kernel,也翻譯為單內(nèi)核)。如下圖所示,微內(nèi)核操作系統(tǒng)僅在內(nèi)核中保留了調(diào)度、基礎(chǔ)IPC、虛擬內(nèi)存管理等少數(shù)核心功能模塊,它們位于內(nèi)核空間,而操作系統(tǒng)的其他功能模塊(譬如文件系統(tǒng)、驅(qū)動程序等)與用戶應(yīng)用程序一起運行于用戶空間;宏內(nèi)核操作系統(tǒng)在內(nèi)核中包括了整個操作系統(tǒng)的大部分功能模塊(譬如文件系統(tǒng)、驅(qū)動程序等),并且這些系統(tǒng)模塊都運行在同一個內(nèi)核地址空間,模塊之間通過簡單的系統(tǒng)調(diào)用進行協(xié)調(diào)工作。
微內(nèi)核(通常縮寫為μ內(nèi)核)由一群數(shù)量盡可能最少的軟件程序組成,它們負(fù)責(zé)提供實現(xiàn)一個操作系統(tǒng)所必須的各種機制。這些機制就是之前提到的線程/進程調(diào)度機制、基礎(chǔ)的進程間通信機制(IPC)、虛擬內(nèi)存管理機制等;而包括文件系統(tǒng)、驅(qū)動程序在內(nèi)的其他各種功能模塊都放到用戶空間。微內(nèi)核的最小化也稱為Jochen Liedtke最小化原則。Jochen Liedtke是一名德國科學(xué)家。這里區(qū)分兩個術(shù)語,操作系統(tǒng)微內(nèi)核即指微內(nèi)核,微內(nèi)核操作系統(tǒng)則指一種基于微內(nèi)核架構(gòu)的操作系統(tǒng)。
???????????????????????????????????????? 圖1?微內(nèi)核與宏內(nèi)核架構(gòu)
從操作系統(tǒng)功能模塊來看,操作系統(tǒng)廠商依據(jù)自己的實際情況,可以將宏內(nèi)核操作系統(tǒng)中的部分功能模塊從內(nèi)核空間移到用戶空間,也可以將微內(nèi)核操作系統(tǒng)中的部分功能模塊從用戶空間移到內(nèi)核空間,由此就構(gòu)成了微內(nèi)核、小內(nèi)核、大內(nèi)核、宏內(nèi)核等稱謂。對于介于微內(nèi)核和宏內(nèi)核之間的小內(nèi)核、大內(nèi)核來說,有時也把它們稱之為混合內(nèi)核。對于操作系統(tǒng)廠商來說,沒有必要嚴(yán)格遵守微內(nèi)核的最小化原則,非要做一個嚴(yán)格意義上的微內(nèi)核,或者完全意義上的宏內(nèi)核。本文在后面主要討論微內(nèi)核和宏內(nèi)核。
3 微內(nèi)核的體系架構(gòu)
3.1 分布式服務(wù)器架構(gòu)
在圖1的微內(nèi)核架構(gòu)中,按照官方說法,位于用戶空間的各個功能模塊被設(shè)計成一個個功能獨立的服務(wù)器(Server),由微內(nèi)核采用消息通信機制來調(diào)度各個服務(wù)器完成工作。為避免混淆,這里的服務(wù)器可以理解為一個服務(wù)器程序。微內(nèi)核相當(dāng)于客戶端程序(Client)。
從理論上來說,基于消息通信的兩個程序(Client和Server)可以位于同一臺機器,也可以位于不同機器。因而,微內(nèi)核操作系統(tǒng)中的這些服務(wù)器可以是分布式的,它們可能位于同一臺機器,也可能位于其他機器。這里再次強調(diào),只是理論上是這樣,真正這樣實現(xiàn)的操作系統(tǒng)還極少。
微內(nèi)核的分布式架構(gòu)是有意義的。從下面鏈接可知,鴻蒙操作系統(tǒng)聲稱自己具有兩個特點:微內(nèi)核、分布式。采用分布式消息通信機制,可以實現(xiàn)鴻蒙操作系統(tǒng)與各類硬件設(shè)備(例如手機、平板、手表、PC等)的互聯(lián)。這種消息通信機制也被說成為分布式總線。
(參見:鴻蒙系統(tǒng):微內(nèi)核,分布式_華為)
????????????????????????????????????????圖2?基于分布式總線的鴻蒙操作系統(tǒng)的萬物互聯(lián)機制
3.2?插件架構(gòu)
在圖1的微內(nèi)核架構(gòu)中,各個服務(wù)器程序相互獨立,也有個別人把這種架構(gòu)稱之為“插件架構(gòu)”。
如下圖所示(微內(nèi)核架構(gòu) - 簡書),在軟件開發(fā)領(lǐng)域,插件化架構(gòu)由一個中間的核心系統(tǒng)和若干插件模塊組成。該架構(gòu)最大的優(yōu)勢是允許第三方開發(fā)者遵循一定的開發(fā)規(guī)范添加額外的插件化應(yīng)用。采用插件架構(gòu)的軟件有很多,例如Eclipse、企業(yè)ERP軟件等,這類軟件自身具備豐富功能,同時支持第三方應(yīng)用的即插即用;并且第三方插件化程序的安裝、運行、卸載以及故障不會對原有系統(tǒng)造成任何影響。
????????????????????????????????????????圖3?軟件插件架構(gòu)
在插件架構(gòu)中,核心系統(tǒng)的功能穩(wěn)定,很少變更。它只擁有能使應(yīng)用運行的最小功能邏輯(例如插件模塊的注冊、加載、卸載,以及插件模塊之間的相互通信等)不涉及任何特定業(yè)務(wù);插件系統(tǒng)具備良好的擴展性,可根據(jù)特定業(yè)務(wù)需求而變更其業(yè)務(wù)邏輯。
插件架構(gòu)本質(zhì)上是將一個軟件系統(tǒng)中的變化部分封裝在插件中,從而實現(xiàn)不同業(yè)務(wù)之間的隔離性,達(dá)到系統(tǒng)快速靈活擴展的目的,同時所有特定業(yè)務(wù)相關(guān)邏輯的變更不會影響整體系統(tǒng)的穩(wěn)定性。
另外,插件架構(gòu)需要解決好三方面的問題:插件管理、插件鏈接和插件通信。
由上可知,理論上的微內(nèi)核確實是一種基于插件架構(gòu)的操作系統(tǒng)內(nèi)核。
4 微內(nèi)核的發(fā)展歷史
4.1 微內(nèi)核起源(參見維基百科)
微內(nèi)核的起源可以追溯到丹麥計算機先驅(qū)Per Brinch Hansen和他在丹麥計算機公司Regnecentralen任職期間的工作。當(dāng)時,他領(lǐng)導(dǎo)了RC 4000計算機的軟件研發(fā)。1967年,Regnecentralen正在普瓦伊的一家波蘭化肥廠安裝RC 4000原型機。這臺計算機使用了一個小型的專門為工廠量身打造的實時操作系統(tǒng)。Brinch Hansen和他的團隊開始關(guān)注RC 4000操作系統(tǒng)缺乏通用性和可重用性。他們擔(dān)心每次在其他公司安裝一臺新機器都需要開發(fā)不同的操作系統(tǒng),1969年,最終完成了RC 4000多道程序設(shè)計系統(tǒng)。它的內(nèi)核提供了基于消息傳遞的進程間通信,最多可以為23個非特權(quán)進程提供進程間通信,其中每次有8個進程相互保護。
繼Brinch Hansen的工作之后,自20世紀(jì)70年代以來,人們開始開發(fā)微內(nèi)核,但“微內(nèi)核”這個術(shù)語大概在1981年之前才首次出現(xiàn)。最早的操作系統(tǒng)內(nèi)核一直都是宏內(nèi)核,不過早期的宏內(nèi)核操作系統(tǒng)因為功能過于簡單而更像一個微內(nèi)核操作系統(tǒng)。隨著計算機技術(shù)的發(fā)展,新的設(shè)備驅(qū)動程序、協(xié)議棧、文件系統(tǒng)和其他低級系統(tǒng)不斷出現(xiàn)導(dǎo)致宏內(nèi)核一直處在開發(fā)過程中,因此需要為管理這些代碼花費大量的時間。由此,微內(nèi)核提出了一個新理念:所有這些新出現(xiàn)的服務(wù)都要像其他程序一樣作為用戶空間程序來實現(xiàn),允許它們像任何其他程序一樣單獨工作、啟動和停止。這不僅可以讓這些服務(wù)更容易操作,而且還可以分離內(nèi)核代碼,使其能夠進行微調(diào),而不必?fù)?dān)心意外的副作用。采用這種方式,操作系統(tǒng)的內(nèi)核部分就不會頻繁修改,進而便于維護和管理。
在20世紀(jì)80年代,當(dāng)?shù)谝粋€可用的局域網(wǎng)出現(xiàn)時,微內(nèi)核是一個非常熱門的話題。AmigaOS Exec內(nèi)核就是一個早期的例子,它于1986年引入,并在一臺在商業(yè)上相對成功的PC中得到了使用。
4.2 三代微內(nèi)核
操作系統(tǒng)微內(nèi)核技術(shù)起始于20世紀(jì)80年代,起初被設(shè)計用來解決傳統(tǒng)宏內(nèi)核操作系統(tǒng)在可維護性、擴展性、可靠性和穩(wěn)定性方面的諸多問題。但是伴隨著微內(nèi)核思想的進一步發(fā)展,最終形成了一整套操作系統(tǒng)設(shè)計的核心理念,即操作系統(tǒng)微內(nèi)核僅提供最簡單、基本的服務(wù),如通信功能,而操作系統(tǒng)的普通服務(wù),如文件管理、設(shè)備管理、網(wǎng)絡(luò)管理等則在微內(nèi)核以外提供。
4.2.1 第一代微內(nèi)核操作系統(tǒng)
以Mach為代表,Mach微內(nèi)核操作系統(tǒng)試圖從架構(gòu)上重構(gòu)宏內(nèi)核操作系統(tǒng)但是仍然能夠維持原有操作系統(tǒng)功能的一次嘗試。為此,Mach微內(nèi)核研究出了一系列概念用來支撐該項目,其中較突出的有核外頁管理器和用戶空間設(shè)備驅(qū)動等。Mach采用的IPC(進程間通信)策略包括消息傳遞、RPC(遠(yuǎn)程過程調(diào)用)、同步和通知等。
然而,包括Mach或IBM的Workplace的第一代微內(nèi)核的性能都不佳。對于Mach3來說,比原來的宏內(nèi)核UNIX運行慢了約50%。最終大部分人傾向于認(rèn)為性能低的原因是因為IPC開銷過大引起的,也有提出其他原因的。
以用戶程序讀寫文件時所涉及到的文件操作的上下文切換為例:
4.2.2 第二代微內(nèi)核操作系統(tǒng)
以L3、L4為代表,第一代微內(nèi)核從概念上驗證了微內(nèi)核技術(shù)的可行性,但是因為性能上的原因,并未在產(chǎn)業(yè)界引起大規(guī)模推廣,但相關(guān)學(xué)術(shù)研究不斷出現(xiàn)。鑒于第一代微內(nèi)核在性能上的劣勢,Jochen Liedtke設(shè)計了高性能的第二代微內(nèi)核L4。相對于第一代微內(nèi)核,第二代微內(nèi)核不再是傳統(tǒng)Unix操作系統(tǒng)的簡單重構(gòu),而是一種全新的設(shè)計,并具有較高的性能。
L4內(nèi)核支持三種抽象概念:地址空間,線程和IPC。它只提供7 個系統(tǒng)調(diào)用,且僅有12K字節(jié)代碼。進程間通信的一個基本問題是數(shù)據(jù)需要跨越不同的地址空間。大多數(shù)操作系統(tǒng)的解決辦法是用兩次數(shù)據(jù)拷貝:用戶地址空間A->內(nèi)核地址空間->用戶地址空間B。為了實現(xiàn)高性能的IPC,L4的解決辦法是通過暫時地址映射實現(xiàn)了1次拷貝:內(nèi)核把數(shù)據(jù)的目的地址暫時映射到一個位于內(nèi)核地址空間的通訊窗口,然后內(nèi)核把數(shù)據(jù)從用戶A 地址空間拷貝到通訊窗口供用戶B 使用。L4還采用了許多新穎的技術(shù)來提高內(nèi)核性能,例如直接地址轉(zhuǎn)換、懶惰調(diào)度(Lazy Scheduling)、使用寄存器傳送短消息、減少緩存及TLB Miss等。
4.2.3 第三代微內(nèi)核操作系統(tǒng)
以seL4為代表,第三代微內(nèi)核更強調(diào)安全性。seL4由澳大利亞人開發(fā),是在第二代微內(nèi)核L4基礎(chǔ)上發(fā)展起來的。L4作為第二代微內(nèi)核,通過采用同步IPC技術(shù)以及使用寄存器而非內(nèi)存拷貝的方式來傳遞消息,解決了第一代微內(nèi)核的性能低、實時性差的問題;但是第二代微內(nèi)核在設(shè)計時為了追求高性能,所使用的線程ID是一種全局共享靜態(tài)資源,任何任務(wù)中的線程都可以通過線程ID向其他服務(wù)器線程發(fā)起服務(wù)請求,由此形成了安全上的隱患。作為第三代微內(nèi)核,seL4通過一種類似對象引用的機制即Capability進行調(diào)用,任何操作系統(tǒng)內(nèi)核對象如線程、中斷、內(nèi)存等都不能直接進行操作,由此解決了第二代微內(nèi)核的安全隱患問題。seL4本身就是security L4的意思。
總之,微內(nèi)核技術(shù)從第一代發(fā)展到了第三代。第一代微內(nèi)核停留在概念層面,試圖從概念上印證微內(nèi)核技術(shù)的可行性;第二代微內(nèi)核更關(guān)心性能,在第一代微內(nèi)核的基礎(chǔ)上印證微內(nèi)核技術(shù)的可用性;第三代微內(nèi)核則關(guān)注安全性。
5 微內(nèi)核的特點
5.1 安全性、可靠性、可移植性、可維護性
在安全性方面,通常認(rèn)為微內(nèi)核操作系統(tǒng)比宏內(nèi)核操作系統(tǒng)更安全。微內(nèi)核之上的模塊之間相對獨立,單個模塊崩潰后可以重啟,通常不影響全局;宏內(nèi)核的模塊之間因為都在內(nèi)核內(nèi)而糾纏在一起,一個模塊的崩潰容易導(dǎo)致整個系統(tǒng)的失敗。宏內(nèi)核不安全的核心問題在于其不符合最低授權(quán)原則POLA(Principle Of Least Authority)。其中,最大的隱患在于宏內(nèi)核可不斷擴張的內(nèi)核模塊。例如,對Linux來說,一旦進入內(nèi)核,所有的代碼都運行在CPU最高等級Ring 0,內(nèi)核級的惡意軟件可以破壞中斷表、系統(tǒng)調(diào)用表等關(guān)鍵數(shù)據(jù)。然而,在微內(nèi)核架構(gòu)中,進程管理、文件系統(tǒng)、網(wǎng)絡(luò)服務(wù)等均運行在Ring 1并且沒有動態(tài)擴展,微內(nèi)核的這種封閉性很好地保障了隔離性,當(dāng)然這種隔離性也帶來了性能開銷。
另外,由于內(nèi)核較小,微內(nèi)核操作系統(tǒng)相比宏內(nèi)核操作系統(tǒng)還具有可靠性好、可移植性好、可維護性好的特點。
5.2 可擴展性
從可擴展性來看,微內(nèi)核操作系統(tǒng)只在內(nèi)核部分包括功能幾乎不變的核心模塊,其他模塊位于內(nèi)核之上,便于擴展新的模塊;宏內(nèi)核操作系統(tǒng)則在內(nèi)核部分包括了大部分操作系統(tǒng)功能模塊,添加新模塊會影響到其他模塊,因而不便于擴展。
5.3 可連續(xù)性
在工控領(lǐng)域,有些系統(tǒng)可以連續(xù)運行幾個月甚至幾年。可連續(xù)性是指長時間運行而不重啟;當(dāng)然,如果失敗后應(yīng)能很快恢復(fù)運行。相比宏內(nèi)核,微內(nèi)核因為功能少,安全性和可靠性高,因而具有更好的連續(xù)性。
5.4 性能
宏內(nèi)核操作系統(tǒng)因為在內(nèi)核部分包括了大部分操作系統(tǒng)功能模塊,這些模塊只需要通過函數(shù)調(diào)用的方式就可以完成相互間的調(diào)用。但是,微內(nèi)核操作系統(tǒng)的大部分功能模塊在內(nèi)核之外,需要通過上下文切換和地址空間(用戶空間和內(nèi)核空間)切換才能夠完成。這樣,微內(nèi)核的性能通常認(rèn)為比宏內(nèi)核差。但即便如此,也有觀點認(rèn)為微內(nèi)核因為其他各種優(yōu)點而會在未來的PC、服務(wù)器等領(lǐng)域占有一席之地。
5.5 實時性
微內(nèi)核與實時性沒有必然聯(lián)系。因為性能和實時性是兩個不同的概念,所以把實時性放在性能之后來討論。實時內(nèi)核的對比對象是分時內(nèi)核或非實時內(nèi)核。實時內(nèi)核要求系統(tǒng)響應(yīng)的實時性,比如火箭、無人機等的操作系統(tǒng)就是實時的,要求對系統(tǒng)的各種狀態(tài)做立即處理;而分時系統(tǒng)則對任務(wù)做分時處理,平分處理器時間,所以不具備實時性。由于一些微內(nèi)核操作系統(tǒng)在實時性方面做了處理,因而具有較好的實時性,但宏內(nèi)核操作系統(tǒng)也可以在實時性方面進行優(yōu)化處理。
6 微內(nèi)核與宏內(nèi)核架構(gòu)之爭
Minix和Linux是兩個著名的開源操作系統(tǒng),Minix于1987年發(fā)布,主要用于教學(xué);Linux最早在1991年發(fā)布,而1.0正式版本則在1994年發(fā)布。
Minix采用微內(nèi)核架構(gòu),Linux采用宏內(nèi)核架構(gòu),那么這兩種架構(gòu)到底誰更勝一籌呢?在1992年,Minix的發(fā)明者Andrew S. Tanenbaum和Linux的創(chuàng)始人Linus Benedict Torvalds為此有過一段著名的爭論。不過那時候,Linux才剛剛開始。看看兩位大佬的爭論,對我們會有所啟發(fā)。(參見:https://www.cnblogs.com/wickedboy237/archive/2013/05/12/3074009.html,郵件中是Andy Tanenbaum)
Andrew主要觀點:
(1)微內(nèi)核架構(gòu)優(yōu)于宏內(nèi)核架構(gòu)。
(2)Linux采用宏內(nèi)核架構(gòu)過時了,那是一些老的操作系統(tǒng)采用的方法,譬如UNIX, MS-DOS, VMS, MVS, OS/360, MULTICS。這是從90年代退回到70年代的一種設(shè)計方法,就像把一個正在運行著的C程序用BASIC重寫了。在1991年還寫一個宏內(nèi)核操作系統(tǒng)真是一個愚蠢的選擇。
(3)宏內(nèi)核唯一可稱道的地方就是性能,但現(xiàn)在有足夠的證據(jù)表明微內(nèi)核系統(tǒng)也能夠和宏內(nèi)核系統(tǒng)跑得一樣快(比如Rick Rashid 發(fā)表的對 Mach 3.0 和宏內(nèi)核系統(tǒng)對比的論文)。
(4)微內(nèi)核架構(gòu)的可移植性更好,沒有必要為所有的CPU都設(shè)計一個不同的宏內(nèi)核。譬如不斷涌現(xiàn)的那些Intel CPUs: 8008、8080、8086、8088、80286、80386、80486,一直到子子孫孫無窮盡。
Linus主要觀點:
(1)Linux幾乎在所有的領(lǐng)域里面都能戰(zhàn)勝Minix。
(2)Minix并沒有把微內(nèi)核的能力發(fā)揮出來,并且對于真正的在內(nèi)核中的多任務(wù)處理還有問題。
(3)事實是Linux可移植性比Minix好。可移植性的存在是為了那些不會編程的人。可移植性是個好東西,但只在有意義的前提下。嘗試著把一個操作系統(tǒng)變得可移植沒有必要,其實只要附帶一個輕便的API就足夠了(例如POSIX標(biāo)準(zhǔn))。一個操作系統(tǒng)的理念是利用硬件的特點,并且把他們隱藏在一層層的高級調(diào)用中。當(dāng)然這也使得內(nèi)核變得不大有移植性,但它也變得更容易設(shè)計。
從1992年到2020年,世間發(fā)生了太多變化:計算機性能變得越來越好,體積越來越小;Linux變得越來越流行;計算機用戶越來越年輕。由于Linux龐大的開發(fā)者和用戶群體,Linux也被開發(fā)者們移植到各類CPU架構(gòu)中,并沒有因為可移植性而受到阻礙。
7 微內(nèi)核的應(yīng)用場景
在微內(nèi)核的發(fā)展過程中,出現(xiàn)了很多的微內(nèi)核操作系統(tǒng),譬如: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等。
從理論上來講,一個操作系統(tǒng)既可以采用微內(nèi)核架構(gòu),也可以采用宏內(nèi)核架構(gòu),只要有開發(fā)人員愿意進行產(chǎn)品研發(fā)。譬如,早期的Windows NT、Mac OS等采用微內(nèi)核架構(gòu),后面因為性能問題將用戶空間的一部分功能移到內(nèi)核空間,構(gòu)成一個混合內(nèi)核。Linux則采用宏內(nèi)核架構(gòu)。
然而隨著計算機技術(shù)和操作系統(tǒng)的不斷發(fā)展,微內(nèi)核和宏內(nèi)核在不同應(yīng)用場景中還是存在著實際差別。
7.1 嵌入式系統(tǒng)
嵌入式系統(tǒng)具有資源相對有限、專用性強、實時性高等特點,因此應(yīng)用于嵌入式系統(tǒng)的操作系統(tǒng)必須滿足系統(tǒng)內(nèi)核小、支持實時多任務(wù)、具有存儲區(qū)保護功能以及可裁剪等要求。嵌入式操作系統(tǒng)負(fù)責(zé)嵌入式系統(tǒng)的全部軟硬件資源的分配、任務(wù)調(diào)度,控制和協(xié)調(diào)并發(fā)活動。它必須體現(xiàn)其所在系統(tǒng)的特征,能夠通過裝卸某些模塊來達(dá)到系統(tǒng)所要求的功能。
嵌入式系統(tǒng)的這種需求與微內(nèi)核操作系統(tǒng)的發(fā)展需求相吻合。現(xiàn)代微內(nèi)核相關(guān)技術(shù)仍在繼續(xù)發(fā)展和不斷完善中,極小化和高IPC性能這兩個基本原則仍然是設(shè)計和實現(xiàn)決定的驅(qū)動力。
對于嵌入式系統(tǒng)領(lǐng)域,很多系統(tǒng)甚至沒有硬盤存儲,它們更多地使用微內(nèi)核操作系統(tǒng)。
7.2 工控機、PC、服務(wù)器
對于工控機、PC、服務(wù)器來說,因為需要操作系統(tǒng)完成的功能很多,處理的任務(wù)非常復(fù)雜,因而更適合使用宏內(nèi)核操作系統(tǒng)。
如果強調(diào)實時性,完成較簡單功能的工控機也可以采用微內(nèi)核操作系統(tǒng),譬如VxWorks等。
再次說明,從理論上講,微內(nèi)核和宏內(nèi)核操作系統(tǒng)都可以應(yīng)用于各種場景,只是目前已經(jīng)研制的各種操作系統(tǒng)所采取的架構(gòu)導(dǎo)致了它們在具體應(yīng)用場景中有所側(cè)重。譬如,微內(nèi)核操作系統(tǒng)也可以運行于一些PC或服務(wù)器上。GNU HURD是一個從1990年就開始研制的微內(nèi)核操作系統(tǒng),運行于Mach或L4之上,目前從官網(wǎng)看到的最新版本為2019年開發(fā)的Debian版本。作為一個微內(nèi)核操作系統(tǒng),它不需要重新啟動機器就可以開發(fā)和測試新的Hurd內(nèi)核組件,運行自己的內(nèi)核組件不會干擾其他用戶,因此不需要特殊的系統(tǒng)特權(quán)。內(nèi)核擴展的機制在設(shè)計上是安全的:不可能將一個用戶的更改強加給其他用戶,除非系統(tǒng)管理員或授權(quán)用戶這樣做。但是,由于開發(fā)人員很少,進展較慢,還沒有達(dá)到完全成熟好用階段。(參見GNU HURD: GNU Hurd)
7.3 移動/物聯(lián)網(wǎng)操作系統(tǒng)
在移動、物聯(lián)網(wǎng)操作系統(tǒng)領(lǐng)域,大家一般把相關(guān)的操作系統(tǒng)歸類為微內(nèi)核操作系統(tǒng),譬如應(yīng)用在智能手機和平板電腦的Android、iOS等(也有人稱它們?yōu)榛旌蟽?nèi)核操作系統(tǒng));之前介紹的鴻蒙操作系統(tǒng),采用Zircon內(nèi)核的谷歌Fuchsia,這兩個微內(nèi)核操作系統(tǒng)可能在未來萬物互聯(lián)的物聯(lián)網(wǎng)系統(tǒng)中發(fā)揮重要作用。(參見:鴻蒙系統(tǒng)的微內(nèi)核是什么 _企業(yè)頭條 - 天眼查)
總之,對于一些專用系統(tǒng),主要是實時系統(tǒng)、嵌入式系統(tǒng)、物聯(lián)網(wǎng)系統(tǒng),微內(nèi)核的思想更有吸引力。究其原因,主要是因為通常這些系統(tǒng)都不帶磁盤,整個系統(tǒng)都必須放在EPROM中,常常受到存儲空間的限制,而所需要的服務(wù)又比較單一和簡單。所以,幾乎所有的實時系統(tǒng)、嵌入式系統(tǒng)和物聯(lián)網(wǎng)系統(tǒng)都采用微內(nèi)核。當(dāng)然,微內(nèi)核也有缺點,將這些服務(wù)的提供都放在進程層次上,再通過進程間通信(通常是報文的傳遞)提供服務(wù),勢必增加系統(tǒng)的運行開銷,降低了效率。
與微內(nèi)核相對應(yīng),其他通用式系統(tǒng)由于所需的服務(wù)面廣而量大,采用宏內(nèi)核就更為合適。
8 基于seL4微內(nèi)核的若干實驗研究
8.1 第三代微內(nèi)核seL4
seL4是一個通過形式化驗證的、代碼被證明是完全正確的操作系統(tǒng)微內(nèi)核。其實,seL4不僅是一個微內(nèi)核,它還是一個類似KVM的虛擬化管理程序(hypervisor),可以在它上面運行一個虛擬機。如下圖所示,seL4支持在虛擬機中運行其他Linux操作系統(tǒng)。
????????????????????????????????????????圖4?基于seL4的虛擬化技術(shù)
8.2 實驗1:基于中標(biāo)麒麟操作系統(tǒng)V7.0搭建seL4編譯和測試環(huán)境
實驗?zāi)康?#xff1a;本實驗是為研究如何搭建和使用seL4系統(tǒng)。
實驗環(huán)境:在搭建seL4編譯和測試環(huán)境時,選取裝有《中標(biāo)麒麟操作系統(tǒng)V7.0》操作系統(tǒng)的x86機器兩臺,一臺用于編譯seL4,另一臺用于測試seL4。
實驗步驟:
編譯環(huán)境搭建步驟如下:
(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
測試環(huán)境搭建步驟如下:
(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)準(zhǔn)備seL4內(nèi)核和應(yīng)用鏡像
從編譯環(huán)境中復(fù)制images文件夾中的kernel-x86_64-pc99和hello-world-image-x86_64-pc99文件到測試環(huán)境的/boot文件夾下
(f)重啟并選擇seL4啟動項
重啟,選擇“sel4-hello-world”啟動項,在串口中出現(xiàn)下圖畫面
????????????????????????????????????????圖5?Hello World測試程序輸出
至此,seL4的編譯環(huán)境和測試環(huán)境搭建完畢。為了進一步研究如何修改helloworld程序,可以在編譯環(huán)境中對/root/sel4-tutorials-manifest/ hello-world/src/main.c文件進行修改,如下圖所示:
????????????????????????????????????????圖6?新Hello World測試源碼
重新回到測試環(huán)境中的/root/sel4-tutorials-manifest/hello-world_ build目錄,執(zhí)行ninja clean && ninja -j 8命令,命令執(zhí)行成功后,把kernel-x86_64-pc99和hello-world-image-x86_64-pc99兩個文件復(fù)制到測試環(huán)境中/boot目錄下,重啟測試機器,選擇“sel4-hello-world”啟動項,可以看到修改后的源碼輸出,如下圖所示:
?????????????????????????????????????? 圖7?新Hello World測試效果
8.3 實驗2:基于seL4進行進程間通訊
實驗?zāi)康?#xff1a;為進一步研究seL4如何使用,需要研究如何在seL4系統(tǒng)下進行進程間通訊。
實驗環(huán)境:與實驗1相同。
實驗步驟:
我們寫了一個server端和兩個client端和CMakeLists.txt文件。
server.c代碼如下圖所示:
????????????????????????????????????????圖8?進程間通訊server源碼
client1端代碼如下圖所示:
????????????????????????????????????????圖9?進程間通訊client1源碼
client2端源碼如下圖所示:
????????????????????????????????????????圖10?進程間通訊client2源碼
CMakeLists.txt代碼如下:
????????????????????????????????????????圖11?進程間通訊CMake文件
對上述文件執(zhí)行cmake . && ninja 命令后,在把images文件夾中的kernel-x86_64-pc99和capdl-loader-image-x86_64-pc99兩個文件復(fù)制到測試環(huán)境中/boot目錄下,增加啟動項,重啟后選擇新建啟動項,則會在串口中發(fā)現(xiàn)如下圖所示輸出:
????????????????????????????????????????圖12?進程間測試效果
8.4 實驗3:seL4性能測試實驗
實驗?zāi)康?#xff1a;為了測試seL4的性能,需要對ipc、irq、schedule、signal、fault、hardware、sync、page_mapping等方面進行性能測試。
實驗環(huán)境:與實驗1相同。
實驗步驟:
使用google-benchmark測試工具庫,對每一個測試項編寫一個測試程序,如下圖所示:
????????????????????????????????????????圖13?性能測試工程樹
針對上述源碼,為每一個測試源碼編寫CMakeLists.txt文件,執(zhí)行ninja命令成功后,把images文件夾中的kernel-x86_64-pc99和sel4benchapp-image-x86_64-pc99文件復(fù)制到測試環(huán)境的/boot目錄下,增加啟動項,重啟后選擇新增加的啟動項。觀察串口輸出,抓取輸出數(shù)據(jù)起始信息如下圖所示:
????????????????????????????????????????圖14?性能測試原始數(shù)據(jù)
對原始數(shù)據(jù)進行格式化處理后,顯示信息如下所示:
????????????????????????????????????????圖15?性能測試結(jié)構(gòu)化數(shù)據(jù)
8.5 實驗4:seL4虛擬化實驗
實驗?zāi)康?#xff1a;為研究如何在sel4上運行Linux。
實驗環(huán)境:與實驗1 相同。
實驗步驟:
(a)準(zhǔn)備內(nèi)核
使用中標(biāo)麒麟安全操作系統(tǒng)V7.0系統(tǒng)中自帶內(nèi)核源碼,對內(nèi)核進行如下修改:
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)準(zhǔn)備initrd
使用中標(biāo)麒麟安全操作系統(tǒng)V7.0系統(tǒng)中自帶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)測試與驗證
執(zhí)行ninja命令成功后,把images文件夾中的kernel-x86_64-pc99和capdl-loader-image-x86_64-pc99文件復(fù)制到測試環(huán)境的/boot目錄下,增加啟動項,重啟后選擇新增加的啟動項。觀察串口輸出,可看到如下圖所示信息:
????????????????????????????????????????圖16 虛擬機啟動界面
8.6 實驗5:seL4與Linux性能對比測試
seL4官方提供了一個性能測試工具sel4bench,直接編譯運行就可以得到測試結(jié)果。我們仔細(xì)研究了sel4bench,然后花時間將每個測試用例移植到了Linux平臺下,從而得出了Linux環(huán)境下的測試結(jié)果。
seL4內(nèi)核版本:?11.0.0-dev
Linux發(fā)行版本CentOS Linux release 8.2.2004 (Core),Linux內(nèi)核版本4.18.0-193.19.1.el8_2.x86_64
seL4微內(nèi)核環(huán)境:使用seL4官方提供的測試工具sel4bench
Linux環(huán)境:將seL4官方提供的測試工具sel4bench移植到Linux內(nèi)核環(huán)境
|
| 最小時間 | 平均時間 | 最大時間 | |||
|
| 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性能測試結(jié)果
?????????????????????????????????????????圖17 seL4與Linux性能對比測試
通過以上對比測試,可以看出seL4內(nèi)核與Linux內(nèi)核綜合性能持平。
d)測試基準(zhǔn)單位
TSC(Time Stamp Counter)時間戳計數(shù)器的值:從pentium開始,很多80x86微處理器都引入TSC,一個用于時間戳計數(shù)器的64位的寄存器,它在每個時鐘信號到來時加一。當(dāng)前使用的CPU主頻為2.90GHz(2903.998MHz),所以計數(shù)器的單位大約是0.34ns
e)測試原理:
seL4微內(nèi)核和Linux內(nèi)核之間主要做了以下對比測試:
ipc Benchmarks:進程間通信機制( Inter-Process Communication,IPC)是一項影響內(nèi)核操作系統(tǒng)整體性能的關(guān)鍵因素。為了評估IPC通信的實時性能, ipc Benchmarks測試用例中通過統(tǒng)計內(nèi)核IPC通信機制下消息在內(nèi)核中的時間消耗,用以測試高實時優(yōu)先級進程的通信延時。
irquser Benchmarks:中斷處理是整個系統(tǒng)中優(yōu)先級最高的代碼,在系統(tǒng)運行過程中,中斷程序可以搶占到任意任務(wù)級別的代碼運行,而且中斷也分等級,高級別中斷搶占低級別中斷。系統(tǒng)實時性是依靠中斷機制來保證的,多任務(wù)的環(huán)境運行基礎(chǔ)也是中斷機制。所以對于衡量內(nèi)核性能,最重要的指標(biāo)就是中斷延遲。irquser Benchmarks測試用例用來測試內(nèi)核的中斷延遲。
scheduler Benchmarks:主要用于統(tǒng)計任務(wù)切換時間(task switching time),即系統(tǒng)在兩個獨立的、處于就緒態(tài)并且具有相同或不同優(yōu)先級的任務(wù)之間切換所需要的時間。切換所需的時間主要取決于保存任務(wù)上下文所用的數(shù)據(jù)結(jié)構(gòu)以及操作系統(tǒng)采用的調(diào)度算法的效率。產(chǎn)生任務(wù)切換的原因可以是資源可得,信號量的獲取等。任務(wù)切換過程增加了應(yīng)用程序的額外負(fù)荷。CPU的內(nèi)部寄存器越多,額外負(fù)荷就越重。任務(wù)切換所需要的時間取決于CPU有多少寄存器要入棧。
signal Benchmarks:信號量混洗時間是指從一個任務(wù)釋放信號量到另一個等待該信號量的任務(wù)被激活的時間延遲。在操作系統(tǒng)中,通常有許多任務(wù)同時競爭某一共享資源,基于信號量的互斥訪問保證了任一時刻只有一個任務(wù)能夠訪問公共資源。信號量混洗時間反映了與互斥有關(guān)的時間開銷,因此也是衡量內(nèi)核實時性能的一個重要指標(biāo)。
fault Benchmarks:異常是可以打斷CPU正在運行流程的一些事情,比如外部中斷、未定義指令、試圖修改只讀數(shù)據(jù)、執(zhí)行swi指令(中斷指令)等。當(dāng)這些事情發(fā)生時,CPU暫停當(dāng)前的程序,先處理異常事件,然后再繼續(xù)執(zhí)行被中斷的程序。中斷也是異常的一種。fault Benchmarks測試用例用于統(tǒng)計內(nèi)核處理異常時間消耗。
hardware Benchmarks:用于統(tǒng)計內(nèi)核執(zhí)行空系統(tǒng)調(diào)用的時間消耗。
sync Benchmarks:互斥鎖是使用簡單的加鎖的方法來控制對共享資源的存取。互斥鎖只有兩種狀態(tài),也就是上鎖和解鎖。可以把互斥鎖看作某種意義上的全局變量。在同一時刻只能有一個線程掌握某個互斥上的鎖,擁有上鎖狀態(tài)的線程能夠?qū)蚕碣Y源進行操作。若其他線程希望上鎖一個已經(jīng)上鎖了的互斥鎖,則該線程就會掛起,直到上鎖的線程釋放掉互斥鎖為止。互斥鎖使得共享資源按序在各個線程中操作。sync Benchmarks使用互斥鎖和信號量實現(xiàn)多線程間的同步,統(tǒng)計同步信號發(fā)出到所有等待線程接收到同步信號的時間消耗。
總結(jié)
以上是生活随笔為你收集整理的操作系统微内核架构研究的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js ejs for语句的第二种遍历
- 下一篇: 基于java SSM的房屋租赁系统设计和