微內核與宏內核比較
內核按照體系結構分為兩類:微內核(microkernel)與宏內核(macrokernel). 微內核的系統有WindowNT,Minix,Mach,etc.宏內核的系統有Unix,Linux,etc.通過比較Minix和Linux來比較微內核和宏內核是很有意思的,因為當年兩個系統的創始人對兩種內核的優劣有過爭論.
兩個系統的內核是通過進程的創建FORK的實現來比較,因為進程的創建涉及到系統調用,內存管理,文件管理等系統的主要方面.因此通過比較FORK的實現可以大致看到內核的差別.
微內核的代表:Minix
在Minix中,操作系統的內核,內存管理,系統管理都有自己的進程表,每個部分的表包含了自己需要的域。表象是精確對應的,為了保持同步,在進程創建或結束時,這三個部分都要更新各自的表。
由內存管理器協調。
系統啟動后,kernel,mm,fs系統進程在各自的空間運行main()函數循環等待消息
While(TRUE)
{…
receive(ANY,&mm_in);
…}
當一個FORK傳給mm’main(),main()調用do_fork(),do_fork()函數把父進程的data segment和stack segment創造了一個精確副本給子進程,並把父進程的text segment 與子進程共享,然后在mm的進程表mproc[]中添加新進程,並設置各屬性。添加完后發送消息給kernel(sys_fork(…))和 fs(tell_fs(…)).,kernel中的函數sys_task()接收到系統信息,調用do_fork(message * m_ptr),copy parent’proc struct to child.並設置進程在內核進程表中的屬性。tell_fs()是內存管理器與文件系統之間的接口,tell_fs(…)調用 _taskcall(…),文件管理器接收到FORK系統消息,調用do_fork()函數,copy parent’fproc struct to child.並設置進程在文件進程表中的屬性。這樣整個進程的屬性就設置完成.
在Minix創建新進程的過程中,可以看到一個很大特點,就是整個系統按功能分成幾個部分,各模塊之間利用消息機制通信,調用其他模塊的函數必須通過目標模塊的守護進程調用.
宏內核的代表:Linux
在Linux中,進程的結構如下:
Struct task_struct{
pid_t pid;
pid_t pgrp;
…
/* filesystem information */
struct fs_struct *fs;
/* memory management 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目前還不算太復雜,宏內核因為是直接調用,所以效率是比較高的。