MINIX吉祥物

[译]从MINIX30年发展历史里得到的经验教训

MINIX 展现了甚至操作系统也可以具有

自我修复功能

作者: ANDREW S. TANENBAUM

招文桃 译

 

MINIX

30年发展

历史里得到

的经验教训

 

Linux已广为人知,它的直接祖先MINIX现在已经有30年历史了,而且这样一个陈年软件至今仍处于活动状态。 然而关于MINIX和Linux是如何开始的故事却鲜为人知。 在MINIX的开发过程中可能有些经验教训值得我们学习。当中有些经验教训是针对于操作系统的,一些针对软件工程的,还有一些关于其他领域的(例如项目管理)。MINIX 或Linux都不是凭空开始的。在两者开始之前有不少相关的历史背景,因此一个简短的介绍有助于理解这篇文章。1960年,在我求学的麻省理工学院有一台房间大小的,基于电子管的科学计算机称为IBM 709。虽然一台现代的苹果 iPad 的运行速度是它的70000倍 运行内存是那的7300倍,但在当时,IBM 709 是世界上计算能力最强的计算机。 用户通常使用FORTRAN在80列的穿孔卡上编写程序,然后拿这些卡片去给操作人员,他们负责输入这些穿孔卡。 几小时之后结果出来了,打印在132列的打字纸上。一个FORTRAN语句中的逗号错误可能导致编译失败,结果浪费程序员数小时的时间。为了更好地为用户提供服务,麻省理工学院开发了兼容分时系统(CTSS),这系统允许用户通过交互式终端来使用,可将周转时间由几小时减少到几秒并同时在后台以稀疏周期运行旧式批处理任务。 在1964年,麻省理工学院、贝尔实验室和通用电气公司(当时是计算机厂商)想合作开发一个能够支持整个波士顿地区的数百个用户的后续版系统,可以将此看作云计算 V.0.0  这系统称作分时信息计算服务系统,或MULTICS。 长话短说,MULTICS早期遇到很多困难,第一个版本需要的运行内存比 GE 645的所有内存 (288kB)还要多。 最后,它的PL/1 编译器改进了, MULTICS可以启动运行了。不过,贝尔实验室很快就对这个项目感到厌倦并退出,留下了他们其中一个程序员在这个项目中,他就是Ken Thompson, 他热切地渴望可以重新开发一个精简版的MULTICS到更加廉价的硬件设备上运行。MULTICS的商业发行是在1973年,在全世界有一定的安装数量,最后一台运行MULTICS的机器直到2000年十月30日才关机,运行了27年。

在贝尔实验室的时候,Thompson发现一台弃置的数字设备公司的PDP-7小型机,之后他用PDP-7的汇编语言写了一个精简版的MULTICS。 因为那只能够同时支持一个用户使用,Thompson的同事Brian Kernioghan 称之为UNIplexed Information and Computing Service(单用户信息计算服务系统), 或UNICS。 虽然双关语EUNUCHS (译注: eunuch[‘junək]阉人、太监,与UNICS发音相近)的意思是阉割了的MULTICS,但UNICS这个名称已经存在,不过后来拼写变成了UNIX,现在有时候写成Unix,因为这已经不是一个缩写词了。在1972年,Thompson跟他在贝尔实验室的同事Dennis Ritchie组队,Dennis设计了C语言并写了一个C语言编译器。他俩一起用C语言在PDP-11小型机上重新实现了UNIX。UNIX经历了好几个内部版本,直到1975年贝尔实验室决定以300美金的许可费用将UNIX V6授权给高校。由于PDP-11 当时非常受欢迎,UNIX在全世界范围迅速传播。在1977年,澳大利亚悉尼的新南威尔士大学的John Lions给V6的源代码写了注释,逐行地解释代码。这是技术版本的逐行注释圣经。全世界数百所大学开始使用Lions的书作为教材来教授UNIX V6课程。贝尔实验室隶属于AT&T,AT&T的律师惊讶地得知有数千名学生在学习他们的产品。他们认为这种情况必须制止。所以在下一个发行版本,V7(1979),添加了一个协议明确禁止任何人进行有关这个版本的写作和教学活动。操作系统课程又回到只有理论的模式,或者只能使用玩具般的模拟器,这让世界各国的教授很沮丧。有关UNIX早期的历史已经在Peter Salus 1994年的书中有所记载。14

MINIX 诞生

事情已告一段落,直到1984年我决定利用在荷兰阿姆斯特丹自由大学教书的空余时间去重写V7,为我的学生一个与UNIX兼容的操作系统,那样我的学生在课程学习或者自学的时候可以用到。我当时的想法是编写一个系统,称作MIni-uNIX,或MINIX,在IBM新出的个人电脑上运行,这样就足够便宜(1565美元起), 每个学生可以拥有一台。因为早期的个人电脑没有硬盘,我将MINIX设计成与V7兼容,并且还能够运行在一台配备256kB内存和单个360kB 5 1/4英寸的软盘IBM PC上,这配置比运行V7的PDP-11要低得多了。 虽然是想着要运行在这样的配置上的(确实可以运行),我一开始就意识到要真的在一台个人电脑上编译和构建整个系统,我将需要一个更大的系统,也就是最大内存约640kB还要有两个360kB 51/4英寸的软盘。

