微内核的回归

(本文写于2018年初,但由于原博客不再维护,原始的Markdown文件也已丢失,于是我重新整理并添加了一些新的内容,再次发布到本博客中)

最近调研了操作系统近几年的发展,特别是微内核操作系统的发展,我越来越清晰地归纳出一个结论,如果操作系统未来还能有突破性发展的话,那也许是发生在微内核上

首先要解释一下微内核和与之相对的宏内核是什么,以及两者的优缺点。微内核是指操作系统的最底层是一个包含最基本功能的kernel(内核),这个kernel通常只负责最基本的最底层的任务,如上下文切换、中断处理、进程间通信(IPC)和时钟处理等,而其他的系统任务,如硬件驱动,文件系统和内存管理都以用户态进程(即ring3)的形式运行,并且相互之间通过IPC进行通信;宏内核则与之相反,所有的系统任务均在内核态(ring0)处理,系统模块之间通过函数调用方式进行交互。这两个不同架构模式的操作系统概念自提出已经过去了三十年(最早的微内核系统是Mach,于1985年被提出,之前的操作系统都是宏内核,如Unix),工业界和学界普遍认为微内核的优势在于kernel很轻(通常C代码在10000行左右),因此攻击面和代码出错的可能性更低,而且大部分任务是以进程的方式运行,一旦出错只会影响到这个进程本身,稳定性更强,而宏内核与之相反,一个驱动的微小错误很容易导致整个系统崩溃。但是微内核最被诟病的是它的性能,因为一个简单的系统调用可能会涉及到多个系统任务,以及大量的IPC和相对应的上下文切换,这样的开销是巨大的,而在宏内核中,一次系统调用只需要两次上下文切换。关于宏内核和微内核有著名的“Linus Tanenbaum debate”,可以算的上操作系统设计和研究最佳的材料,值得反复阅读。

由于历史和性能的原因,我们日常接触到的操作系统,90%以上都是宏内核(包括类Unix和Windows,Mac OS X最初是基于微内核,但是最后也加了很多宏内核的方式),微内核一度仅仅局限于研究目的,除了QNX这种车载娱乐等专业领域上的操作系统之外。但是最近几年的微内核的发展以及不断涌现的新操作系统,可以说是给人耳目一新的感觉,这里简单介绍三个项目:

  1. seL4: 提到seL4,不得不提到L4微内核操作系统家族。因为Mach的IPC简直就是性能灾难,所以Jochen Liedtke提出了L3和后续的L4结构,对IPC的性能改进很大,甚至相比较Unix都有很大的性能优势。而seL4是在L4操作系统上,运用形式化验证(formal verfication)的方法来证明kernel在模型上的正确性。在其SOSP09的论文中宣称这是一个”bug free”的内核,它付出的代价也是巨大的,总共花了11person year 的工作量进行形式化验证。但是这样的付出对于一个严肃和safety-critical的系统是值得的,而显然这对于宏内核是完全不可能的事情。

  2. Fuchsia:这是Google在2016年公开的一个项目,尽管Google一直没有对外公布它的目的和计划,但是它普遍被认为将用于取代Android系统,以求彻底解决Android及其底层的Linux kernel的各种历史问题。Fuchsia的底层Zircon本身是基于lk,而lk原本是一个嵌入式微控制器系统,最具有最基本的任务调度,同步原语等功能。但是Zircon在lk基础上构建各种系统服务,而Fuchsia又在Zircon上构建了图像化服务和其他应用程序,从最近的[测试视频][Fuchsia-demo上看,Fuchsia已经达到了基本可用的状态。

  3. Redox OS:这是一个从2015年开始的开源微内核操作系统项目,它最大的特点在于完全使用rust(和少量必需的汇编)作为内核开发的语言,显示了rust在保持强大的表述能力的同时,对底层资源的操作也能灵活自如。但是让我最惊讶不已的是,Redox在仅两名核心开发人员(加上一些GSoc参与者)的条件下,用了不到三年的时间,已经差不多宣称要实现self-hosting,并具有比较完整的图形化子系统。这也从某种程度上显示了rust生态的威力。

当再一次从头比较微内核和宏内核的几个关键争论点,我惊讶的发现它们或多或少已经发生了改变,其一是性能问题,硬件和处理器得到了很大的发展,摩尔定律和多核技术使得硬件能力基本处于过剩状态,现在的大部分性能问题可以说是软件造成的(我还清晰地记得本科计算机原理课老师经常要把写软件的人拿出来批判一番……),而且L4在微内核本身的IPC性能已经有了长足的发展,就更没有理由认为微内核比宏内核性能更差。其二,越来越多的新场景,包括IoT,自动驾驶和区块链等,对操作系统的稳定性和可靠性提出了更高的要求,从CVE的统计中我们可以看出,Linux内核的漏洞数量基本呈逐年上升的趋势,虽然微内核并不能从根本上解决所有漏洞,但seL4给我们的启示是,通过形式化验证或模型检验的方式可以消除大部分kernel中的bug,而这些方法巨大的工作量,只可能在微内核上才可能被接受。另外,seL4和fuchsia中基于capabilities的权限验证,redox中rust提供的内存安全性等,都是提高系统安全性的有效方式,而这些方式似乎已经很难加入到现有的操作系统。

至于为什么没有一款真正的微内核操作系统进入大部分人的生活,我想这是因为既有的软件生态和强大的惯性。Linux和Windows在大部分时间里已经just work,我们没有理由也没有可能在现有场景下重复造轮子,更没法从零构建出如此庞大的生态。但是历史的车轮也在向前,新生事物也是在不断批判旧事物的基础上产生的,当系统需求和使用场景发生变化时也将相应的对软件设计提出新的要求。如部署于自动驾驶中枢位置的操作系统,对安全性和稳定性的要求将大于兼容性和灵活性,也行将是微内核发挥自己长处的地方,而我也期待着见证这个历史过程。