Linux與Windows內核Compare

(~.~從win切換到linux,剛開始總有那麼點不舒服。。) html

本文轉自:http://www.2cto.com/os/201203/121539.html linux


我以爲兩者最大的區別在於WINDOWS是個商業軟件,而LINUX是開源軟件。商業軟件的好處是能夠集中一大批人力物力作一件事情。容易統一,兼容(由於客戶需求)。而開源的好處在於靈活,開放。
 
在下面的比較中,我通常先介紹下WINDOWS的,而後再介紹LINUX的。
 
一、觀念:商業VS 開源
 
WINDOWS是個商業軟件,它的源碼是保密的. 固然,其餘非MS的人也仍是有機會看到源碼的. 若是你和MS 簽定一個NDA(NON DISCLOSURE AGREEMENT),那麼你也有可能拿到WINDOWS代碼.
 
言規正傳,我以爲商業也仍是有好處的。好比兼容性好,我之前用WDM寫一個驅動,最多改下編譯選項就能夠在WIN 98, WIN 2K, WIN XP下運行。十分方便。而若是換成LINUX,那麼你只好祈禱不一樣的內核版本之間沒改那些你用到的頭文件,函數接口。不然就要改代碼了。
 
同時,開源的好處是適合學習,十分靈活。我以爲LINUX十分適合學校,學生。由於開源,當你發現不明白的地方的時候,能夠直接去看源碼(還記得RTFS? )。看不懂還能夠到論壇上問。而對於WINDOWS,你想了解它的內部機制就只好GOOGLE,而後祈禱了。比較好的一個資源是MSDN下面的一個雜誌,其中有一個主題叫UNDER THE HOOD, 或者搜搜BUGSLAYER 也能夠。這2個專題的做者Matt Pietrek和John Robbins都是大牛級的人物。
 
順便說下UNDER THE HOOD 這個名字自己。之前一直不太理解,由於查字典的話,HOOD 的意思也就是個蓋子。那麼蓋子下面有啥呢?爲啥要看蓋子下面呢?
 
來到美國以後,我漸漸明白了。HOOD 在這裏應該理解爲汽車的引擎蓋。在美國,汽車是很廣泛的。若是你開車,可是歷來沒打開過引擎蓋,那麼說明你只會用,而不瞭解汽車內部。那麼若是你打開蓋子看看呢?就能夠看到不少內部細節,好比發動機啥的了。
 
在美國這個汽車王國,不少軟件術語和汽車有關,由於人們平常生活中對汽車也很瞭解。好比「引擎」這個詞,之前玩3D遊戲的時候,常會看到介紹說,本遊戲採用了最新的3D引擎。啥意思呢?就是遊戲最核心的部分(汽車引擎)已經升級了。不是隻把外面的人物形象改了下而已。
 
另外,開源軟件也常常用汽車來類比。開源意外着你買了車(軟件)後,能夠隨便拿到一個修理廠去修。也就是什麼人均可以改,只要他懂。而COPY RIGHT 軟件呢,就是你買了車,可是引擎蓋子是鎖着的,壞了只能去生產廠家修,其餘人修不了。若是萬一輩子產廠家不想修或者不會修呢?那你就只能認命了。
 
扯得有點遠了,打住。
 
1.一、發佈:2進制VS 源碼
 
這裏主要討論下WINDOWS和LINUX在發佈程序採用的不一樣的形式和觀念,這些和前面的商業仍是開源的基本觀念是聯繫在一塊兒的。
 
在WINDOWS 世界,安裝程序幾乎所有都是以二進制形式發佈的。也就是說,用戶下載了一個程序,而後雙擊,一路NEXT,NEXT,NEXT就能夠了。這個方法很適合初學者。在LINUX世界也有相似的機制,好比YUM, APT-GET 等。不過YUM和APT-GET都是比較晚纔出現的,在那以前,在LINUX世界安裝程序要更麻煩些。
 
有的時候,LINUX的YUM, APT-GET還不夠用。好比有的人寫的一個小軟件,沒有放到這些大的公共的庫裏面。這時,你就會發現他們通常提供一個或者一堆源文件,而後須要使用者本身下載,「編譯」,安裝。這也就是LINUX世界常見的源代碼發佈的形式。
 
一開始的時候,十分不習慣LINUX的這種發佈形式。用慣了WINDOWS的雙擊安裝,總以爲LINUX的安裝很麻煩,又要本身./CONFIGURE, MAKE, MAKE INSTALL. 萬一這個軟件又依賴於其餘的庫,那麼又要本身去找那些庫,萬一那些庫又依賴其餘的庫...... 另外,各類庫的版本也是一個問題,萬一不兼容,那麼又要找一個兼容的。
 
爲何LINUX世界這麼多源代碼發佈呢?爲何WINDOWS世界流行2進制文件發佈,而不是源代碼呢?關於後者,很好解釋,由於WINDOWS那邊不少源代碼都是商業祕密,是不公開的。同時,WINDOWS的程序用到的那些庫在通常的系統裏都裝好了。因此2進制發佈可行,也十分方便。
 
