Blackrose's Blog Blackrose's Blog

Mac OS X的内核——三位一体

in growth-logread (311) 文章转载请注明来源!

本文转载自Weiphone论坛,作者fantacyleo(weiphone's id)。遵循CC版权协议。原文链接

乔帮主年轻的时候玩high了,弄出了人命,也就是他的女儿Lisa(话说这女儿果然像老爸):

尽管乔帮主一开始不愿意承认这个女儿(当时也没啥亲子鉴定的高科技玩意儿,乔帮主不承认,孩子妈也没办法),但他还是用Lisa命名了他主持的一个革命性的新项目——带有图形用户界面(GUI)并用鼠标操作的电脑Apple Lisa:

以后的GUI篇中我还会提到这台前卫却在商业上失败的电脑,现在大家所要知道的是,这台电脑的操作系统设计理念在当时的个人电脑领域同样前卫,例如多任务。今天我们早已习以为常的多任务在20世纪80年代的个人电脑中完全是个新鲜事物,比如当时IBM-PC上跑的MS-DOS就不支持多任务(当然也不是完全无解,DOS提供了一个很不靠谱的实现机制。另外,APP可以绕过DOS系统,直接操纵硬件来实现多任务,这种方式当然不安全,软件开发者的一个不小心就会让导致系统崩溃,还记得第一章的那些系统内核崩溃图吗?在后来实现了多任务的Windows系统中,为了兼容老板本的程序,依然允许APP直接访问硬件)。其实多任务只是让用户感觉似乎有多个程序在同时运行,在电脑内部,实际上是多个程序轮流使用CPU,每个时点只有一个程序能够得到CPU的响应。在Lisa OS中,“轮流”是基于自愿的,每个APP执行完自己的任务后,就给OS打个报告说我的任务完成了,OS就让它暂时靠边,把CPU让给其他APP,这被称为协作式多任务(Cooperative Multitasking)。

乔帮主没有等到Lisa开发完成就离开了Lisa项目组,投入了Macintosh的开发。Macintosh成为了世界上第一个在商业上成功的GUI操作系统,然而,Macintosh的操作系统并未实现多任务等先进功能,我猜想这是因为Macintosh的重点是GUI,特别是在GUI的处女秀(Lisa)失败的情况下。当然,乔帮主并没有忘记Lisa OS中的那些前卫设计。

1983年,乔帮主在布朗大学计算机科学系演示了尚未发布的Macintosh电脑。不过,学校里的那些老学究们对GUI这玩意儿并没有太大的兴趣,系主任Andy van Dam就给乔帮主浇了盆冷水,他指出,Macintosh的性能不能满足他们的科研需要。乔帮主说那你有什么要求。Dam说,我要3个M。乔帮主差点把嘴里的水喷出来,老兄,我们是卖电脑的,不玩霓虹国那一套。Dam连忙摆摆手,No,No,No,我说的3个M是指一台具备1兆(Megabyte)以上内存、百万(Million)像素显示屏、每秒百万次浮点运算能力(Megaflop)CPU的电脑。乔帮主定了定神,把水咽回去说,你就不能直说你要一台高配置个人电脑吗,搞电脑我是专家,什么M之类的你该找埃里克施密特去(原谅我让乔帮主穿越了,原谅我调侃了Android)。

Brown大学归来,乔帮主就开始让那3个M的项目上马。这个项目有着一个可口的名字:BigMac(没错,“Big Mac”就是麦当劳大名鼎鼎的明星产品——巨无霸。如果这台电脑成功上市,不知道麦当劳会不会起诉苹果公司):

这个可能就是传说中的BigMac样机

这BigMac作为工作站,和一般的个人电脑还是有些不同的,多种多样的外部设备接口是少不了的,还有什么并行啦,多任务啦,这就意味着操作系统的任务多了、复杂了。苹果公司当时估计还没这方面的经验,而且IT界有一句名言:不要重复发明轮子。历史早已为BigMac准备好了一个优秀的操作系统内核——Unix,也就是本章的主角。

话说20世纪60年代的时候,电脑上用的操作系统还比较落后,于是AT&T、GE等业界大佬联合了学术界大佬MIT就准备搞一个非常先进的操作系统,代号MULTICS。不过,理想丰满,现实骨感,这个项目过于复杂和庞大,以至于多年都没有实质性进展。大事干不了,贝尔实验室的一位工程师Ken Thompson就用MULTICS的半成品来测试自己开发的一款太空打机,呃不对,是太空射击游戏。结果这破系统不但慢得要死,还烧钱,打一次飞机,呃,又错了,是玩一次太空射击要75刀的费用。要放现在,一程序员发现自己设计的游戏跑得慢,他肯定是在自己身上找原因,想方设法优化程序。可贝尔实验室的工程师的想法就不一样,人家压根不认为自己的程序写得有问题,跑得慢是因为操作系统烂。Thompson喊来了同事Dennis Ritchie,两人合写了一个新的操作系统,大名鼎鼎的Unix诞生了! Thompson和Ritchie两位老爷子:

Unix一开始就是先进、前卫的:

引入了数据存储的基本单元——文件。支持先占式多任务(preemptive multitasking)。CPU的分配不再像协作式多任务那样基于自愿,而是完全由操作系统控制(搞编程的应该很熟悉,类似多线程里的运行、阻塞、中断、锁等等),不但可以优化对硬件资源的使用,还从根本上防止了APP中的BUG导致某个程序长时间占用CPU。

强大的网络功能,由加州大学伯克利分校开发的Unix分支,即著名的BSD率先实现了TCP/IP协议,Windows的TCP/IP实现也是参照了BSD中的相关源代码。

Thompson和Ritchie在20世纪70年代初用C语言重写了Unix,从而使Unix获得了极强的可移植性和适应性。Unix被移植到各种硬件平台,从嵌入式系统到大型机都可以看到它的身影。而我们的老朋友Windows则基本上没有可移植性,离开了Intel平台它几乎哪儿也去不了。

Unix+苹果的图形用户界面就是乔帮主为BigMac规划的完美蓝图,也就是说,Mac OS X的基本架构在它诞生前10多年就已经奠定。可惜,乔帮主很快就因为内斗被剥夺了实权,到了后来更是被扫地出门,BigMac也被乔帮主的继任者废止了。但是,在乔帮主心中,BigMac的信念并未熄灭。1985年8月,乔帮主和生物学家、诺奖得主保罗·伯格(PaulBerg)在斯坦福大学会面,又聊起了科研人员对电脑的需求,《乔布斯传》中这样写道:

他们在斯坦福大学的校园里散步,最后在一个小咖啡店里吃午饭,探讨问题。伯格向乔布斯解释了在生物实验室做实验的困难程度,做一个实验并获得结果可能需要数周时间。

“为什么不在计算机上进行模拟实验呢?”乔布斯问道,“这样不仅你自己能够更快地开展实验,而且,有一天,美国的微生物学新生都会用到保罗·伯格的基因重组软件。”

伯格解释说,对于大学实验室来说,具备这种能力的计算机太贵了。“突然间,乔布斯就为这种现状所蕴含的可能性兴奋起来,”伯格回忆说,“他想到要创办一家新企业。他年轻、富有,要为自己今后的生活找点儿事做。”

于是,乔帮主不惜与苹果公司翻脸,带走了负责高校市场的营销干将,以及Lisa项目的部分成员。他决心在他的新王国NeXT公司复活BigMac项目。

Unix无疑是非常优秀的,但随着其不断发展,也开始出现一个问题——内核太大。这里的“内核太大”并不是说内核占用空间大(实际上Unix刚出来的时候,其内核只占用12K的内存),而是说内核要操心的事情太多。在现代操作系统中,一个普通的APP不能想干啥就干啥,一不高兴把内存中属于内核的数据改了,引起系统崩溃那还得了。所以,现代操作系统中,一个APP启动时通常都被限制在一个被称为“用户态”的筐里,能做的事情有限。APP想做点更高级的动作咋办?那就必须向内核打报告,让内核把APP临时提升到“内核态”(关于内核态和用户态,请参阅http://book.51cto.com/art/201001/177431.htm),任务完成后再打回“用户态”。但是这一来一回的切换要耗费时间,对于一些要基础性、需要大量重复执行的程序来说,每次都要打报告显然效率很低。对此,操作系统的设计者可以把这些程序安排在“内核态”执行,这些程序通常包括进程管理、文件管理、输入输出管理、硬件驱动等,具备此特点的内核被称为“宏内核”。传统的Unix、早期的Windows和Linux内核都是宏内核。宏内核避免了“用户态”和“内核态”的频繁切换,执行效率最高,但缺点也很致命。在内核态中运行的程序只要出一丁点错,都有可能让整个系统崩溃。你把越多的东西放到内核,崩溃几率也就越大。

站在宏内核对立面的是微内核。微内核只把少数核心的操作系统功能放进内核态,其他的通通作为外*挂服务,挂载在内核之外,以用户态启动,即使某一服务出错,也不容易造成整个系统崩溃。当然其缺点也是显而易见,频繁的用户态和内核态切换,以及不同服务之间的通讯(IPC),都要耗费更多的时间,降低效率。

这两种内核形态各有优劣,也可以互相学习,共同进步。不过有人的地方就有纷争,关于两种内核优劣的争议不断,其中最著名的当属Linus和Tanenbaum之间的大辩论(其实这两人可算是师生,Tanenbaum开发了Minix用于课堂教学,而Linus上课时不满于Minix过于简单,就加以改进并发明了Linux系统。),我这里给出google group上的完整版:。也有很多人试图找出操作系统功能在用户态和内核态之间的最优划分,即所谓的混合内核。Mac OS X和现在大家用的win版本皆属此类。我详述不同的内核形态,一是为了引出Mac OS X的内核特点,二是为第三章的内容作个铺垫。有了宏内核、微内核、混合内核的概念,第三章的小故事看起来会更有趣。

下面该回到我们的故事主线,乔帮主的BigMac计划,嗯,等一下,在NeXT,它有了个新名字,叫NeXTSTEP。乔帮主向来讲究软硬件不分家,承载NeXTSTEP的硬件叫NeXT计算机,由Lisa项目的原班人马负责,而NeXTSTEP OS则由卡内基梅隆大学的高材生Avie Tevanian博士负责。

Avie Tevanian:

前面说过,Unix是宏内核,随着功能的不断扩展,内核日渐臃肿,卡内基梅隆大学就想搞一个没那么臃肿但又与Unix兼容的系统,取名为Mach,Avie Tevanian便是开发组中的干将之一。Mach的终极目标就是走到Unix的对立面,成为一个纯粹的微内核,而把部分Unix的功能作为外*挂服务。但这家伙也是个理想丰满现实骨感的典型。Mach的起点就是BSD Unix的源代码,开发人员试图将新理念和新代码逐步替换原有代码,最终完成一个新系统。可是,直到2.5版本,Mach内核都还是一个未能摆脱Unix的宏内核。

Tevanian领*导下的软件组当然采用了Mach,并于1988年10月12日发布了NeXTSTEP OS预览版(0.8版),第二年9月18日发布1.0版。从3.1版开始,NeXTSTEP OS又包括了一个用Objective-C写的全新的驱动程序框架Driver Kit,但Unix和Mach仍未彻底分开。后来,Mach 3.0内核终于将Mach和Unix服务完全独立,到1997年NeXT被苹果公司收购前,NeXTSTEP OS(其实已经改名为OPENSTEP)也采用了Mach 3.0,形成Mach、BSD Unix服务、Driver Kit三合一的OS底层,这已经非常接近Mac OS X的架构了。

NeXTSTEP OS的GUI:

乔帮主回归后,Tevanian担任苹果公司软件技术的主管,Mac OS X的底层也沿用NeXTSTEP的架构,但又有所不同。其中Mach改用一个名为osfmk的变体,BSD在2000年之后逐步转向FreeBSD,而最惨的当属Driver Kit,不但改了个名叫I/O Kit,连实现它的编程语言都改成了C++,按“Mac OS X背后的故事(三)”中的说法,这是为了“迎合大众的口味”。我认为,NeXT岁月对乔帮主最大的影响就是让他那张扬、特立独行的性格有所收敛。根据《乔布斯传》的描述,帮主原来连电路板印刷工厂都要亲自设计,亲自监督,后来他终于放弃这种古怪的偏好,将电路板制造外包出去了。

2000年Mac OS X public beta发布会上,乔帮主的keynotes中,BSD已经换成了FreeBSD:

就这样,Mach、FreeBSD、I/O Kit三位一体的Mac OS X内核正式成型,它被称作XNU:

在苹果的开发者文档中,经常把文件系统和网络功能与Mach、FreeBSD、I/O Kit并列,例如这里。但文档里也明确说明,Mac OS X中的文件系统和网络功能也都是基于Unix,最明显的,大家打开“实用工具”里的“终端”,输入命令“ls /”看看列出来的那些/usr /bin /dev文件夹都是标准的Unix文件夹。因此,我只把Mac OS X的内核分为Mach、FreeBSD、I/O Kit三部分。

XNU是完全开源的,它的各版本源代码可以在这里找到:http://www.opensource.apple.com/source/xnu/ 。 XNU加上一些被称为“Core OS”和“Core Service”的开源工具,就构成了一个完整的不带GUI的操作系统(Mac OS X的GUI是有版权的,不开源),也就是大家熟知的Darwin。Darwin是个完整的开源操作系统,而XNU是它的内核。

文章二维码

扫描二维码,在手机上阅读!

mac
发表新评论
博客已萌萌哒运行
© 2018 由 Typecho 强力驱动.Theme by Yodu
前篇 后篇
雷姆
拉姆