我的MINIX设计目标如下:

  • 构建一个可运行在一台只有一个360kB软盘的IBM 个人电脑上的V7克隆版;
  • 使用自身构建和维护这个系统,或者是“自托管”;
  • 将所有源代码对所有人开放;
  • 采用简洁的设计,学生更容易学习;
  • 让(微)内核尽可能小,因为内核有错误是致命的;
  • 将余下部分划分为独立的用户模式进程;
  • 将中断隐藏在相当低级的层次;
  • 只用同步消息传递信息,使用清晰的协议,并且
  • 尽量使得系统更容易地移植到将来的硬件上。

 

最初,我在家用一台运行Mark Williams Coherent 上做开发软件,那是一个由滑铁卢大学的alumni所写的一个V7 克隆版。它的源代码没有公开,使用Coherent 在初始阶段是很有必要的,因为一开始我没有(MINIX上的)C编译器。当我们的程序员,Ceriel Jacobs 可以将一个基于我在自由大学所做研究的一部分的Amsterdam Compiler Kit18的C编译器,移植到了MINIX上。之后这系统就成为了“自托管系统”。因为我现在可使用MINIX来编译和构建MINIX,所以我对任何可能会出现的漏洞或者错误尤为敏感,所有开发者都应该尽早地使用他们自己开发的系统,这样可知道软件的用户体验。

 

