1.7.3 微内核

在分层方式中,设计者要确定在哪里划分内核-用户的边界。在传统上,所有的层都在内核中,但是这样做没有必要。事实上,尽可能减少内核态中功能的做法更好,因为内核中的错误会快速拖累系统。相反,可以把用户进程设置为具有较小的权限,这样,某一个错误的后果就不会是致命的。

有不少研究人员对每千行代码中错误的数量进行了分析(例如,Basilli和Perricone,1984;Ostrand和Weyuker,2002)。代码错误的密度取决于模块大小、模块寿命等,不过对一个实际工业系统而言,每千行代码中会有10个错误。这意味着在有5百万行代码的单体操作系统中,大约有50 000个内核错误。当然,并不是所有的错误都是致命的,诸如给出了不正确的故障信息之类的某些错误,实际是很少发生的。无论怎样看,操作系统中充满了错误,所以计算机制造商设置了复位按钮(通常在前面板上),而电视机、立体音响以及汽车的制造商们则不这样做,尽管在这些装置中也有大量的软件。

在微内核设计背后的思想是,为了实现高可靠性,将操作系统划分成小的、良好定义的模块,只有其中一个模块——微内核——运行在内核态上,其余的模块,由于功能相对弱些,则作为普通用户进程运行。特别地,由于把每个设备驱动和文件系统分别作为普通用户进程,这些模块中的错误虽然会使这些模块崩溃,但是不会使得整个系统死机。所以,在音频驱动中的错误会使声音断续或停止,但是不会使整个计算机垮掉。相反,在单体系统中,由于所有的设备驱动都在内核中,一个有故障的音频驱动会很容易引起对无效地址的引用,从而造成恼人的系统立即停机。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

有许多微内核已经实现并投入应用(Accetta等人,1986;Kirsch等人,2005;Heiser等人,2006;Herder等人,2006;Hildebrand,1992;Haertig等人,1997;Liedtke,1993,1995,1996;Pike等人,1992;Zuberi等人,1999)。微内核在实时、工业、航空以及军事应用中特别流行,这些领域都是关键任务,需要有高度的可靠性。知名的微内核有Integrity、K42、L4、PikeOS、QNX、Symbian,以及MINIX 3等。这里对MINIX 3做一简单的介绍,该操作系统把模块化的思想推到了极致,它将大部分操作系统分解成许多独立的用户态进程。MINIX 3遵守POSIX,可在www.minix3.org(Herder等人,2006a;Herder等人,2006b)站点获得免费的开放源代码。

MINIX 3微内核只有3200行C语言代码和800行用于非常低层次功能的汇编语言代码,诸如捕捉中断、进程切换等。C代码管理和调度进程、处理进程间通信(在进程之间传送信息)、提供大约35个内核调用,它们使得操作系统的其余部分可以完成其工作。这些调用完成诸如连接中断句柄、在地址空间中移动数据以及为新创建的进程安装新的内存映像等。MINIX 3的进程结构如图1-26所示,其中内核调用的句柄用Sys标记。时钟设备驱动也在内核中,因为这个驱动与调度器交互密切。所有的其他设备驱动都作为单独的用户进程运行。

阅读 ‧ 电子书库
图 1-26 MINIX 3系统的结构

在内核的外部,系统的构造有三层进程,它们都在用户态中运行。最底层中包含设备驱动器。由于它们在用户态中运行,所以不能物理地访问I/O端口空间,也不能直接发出I/O命令。相反,为了能够对I/O设备编程,驱动器构建了一个结构,指明哪个参数值写到哪个I/O端口,并生成一个内核调用,通知内核完成写操作。这个处理意味着内核可以检查驱动正在对I/O的读(或写)是否是得到授权使用的。这样,(与单体设计不同),一个有错误的音频驱动器就不能够偶发性地在硬盘上进行写操作。

在驱动器上面是另一用户态层,包含有服务器,它们完成操作系统多数的工作。有一个或多个文件服务器管理着文件系统,进程管理器创建、破坏和管理进程等。通过给服务器发送短消息请求POSIX系统调用的方式,用户程序获得操作系统的服务。例如,一个需要调用read的进程发送一个消息给某个文件服务器,告知它需要读什么内容。

有一个有趣的服务器,称为再生服务器(reincarnation server),其任务是检查其他服务器和驱动器的功能是否正确。一旦检查出一个错误,它自动取代之,无须任何用户的干预。这种方式使得系统具有自修复能力,并且获得了较高的可靠性。

系统对每个进程的权限有着许多限制。正如已经提及的,设备驱动器只能与授权的I/O端口接触,对内核调用的访问也是按单个进程进行控制的,这是考虑到进程具有向其他多个进程发送消息的能力。进程也可获得有限的许可,让在内核的其他进程访问其地址空间。例如,一个文件系统可以为磁盘驱动器获得一种允许,让内核在该文件系统的地址空间内的特定地址上进行对盘块的一个新读操作。总体来说,所有这些限制是让每个驱动和服务器只拥有完成其工作所需要的权限,别无其他,这样就极大地限制了故障部件可能造成的危害。

一个与小内核相关联的思想是在内核中的机制与策略分离的原则。为了更清晰地说明这一点,让我们考虑进程调度。一个比较简单的调度算法是,对每个进程赋予一个优先级,并让内核执行在具有最高优先级进程中可以运行的某个进程。这里,机制(在内核中)就是寻找最高优先级的进程并运行之。而策略(赋予进程以优先级)可以由用户态中的进程完成。在这个方式中,机制和策略是分离的,从而使系统内核变得更小。