18.3 Why micro kernel?
Last updated
Last updated
人们构建微内核的动机是什么?
其中一个动机你可能不常看到,这就是审美(注,原话是sense of aesthetic)。我认为很多人都觉得像Linux内核这样大的复杂的程序并不十分优雅。我们肯定可以构建一些小得多且专注得多的设计,而不是这样一个巨大的拥有各种随机特性的集合体。所以从审美角度来说,我们必然可以做的比大的内核更好。
其他还有一些更具体且可量化的动机。
更小的内核或许会更加的安全。只有几行代码的话,Bug也不会太多,其他人利用Bug来破坏安全性的可能也就更小。
在特殊场景下,你需要证明一个操作系统是正确的,没有Bug,并且只做了它应该做的事情。现实中至少有一种经过验证是安全的微内核系统:seL4。这是L4微内核的多个衍生项目之一。人们知道怎么去验证中小型程序,但是不知道怎么验证巨大的程序。微内核通常都很小,这是它能够被证明是安全的一个关键因素。
小内核的另一个优势是,少量代码的程序比巨大的程序更容易被优化。
小内核可能会运行的更快,你不用为很多用不上的功能付出代价。相比monolithic kernel,微内核几乎不会做任何事情,所以你不用为你不使用的很多功能付出代价。
使用小内核的另一个原因是,小内核或许自带了少得多的设计限制,进而使得应用程序的设计限制也更少。这样给应用程序提供了更多的灵活性,使得应用程序可以自己做出设计决定。
以上都不是微内核必须要支持的特性,只是说人们期望通过使用微内核可以得到的特性。
另一个微内核吸引人的原因是,有很多我们习惯了位于内核的功能和函数,现在都运行在用户空间。这种将内核拆分,并在用户空间的不同部分运行,比如说在用户空间运行文件系统服务,可以使得代码更模块化。
用户空间代码通常会比内核更容易被修改,调整和替换,所以它更容易被定制化。
将操作系统放在用户空间,或许可以使得它更加的健壮。如果内核出错了,通常你需要panic并重启,因为如果内核有Bug,并且会随机更改数据,那就不能信任内核了。然而,如果你将内核运行成一些用户空间的服务,其中一个出现故障,比如说除以0,索引了一个野指针,或许只有这一个服务会崩溃,操作系统的剩余部分还是完好的,这样你可以只重启那一个服务。所以,将操作系统的功能移到用户进程可以使得系统更加健壮。这对于驱动来说尤其明显,内核中大部分Bug都在硬件驱动中,如果我们能将设备驱动从内核中移出的话,那么内核中可能会有少的多的Bug和Crash。
最后一个优势是,你可以在微内核上模拟或者运行多个操作系统。所以尽管微内核几乎不做任何事情,你还是可以在它之上运行一个Unix系统之类的,或许还可以在同一个机器上运行超过一个操作系统。今天的论文主要就是描述如何在微内核之上将Linux作为服务来运行。
以上就是人们在微内核这条道路上期望得到的一些好处。
当然,这里也有一些挑战。
如果你想要设计属于你自己的微内核,其中一个挑战是你会想要你的微内核的系统调用接口尽可能的简单,因为使用微内核的出发点就是内核很小。那么什么才是有用的系统调用的最小集?这一点并不十分明确。所以这里我们要确定最少的系统调用API,你需要这些系统调用API尽可能的少,但是你又需要基于这些API构建一些非常复杂的功能,因为即使内核没有做太多工作,你最终还是要运行程序。或许你想要在微内核之上运行Unix,你需要能执行类似fork,mmap的工作。所以底层的系统调用在简单的同时,需要能够足够强大以支持人们需要做的各种事情,比如说exec,fork,copy-on-write fork,mmap file。
但是内核又完全不知道文件和文件系统。所以现在系统调用需要支持exec,而内核又不知道文件。微内核或许会非常简单,但是我们仍然需要开发一些用户空间服务来实现操作系统的其他部分。
最后,微内核的设计需要进程间通过IPC有大量的通信。所以有很大的需求使得IPC能够足够的快。我们会好奇,IPC可以足够的快来使得微内核足够有竞争力吗?
有关性能,不仅与IPC的速度相关。通常来说,monolithic kernel可以获得更好的性能,是因为它里面的文件系统代码和与虚拟内存代码可以直接交互,它们开心的位于一个巨大的程序中。但是如果你需要将这些模块都拆分开成为不同的服务,那么在集成的时候就有更少的机会可以优化,这或许会影响性能。
以上就是许多微内核项目要面对的用户期望和潜在的挑战。