宏內核與微內核,Linux內核與Unix內核

操作系統內核可能是微內核,也可能是單內核(後者有時稱之爲宏內核Macrokernel)。按照類似封裝的形式,這些術語定義如下:

單內核:也稱爲宏內核。將內核從整體上作爲一個大過程實現,並同時運行在一個單獨的地址空間。所有的內核服務都在一個地址空間運行,相互之間直接調用函數,簡單高效。微內核:功能被劃分成獨立的過程,過程間通過IPC進行通信。模塊化程度高,一個服務失效不會影響另外一個服務。Linux是一個單內核結構,同時又吸收了微內核的優點:模塊化設計,支持動態裝載內核模塊。Linux還避免了微內核設計上的缺陷,讓一切都運行在內核態,直接調用函數,無需消息傳遞。

Linux大部分都是單內核的。

微內核(Microkernel kernel)――在微內核中,大部分內核都作爲單獨的進程在特權狀態下運行,他們通過消息傳遞進行通訊。在典型情況下,每個概念模塊都有一個進程。因此,假如在設計中有一個系統調用模塊,那麼就必然有一個相應的進程來接收系統調用,並和能夠執行系統調用的其他進程(或模塊)通訊以完成所需任務。

在這些設計中,微內核部分經常只但是是個消息轉發站:當系統調用模塊要給文檔系統模塊發送消息時,消息直接通過內核轉發。這種方式有助於實現模塊間的隔離。(某些時候,模塊也能夠直接給其他模塊傳遞消息。)在一些微內核的設計中,更多的功能,如I/O等,也都被封裝在內核中了。但是最根本的思想還是要保持微內核儘量小,這樣只需要把微內核本身進行移植就能夠完成將整個內核移植到新的平臺上。其他模塊都只依賴於微內核或其他模塊,並不直接直接依賴硬件。

微內核設計的一個長處是在不影響系統其他部分的情況下,用更高效的實現代替現有文檔系統模塊的工作將會更加容易。我們甚至能夠在系統運行時將研發出的新系統模塊或需要替換現有模塊的模塊直接而且迅速的加入系統。另外一個長處是無需的模塊將不會被加載到內存中,因此微內核就能夠更有效的利用內存。

-----------------------------------------------------------------------------------------------------------------------------------------------

單內核(Monolithic kernel)――單內核是個很大的進程。他的內部又能夠被分爲若干模塊(或是層次或其他)。但是在運行的時候,他是個單獨的二進制大映象。其模塊間的通訊是通過直接調用其他模塊中的函數實現的,而不是消息傳遞。

單內核的支持者聲稱微內核的消息傳遞開銷引起了效率的損失。微內核的支持者則認爲因此而增加的內核設計的靈活性和可維護性能夠彌補任何損失。

我並不想討論這些問題,但必須說明很有趣的一點是,這種爭論經常會令人想到前幾年CPU領域中RISC和CISC的鬥爭。現代的成功CPU設計中包含了任何這兩種技術,就像Linux內核是微內核和單一內核的混合產物相同。Linux內核基本上是單一的,但是他並不是個純粹的集成內核。前面一章所介紹的內核模塊系統將微內核的許多長處引入到Linux的單內核設計中。(順便提一下,我考慮過一種有趣的情況,就是Linux的內核模塊系統能夠將系統內核轉化成爲簡單的不傳遞消息的微內核設計。雖然我並不贊成,但是他仍然是個有趣的想法。)

爲什麼Linux必然是單內核的呢?一個方面是歷史的原因:在Linus的觀點看來,通過把內核以單一的方式進行組織並在最初始的空間中運行是相當容易的事情。這種決策避免了有關消息傳遞體系結構,計算模塊裝載方式等方面的相關工作。(內核模塊系統在隨後的幾年中又進行了不斷地改進。)

另外一個原因是充足的研發時間的結果。Linux既沒有研發時間的限制,也沒有深受市場壓力的發行進度。任何的限制只有並但是分的對內核的修改和擴充。內核的單一設計在內部實現了充分的模塊化,在這種條件下的修改或增加都並不怎麼困難。而且問題還在於沒有必要爲了追求尚未證實的可維護性的微小增長而重寫Linux的內核。(Linus曾多次特別強調了如下的觀點:爲了這點利益而損耗速度是不值得的。)後面章節中的部分內容將周詳的重新考慮充足研發時間的效果。