關於前一個問題,我以爲源代碼發佈的一個好處是能夠在編譯的時候進行一些優化和設置。好比一樣的代碼,在32或64位平臺下編譯的時候能夠進行適當的優化。另外,用戶也能夠在編譯的時候設置一些開關,這樣在編譯期間的優化通常要好於運行時間的優化。
 
不過源代碼發佈的一個壞處就是對使用者要求較高。若是運行configue,make命令順利的話還好。若是萬一不順利,要本身改下頭文件啥的,無疑是通常的使用者沒法作到的。另外庫之間的依賴關係若是是人手工處理的話也十分麻煩。好在LINUX世界後來有了YUM APT-GET之類的包管理系統。大多數軟件均可以很方便的安裝了。
 
二、進程及其建立CreateProcess VS fork+execv
 
在WINDOWS世界,建立進程最經常使用的WIN 32 API 是CreateProcess以及相關函數。這個函數須要一堆參數(WINDOWS API 的特色),不過不少參數能夠簡單的用NULL, TRUE OR FALSE來表示。另外,你直接告訴它要執行的是哪一個文件。
 
到了LINUX世界,我模糊的知道fork是用來建立一個新進程的。可是當我看fork的函數說明的時候,呆住了。由於fork不須要任何參數。習慣了CreateProcess 的10來個參數,忽然換成一個不要任何參數的函數,感受很奇妙。一方面以爲彷佛事情簡單了不少,不用去把10來個參數的每一個意思都搞明白。另一方面又很疑惑,我怎麼告訴它我要執行某個文件呢?
 
後來才知道,LINUX中的進程的含義和WINDOWS中是不同的。LINUX中的進程自己是能夠執行的。而WINDOWS中,進程只是表示一個資源的擁有體,是不能執行的。要執行的話,必定須要一個線程。這也部分解釋了爲何CreateProcess中爲啥必定要傳入要執行的文件的名字。
 
而fork的含義是把進程自己CLONE一個新的出來。也就是說,FORK以後,父進程和子進程都執行一樣的一段代碼。若是想區分的話,能夠根據FORK的返回值來區分。引用一段fork的說明:
 
On success, the PID of the child process is returned in the parent's thread of execution, and a 0 is returned in the child's thread of execution.
 
同時在LINUX程序中,常見的寫法以下:
int pid;
pid = fork();
switch (pid)
{
  case 0: //I am the child
 
  ;
  case -1: //failed.
 
  ;
  default: //I am the parent
 
 
}
 
 
爲何要這樣設計呢?由於LINUX的設計目標之一就是應用於服務器。這種狀況下,一個SERVICE可能會啓動不少進程(線程)來服務不一樣的CLIENT. 因此FORK設計成快速複製父進程。子進程直接使用父親的地址空間,只有子進程加載一個新的可執行文件的時候才建立本身的地址空間。
 
這樣節省了建立地址空間這個龐大的開銷,使得LINUX的進程建立十分快。不過實際上,這裏的進程相對於WINDOWS中的線程,因此同WINDOWS中的線程建立相比,兩者的開銷應該差很少。
 
那麼如何才能讓新的進程加載一個可執行文件呢,這時就要用execv以及相關函數了。因此LINUX中,代替CreateProcess()的函數是fork+execv
 
三、文件格式PE VS ELF
 
WINDOWS中的可執行文件格式是PE。到了LINUX就變成了ELF。2者有類似的地方,好比都分紅幾個SECTION,包含代碼段,數據段等。可是2個又不同。使得從一個轉到另一個的人不得不從新學習下。有點象在國內開慣了車的人,到了香港或者英國開車,雖然也是4個輪子一個方向盤,可是一個靠左行駛,一個靠右。老是須要些時間來習慣。
 
那麼爲啥LINUX不能和WINDOWS用一樣的文件格式呢?我以爲可能的緣由有幾個。首先多是2個差很少同時在設計的,彼此不知道對方的存在。因此也無法一方壓倒一方。另一個可能的緣由是PE格式最開始仍是保密的(後來MS公開了PE的SPEC),因此即便LINUX想直接用PE都不行。
 
順便說下,MS OFFICE 的文檔格式之前也是保密的,直到最近(好像是2008年)才公開。但願這可使得OPEN OFFICE的開發順利不少。
 
四、內核API:固定VS 非固定
 
WINDOWS內核有一套固定的API,並且向後兼容。這使得WINDOWS 驅動的開發人員在不一樣版本之間移植時變得很容易。好比我用WDM (WINDOWS DEVICE MODEL) 開發一個驅動,最多改下編譯選項就能夠在WIN 98, 2K, XP, 2003 下使用。VISTA 我以爲也許均可以。
 
而LINUX沒有固定的內核API。2.4版本的內核模塊在2.6幾乎很大多是不能兼容的。要移植的話,不僅是改個編譯選項,而是要改一堆的頭文件和實現文件等。而麻煩的是,即便都是2.6內核,不一樣的小版本之間也有些不一樣。若是你的內核模塊恰好用到了變化的部分,那麼也只好從新學習,而後改本身的頭文件或者實現文件了。
 
