2.3: 操作系统内核组织(Kernel organization)

一个关键的设计问题是:操作系统的哪些部分应该运行在管理模式(supervisor mode)下?一种可能的方案是将整个操作系统放在内核中,这样所有系统调用的实现都运行在管理模式下。这种组织方式被称为单体内核(monolithic kernel)。

单体内核(monolithic kernel)

在这种架构下,整个操作系统由一个具有完全硬件权限的单一程序组成。这种方式很方便,因为操作系统设计者不需要决定哪些部分不需要完整的硬件权限。此外,这种方式使操作系统的不同部分更容易协同工作。例如,操作系统可能拥有一个缓冲区缓存(buffer cache),可以同时被文件系统和虚拟内存系统共享。

然而,单体内核的缺点在于操作系统不同部分之间的交互通常非常复杂(正如本书后续内容将展示的那样),因此开发人员很容易犯错。在单体内核中,这种错误往往是致命的,因为管理模式下的错误通常会导致内核崩溃。一旦内核崩溃,计算机就会停止工作,所有的应用程序也会随之失败,必须重新启动计算机。

微内核(microkernel)

为了降低内核中的错误风险,操作系统设计者可以最小化运行在管理模式下的操作系统代码量,将操作系统的大部分功能放在用户模式(user mode)下执行。这种内核组织方式被称为微内核(microkernel)。

alt text

上图展示了这种微内核设计。在图中,文件系统作为一个用户级进程运行。运行为进程的操作系统服务被称为服务器(servers)。为了让应用程序能够与文件服务器交互,内核提供了一种进程间通信(inter-process communication)机制,用于在用户模式的进程之间发送消息。例如,如果一个像 Shell 这样的应用程序希望读取或写入文件,它会向文件服务器发送一条消息并等待响应。

在微内核中,内核接口由一些底层功能组成,例如启动应用程序、发送消息、访问设备硬件等。这种架构使内核相对简单,因为操作系统的大部分功能都存在于用户级服务器中。

两种内核模式的应用和比较

在现实世界中,单体内核和微内核都很流行。许多 Unix 内核是单体内核。例如,Linux 使用的是单体内核,尽管某些操作系统功能运行为用户级服务器(例如,窗口系统)。Linux 能够为依赖操作系统的密集型应用程序提供高性能,部分原因在于其内核子系统可以紧密集成。

一些操作系统,如 Minix、L4 和 QNX,采用微内核和服务器的组织方式,并在嵌入式场景中得到了广泛应用。L4 的一个变种 seL4 足够小,能够通过形式化验证保证内存安全和其他安全属性。

关于哪种组织方式更优,不同的操作系统开发者之间存在很大的争议,目前还没有确凿的证据支持任何一方。此外,这还取决于“更好”意味着什么:是更快的性能、更小的代码规模、更高的内核可靠性,还是整个操作系统(包括用户级服务)的可靠性。

也有一些实际因素可能比选择哪种组织方式更重要。例如,一些操作系统使用微内核,但为了性能原因将部分用户级服务运行在内核空间。一些操作系统使用单体内核,因为它们起初就是这样设计的,缺乏动机迁移到纯微内核架构,因为开发新功能可能比重写现有操作系统以适应微内核设计更重要。

从本书的角度来看,微内核和单体内核操作系统共享许多关键思想。它们都实现了系统调用、使用页表、处理中断,并支持多任务处理。

xv6的实现

Xv6 被实现为一个单体内核(monolithic kernel),类似于大多数 Unix 操作系统。因此,Xv6 的内核接口对应于操作系统接口,而内核实现了完整的操作系统。由于 Xv6 提供的服务较少,其内核比某些微内核(microkernels)更小,但从概念上讲,Xv6 仍然属于单体内核。