假如Linux是純微內核設計,那麼向其他體系結構上的移植將會比較容易。實際上,有一些微內核,如Mach微內核,就已成功的證實了這種可移植性的長處。實際的情況是,Linux內核的移植雖然不是很簡單,但也絕不是不可能的:大約的數字是,向一個全新的體系結構上的典型的移植工作需要 30,000到 60,000行代碼,再加上不到20,000行的驅動程式代碼。(並不是任何的移植都需要新的驅動程式代碼。)粗略的計算一下,我估計一個典型的移植平均需要50,000行代碼。這對於一個程式員或最多一個程式小組來說是力所能及的,能夠在一年之內完成。雖然這比微內核的移植需要更多的代碼,但是 Linux的支持者將會提出,這樣的Linux內核移植版本比微內核更能夠有效的利用底層硬件,因而移植過程中的額外工作是能夠從系統性能的提高上得到補償的。

這種特別設計的權衡也不是很輕鬆就能夠達到的,單內核的實現策略公然違背了傳統的看法,後者認爲微內核是未來發展的趨勢。但是由於單一模式(大部分情況下)在Linux中運行狀態良好,而且內核移植相對來說比較困難,但沒有明顯地阻礙程式員團體的工作,他們已熱情高漲地把內核成功的移植到了現存的大部分實際系統中,更不用說類似掌上型電腦的一些看起來很不實際的目標了。只要Linux的衆多特點仍然值得移植,新的移植版本就會不斷涌現。

所有的Unix內核都同宗同源,並且提供相同的API,現代的Unix內核存在許多設計上的相似之處。Unix內核幾乎毫無例外的都是一個不可分割的靜態可執行塊(文件)。也就是說,它們必須以完整、單獨的可執行塊的形式在一個單獨的地址空間中運行。

Unix內核幾乎都需要硬件系統提供頁機制以管理內存。這種頁機制可以加強內存空間的保護,並保證每個進程都可以運行於不同的虛地址空間上。

單內核與微內核設計之比較

操作系統內核可以分爲兩大設計陣營:單內核和微內核(第三陣營外內核,主要用在科研系統中,但也逐漸在現實世界中壯大起來)。

單內核是兩大陣營中一種較爲簡單的設計,在1980年之前,所有的內核都設計成單內核。所謂單內核就是把它從整體上作爲一個單獨的大過程來實現,並同時運行在一個單獨的地址空間。因此,這樣的內核通常以單個靜態二進制文件的形式存放於磁盤。所有內核服務都在這樣的一個大內核空間中運行。內核之間的通信是微不足道的,因爲大家都運行在內核態,並身處同一地址空間:內核可以直接調用函數,這與用戶空間沒有什麼區別。這種模式的支持者認爲單模塊具有簡單和高性能的特點。大多數Unix系統都設計爲單模塊。

另一方面,微內核並不作爲一個單獨的大過程來實現。相反,微內核的功能被劃分爲獨立的過程,每個過程叫做一個服務器。理想情況下,只有強烈請求特權服務的服務器才運行在特權模式下,其他服務器都運行在用戶空間。不過,所有的服務器都保持獨立並運行在各自的地址空間。因此,就不可能像單模塊內核那樣直接調用函數,而是通過消息傳遞處理微內核通信:系統採用了進程間通信(IPC)機制,因此,各種服務器之間通過IPC機制互通消息,互換“服務”。服務器的各自獨立有效地避免了一個服務器的失效禍及另一個。

同樣,模塊化的系統允許一個服務器爲了另一個服務器而換出。因爲IPC機制的開銷比函數調用多,又因爲會涉及內核空間到用戶空間的上下文切換,因此,消息傳遞需要一定的週期,而單內核中簡單的函數調用沒有這些開銷。基於此,付之於實際的微內核系統讓大部分或全部服務器位於內核,這樣,就可以直接調用函數,消除頻繁的上下文切換。Windows NT內核和Mach(Mac OS X的組成部分)是微內核的典型實例。不管是Windows NT還是Mac OS X,都在其新近版本中不讓任何微內核服務器運行在用戶空間,這違背了微內核設計的初衷。

Linux是一個單內核,也就是說,Linux內核運行在單獨的內核地址空間。不過,Linux汲取了微內核的精華:其引以爲豪的是模塊化設計、搶佔式內核、支持內核線程以及動態裝載內核模塊的能力。不僅如此,Linux還避其微內核設計上性能損失的缺陷,讓所有事情都運行在內核態,直接調用函數,無需消息傳遞。至今,Linux是模塊化的、多線程的以及內核本身可調度的操作系統。實用主義再次佔了上風。

