1. 程式人生 > >返璞歸真系列——————微核心與巨集核心

返璞歸真系列——————微核心與巨集核心

        我發現我一直是一個後知後覺的人。不知道是心裡的浮躁還是自己腦子小裝不下那麼多知識。不過幸好我還是一個善於思考的人。現在重新想到了要區分一下這兩個概念。也不至於稀裡糊塗的過著。瞭解瞭如下的問題之後更有利於對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還不算太複雜,巨集核心因為是直接呼叫的,所以效率比較高。