當(dāng)前位置:首頁(yè) > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 微內(nèi)核與宏內(nèi)核
了解Linux發(fā)展史的同學(xué)都知道,關(guān)于linux吵架史的一段佳話,就是關(guān)于內(nèi)核設(shè)計(jì)思想之爭(zhēng),這段故事在linus Tovalds的自傳中也有提到。我們都知道linux操作系統(tǒng)由Linus Tovalds模仿minix操作系統(tǒng)開(kāi)發(fā)的。
雖然Linux是受MINIX啟發(fā)而發(fā)明,但是在設(shè)計(jì)思想上采取了和原始UNIX一樣的宏內(nèi)核的設(shè)計(jì)哲學(xué),而不是MINIX采用的微內(nèi)核的設(shè)計(jì)原則。
個(gè)人認(rèn)為L(zhǎng)inus Tovalds的偉大之處不在于他發(fā)明了Linux,而是他發(fā)明了Linux且在自由軟件之父Richard Stallman精神的影響下,把Linux開(kāi)源了,成為開(kāi)源領(lǐng)域的代表。
在Linux發(fā)展之初,林納斯和安德魯于1992年在新聞組上有過(guò)一場(chǎng)精彩的理念爭(zhēng)論。Minix的作者和支持者認(rèn)為L(zhǎng)inux的宏內(nèi)核構(gòu)造是“向七十年代的大倒退”,而Linux的支持者認(rèn)為Minix本身沒(méi)有實(shí)用性。
這場(chǎng)吵架從1992年1月29日, 一直吵到1992年2月10日。帖子的導(dǎo)火索是安德魯教授發(fā)的一個(gè)帖子,名字為L(zhǎng)inux已經(jīng)過(guò)時(shí)了。帖子在1992年2月10日,一個(gè)叫尼爾斯的管理員受不了了,然后開(kāi)了一個(gè)新的論壇給linux。從此Minix和Linux,大路朝天,各走一邊。 由于當(dāng)時(shí)參與討論的好多大牛,包括Unix和創(chuàng)始人肯•湯姆森和日后成為L(zhǎng)inux內(nèi)核的二號(hào)人物大衛(wèi)•米勒,還有幾個(gè)開(kāi)發(fā)BSD內(nèi)核的人,使這場(chǎng)討論成為L(zhǎng)inux發(fā)展史上的佳話。
那究竟什么是微內(nèi)核的設(shè)計(jì)原則?什么是宏內(nèi)核的設(shè)計(jì)思想?
微內(nèi)核(Microkernelkernel)
微內(nèi)核的功能被劃分為獨(dú)立的過(guò)程,每個(gè)過(guò)程叫做一個(gè)服務(wù)器。理想情況下,只有強(qiáng)烈請(qǐng)求特權(quán)服務(wù)的服務(wù)器才運(yùn)行在特權(quán)模式下,其他服務(wù)器都運(yùn)行在用戶空間。不過(guò),所有的服務(wù)器都保持獨(dú)立并運(yùn)行在各自的地址空間。因此,就不可能像單模塊內(nèi)核那樣直接調(diào)用函數(shù),而是通過(guò)消息傳遞處理微內(nèi)核通信:系統(tǒng)采用了進(jìn)程間通信(IPC)機(jī)制,因此,各種服務(wù)器之間通過(guò)IPC機(jī)制互通消息,互換“服務(wù)”。服務(wù)器的各自獨(dú)立有效地避免了一個(gè)服務(wù)器的失效禍及另一個(gè)。
同樣,模塊化的系統(tǒng)允許一個(gè)服務(wù)器為了另一個(gè)服務(wù)器而換出。因?yàn)镮PC機(jī)制的開(kāi)銷比函數(shù)調(diào)用多,又因?yàn)闀?huì)涉及內(nèi)核空間到用戶空間的上下文切換,因此,消息傳遞需要一定的周期,而宏內(nèi)核中簡(jiǎn)單的函數(shù)調(diào)用沒(méi)有這些開(kāi)銷;诖,付之于實(shí)際的微內(nèi)核系統(tǒng)讓大部分或全部服務(wù)器位于內(nèi)核,這樣,就可以直接調(diào)用函數(shù),消除頻繁的上下文切換。Windows NT內(nèi)核和Mach(Mac OS X的組成部分)是微內(nèi)核的典型實(shí)例。不管是Windows NT還是MacOS X,都在其新近版本中不讓任何微內(nèi)核服務(wù)器運(yùn)行在用戶空間,這違背了微內(nèi)核設(shè)計(jì)的初衷。
在這些設(shè)計(jì)中,微內(nèi)核部分經(jīng)常只但是是個(gè)消息轉(zhuǎn)發(fā)站:當(dāng)系統(tǒng)調(diào)用模塊要給文檔系統(tǒng)模塊發(fā)送消息時(shí),消息直接通過(guò)內(nèi)核轉(zhuǎn)發(fā)。這種方式有助于實(shí)現(xiàn)模塊間的隔離。(某些時(shí)候,模塊也能夠直接給其他模塊傳遞消息。)在一些微內(nèi)核的設(shè)計(jì)中,更多的功能,如I/O等,也都被封裝在內(nèi)核中了。但是根本的思想還是要保持微內(nèi)核盡量小,這樣只需要把微內(nèi)核本身進(jìn)行移植就能夠完成將整個(gè)內(nèi)核移植到新的平臺(tái)上。其他模塊都只依賴于微內(nèi)核或其他模塊,并不直接直接依賴硬件。
微內(nèi)核設(shè)計(jì)的一個(gè)長(zhǎng)處是在不影響系統(tǒng)其他部分的情況下,用更高效的實(shí)現(xiàn)代替現(xiàn)有文檔系統(tǒng)模塊的工作將會(huì)更加容易。我們甚至能夠在系統(tǒng)運(yùn)行時(shí)將研發(fā)出的新系統(tǒng)模塊或需要替換現(xiàn)有模塊的模塊直接而且迅速的加入系統(tǒng)。另外一個(gè)長(zhǎng)處是無(wú)需的模塊將不會(huì)被加載到內(nèi)存中,因此微內(nèi)核就能夠更有效的利用內(nèi)存。
宏內(nèi)核(Monolithic kernel)
宏內(nèi)核是兩大陣營(yíng)中一種較為簡(jiǎn)單的設(shè)計(jì),在1980年之前,所有的內(nèi)核都設(shè)計(jì)成宏內(nèi)核。所謂宏內(nèi)核就是把它從整體上作為一個(gè)單獨(dú)的大過(guò)程來(lái)實(shí)現(xiàn),并同時(shí)運(yùn)行在一個(gè)單獨(dú)的地址空間。因此,這樣的內(nèi)核通常以單個(gè)靜態(tài)二進(jìn)制文件的形式存放于磁盤(pán)。所有內(nèi)核服務(wù)都在這樣的一個(gè)大內(nèi)核空間中運(yùn)行。內(nèi)核之間的通信是微不足道的,因?yàn)榇蠹叶歼\(yùn)行在內(nèi)核態(tài),并身處同一地址空間:內(nèi)核可以直接調(diào)用函數(shù),這與用戶空間沒(méi)有什么區(qū)別。這種模式的支持者認(rèn)為單模塊具有簡(jiǎn)單和高性能的特點(diǎn)。大多數(shù)Unix系統(tǒng)都設(shè)計(jì)為單模塊。
宏內(nèi)核的內(nèi)部又能夠被分為若干模塊(或是層次或其他),但是在運(yùn)行的時(shí)候,他是個(gè)單獨(dú)的二進(jìn)制大映象。其模塊間的通訊是通過(guò)直接調(diào)用其他模塊中的函數(shù)實(shí)現(xiàn)的,而不是消息傳遞。
宏內(nèi)核的支持者聲稱微內(nèi)核的消息傳遞開(kāi)銷引起了效率的損失。微內(nèi)核的支持者則認(rèn)為因此而增加的內(nèi)核設(shè)計(jì)的靈活性和可維護(hù)性能夠彌補(bǔ)任何損失。
為什么Linux必然是宏內(nèi)核的呢?一個(gè)方面是歷史的原因:在Linus的觀點(diǎn)看來(lái),通過(guò)把內(nèi)核以單一的方式進(jìn)行組織并在初始的空間中運(yùn)行是相當(dāng)容易的事情。這種決策避免了有關(guān)消息傳遞體系結(jié)構(gòu),計(jì)算模塊裝載方式等方面的相關(guān)工作。(內(nèi)核模塊系統(tǒng)在隨后的幾年中又進(jìn)行了不斷地改進(jìn)。)
另外一個(gè)原因是充足的研發(fā)時(shí)間的結(jié)果。Linux既沒(méi)有研發(fā)時(shí)間的限制,也沒(méi)有深受市場(chǎng)壓力的發(fā)行進(jìn)度。
任何的限制只有并但是分的對(duì)內(nèi)核的修改和擴(kuò)充。內(nèi)核的單一設(shè)計(jì)在內(nèi)部實(shí)現(xiàn)了充分的模塊化,在這種條件下的修改或增加都并不怎么困難。而且問(wèn)題還在于沒(méi)有必要為了追求尚未證實(shí)的可維護(hù)性的微小增長(zhǎng)而重寫(xiě)Linux的內(nèi)核。(Linus曾多次特別強(qiáng)調(diào)了如下的觀點(diǎn):為了這點(diǎn)利益而損耗速度是不值得的。)
假如Linux是純微內(nèi)核設(shè)計(jì),那么向其他體系結(jié)構(gòu)上的移植將會(huì)比較容易。實(shí)際上,有一些微內(nèi)核,如Mach微內(nèi)核,就已成功的證實(shí)了這種可移植性的長(zhǎng)處。實(shí)際的情況是,Linux內(nèi)核的移植雖然不是很簡(jiǎn)單,但也絕不是不可能的:大約的數(shù)字是,向一個(gè)全新的體系結(jié)構(gòu)上的典型的移植工作需要30,000到60,000行代碼,再加上不到20,000行的驅(qū)動(dòng)程式代碼。(并不是任何的移植都需要新的驅(qū)動(dòng)程式代碼。)粗略的計(jì)算一下,我估計(jì)一個(gè)典型的移植平均需要50,000行代碼。這對(duì)于一個(gè)程式員或多一個(gè)程式小組來(lái)說(shuō)是力所能及的,能夠在一年之內(nèi)完成。雖然這比微內(nèi)核的移植需要更多的代碼,但是Linux的支持者將會(huì)提出,這樣的Linux內(nèi)核移植版本比微內(nèi)核更能夠有效的利用底層硬件,因而移植過(guò)程中的額外工作是能夠從系統(tǒng)性能的提高上得到補(bǔ)償?shù)摹?/p>
這種特別設(shè)計(jì)的權(quán)衡也不是很輕松就能夠達(dá)到的,宏內(nèi)核的實(shí)現(xiàn)策略公然違背了傳統(tǒng)的看法,后者認(rèn)為微內(nèi)核是未來(lái)發(fā)展的趨勢(shì)。但是由于單一模式(大部分情況下)在Linux中運(yùn)行狀態(tài)良好,而且內(nèi)核移植相對(duì)來(lái)說(shuō)比較困難,但沒(méi)有明顯地阻礙程式員團(tuán)體的工作,他們已熱情高漲地把內(nèi)核成功的移植到了現(xiàn)存的大部分實(shí)際系統(tǒng)中,更不用說(shuō)類似掌上型電腦的一些看起來(lái)很不實(shí)際的目標(biāo)了。只要Linux的眾多特點(diǎn)仍然值得移植,新的移植版本就會(huì)不斷涌現(xiàn)。
很有趣的一點(diǎn)是,這種爭(zhēng)論經(jīng)常會(huì)令人想到前幾年CPU領(lǐng)域中RISC和CISC的斗爭(zhēng)。現(xiàn)代的成功CPU設(shè)計(jì)中包含了任何這兩種技術(shù),就像linux內(nèi)核是微內(nèi)核和單一內(nèi)核的混合產(chǎn)物相同。Linux內(nèi)核基本上是單一的,但是他并不是個(gè)純粹的集成內(nèi)核。
內(nèi)核模塊系統(tǒng)將微內(nèi)核的許多長(zhǎng)處引入到Linux的宏內(nèi)核設(shè)計(jì)中。
Linux是一個(gè)宏內(nèi)核,也就是說(shuō),Linux內(nèi)核運(yùn)行在單獨(dú)的內(nèi)核地址空間。不過(guò),Linux汲取了微內(nèi)核的精華:其引以為豪的是模塊化設(shè)計(jì)、搶占式內(nèi)核、支持內(nèi)核線程以及動(dòng)態(tài)裝載內(nèi)核模塊的能力。不僅如此,Linux還避其微內(nèi)核設(shè)計(jì)上性能損失的缺陷,讓所有事情都運(yùn)行在內(nèi)核態(tài),直接調(diào)用函數(shù),無(wú)需消息傳遞。至今,Linux是模塊化的、多線程的以及內(nèi)核本身可調(diào)度的操作系統(tǒng)。實(shí)用主義再次占了上風(fēng)。
當(dāng)Linus和其他內(nèi)核開(kāi)發(fā)者設(shè)計(jì)Linux內(nèi)核時(shí),他們并沒(méi)有完全徹底地與Unix訣別。他們充分地認(rèn)識(shí)到,不能忽視Unix的底蘊(yùn)(特別是Unix的API)。而由于Linux并沒(méi)有基于某種特定的Unix,Linus和他的伙伴們對(duì)每個(gè)特定的問(wèn)題都可以選擇已知理想的解決方案——在有些時(shí)候,當(dāng)然也可以創(chuàng)造一些新的方案。以下是對(duì)Linux內(nèi)核與Unix各種變體的內(nèi)核特點(diǎn)所作的分析比較:
•Linux支持動(dòng)態(tài)加載內(nèi)核模塊。盡管Linux內(nèi)核也是宏內(nèi)核,可是允許在需要的時(shí)候動(dòng)態(tài)地卸除和加載部分內(nèi)核代碼。
•Linux支持對(duì)稱多處理(SMP)機(jī)制,盡管許多Unix的變體也支持SMP,但傳統(tǒng)的Unix并不支持這種機(jī)制。
•Linux內(nèi)核可以搶占(preemptive)。與傳統(tǒng)的Unix不同,Linux內(nèi)核具有允許在內(nèi)核運(yùn)行的任務(wù)優(yōu)先執(zhí)行的能力。在其他各種Unix產(chǎn)品中,只有Solaris和IRIX支持搶占,但是大多數(shù)傳統(tǒng)的Unix內(nèi)核不支持搶占。
•Linux對(duì)線程支持的實(shí)現(xiàn)比較有意思:內(nèi)核并不區(qū)分線程和其他的一般進(jìn)程。對(duì)于內(nèi)核來(lái)說(shuō),所有的進(jìn)程都一樣—只不過(guò)其中的一些共享資源而已。
•Linux提供具有設(shè)備類的面向?qū)ο蟮脑O(shè)備模型、熱插拔事件,以及用戶空間的設(shè)備文件系統(tǒng)(sysfs)。
•Linux忽略了一些被認(rèn)為是設(shè)計(jì)得很拙劣的Unix特性,像STREAMS,它還忽略了那些實(shí)際上已經(jīng)根本不會(huì)使用的過(guò)時(shí)標(biāo)準(zhǔn)。
•Linux體現(xiàn)了自由這個(gè)詞的精髓。
現(xiàn)有的Linux特性集就是Linux公開(kāi)開(kāi)發(fā)模型自由發(fā)展的結(jié)果。如果一個(gè)特性沒(méi)有任何價(jià)值或者創(chuàng)意很差,沒(méi)有任何人會(huì)被迫去實(shí)現(xiàn)它。相反的,在Linux的發(fā)展過(guò)程中已經(jīng)形成了一種值得稱贊的務(wù)實(shí)態(tài)度:任何改變都要針對(duì)現(xiàn)實(shí)中確實(shí)存在的問(wèn)題,經(jīng)過(guò)完善的設(shè)計(jì)并有正確簡(jiǎn)潔的實(shí)現(xiàn)。于是,許多其他現(xiàn)代Unix系統(tǒng)包含的特性,如內(nèi)核換頁(yè)機(jī)制,都被毫不遲疑的引入進(jìn)來(lái)。
現(xiàn)狀
除了QNX和基于Mach的UNIX等個(gè)別系統(tǒng)外,幾乎全部采用宏內(nèi)核結(jié)構(gòu),例如大部分的Unix、Linux,以及Windows(微軟聲稱Windows NT是基于改良的微內(nèi)核架構(gòu)的,盡管理論界對(duì)此存有異議)。
作為微內(nèi)核代表的GNU/Hurd的緩慢的發(fā)展現(xiàn)狀,似乎也在告訴我們微內(nèi)核的優(yōu)勢(shì)是學(xué)術(shù)理論的結(jié)果,而不是從實(shí)際應(yīng)用得出的經(jīng)驗(yàn)。當(dāng)然和HURD本身的發(fā)展計(jì)劃及開(kāi)發(fā)模式也有一定關(guān)系,事實(shí)上以Hurd為代表的微內(nèi)核的設(shè)計(jì)思想,其理論上的先進(jìn)性并沒(méi)有真正的轉(zhuǎn)化為生產(chǎn)力。
Linux和HURD的現(xiàn)狀說(shuō)明了只有經(jīng)歷市場(chǎng)檢驗(yàn)的技術(shù)才具有真正的生命力,就像1995年才推出的JAVA語(yǔ)言,因?yàn)槠漤槕?yīng)了INTERNET編程的需要,現(xiàn)在已經(jīng)是主流網(wǎng)絡(luò)編程語(yǔ)言之,誕生于70年代的C語(yǔ)言,現(xiàn)在活力依舊。
Linux的蓬勃發(fā)展,似乎說(shuō)明技術(shù)實(shí)現(xiàn)上相對(duì)簡(jiǎn)單的操作系統(tǒng)更具有強(qiáng)勁的生命力,而隨著Linux不斷汲取了微內(nèi)核的設(shè)計(jì)思想說(shuō)明其并沒(méi)有局限于原有的設(shè)計(jì)思想,其在實(shí)用性層面又一次走在了前面。