當Linus和其他內核開發者設計Linux內核時,他們並沒有完全徹底地與Unix訣別。他們充分地認識到,不能忽視Unix的底蘊(特別是 Unix的 API)。而由於Linux並沒有基於某種特定的Unix,Linus和他的夥伴們對每個特定的問題都可以選擇已知最理想的解決方案—在有些時候,當然也可以創造一些新的方案。以下是對Linux內核與Unix各種變體的內核特點所作的分析比較:

·Linux支持動態加載內核模塊。儘管Linux內核也是單內核,可是允許在需要的時候動態地卸除和加載部分內核代碼。

·Linux支持對稱多處理(SMP)機制,儘管許多Unix的變體也支持SMP,但傳統的Unix並不支持這種機制。

·Linux內核可以搶佔(preemptive)。與傳統的Unix不同,Linux內核具有允許在內核運行的任務優先執行的能力。在其他各種Unix產品中,只有Solaris和IRIX支持搶佔,但是大多數傳統的Unix內核不支持搶佔。

·Linux對線程支持的實現比較有意思:內核並不區分線程和其他的一般進程。對於內核來說,所有的進程都一樣—只不過其中的一些共享資源而已。

·Linux提供具有設備類的面向對象的設備模型、熱插拔事件,以及用戶空間的設備文件系統(sysfs)。

·Linux忽略了一些被認爲是設計得很拙劣的Unix特性,像STREAMS,它還忽略了那些實際上已經根本不會使用的過時標準。

·Linux體現了自由這個詞的精髓。現有的Linux特性集就是Linux公開開發模型自由發展的結果。如果一個特性沒有任何價值或者創意很差,沒有任何人會被迫去實現它。相反的,在Linux的發展過程中已經形成了一種值得稱讚的務實態度:任何改變都要針對現實中確實存在的問題,經過完善的設計並有正確簡潔的實現。於是,許多其他現代Unix系統包含的特性,如內核換頁機制,都被毫不遲疑的引入進來。

不管Linux和Unix有多大的不同,它身上都深深地打上了Unix烙印

------------------------------------------------------------------------------------------------------------------------------------------

以下是摘自wiki的一段關於宏內核的介紹


 

宏內核有時也稱單內核,原文爲英文的Monolithic kernel。

宏內核是操作系統內核架構的一種,此架構的特性是整個內核程序都是以內核空間(Kernel Space)的身份及監管者模式(Supervisor Mode)來運行。相對於其他類型的操作系統架構,如微內核架構或混內核架構等,這些內核會定義出一個高級的虛擬接口,由該接口來涵蓋描述整個計算機硬件,這些描述會集合成一組硬件描述用詞,有時還會附加一些系統調用,如此可以用一個或多個模塊來實現各種操作系統服務,如進程管理、共時(Concurrency)控制、存儲器管理等。

即使有的宏內核將其運作從整體性運作拆分成幾個服務模塊,並讓各模塊各自運作,其操作系統的代碼依然是高度緊密的,很難修改成其他類型的操作系統架構。此外,所有的模塊也都在同一塊尋址空間內運行,倘若某個模塊有錯誤、瑕疵(Bug),運行時就會損及整個操作系統運作。反過來,如果宏內核架構的操作系統在開發設計時相當完善,並經測試驗證後具有高度可靠性,則操作系統內的各軟件組件因具有高度緊密性,如此在系統的低級運作上將格外有效率。

 

可加載性的模塊

 

現在多數採行宏內核架構設計的操作系統,如OpenVMS、Linux、FreeBSD、以及Solaris等,都已經能在運作運行階段中,以動態方式來加載(Load)、卸載(Unload)可運行的模塊,不過這些模塊是屬於二進制代碼的層次,或稱鏡像層次,而非內核架構的層次。即使宏內核進行模塊化轉化,也不會與微內核或混內核架構的內核產生區分上的混淆,因爲微內核、混內核的模塊是屬於系統架構的層次。

就實務上,動態加載/卸載模塊的作法,等於是用一種較簡易的方式來彈性管控運行中的操作系統內核,若沒有動態加載/卸載機制,操作系統的內核想要進行任何的調整、變換,都必須重新開機才能達成。因此模塊化是必然且必要的,如此才能讓內核功效輕鬆地擴展、延伸,此外也能適時減輕硬件的運行運作負擔。

另外,有些整塊性操作系統爲了讓它的內核空間達到最小化,也會運用動態加載/卸載機制來達成此一目標。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章