固定內核API的好處是兼容性好,壞處是包袱比較大,不得不隨時支持老的,也許是過期的接口。好比WINDOWS內核裏有WDM 一套API, 可是又有網卡專用的NDIS 一套API. 實際上2套API的不少設計目標是重合的。那麼爲何有2個呢?由於NDIS是先出來的,爲了兼容性,必定要支持。而NDIS又只針對網卡,因此又出來了WDM。
 
不固定API的壞處是升級很麻煩,外圍的內核模塊維護者很辛苦。好處是能夠隨時採用更新的設計。
 
5. WINDOWS與LINUX中的中斷處理比較
 
5.1不一樣之處:
 
在WINDOWS中,有一個IRQL (注意不是IRQ)的概念。最先的時候,我覺得是CPU設計裏就包括了這個東東。後來看INTEL CPU手冊,發現彷佛沒有。最近又看了一遍WINDOWS INTERALS 4TH。感受這個東西應該是包括在PIC OR APIC裏面的(關於APIC,能夠看我之前的帖子)。對於X86-32,硬件設備的IRQ於IRQL之間的關係是:IRQL= 27-IRQ。引入IRQL的動機彷佛是這樣的:當CPU運行在低IRQL時,若是來了一個高IRQL對應的中斷,那麼低的中斷的ISR是會被高的ISR搶過去的。就是說低的ISR又被一個更高級的ISR中斷了。這樣的好處是優先級高的ISR能夠更快的獲得響應。
 
另外,在具體實現中,因爲操做PIC OR APCI改IRQL是比較費時的,因此WINDOWS是儘可能不去直接操做硬件,而是等到萬不得已的時候才改。
 
在LINUX中,彷佛沒有相似IRQL這樣的觀念。就我目前看過的書和代碼來看,LINUX中的ISR或者是KERNLE最可能是操做下CPU上的中斷標誌位(IF)來開啓或者關閉中斷。也就是說,要麼中斷全開,要麼全關。
 
從這一點來看,LINUX在這部分的設計上比WINDOWS簡單。
 
5.2 類似之處:
 
WINDOWS和LINUX彷佛都把中斷分紅了2部分。在LINUX中叫ISR(仍是其餘?)和BOTTOM HALF。而WINODWS中,DPC(Deferred Procedure Calls)和APC(Asynchronous Procedure Calls)就很是相似BOTTOM HALF。兩者把中斷分紅兩部分的動機是差很少的。都是爲了把ISR搞得越快越好。LINUX中,在ISR裏通常關中斷,因此時間太長的話,其餘中斷就得不到響應。WINDOWS中,ISR跑在一個很高的IRQL裏面,一樣會阻塞其餘IRQL比較低的任務。
 
LINUX中的BOTTOM HALF 又能夠分爲TASKLET 和SOFIRQ。兩者的主要區別是複雜度和併發性(CONCURRENCY)。下面COPY自<UNDERSTANDING LINUX NETWORK INTERNALS>一書。
Tasklet: Only one instance of each tasklet can run at any time. Different tasklets can run concurrently on different CPUs.
Softirq: Only one instance of each softirq can run at the same time on a CPU. However, the same softirq can run on different CPUs concurrentlyOnly one instance of each softirq can run at the same time on a CPU. However, the same softirq can run on different CPUs concurrently.
 
WINDOWS中的DPC有點相似TASKLET和SOFTIRQ。DPC是系統範圍內的,而且運行在DPC IRQL。是一個相似中斷上下文的環境(INTERRUPT CONTEXT)。APC和DPC的區別是運行在更低級別的APC IRQL。另外,APC是針對每個線程的。執行在某個線程環境中。主要目的也是把一部分事情放到之後去執行。APC又分爲KERNEL APC 和USER APC。APC這個觀念在LINUX中彷佛沒有相似的?至少我還沒想到。
 
5.3 參考文獻:
1.        WINDOWS INTERALS 4TH
2.        UNDERSTANDING LINUX NETWORK INTERNALS, 2005
 
 
UNICODE VS ASCII
KERNEL 4M/4K MIXED PAGE VS 4K PAGE
FS SEGMENT VS NO FS
GDI VS XWINDOWS
IRP VS FUNCTION POINTER
 
 
六、註冊表VS 普通文件
     windows下的註冊表在內核模式下的全部進程及線程均可以訪問到,均可以修改,很方便對系統配置的修改。而linux下沒有註冊表的概念,系統配置必須在鏡像產生前就配置好了(makeconfig)。所以相比之下,Linux不適合動態地定製系統功能,而windows適合快速修改配置,實現系統的功能定製。
 
2、一致的地方
 
WINDOWS和LINUX不少地方又很類似。我以爲基本緣由有2個。一個是2者都繼續了一部分UNIX中的東西。另一個是2者都主要基於X86體系結構。固然2者也都支持不少其餘體系結構,特別是LINUX。
 
我下面主要討論在X86體系下一致的地方。
 
一、觀念
一切皆文件。
 
二、內核映射:2G:2G, 1G:3G. 線性映射
 
三、SOCKET
 
四、DEVICE DRIVER OR KERNEL MODULE
 
五、系統調用,中斷 windows

相關文章
相關標籤/搜索