我發現我一直是一個後知後覺的人。不知道是心裡的浮躁還是自己腦子小裝不下那麼多知識。不過幸好我還是一個善于思考的人。現在重新想到了要區分一下這兩個概念。也不至於稀裡糊塗的過著。瞭解了如下的問題之後更有利於對linux架構的認識。
在通常情況下,我們會想到把凡是能夠為進程服務的模組就應該放在作業系統的核心中。例如:檔案管理模組是為進程服務的,所以放在核心中;各種驅動模組是為進程服務的,所以要放在核心中;進程模組當然要放在核心中。隨著進程服務要求的增加,作業系統核心就會越來越大,隨之也將出現一系列的問題。
首先,核心是常駐記憶體的,因此大核心佔用的儲存空間就大,這樣在硬體系統比較小,儲存空間資源比較緊張的系統就不太適用;其次,是維護起來也比較困難,假設核心中的某一個服務模組進行了修改,那麼修改之後就必修對整個系統進行一次編譯,顯得極不方便;再次,就是使得處理器在核心啟動並執行時間比較長,從而不適合在速度要求比較高的場合下應用。
總之,作業系統核心大到一定程度之後,會出現一系列因為大而產生的諸多問題。為瞭解決這些問題,人們想了一系列的辦法試圖在滿足應用程式所需服務的前提下把核心做小。其中一個有效辦法是,把核心各個服務程式模組中的部分內容移到核心外面作為一個進程來看待,在核心中只保留核心服務與使用者進程的介面。核心只作為一個訊息的中轉站,這樣核心就大大變小了。這樣的核心就叫做微核心。
宏核心和微核心誰好誰壞也不是我這個菜鳥級水平的人能夠評判的。但是如果我把這些代表請上來的話也許大家會在內心對他們有個自己的評價。
微核心系統有WindowNT,Minix,Mac,etc.宏核心的系統有Unix,Linux,etc。其中有個有意思的現象:Unix是宏核心,而Mac卻是微核心。另外廢話一句:minix和linux也都沒說服對方。
兩個系統的核心是通過進程的建立FORK的實現比較,因為進程的建立涉及到系統調用,記憶體管理,檔案管理等系統的主要方面。因此可以通過比較fork來大致瞭解一下核心的差別。
微核心的代表Minix
在Minix中,作業系統的核心,記憶體管理,系統管理都有自己的進程表,每個部分的表包含了自己需要的域。表是精確對應的,為了保持同步,在進程建立和結束時,這三個部分都要更新自己的表。由記憶體管理器協調。
系統啟動後,kernel,mm,fs系統進程在各自的空間運行main()函數迴圈等待訊息
while (true)
{
……
receive(ANY,&mm_in);
……
}
當一個fork傳給mm的main(),main()調用do_fork(),do_fork()函數把父i函數的data、segment和stack segment創造了一個完全重複項給子進程,並把父進程的text segment與子進程共用,然後在mm的進程表mproc[ ]中添加新進程,並設定各屬性。添加完後發送訊息給kernel(sys_fork(...))和fs(tell_fs(...)),kernel中的函數sys_task()接收到系統訊息,調用do_fork( message *m_ptr),拷貝父進程的proc
結構體到子進程,並設定進程在核心進程表中的屬性。tell_fs( )是記憶體管理器與檔案系統之間的介面。tell_fs(...)調用_taskcall(...),檔案管理工具接收到fork系統訊息,調用do_fork( )函數,拷貝父進程的 fproc 結構體到子進程並設定進程在檔案進程表中的屬性。這樣整個進程的屬性就設定完成。
在Minix建立新進程的過程中,可以看到一個很大特點,就是整個系統按照功能分成幾個部分,各模組之間利用訊息機制通訊,調用其他模組的函數必須通過目標模組的守護進程調用完成。
宏核心的代表:linux
在linux中,進程的結構如下:
struct task_struct{
pid_t pid;
pid_t pgrp;
...
/*filesystem information*/
struct fs_struct *fs;
/*memory managment info */
struct mm_struct *mm;
...
};
在linux進程的結構定義中,task_struct包含了所有的資訊,包括進程的記憶體情況,檔案系統情況。在建立進程時,系統調用sys_fork調用do_fork(...)函數。
int do_fork(unsigned long clong_flags,...)
{
struct task_struct *p;
p->pid = get_pid(clone_flags);
....
/*copy all the process information*/
copy_files(clone_flags,p);
copy_fs(clone_flags,p);
copy_mm(nr,clone_flags,p);
...
}
在建立進程時,do_fork函數把所有的工作完成,分配pid。。。號,拷貝父進程資料區段,堆棧段,等等。linux的進程建立過程是一個完整的過程,直接調用其他模組的函數,而不是訊息傳遞。
Minix與Linux建立新進程的過程比較可以看出兩者之間的區別,Minix是建立在分模組之上的,模組之間以資訊傳遞聯絡。Linux內部是分模組的,但是在啟動並執行時候,它是一個獨立的二進位大映像,其模組之間的通訊是直接調用其他模組中的函數實現的。宏核心與微核心的區別也就在此。微核心是一個資訊中轉站,自身完成的功能很少,主要是傳遞一個模組對另一個模組的功能請求,而宏核心則是一個大主管,把記憶體管理,檔案管理等等一股腦全部接管。
從理論上來看,微核心的思想更好一些,微核心把系統分為各個小的功能模組,降低了設計難度,系統的維護與修改也容易,但是通訊帶來的損失效率是個問題。宏核心的功能塊之間的耦合度太高造成修改與維護的代價太高,不過在目前的linux裡面還不是太大的問題,因為目前linux還不算太複雜,宏核心因為是直接調用的,所以效率比較高。