文章目录
我们已经知道 macOS 的内核主要是由 BSD 和 Mach 组成,但是为什么是这样的混合设计呢?
Amit Singh 的 《Mac OS X Internals》一书在开头就介绍了从 Apple OS X 诞生的历史,几年前刚买这本书的时候我还觉得为啥讲这么长的故事一直不进入“干货”部分。现在回过头来看,正是作者介绍了这段历史,后面内核中一些有点疑惑的地方才顺理成章。
本文主要来自 Amit Singh 书中所述,再加上我查阅的资料所写。年代久远,如有谬误,烦请诸位不吝雅正。
一、苹果公司早期(1972-1991)
乔布斯(Steve Jobs)和史蒂夫·沃茲尼克(Steve Wozniak) 1976 创办苹果公司,关于这家公司的故事已经广为流传,Mac OS X 的诞生也与乔布斯后来的回归息息相关。我们知道乔布斯离开苹果后创办了 NeXT 公司,也知道今天我们开发的 iOS/macOS 系统跟 NeXTSTEP 系统有千丝万缕的关系。但是乔布斯一回归 NeXTSTEP 就变成今天的 macOS 了吗?并不是,历史的道路是非常曲折的。
时间回到 1977 年,乔布斯在 West Coast Computer Faire 发布了 Apple II 这款个人电脑,这是苹果公司对外发售的第一款消费级个人电脑。这款产品大获成功,也让两位创始人成为百万富翁。
1984 年 1 月 22 日,苹果在超级碗(Super Bowl)中场休息时播放了一个堪称历史经典的广告—— 《1984》 ,以此发布新产品 Macintosh 计算机。
但是在苹果公司内部,与 Macintosh 研发的同一时期,乔布斯还带领了一个团队开发 Lisa 电脑(1983 年发布)。现在我们知道这是一个失败的产品,并且乔布斯也于 1985 年被董事会赶出了苹果,后来自己创办了 NeXT 公司。
一晃四年过去,1988 年苹果的团队在开会讨论下一代操作系统应该带上什么特性。他们在白板上用三种颜色的便利贴表示不同的 idea:
- 蓝色 是对现有系统的改进,最终将合入 System 7 版本
- 粉红色 则代表革命性的特性: 面向对象特性,内存保护,轻量级多线程多任务处理等等
- 红色 是比粉红色还要革命的超前特性
当时 Macintosh 上跑的系统版本是闭源的 System 6,1988 年 4 月发布,苹果自家的很多产品都使用这个系统。在这个阶段,苹果的图形界面操作系统依然还是处于比较领先的地位,市面上有 GUI 的操作系统还不算多 ,做得好的更没几个。但是苹果的下一代系统 System 7 的研发却出现了问题,一连好几年没法发布。
这时候隔壁家微软已经在 1990 年发布了 Windows 3.0 (1.0 和 2.0 市场反响都一般),借此一炮而红,成为当年最流行的图形界面操作系统。
1991 年苹果终于发布了 System 7 版本,但是这些“蓝色”的 idea 不过是对现有系统的改进,并没有特别大的突破。
而微软在 Windows 3.0 成功后,又继续在操作系统上发力。当时微软内部有一个代号为 Chicago 的项目,原计划在 1993 年发布。但是项目一直延期,最终在 1995 年才终于面世。这款产品就是广为人知的 Windows 95。除了家用系统,微软在 1993 年也发布了面向服务器的 Windows NT 系统,自带网络服务, NTFS 文件系统,支持 Win32 API。
反过来看苹果,却陷入了深深的危机。1998 年开始苹果一直在探索自家操作系统未来的方向。除了已经发布的“蓝色” System 7,“粉红色”的部分苹果与 IBM 合作,成立 Taligent 公司试图研发下一代操作系统,但是该项目一直没有产出,直到最后公司被 IBM 收购也没有对外发布过任何系统。
至于更加激进的“红色”项目,代号为 Raptor,则无疾而终。个中细节在网络上未有记录,只在《Mac OS X Internals》一书有所提及。可以说 1990 年代的苹果,正在一步步走向深渊。
二、苹果在操作系统上的尝试(1991-1997)
面对微软的挑战,苹果做了很多操作系统的探索和尝试,内部开发与外部合作兼备。当时的 CPU 还不像今天基本只剩 Intel 和 AMD 两家(手机端基本都是 ARM),Macintosh 的机器使用的是摩托罗拉 68K 系列的 CPU,而 Windows 则使用的是 Intel 的 x86 系列 CPU。68K CPU 虽然能提供 Intel 486 一样的能力但是发热比 486 高,这时候如果苹果也开始迁移到 Intel 平台那可能历史就改写了。
Intel 的 CEO Andy Grove 还找过苹果,期望能让 Macintosh 支持 Intel CPU。但是当时苹果评估之后觉得 Intel 的 CISC (复杂指令集) 设计未来肯定打不过 RISC (精简指令集),所以没有投入 Intel 的怀抱。他们选择了与 IBM, 摩托罗拉合作成立 AIM 联盟,研发 RISC 的 PowerPC CPU。
1994 年苹果发布的高性能机器 Power Macintosh 首次搭载了这颗芯片,在市场上获得不错的反响,在 9 个月内卖出超过 100 万台。但是长期来看当时没有选择 Intel 是个 错误的决定 。
2.1 Star Trek 项目 (1992-1993)
但是研发 PowerPC 的同时,苹果也没有放弃 Intel x86 架构。1992 年他们跟 Novell 公司合作,打算把 System 7 移植到 x86 架构上。苹果有操作系统经验,Novell 则有跨平台经验。但是 1993 年中,PC 价格战开始后因为业绩压力董事会把 CEO John Sculley (也就是那位著名的卖可乐的 CEO,也是他把乔布斯赶走的)辞退了,新任 CEO Michael Spindler 对 Intel 不感兴趣于是这个项目就被取消了。
2.2 Copland-Mac OS 8 (1994-1996)
Michael Spindler 在 CEO 的位子只坐了 3 年,他在职期间发布了 PowerPC 倒是挺成功的,但是后来的 Newton 和 Copland 操作系统却均是失败之作。
苹果一直以来都自信自家的产品能提供远超其他产品的用户体验,但是随着 Windows 95 的发布这种差距在缩小,并且随着 PC 价格的下降苹果的性价比已然极低,于是苹果急于让自家的操作系统提供远超微软 Windows 的能力。
从 System 7.6 开始,Macintosh 的操作系统正式改名为 Mac OS 8。1994 年苹果宣布 Mac OS 8 将提供非常革命性的新特性,项目代号为 Copland。
Copland 的目标包括拥抱 RISC 让整个系统原生支持 PowerPC 架构,集成并改进苹果现有的技术比如 OpenDoc,ColorSync 等等。保留现有的 Mac OS 界面并提供可自定义的能力。扩展系统能力,允许跟 DOS 和 Windows 系统协作。支持多用户登录,以及一些其他革命性的特性。
一开始这个项目在公司内是非常激动人心的,1995 年还对 50 个 Mac 开发者放出了 Beta 版。但是从那以后,Copland 就再也没有更新过,也从来没有正式对外发布过。
当时的苹果公司已经负债累累,John Sculley 辞职的时候苹果公司还有 20 亿美元的现金与 2 亿美元的负债。到了 1996 年,有超过 500 名工程师投入到 Copland 项目中,光这个项目一年就要花去 2.5 亿美元的预算。那一年苹果亏损 7.4 亿美元,CEO Michael Spindler 被辞退,Gil Amelio 上任,该项目被正式取消。
Gil 后来在他的 《On the Firing Line: My 500 Days at Apple》一书中是这样描述这个项目的:
just a collection of separate pieces, each being worked on by a different team… that were expected to magically come together somehow…
Copland 项目虽然失败了,但是它让苹果重新思考了自家操作系统的定位,同时感受到了强烈的生存危机,毕竟从 1991 年发布 System 7 到 1997 年之间,苹果一直没能发布一个正式的大版本。
此时的苹果急需寻找一款足够优秀的操作系统来拯救苹果。这时候收购一个操作系统公司的选项浮出水面。差不多是时候乔布斯要出场了,但是在他出现之前,还有另外一家公司成为苹果的候选。
三、收购与转折(1996-1997)
1996 年 Gil Amelio 上任后苹果已岌岌可危。当时考虑过跟微软合作,开发基于 Windows NT 的 Apple OS。同时也考虑采用 Sun 公司的 Solaris 系统,或者收购 Be 公司的 BeOS。
Be 公司也跟 Apple 颇有渊源,甚至有点狗血。BeOS 的创始人 Jean-Louis Gassée 曾经是苹果公司欧洲运营负责人。1985 年 Gassée 得知乔布斯准备把当时人还在中国的 CEO John Sculley 赶走的时候,通知了 John Sculley,于是 Sculley 召开了董事会讨论这件事情。当时乔布斯在苹果内部可谓是众叛亲离,这是他自己盲目自信带来的后果。当时他利用自己的权威给 Macintosh 部门很多资源,员工的收入都比隔壁 Apple II 高得多,但实际上 Apple II 才是真正贡献公司利润的部门。1985 年初连创始人史蒂夫·沃茲尼克也离开了苹果,连带着很多高层也相继离开。所以最终董事会站在 Sculley 这边,反而把乔布斯赶走了。
John Sculley 成功把乔布斯赶走了之后,就让 Gassée 主管 Macintosh 产品。1988 年 Gassée 主管苹果的高级产品开发和全球市场,有传言称他要取代 Sculley 成为 CEO。不过 1990 年他就被 Sculley 和其他董事会成员要求离职了。
1991 年离开苹果之后 Gassée 创办了 Be 公司,带走了一堆苹果员工。他们开发了 BeOS,能在 PowerPC 上跑,目标很明确就是希望苹果可以收购他们,取代前面说的已经快挂掉的 Mac OS。BeOS 的特性很多,首先可以在 PowerPC 运行,然后支持内存保护,抢占式多任务,支持对称多处理等等。但是,BeOS 当时还没有完全实现,也并没有经历过市场的考验。
1996 年苹果给 Be 开价 5000 万美元(Be 公司的总投资大约 2000 万美元),但是 Gassée 非常自信地给出 5 亿美元回价。苹果又协商给 1.25 亿,Gassée 回 3 亿,苹果再开价 2 亿,但是 Gassée 仍不接受,给了个最终价 2.75 亿。
于是交易告吹。
苹果于同年底宣布以 4 亿美元收购了乔布斯的 NeXT,1997 年 2 月正式完成收购,乔帮主回归苹果,7 月份说服董事会辞退 Amelio,自己成为公司 CEO,开启了苹果的新世纪。
四、NeXT 篇章
NeXT 的操作系统 NEXTSTEP (也写作 NeXTstep, NeXTStep) 跟 BeOS 不一样,它是经历过市场验证的。苹果当时的 CEO Amelio 还戏称这场收购是用 “plan A” 取代了 “plan Be”。
最终 NEXTSTEP 与 Mac OS 的结合诞生了如今我们使用的 Mac OS X (macOS)。不过并不是说乔布斯一回到苹果这系统就整合完了,他的回归到 OS X 诞生大约隔了 3 年。
4.1 NEXTSTEP(1985-1997)
1985 年乔布斯离开苹果的时候,带走了 5 个苹果员工创办 NeXT 公司,专做面向教育的产品。四年后,1988 年 10 月 12 日, 乔布斯在旧金山市区的 Davies Symphony Hall 发布了 NeXT Computer ,跑在上面的操作系统就是 NEXTSTEP。
NeXT 公司的创始团队还包括来自 CMU Mach 内核的团队的成员 Avie Tevanian。他是 Mach 内核的主要设计者和开发者之一。所以 NEXTSTEP 系统从第一天起就是基于 Mach 和 BSD 内核进行开发。当时发布的第一个版本采用的是 Mach 2.0 版本和 BSD 4.3 版本。Avie Tevanian 后来也成为苹果公司软件工程的高级 VP,2003 年当上 CTO,2006 年离职。
NEXTSTEP 系统提供了图形界面和 Unix 风格的命令行操作。可以说今天我们见到的 macOS 的很多特性都来自于 NEXTSTEP。比如说:Application Kit。
1992 年,NEXTSTEP 发布了可以跑在 x86 架构上的版本。当时它们可以支持在 68K(摩托罗拉), x86(英特尔), PA-RISC(惠普), SPARC(Sun)等多种不同的芯片上运行。并且可以把多种架构的代码打包成一个 fat binary,也就是我们今天在 iOS 上常见的所谓 Universal Binary。
4.2 OpenStep(1993-1997)
NeXT 公司还和 Sun 公司合作开发了 OpenStep。这是一套能跑在 SunOS, HP-UX 和 Windows NT 上的面向对象的接口。基于这个接口,一个精简版的 NEXTSTEP 就可以跑在支持这个接口的机器上。1994 年 OpenStep 发布了第一个版本。
不过没多久 NeXT 公司就转而专注在 WebObjects 技术上了。1996 年乔布斯还在微软的 Professional Developers conference 演示了这一技术: [Microsoft Professional Developers Conference 1996 Keynote Speaker: Steve Jobs](Microsoft Professional Developers conference)
WebObjects 简单说这个技术就是用 Java 开发网站的技术。这项技术在 NeXT 被苹果收购之后也用在了部分苹果产品上,但是从 2008 年开始就不更新了,2016 年官方宣布中止开发。据称目前还用于 Apple Store 以及 iTunes Store 的一部分,不过除非内部负责该项目的开发者,不然无从考证了。
五、Mach 的历史
我们知道 Mach 是 NEXTSTEP 以及后来的 OS X 非常重要的组成部分。它是由 CMU (Carnegie Mellon University) 开发的微内核。它的前身是 CMU 开发的 Accent 内核,Accent 的前身则是 UR (University of Rochester) 开发的 RIG (Rochester’s Intelligent Gateway) 项目的一部分。
5.1 Rochester’s Intelligent Gateway (1976)
1975 年一群来自罗切斯特大学(University of Rochester)的学者在开发一个智能网关系统,叫做 RIG (Rochester’s Intelligent Gateway)。这个项目跑在 Aleph 系统上,这个系统跑在 Data General 公司的 Eclipse 小型机上。
这个内核的主要功能是提供 IPC 能力(interprocess communication),也就是我们常说的“进程间通信”。我们可以从 Aleph 的 IPC 抽象上看到 Mach IPC 的设计。系统采用 Message 在多个进程间传递信息,采用 Port 来对应信息的接收方。跟后来的 Mach 设计是一样的。但是当时这个系统有几个非常严重的基础缺陷,比如说:
- 没有虚拟内存换页支持
- 一条消息最多只有 2KB (因为当时的硬件限制)
- 效率很低的 IPC 通信因为 message size 就 2KB
- 没有网络设计
关于 RIG 的论文可以到 这里下载 。
5.2 Accent (1981-1985)
RIG 项目的其中一个成员——也是 RIG 论文的作者之一——Richard Rashid 在 1979 年转到 CMU 当教授。在 CMU 工作的其中一个项目就是 Accent 内核,从 1981 年开始正式启动。这个内核面向的是网络操作系统。作为一个面向通信的系统,Accent 也采用了类似 RIG IPC 通信方式的设计,不过做了很多改进:
- 支持虚拟内存,进程有 4GB 内存可供使用
- 强大的虚拟内存管理设计,甚至连内核自身都能被换出,除了部分关键内存被 wire 到物理内存上(还记得我们之前分析内存接口的时候有一个 wire 类型的内存占用吗?)
- Cop-onwrite 技术支持更大的消息体
- ports 的设计具备语义性和能力描述(应该指的是后来 Mach Port 的 rights)
- 消息体通过一个中间进程传递(跟后来的 Mach Port 设计非常像了)
看起来 Accent 比 RIG 好多了,但是这个内核设计的时候是跑在 PERQ 工作站上的。虽然它拥有很多厉害的特性但是设计的时候非常依赖硬件,也不支持 Unix 软件运行。
为了支持 Unix, Richard Rashid 开始了 Mach 项目,并于 1985 年发布了第一个版本。这位厉害的学者因为 Mach 一战成名,1991 年加入微软,后来成为微软的 VP 直到 2012 年。
关于 Accent 的论文可以到 这里下载 。
5.3 Mach (1985-1994)
Mach 内核的设计目标之一是要兼容 Unix 系统。在这个项目启动的时候,Unix 已经存在了 15 年之久,有大量的 feature 被集合到这个巨大的内核里。
Richard 甚至把 Unix 戏称为”所有新特性或功能的垃圾场”(dumping ground for virtually every new feature or facility)。所以 Mach 项目就是要设计一个可以作为其他操作系统内核基础的一个微内核,他们的目标包括:
- 提供完整的多进程支持
- 分离现代硬件相关架构实现代码,支持多种硬件架构。
- 支持透明性与分布式操作,原文是
Support transparent and seamless distributed operation
这个我没太理解,猜测和分布式操作系统是类似的意思。理解的读者朋友可以留言指点一下。 - 精简内核特性,降低复杂度,给出最小的抽象接口,让 App 或者其他操作系统可以在 Mach 内核上运行
- 兼容 Unix
- 解决 Accent 系统中的一些缺陷与不足
Mach 内核设计的时候主要 focus 在 CPU 支持与内存管理上,没有考虑支持文件系统,网络接口或者设备 I/O 接口。当初他们的设想是,真正的操作系统可以作为一个用户态的程序跑在 Mach 内核上。Mach 内核采用 C 语言开发,这意味着可以很轻易地移植到各个平台。
Mach 内核开发的时候以 4.3BSD 为基础进行开发。Richard 由于有 RIG 和 Accent 的经验,在 Mach 内核的设计上可谓驾轻就熟。1986 年正式对外发布的时候,他们在论文上称这是”为 UNIX 开发的一个新内核”。
当时选择新的 Mach 内核作为自家操作系统内核的,不止 NeXT 一家。1994 年苹果还没收购 NeXT 之前,在 Copland 项目中也用 Mach 3.0 作为系统内核。但是在对外公布的测试版中却极其不稳定。这个内核项目叫做 NuKernel,当然后来也随着 Copland 项目的结束也无疾而终。
Mach 内核的基础抽象
在前面的文章中我们也提到过 Mach 内核的一些基本抽象,这里还是简单介绍一下:
- task 表示一个或多个线程资源的集合,资源包括内存,ports(翻译成端口好像不太合适), CPU 核心等等。我们可以简单理解为大家熟悉的“进程”。
- thread (线程)是一个 task 的基本执行单元。 task 负责提供线程的运行环境,多个线程共享相同的资源。这点与 Accent 不同,Process 被进一步分为 task 和多个 threads。
- port 跟 Accent 的 port 很像,也是一个内核维护的消息队列,用于 IPC 通信。在 Mach 里一个 port 表示为一个整数。
- message (消息)就是用于 IPC 的结构体,可以在不同的 task 之间通信,也可以在同一个 task 里的不同 thread 通信。
- memory object 可以看成是映射到一个 task 内存空间的的一个数据集合(包括文件数据)。Mach 的内存管理分为 pmap 物理内存层和 vmmap 虚拟内存层。需要 PMMU 硬件支持换入换出,现代 CPU 都集成 MMU 了,当年的 MMU 还是外置的。
当年 CMU 做了一个非常重要的决定,就是 Mach 内核开源且无任何 licensing 约束。这意味着任何人都可以免费发行 Mach 内核。
5.4 MkLinux (1996)
1996 年 12 月苹果宣布收购 NeXT 公司 , 但是在那之前,2 月份苹果就已经开始了一个特别的项目:把 Linux 移植到 PowerPC 平台,让 Macintosh 机器也能跑 Linux 。
这个项目的产品叫做 MkLinux , 由 OSF ( Open Software Foundation ) 和苹果公司联合开发的,目标是让 Linux 内核跑在 Mach 3.0 内核上。
OSF 早期的成立是为了给 UNIX 系统提供一个开放标准。在 CMU 开发 Mach 2.5 版本的时候,OSF 宣布用于其开发的 OSF/1 系统,并将 host Mach 内核的未来版本。事实上 Mach 3.0 版本是从 CMU 开始,后来也是由 OSF 开发完成。当时 NEXTSTEP 用的是 Mach 2.x 内核。
1996 年在 WWDC 上苹果公司 正式宣布将把 Linux 移植到 Power Macintosh 机器上 ,名为 MkLinux (Microkernel Linux)。
这个项目后来也随着 OS X 的整合而终止,交回给社区维护。但是这个项目对苹果整合 NEXTSTEP 帮助不小,在官方的 Kernel Programming Guide 有曰:
OS X is based on the Mach 3.0 microkernel, designed by Carnegie Mellon University, and later adapted to the Power Macintosh by Apple and the Open Software Foundation Research Institute (now part of Silicomp). This was known as osfmk, and was part of MkLinux (http://www.mklinux.org). Later, this and code from OSF’s commercial development efforts were incorporated into Darwin’s kernel.
这也是为什么我们看 XNU 代码里面,Mach 的部分都放在 osfmk 目录下。目前 MkLinux 社区也没什么声音了,最后一个发布版本在 2002 年。
P.S. osfmk 就是 Open Software Foundation Mach Kernel 的缩写。
5.5 Mach 内核的性能问题
前面我们提到 CMU 开发 Mach 内核时嫌弃传统 UNIX 内核什么都干,过于臃肿。所以设计目标是要取代 UNIX,让 UNIX 跑在 Mach 内核的用户空间里。这个特性在 Mach 3.0 真正实现了。但是众所周知 Mach 内核并不提供文件系统和网络实现,所以依然需要和 UNIX 做大量的数据交换。这种交换的方式就是通过 Mach 的 IPC 通信。而让几乎所有进程都在两个空间之间做 IPC 通信是非常低效 的。
所以 NEXTSTEP 系统修改了 Mach 内核的实现,让 Mach 和 BSD 都跑在同样的内核空间上,同时让用户空间发起的文件、网络请求等本来要通过 IPC 调用的接口都改成 system call。
六、OS X (1997-)
1997 年 1 月份 Macworld 上的演讲是乔布斯回归后的第一次登台,讲了一堆苹果过去十年犯下的错误之后,宣布 Rhapsody 项目,很有救世主之风。
同年 WWDC 是乔布斯第一次演示了 Rhapsody 的 demo。在他登台之后,现场响起了绵延不绝的掌声。
Rhapsody 基于 NeXT 的 OPENSTEP 开发,可以认为是 Mac OS X 的过渡产品。经过漫长的研发阶段,终于在 2000 年 12 月正式发布第一个 Public Beta 版。这期间大概的时间线是这样的:
- 1997 Rhapsody 项目开始
- 1999 发布 Mac OS X Server 1.0
- 2000 发布 Mac OS X Public Beta
- 2001 发布 Mac OS X 10.0
其中在 1999 开始开源了系统的核心部分,名为 Darwin。其核心就来自 NEXTSTEP 的 XNU,也就是 Mach/BSD 混合内核。Mach 部分更新了 OSFMK 的 Mach 3.0 和部分来自 University of Utah 的 Mach 4 项目,BSD 部分更新了 FreeBSD 项目的代码。早期苹果甚至提供了 Darwin 安装包,可以作为一个独立系统安装到 x86 和 PowerPC 机器上。不过现在只开放源代码了。
2000 年乔布斯在 Macworld Expo 上首次介绍了 Mac OS X,演讲风格非常乔帮主,有兴趣的朋友可以看看: Macworld San Francisco 2000-The Mac OS X Introduction (Pt.1) – YouTube
严格来说现在我们接触到的 macOS 内核,官方叫做 Darwin,它的核心是 XNU,可以独立安装。严格意义上 XNU 和 Darwin 并不完全相等,较真地讲 XNU 只是 Mach/BSD 部分。在前面的文章里我基本上把 Darwin 和 XNU 当做同义词,这并不严谨。但是根据我的考证,目前 Darwin, XNU 和 macOS Kernel 基本等同于一个意思,只要读者朋友不会产生歧义即可。
使用 uname -a
可以查看自己的系统版本:
Darwin xxx.local 19.0.0 Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64 x86_64
Mach 内核最初的设计是一个微内核,但是现在 Darwin 已经是一个什么都干的宏内核(Monolithic kernel)了。在看这段历史的时候颇有一种天下大势,分久必合,合久必分的感觉。想想从 1971 年第一个 Unix 版本到现在(2019 年)已经 48 年过去了,OS X 10.0 也过去 18 年了。2016 年,苹果在 WWDC 宣布 OS X 改名为 macOS。
风云变幻几十年,既有技术的发展也有商业的博弈,很多今天看起来完全看不懂的代码,都是当年历史遗留的未解之谜。XNU 代码里的注释,也有历史的痕迹:
/* * Well-known UDP port, debugger side. * FIXME: This is what the 68K guys use, but beats me how they chose it... */#define KDP_REMOTE_PORT 41139
/* pick one and register it */
至少现在我终于明白,什么是 68K guys 了。XDDD