宏内核与微内核
宏内核(monolithic)是传统的内核,UNIX和Linux都采用这样的结构。微内核是源自学术界的创新。他们的区别有很多方面,我想从进程的角度来说一下。
宏内核
- 我们都知道进程至少包括三个段,正文(程序),堆栈,数据。当进程调用系统调用的时候,进程就进入内核态,效果相当于调用了操作系统内核的一个函数,执行完返回。
但是内核态有自己的正文、堆栈、数据——其中正文(内核程序)和数据(内核数据)是与别的进程的内核态共享的,堆栈(内核栈)是进程自己的。所以内核态其实也可以是一个“进程”。 - 一个完整的进程由用户态部分与内核态部分构成。用户态部分是用户写的应用程序,内核态部分就是操作系统。
- 这两个部分是一一对应的,用户程序->(syscall)->内核态->(返回)->用户程序,这中间可以没有并发的成分,可以理解为顺序执行。
这就好像1对1的服务。 - 所以这种操作系统自己本身并不需要有(不对应任何用户程序的)“纯内核进程”,可以理解为调度器调度的对象都是用户程序,只不过用户程序有2个态。
当然现在的Linux有(不对应任何用户态进程的)内核任务,这是为了优化,并不是理论上必须的——有一些任务跟用户态程序并发执行会更有效率,或者有一些任务要收集到一定程度再整批执行。
微内核
- 微内核的用户进程可以理解为只有用户态,没有象宏内核那种与之一一对应的内核态,或者说它也有内核态,但是内核态的功能极简,只对用户提供进程间消息传递的功能。
- 操作系统运行了很多纯OS任务,比如说一个任务提供内存管理功能,一个任务提供文件系统功能等等。这些任务与用户进程一样,都是调度器调度的对象。
- 用户的系统调用被“翻译”成进程间的消息传递,需要内存,就向内存管理任务发一条消息,需要操作文件,就向文件系统任务发一条消息。
- 所以比如文件操作,就不是在用户进程的内核态完成,而是在文件系统任务中完成的。
系统启动
- 所以宏内核在系统启动的时候,只要把第一个用户进程init启动起来(init会去启动shell),系统就运作起来了。(调度器只有一个调度对象。并且没有一个调度对象叫做操作系统。)
- 而微内核的系统启动的时候,要先把各个系统任务启动起来,然后才把第一个用户进程启动起来。(调度器一开始就有多个调度对象。1个用户进程,n个操作系统任务)
操作系统内部
前面所说的是用户程序和操作系统的调用关系。操作系统内部不同模块要互相调用也不一样。
- 对于宏内核,整个操作系统就是一个程序,模块间的调用就是一个程序内部的普通函数调用。
- 对于微内核,整个操作系统被分为很多任务。文件系统要叫内存管理器做什么事,还要用进程间通信。
宏内核就是1个人,自己十项全能。微内核是n个人在合作,要交流沟通。