教训: 吃你自家的狗粮(译者注:Eating your own dog food(直译为“吃你自家的狗粮”,亦略称为dogfooding)是一句英语俚语,常用于描述公司(尤指软件公司)使用自己生产的产品这一情况,见https://zh.wikipedia.org/wiki/Eating_your_own_dog_food

 

那个微内核真的很小。里面只有一个调度器,低层次的进程管理,进程间通信管理以及设备驱动。虽然设备驱动是编译进了微内核的可执行程序里面,但实际上它们是作为普通进程独立地调度的。这是一个折中,因为我觉得要在主频为4.77MHz的8088上做全地址空间寻址切换实在太痛苦了,那时IBM PC的CPU就是8088。微内核是单独立编译的一个可执行文件,每个其他的操作系统组件,包括文件系统和内存管理,是另外编译的程序,并且作为独立的进程运行。由于8088没有内存管理单元(MMU),我本来可以走捷径,将所有东西放在一个可执行文件里,但我不打算这样,因为我想这设计可以用在以后带有MMU的CPU上。我只在晚上和周末做开发,大概花了我两年就差不多可以让它运行起来。系统基本上能用的时候,它往往在运行了一个小时操作后就无故奔溃,而且没有可观察的规律。在裸机上调试操作系统几乎是不可能的,我差一点儿就放弃了这个项目。

然后我做了最后的努力。 我写了一个8088模拟器用来运行MINIX,那样当它奔溃的时候我就可以获得一些转存文件和栈跟踪信息。让我感到吃惊的是,MINIX无错误地在同一个模拟器上运行了几天,甚至是几个星期。它一次都没有奔溃,我当时就懵了。我跟我的学生Robbert van Renesse说了这个奇怪的情况,MINIX可以在模拟器上正常运行但在硬件上不可以。然后他跟我说,听说8088发热的时候会产生中断15。我告诉他8088的文档里面没有提到这个,但是他坚持说他在某处听说过。 于是我插入一些代码去捕获中断15。 在一个小时内,我在屏幕上看到这个消息:“你好,我是中断15,你永远不会看到这个消息” ,我立即打了必要的补丁去捕获中断15。之后MINIX就没错误地运行并且准备发布了。

 

教训:不要盲目地相信文档,那可能是错误的

 

Van Renesse漫不经心的话产生的影响在30年后是巨大的。如果他当时没有提到中断15,我可能最终绝望地放弃了。没有MINIX,很难说会有Linux,因为Linus Torvalds 通过详细研究MINIX的源代码,然后再此基础上写了Linux。 没有Linux,Android就不可能存在,因为它是在Linux的基础上构建的。没有Android,可能现在苹果公司和三星公司股票价格会相差很大。

 

教训: 听学生的意见;他们可能知道的比你多

 

我自己写了绝大部分的基础实用软件,从ar 到wc ,MINIX 1.1包含了其中的60个,一个典型的程序大小约为4kB,现代的一个bootloader大小可能是那的100倍。 MINIX的所有,包括二进制文件和源码,刚好能塞进8张360kB的软盘,其中四张分别是启动盘、根文件系统、/usr和/user目录(见图1)。另外4张包含了完整的操作系统源码以及60个实用程序的源码。只有编译器的源码没有放进去,因为那太大了。

 

minix floppy disk
MINIX的软盘

图1

 

教训: Nathan Myhrvold的定律是真的:软件是气体,它会膨胀然后充满它的容器 (译者注: Nathan 曾是微软CTO,参考见https://blogs.msdn.microsoft.com/larryosterman/2005/06/17/nathans-laws-of-software/

 

在遵循一些惯例的情况下,开发者可以尝试打破这个“定律“,但是要下苦功。通常软件只会是“更加膨胀”。

想办法如何去分发这些代码是一个大问题。在当时(1987年)几乎没什么人有良好的网络连接,(虽然一些大学里有电子邮件以及通过UUCP连接到USENET的新闻组)。  我决定写一本书15描述源代码,就像Lions之前那样做,然后我找到出版商, Prentice Hall,去分发这个系统,包括所有的源代码,作为书本的附件。经过一番磋商,Prentice Hall同意将包装良好的,含8张5 1/4英寸软盘和500页手册的系统定价为69美元。 这基本上是成本价了。Prentice Hall不知道那是什么软件,只是知道我想以成本价售卖书籍。到后来高容量 1.44MB 3 1/2英寸软盘出现了,我也制作了使用那些软盘的版本。

 

教训:无论你的产品多好,你需要一个渠道推广或分发它

 

MINIX发布没几天,一个USENET新闻组,comp.os.minix,上线了。不到一个月,新闻组已经有40000读者了,相对于当时的USENET用户数量来说,这已经是一个很大的数目了。 MINIX突然成为了受到追捧的东西。不久我收到了来自Dan Dernberg的电子邮件信息,他是硅谷的一间(现已结业的)计算机文化书店的共同创始人之一,当时他邀请我去做一个关于MINIX的演讲,如果我当时有在那边的话。后来发现,我当时几周后打算去旧金山湾区参加一个大会,所以我接受了邀请。我以为他会布置一张桌子和椅子在他的书店里给我签售书籍。 当时我一点都没想到的是他会在圣塔克拉会议中心租用主会议室,而且宣传工作做得很好,观众几乎满座。在我演讲结束之后,观众提问不断,直到午夜结束之时。

我开始收到数百封电子邮件,请求我(不,是要求我)添加这样或者那样的功能。我拒绝了一些(但不是所有)要求,因为我担心可行性,还有系统会变得如此大,可能需要更加昂贵的硬件,学生买不起。 而且很多人,包括我在内,认为GNU/Hurd或BSD会占领开源产品市场,所以我将重心放在教学上。

人们也开始提交软件,有些是非常有用的。在众多贡献者之中,Jan-Mark Wams,他写了大量的有用的测试程序有助于调试系统。他也写了一个新的压缩程序,那比当时所有的压缩程序都要好。 这样就可以减少两张软盘的使用量。甚至在后来在网络上发行时,这仍起到重要作用,因为当时不是所有人都有高速 56kbps 调制解调器。

 

教训:尺寸大小是关键

 

在 1985年, Intel发布了带有保护模式的32位体系结构386处理器。在众多用户的帮助下,特别是澳大利亚的Bruce Evans, 我能够发布带32位保护模式的版本的MINIX了。 从第一天起我就总是考虑到未来的硬件,因此代码上清楚地区分什么代码运行在“内核状态”,然后什么代码运行在独立的“用户状态”, 即使8088处理器只有一种模式。 这种做法对处理之后在386上出现的这些(保护)模式很有帮助。还有,原始代码清楚地区分虚拟地址和物理地址,这对于8088来说没什么影响,但是在386上就很重要,这使得移植更加容易。大约是这个时候,在自由大学的两个人,Kees Bot和Philp Homburg,创作了一个优秀的带虚拟内存的32位版本,但我打算继续用Evans的那个,因为那更接近原始设计。

 

教训:尽量让你的设计适应未来可能出现的硬件

 

到了1991年,MINIX 1.5已经移植到苹果的麦金塔电脑,Amiga, Atari,还有Sun公司的SPARCstation等其他系统(见图2)

mac & amiga

atari & sparcstation

 图2

 

教训:不依赖于硬件的特定功能,可以使得移植更加容易

 

随着系统开发进行,没想到的问题出现了。其中一个特别烦的是和网卡有关的驱动没办法调试。最后有人发现网卡没有符合它的标称规格。

 

教训:就像软件,硬件也可能存在bugs

 

一个硬件“特性”有时候可以看作硬件的漏洞。一个由Olivetti移植到个人电脑克隆机上的MINIX,Olivetti是当时意大利的计算机厂商,不断出问题,直到被我发现,那是因为一个没有考虑到的问题,Olivetti的键盘上有一些键返回跟标准IBM键盘不一样的扫描码。这让我想到,很多国家有他们自己的标准键盘。为此,我修改MINIX,让它支持多种键盘,可以在系统安装的时候选择。这个特性对于意大利、法国、德国和其他国家的专用键盘的用户很有用。因此,当我发现可以有机会让MINIX变得更加便于其他(非美国的)国家的用户使用,我原本为Olivetti一事的烦恼就没了。同样的道理,在后来的一些情况里,一些我们原来看作是bugs的情况,让我有了改善系统,让其普适化的动力。

 

教训:当别人给你一个柠檬,你用来做柠檬汁

(译者注:参考:柠檬法Lemon Laws)是一种美国的消费者保护法,主要是在保障汽车买主的权益。柠檬法的名称起源于美国经济学家乔治·阿克罗夫(George A. Akerlof)所发表的一篇经济学论文,因为这缘故,对于出厂后有瑕疵问题的汽车,通常也会称呼其为柠檬车(Lemon Car)或直接就称为柠檬。在这里,作者应该指Olivetti的PC克隆机。

 

Linus Torvalds买了一台电脑

 

在1991年1月5日,Linus Torvalds,一个芬兰赫尔辛基大学前所未有的学生,做了一个重要的决定。他买了一台很快(33MHz),大存储空间(4MB 内存,40MB硬盘空间),的电脑,主要目的是运行和学习MINIX。 在1991年3月29日。Torvalds,在USENET 新闻组,comp.os.minix上面第一次发消息:

“哈喽,各位,我使用MINIX一周了,而且升级到386-minix(很赞)了,还有适时地给minix下载了gcc…”

他在comp.os.minix上发布的第二个消息是在1991年4月1日,那是回复一个别人的简单问题:“RTFSC(去读他*的源代码 :-))—— 那已经有很多注释了,而且解决方案是显而易见的……” 这个贴子说明了,Torvalds在10天之内将MINIX的源代码学得很好了,好到可以鄙视那些学得没他那么好的人。当时MINIX的目的,当然就是让学生更容易学习。从Torvalds的情况来看,MINIX是非常成功的。

然后在1991年8月25日,Torvalds发表了另一个贴子在comp.os.minix:

“哈喽,各位使用MINIX的朋友—— 我正在开发一个(免费的)操作系统(只是一个爱好,不会像gnu那样专业和庞大)运行在386(486) AT 克隆机上。这东西在四月份就开始酝酿,现在开始准备好了。 我想知道一些关于大家喜欢或不喜欢MINIX,以及我重组的操作系统上的东西,它在某种程度上是(相同的文件系统布局,因为一些现实问题和其他原因)”

在接下来的一年,Torvalds继续学习MINIX并用它来开发他的新系统。这就是第一个版本的Linux 内核。Linux与MINIX之间的联系,已成为历史印记,在软件考古历史中可以看出来,例如Linux内核的文件系统使用了MINIX文件系统,还有源码树的组织形式。

在1992年1月29日,我在comp.os.minix上发了个贴子,说微内核比宏内核更加优秀,除了在性能方面。这个贴子引起了一场论战,一直持续至今,甚至是24年之后,仍鼓舞着世界各国的学生写信告诉我他们在这场争论中的立场。

 

教训:网络就像一头大象,它不会忘记东西 (译者注: 惯用语 have a memory like an elephant,形容记性好)

 

也就是说,要小心注意你在互联网上的言论,那可能在数十年后回来烦扰你。

 

事实证明在某些人看来性能比我认为的更重要。 Windows NT 最初是微内核设计, 但是由于性能不足,微软后来改为混合内核设计。 在NT系统,以及Windows 2000、XP、7、8和10,里面都有一个硬件抽象层在很底层(用来屏蔽不同主板之间的差异)。 在此之上是一个微内核负责处理中断,线程调度,低级进程间通信,还有线程同步。在微内核之上是Windows Executive,一组独立的组件用于管理进程,内存管理,I/O管理,安全等跟其他东西组成了操作系统的核心。它们通过定义好的协议来通信,就像MINIX那样,只不过在MINIX中那是用户模式进程。 NT(以及它的后继者)是混合内核,由于性能问题,所有这些部分都以内核模式运行,这意味着更少的上下文切换。所以在软件工程的观点来看,这是微内核设计,不过在可靠性的角度看,这是宏内核。因为只要是任何组件中有一个bug,整个系统就可能崩溃。 苹果公司的 OS X 也是有类似的混合设计,在它的底层是Mach 3.0微内核在此之上是 Darwin (来自FreeBSD——由加州大学伯克利分校开发的BSD的一个后代)

同样值得关注的是在嵌入式计算世界,这个领域里面,可靠性通常比性能更重要,微内核设计是主流。QNX,一个商业的类UNIX实时操作系统,广泛用于汽车、工厂自动化,发电厂以及医疗设备。 L4微内核运行在世界上超过一亿台手机上的无线电芯片上,还有最近的iOS设备上的安全处理器,例如iPhone 6。 L4是如此的小,一个版本大概由9000行C语言代码构成,这点在它的规范里面可以佐证9,而宏内核有难以想象的数百万行代码。不管怎么说,微内核由于历史原因如今还是受争议的,某种程度上是因为相对低的性能16

1992年,在comp.os.minix的新闻组上,我又发表言论指出,Linix太紧密地与386体系结构捆绑在一起不是一种好的设计,因为RISC机器会最终主导市场。很大程度上这件事正在发生,因为超过50亿(RISC 精简指令集)ARM芯片发行了。绝大部分智能手机和平板电脑使用ARM CPU, 包括一些变体如,高通骁龙,苹果的A8 还有三星的 Exynos。再往前一步,64位的ARM服务器和笔记本已经逐步出现。Linux后来已经移植到ARM平台,但是如果在开始没有那么紧密地绑定到 x86体系结构,移植的时候就不会那么困难。

 

教训:不要想着现在的硬件会永远是主流

 

同样是在这方面,Linux太过紧密地与gcc编译器捆绑在一起,如果要用更新的(按理说更好的)编译器,例如clang/LLVM,那就需要给Linux源码打很多补丁。

 

教训:当标准存在(例如ANSI 标准C),紧跟标准

 

除Linux项目正式开始,还有另一个重要的发展期间是在在1992年。 当时AT&T控告BSDI(一间由BSD开发者创立的公司,他们销售BSD并提供支持),和加州大学。AT&T宣称 BSD包含了一些AT&T的代码,还有BSDI的电话号码: 1-800-ITS-UNIX 侵犯了AT&T的知识产权。 这个案件在1994年庭外和解,到那时BSD像被戴上了手铐,发展受到限制。这给了新生的Linux关键的发展时间。 如果当时AT&T更明白事理,只是收购BSDI并作为他们赢得市场的武器,那么Linux可能永远赶不上如此成熟和稳定,还有安装广泛的竞争对手。

 

教训:如果你经营着世界上最大的公司,然后一间小的创业公司出现在你关注的领域,但是你们一点都不了解这领域。 去问小公司的拥有者,他们想以什么价格卖掉公司,然后给他们写一张支票

 

在1997年, MINIX 2 发布了,那已经修改为比V7 更符合POSIX标准。同时发布的还有我的书的第二版,《操作系统设计与实现》,那时我和Albrt Woodhull合著第二版,他是麻省罕布什尔学院的一位教授。 在2000年,我终于说服Prentice Hall 以BSD许可发行MINIX 2,并将MINIX 2 及其所有源代码在网上免费发行。我早就应该这样做了,特别是怎么说当时原来的许可都已经允许在大学里无限制地复制代码,还有几乎是以出版商成本价出售了。

 

教训:即使你已经选择了一种策略,你仍然应该时不时地重新审视它

 

MINIX 研究项目

 

MINIX 2 继续缓慢地发展了几年,不过发展方向在2004年急转,当我受到一笔来自荷兰科学研究组织(http://www.nwo.nl)的研究拨款,我将一个教学上的爱好转为严肃的,有基金支持的研究项目,目的是构建一个高可靠的系统。 在2004年之前,我们没有外来基金支持。不久之后,我获得了在阿姆斯特丹的荷兰皇家艺术与科学学会授予的科学院教授。加起来,这些资金提供了接近3百万美金用于研究基于MINIX的可靠操作系统。

 

经验:从事一些重要的研究可以获得研究基金,即使这不是主流的东西

 

MINIX当然不是唯一关注微内核的项目。早在1970年的就有一些微内核系统,包括Amoeba17, Chorus12, L310, L411, Mach,RC 4000 Nucleus3和V4系统这些。MINIX当中的新特点就是,尝试在微内核的基础之上开发一个可容错的,多服务器的,符合POSIX的操作系统。在2004年我跟我学生和程序员一起,开始开发MINIX 3。 我们第一步先将设备驱动完全从微内核移出。在MINIX 1和MINIX2的设计中,设备驱动是作为独立的进程来处理和调度的,但是存在于微内核的(虚拟)地址空间。 我的学生Jorrit Herder 的硕士论文是关于将设备驱动全部作为用户模式进程。这个改进使得MINIX的可靠性非常高而且很健壮。后来我在自由大学指导他的博士研究期间,Herder 演示了失效的驱动程序可以在运行中被替换,系统正在运行的时候,完全没有不良影响7。甚至失效的磁盘驱动也可以在运行过程中替换,因为内存中总会有一个驱动副本存在;其他的驱动总是可以从磁盘中读取。这是通往可自我修复的操作系统的第一步。实际上MINIX现在可以做到不需要重启系统就可以替换一些奔溃的关键的系统组件, 甚至连正在运行的应用程序进程都没有发现这过程。没有任何其他系统可以做到这一点,这给我们团队很多信心,我们真的取得了一些成绩。

 

教训:尽量早点取得某些突破,这可以鼓舞大家的士气

 

这个改进为实现最低特权原则(或最低权限原则13更适合)提供了可能性。 现在一个驱动程序想接触到设备的寄存器,即使是设备自身的寄存器,都需要调用微内核,那将会检测驱动程序是否具有设备的访问权限,这大大地增强了健壮性。在像Windows或Linux那样的宏内核系统中,音频驱动的一个小小的失常或故障就有权限擦除掉磁盘的数据,在MINIX,微内核不会让这种情况发生。如果有一个输入输出内存管理单元的话,就不需要微内核去调节也可以达到同样的效果。此外,系统组件之间的通信必须要得到微内核的允许才能够进行,而且组件只能够调用微内核允许的系统调用,这一切都由微内核当中的表和位图控制。这种包含对操作系统组件(以及其他组件)有严格限制的新设计称作MINIX 3 并且与此配套的有我和Woodhull的书 《操作系统设计与实现》 第三版

 

教训:每一个设备驱动都应该作为没有特权的独立用户模式进程

 

微软早已清楚地明白并且现在仍然理解这个道理,然后他们在Windows XP及其后的操作系统引入了用户态驱动框架,目的是鼓励设备驱动作者,开发用户态的设备驱动,就像MINIX那样。

在 2005年,我受邀到ACM的关于操作系统原理的研讨会(http://www.sosp.org)讲座上发言,那是操作系统研究领域最顶尖的会议。那是当年十月份在英国布莱顿大酒店举行的。我决定在这次发言中,在被邀请过来的操作系统专家们面前正式地宣布MINIX 3。在我讲话过程中,我在台上脱去了我的上衣,秀出一件MINIX 3的T恤。 从那天起MINIX的网站上线了,并允许大家下载MINIX。不用多说,我想在会议期间在线,看看服务器是否能处理这样的负载量。 我当时被安排在皇家套房,那是英格兰女王访问布莱顿的时候可能会选择的住的地方。这是一个大房间,有无敌海景。遗憾的是,那是酒店里唯一没有网络连接的房间,因为女王不是经常使用网络。更加糟糕的是,酒店没有Wi-Fi。 还好,一位会议组织者可怜我,愿意帮我换到普通的,但是要对我来说很重要的,有以太网连接的房间。

 

教训:将重心放在你真正的目标上

 

那就是说,不要为一些突然出现的看似很美好的(例如漂亮的酒店房间)但实际是障碍的事物分心。

2005年那会,MINIX3已经是一个很正经的系统了,但是很多阅读过操作系统设计与实现这本书,并且在大学期间学习过MINIX的人很难相信这已经不再是一个玩具系统了。所以很讽刺的是,我有一个很著名的系统,但是由于历史原因,我还要想方设法让人们认真对待它。 微软以前就聪明了早期的Windows版本包括Windows 95和Windows 98只是MS-DOS系统加上一个图形化外壳而已。 但如果他们当时以“图形化MS-DOS”这个名称去推销,而不是将系统重命名为“Windows”,微软可能就不会发展得那么好,事实是微软的确将产品改名了。

 

教训: 如果你的第三代产品和第二代产品有很大差别, 使用一个新的名称

 

在2008年, MINIX项目获得另一份好运。 多年以来,欧盟一直有考虑修订产品责任法律使其适用于软件这个想法。如果10百万个轮胎中有一个爆炸造成人员伤亡了,厂商不能推脱说,“轮胎爆炸很平常”。在软件领域,像那样的论点是说得过去的。因为一个国家或者其他辖区不能对于一些在技术上来讲是不可能的事情立法。由欧盟成立的欧洲研究委员会,决定给予我大概三百五十万美金的欧洲研究委员会高级研究基金,看我是否能够在MINIX的基础之上开发出一个具有高可靠性和自我修复功能操作系统。当我非常感激可以有这个机会的时候,这个极好的运气同时也带来了一个重大问题。 当时我可以雇佣四个专业程序员去开发“MINIX 3 产品”,同时也资助6个博士学生和几个博士后去挑战研究的极限。没过多久,每个博士生都复制了MINIX的代码树,并开始修改用于他们的主要研究方向。与此同时,程序员们忙着对代码优化和“产品化”。两三年后,我们没办法再将损坏的事物修复了——小心翼翼地开发的原型和学生的版本有太多分歧,我们无法将他们做的修改再放回到MINIX里面,尽管我们有使用git和其他流行的工具。各版本之间实在是太不兼容了。例如,如果两个人用完全不同的算法重新写了调度器,那么这些修改在后期是很难自动合并的。

还有,虽然我之前有说过想将研究成果放到产品中,但是程序员们强烈拒绝,因为他们对待代码是超级谨慎的,而且(说得委婉点)对于将大量几乎没有经过测试的学生水平的代码,注入到一个已经充分测试过的产品及系统这件事没有什么热情。花费了大量的努力,我们团队才成功地将我们其中的一项研究成果应用在产品上。不过我们有发表过很多论文,就譬如说,Appuswamy et al.2, Giuffrida et al.5, Giuffrida et al.6, 还有 Hruby et al.8

 

教训: 在同一时间做博士研究和开发一个软件产品结果是很难结合在一起的

 

有时候研究人员和程序员都会遇到相同的问题。其中一个这样的问题是关于使用同步通信的。同步通信一开始就已经有,而且很简单。但这也跟可靠性有冲突。如果一个客户端进程C发送一个消息给服务器进程S,之后C奔溃了或者是陷入了一个无限死循环,然后没办法监听到服务器的回复,那么服务器就会被挂起,因为它没有办法成功发送它的回复消息。这是同步通信的固有缺陷。为了避免这个问题,我们强制加入了虚拟终结点,异步通信和其他一些远不及原来设计那么优雅的东西。

 

教训:爱因斯坦是对的:事物应该尽可能简单,但是不能过分简单

 

爱因斯坦的意思是任何人都应该追求简洁并且他们的解决方案是易于理解以便于开展工作,但不是过分简洁。这是由始至今的指导原则。很遗憾的是,这个原则在很多现代膨胀增长的软件中消失了。

大概在2011年,我们想做产品的方向变得更加明确,而且我们做了两个重要的决定。 第一,我们意识到要让人们使用这个系统,我们必须要有应用程序,所有我们移植了大量来自BSD(尤其是NetBSD)的头文件、库文件以及包管理工具。事实上,我们已经在一个能可容错的子结构上重新实现了NetBSD的用户空间。当中的进步就是 6000 个NetBSD的软件包一下子可以用了。

 

教训: 如果你希望人们使用你的产品,你的产品必须有些有用的东西

 

第二个决定是:我们意识到要去跟Windows、Linux、 OS X以及一堆BSD这些老大哥争夺桌面环境的市场还是很难的,虽然MINIX3可以很好地用在大学里做关于可容忍错计算研究。 因此我们将MINIX3 移植到ARM处理器并且开始专注于嵌入式系统,这个领域,高可靠性是很重要的。 还有一个原因是,当工程师在给相机、机顶盒、数字摄像机、路由器或者是其他产品的嵌入式系统寻找一个操作系统时,他们不需要满足数百万尖声怪气的奇葩要求,如往后兼容到1981年,并可以运行他们所有的MS-DOS游戏,就像他们之前的产品那样。所有用户都是看到外部,而不是内部原理。特别地,我们让MINIX 3运行在BeagleBone系列的单板计算机上,这板子使用ARM Cortex-A8 处理器(见图3)。 这基本上相当于一台个人电脑,售价大概是50美元。 它们通常用于嵌入式系统原型开发。它们都是开源硬件,因此想要了解它们是如何工作是容易的。

beagleboneblack

图3

教训:如果你按计划A去推广产品不成功的话,转计划B

回顾

作为事后诸葛亮,现在一些事情看得清楚了。首先,小的微内核和由硬件MMU分别保护的用户模式级别的系统组件,可能仍然是针对高可靠的,可自我修复系统的首选。因为这种设计防止一个组件中的问题扩散到其他组件。可能这会让人感到惊讶,30年来几乎没有代码被移进MINIX的微内核。实际上,一些主要软件组件,包括所有的驱动和大部分调度器,从中移出来了。这个世界同样在(慢慢地)往这个方向移动(例如Windows 用户态驱动和嵌入式系统)。 不管怎么说,让大部分操作系统以用户状态进程运行这个做法是颠覆性的,要让颠覆性的观点成为主导需要一些时间。这样的例子有,FORTRAN, Windows XP, 大型机, QWERTY键盘, x86体系结构,传真机,磁条信用卡还有,隔行扫描的NTSC制式彩色电视标准,在它们被发明时觉得挺合理的,但现在不怎么合理了。然而它们并不会好好地退出历史舞台。例如,根据微软的数据,在2016年3月, 过时的Windows XP仍然运行在2.5亿台计算机上。

 

 教训:一些已经根生蒂固的行为方式难以改变

 

此外,到了一定阶段,计算机会具有更强大的计算能力,效率变得不那么重要了。例如,Android使用Java写的,那比C语言慢很多,但好像没什么人在乎。

我当初在1984年决定在整个系统使用固定长度的消息并且避免动态地分配内存(例如malloc),还有避免在内核中的堆至今都没有给我带来问题,而且这就避免了由于动态内存管理而产生的问题(例如内存泄漏和缓冲区溢出)。
另一个在MINIX中表现很好的是事件驱动模型。 每个驱动和服务器具有一个循环组成了

这种设计使得它们容易单独测试和调试。

在另一方面,MINIX 1 的简洁限制了它的可用性。 缺少像内核多线程和充分的分页机制,在有256kB内存的IBM个人电脑上这个选择是不现实的。 我们本来可以合适的时候添加这些东西的(以及这些特性带来的复杂性),但是我们并没有这样做(尽管我们有做一些工作),并且如今为此付出了代价,因为移植一些软件更加困难了。虽然,基金支持现在已经结束了,MINIX项目并没有结束。它转而成为一个开源项目,就像很多其他的开源项目。现在有不少各种改进正在进行中,包括一些很有趣的(例如可以更新几乎整个操作系统的驱动、文件系统、内存管理以及进程管理部分)到新的主要版本而不用重启5,6 (可能使用了不同的数据结构)。 这些更新不需要关机而且不会影响到正在运行的进程,除了系统会暂停一小会才能继续运行。系统结构由一些服务器结合构成,这使得实时更新比原来的设计更加容易。例如,更新内存管理器而不影响到其他(独立的)组件,因为它们是在不同的地址空间。 在某些系统中,指针在内核里在不同子系统之间传递,要实时更新其中一个组件而不更新所有组件是很困难的。这个领域是少数的我们研究希望将其成果应用到产品中的其中一个。但这是一个重要的,很少(如果有的)其他系统具备的特性。MINIX 3可以在http://www.minix3.org 免费下载。

致谢

我想感谢30年来为MINIX项目做过贡献的数百人。 遗憾的是太多不能在此一一列举。 虽然如此,一些突出贡献者值得特别提名: Kees Bot, Ben Gras, Philip Homburg, Kees Jongenburger, Lionel Sambuc, Arun Thomas, Thomas Veerman, 和 Jan-Mark Wams。这些工作部分由荷兰科学研究组织高级资助227874以及欧洲研究委员会概念验证资助基金 297420 支持

 

参考引用

1. Accetta, M., Baron, R., Golub, D., Rashid, R., Tevian, A., and Young, M. Mach 1986: A new kernel foundation for Unix development. In Proceedings of the USENIX Summer Conference (Atlanta, GA, June 9–13).USENIX Association, Berkeley, CA, 1986, 93–112.
2. Appuswamy, R., van Moolenbroek, D.C., and Tanenbaum, A.S. Loris: A dependable, modular file-based storage stack. In Proceedings of the 16th Pacific Rim International Symposium of Dependable Computing (Tokyo, Dec. 13–15). IEEE Computer Society, Washington, D.C., 2010, 165–174.
3. Brinch Hansen, P. The nucleus of a multiprogramming system. Commun. ACM 13, 4 (Apr. 1970), 238–241.
4. Cheriton, D.R. The V kernel, a software base for distributed systems. IEEE Software 1, 4 (Apr. 1984), 19–42.
5. Giuffrida, C., Iorgulescu, C., Kuijsten, A., and Tanenbaum, A.S. Back to the future: Fault-tolerant
live update with time-traveling state transfer. In Proceedings of the 27th Large Installation System Administration Conference (Washington D.C., Nov. 3–8). USENIX Association, Berkeley, CA, 2013, 89–104.
6. Giuffrida, C., Kuijsten, A., and Tanenbaum, A.S. Safe and automatic live update for operating systems. In Proceedings of the 18th International Conference on Architectural Support for Programming Languages and Operating Systems (Houston, TX, Mar. 16–20). ACM Press, New York, 2013, 279–292.
7. Herder, J. Building a Dependable Operating System, Fault Tolerance in MINIX 3. Ph.D. Thesis, Vrije Universiteit, Amsterdam, the Netherlands, 2010; http://www.cs.vu.nl/~ast/Theses/herder-thesis.pdf
8. Hruby, T., Bos, H., and Tanenbaum, A.S. When slower is faster: On heterogeneous multicores for reliable systems. In Proceedings of the Annual Technical Conference (San Jose, CA, June 26–28). USENIX Association, Berkeley, CA, 2013, 255–266.
9. Klein G., Elphinstone, K., Heiser, G., Andronick, J., Cock, D., Derrin, P., Elkaduwe, D.,Engelhardt, K., Kolanski, R., Norrish, M., Swell, T., Tuch, H., and Winwood, S. seL4: Formal verification of an OS kernel. In Proceedings of the 22nd Symposium on Operating Systems Principles(Big Sky, MT, Oct. 11–14). ACM Press, New York, 2009, 207–220.
10. Liedtke, J. Improving IPC by kernel design. In Proceedings of the 14th ACM Symposium on Operating Systems Principles (Asheville, NC, Dec. 5–8). ACM Press, New York, 1993, 174–188.
11. Liedtke, J. On microkernel construction. In Proceedings of the 15th ACM Symposium on Operating Systems Principles (Copper Mountain Resort, CO, Dec. 3–6). ACM Press, New York, 1995, 237–250.
12. Rozier, M., Abrossimov, V., Armand, F., Boule, I., Gien, M. Guillemont, M., Herrmann, F., Kaiser,C., Langlois, S., Leonard, P., and Neuhauser, W. The CHORUS distributed operating system. Computing Systems Journal 1, 4 (Dec. 1988), 305–370.
13. Saltzer, J.H. and Schroeder, M.D. The protection of information in computer systems. Proceedings of the IEEE 63, 9 (Sept. 1975), 1278–1308.
14. Salus, P.H. A Quarter Century of UNIX. Addison-Wesley, Reading, MA, 1994.
15. Tanenbaum, A.S. Operating Systems Design and Implementation, First Edition. Prentice Hall, Upper Saddle River, NJ, 1987.
16. Tanenbaum, A.S., Herder, J., and Bos, H.J. Can we make operating systems reliable and secure? Computer 39, 5 (May 2006), 44–51.
17. Tanenbaum, A.S. and Mullender, S.J. A capabilitybased distributed operating system. In Proceedings of the Conference on Local Networks & Distributed Office Systems (London, U.K., May 1981), 363–377.
18. Tanenbaum, A.S, van Staveren, H., Keizer, E.G., and Stevenson, J.W. A practical toolkit for making portable compilers. Commun. ACM 26, 9 (Sept. 1983), 654–660.

 

Andrew S. Tanenbaum(ast@cs.vu.nl) 是荷兰阿姆斯特丹自由大学科学院计算机科学系的计算机科学荣誉教授,也是ACM会员。

版权由作者持有

A9R1378dpw_1bpxlzj_ug

 

 

 

 

在这个独家通信视频观看作者谈论他的杰作:http://cacm.acm.org/videos/lessons-learned-from-30-years-of-minix
中文字幕版视频见: Lessons Learned From 30 Years Of Minix(720p_中文字幕)
原文地址: http://cacm.acm.org/magazines/2016/3/198874-lessons-learned-from-30-years-of-minix/fulltext

翻译已经原作者许可

转载请联系: gdouzwt@gmail.com

发表评论