OS

MIT 6.S081—微内核

Micro Kernel

Posted by PYQ on July 25, 2023

Monolithic kernel

Monolithic kernel是一种操作系统设计范例,将操作系统的核心功能集中在一个单一的内核中。在Monolithic kernel中,操作系统的所有功能,包括进程管理、内存管理、设备驱动程序、文件系统和网络协议栈等,都实现为内核的一部分。Monolithic kernel的设计简单直接,因为所有的功能都在一个内核空间中运行,它们之间可以直接访问和共享资源,这使得Monolithic kernel具有较高的性能和效率。包括Windows、Linux、Mac OS、IOS和Android在内的我们熟知的操作系统几乎都是Monolithic kernel的设计。

典型的Linux操作系统提供了功能强大的抽象,例如提供文件系统这样一个极其复杂的组件,并将文件、目录、文件描述符作为文件系统的接口,而不是直接将磁盘硬件作为接口暴露给应用程序。正因为这种抽象,Linux有着巨大的优势:

  • 这些高度抽象的接口通常是可移植的,拥有相同的接口,可以在不修改应用程序的前提下,将其运行在各种各样的硬件之上。
  • 除了提供可移植性,抽象还可以向应用程序隐藏复杂性,这对于编程人员来说是极好的,只需要调用相关的接口,但内核却因此变得十分庞大而复杂。
  • 强大的抽象还可以帮助管理共享资源,例如内存、CPU、磁盘等。内核会负责这个功能,简化了应用程序的设计,同时也提供了健壮性和安全性。
  • 几乎所有的功能都集成在内核中,这意味着它们可以访问彼此的数据结构,进而使得依赖多个子系统的工具更容易实现。
  • 内核所有的代码都以完整的硬件权限运行,这使得操作系统可以更简单的实现软件。

当然凡事必有两面性,Monolithic kernel也有一些缺点,这也产生了Micro Kernel的概念:

  • Linux有数十万到数百万行代码,内部代码有大量的交互和依赖,十分庞大复杂,因此也无法避免的会出现一些bug和安全漏洞。
  • Monolithic kernel通常是设计为通用操作系统,但是另一方面通用意味着“慢”:对于各种不同的场景都支持,但或许不能对某些特定场景进行优化。
  • Monolithic kernel还有一个问题是可扩展性。

Micro Kernel

微内核从1980年代中后期开始就是一个非常热门的研究课题,它是指一种通用的方法或者概念,它并不特指任何特定的产品。在今天仍然有使用微内核的场景,比如一些微型嵌入式系统。有很多遵循微内核的设计思想的操作系统,但都各不相同。微内核的核心就是实现了IPC(Inter-Process Communication)以及线程和任务的tiny kernel。所以微内核只提供了进程抽象和通过IPC进程间通信的方式,除此之外别无他物。任何你想要做的事情,例如文件系统,你都会通过一个用户空间进程来实现,完全不会在内核中实现。

从上图可以看到在微内核设计中,用户空间除了熟悉的应用程序外,还有宏内核中包含的文件系统、虚拟内存系统等进程。在这种设计中,当vi需要读取一个文件时,它需要与文件系统进行交互,所以它通过IPC会发送一条消息到文件系统进程。文件系统进程中包含了所有的文件系统代码,文件系统进程需要与磁盘交互,所以它会发送另一个IPC到磁盘驱动程序。磁盘驱动程序再与磁盘硬件进行交互,之后磁盘驱动会返回一个磁盘块给文件系统。之后文件系统再将VI请求的数据通过IPC返回给VI。因此,在这个场景下,在内核中唯一需要做的是支持进程/任务/线程,以及支持IPC来作为消息的传递途径,除此之外,内核不用做任何事情。内核中没有任何文件系统,没有任何设备驱动,没有网络协议栈,所有这些东西以普通用户进程在运行。所以这提供给你一种非常小的内核,以及相对少的代码去优化,你可以优化IPC,除此之外也没有别的东西了。

既然宏内核设计在众多场景下都能完成我们的工作,那么人们设计微内核的动机是什么呢:

  • 微内核的设计更加的优雅(robert觉得)。
  • 更小的内核或许会更加安全,代码量少的话,bug也不会太多。
  • 少量的代码程序更容易被优化。
  • 微内核可能运行的更快,因为相比于宏内核,微内核几乎不会做任何事情。
  • 给应用程序的设计提供了更多的灵活性。
  • 将宏内核的一些功能移到用户空间可以使得系统更加健壮,如果一个服务崩溃了,操作系统的剩余部分还是完好的,那我们可以只重启那一个服务而非整个系统。

当然我们已经知道微内核最终还是没有变得流行,因为其存在很多问题。首先便是微内核的系统调用接口尽可能的需要简单,但具体哪些系统调用呢。此外,微内核的设计需要进程间有大量的IPC通信,这会使得微内核系统十分的慢。另一方面,本在宏内核设计中可以直接交互的功能,在微内核设计中变成了不同的模块和服务,这也影响了性能。

L4

在一系列微内核设计的操作系统中,L4微内核系统由于其出色的性能和很小的体积被计算机工业所认知。L4只有7个系统调用,而Linux有几百个,即使是xv6这个极其简单的内核,也有21个系统调用。其次,L4只有13000行代码(论文发表时),只有Linux代码的几十分之一。Task,线程(相比于xv6,L4中的一个task可支持多个线程),地址空间,IPC是L4唯一有的抽象。

在一些更通用的场景下,像是工作站和服务器, 微内核从来没有真正的流行过,并不是因为这里的设计有什么问题,只是为了能够吸引一些软件,微内核需要做的更好,这样人们才会有动力切换到微内核。对于人们来说很难决定微内核是否足够好,这样才值得让他们经历从现在正在运行的Linux或者其他系统迁移到微内核的所需要的各种麻烦事。所以,微内核从来没有真正流行过,因为它们并没有明显的更好。另一方面来看,微内核的很多思想都有持久的影响。

  • 人们实现了更加灵活和有趣的方法来在微内核上使用虚拟内存。这些复杂的多的接口导致了mmap这样的系统调用合并到了例如Linux的主流操作系统中。
  • 微内核设计可以将一个操作系统作为一个用户程序运行另一个操作系统之上,今天以另一种方式非常流行的存在:在Virtual Machine Monitor上运行虚拟机。这种方式在各种场景,例如云主机上,都有使用。
  • 为了让内核能够具有一个用户空间服务一样的可扩展性,在Linux中演进成了可加载的内核模块,这使得你可以在线修改Linux的工作方式。
  • 这里基于IPC的Client-Server支持,也在macOS有所体现,macOS中也有好用的IPC。