第1章 Unix 与 Linux 简介(The History of Operating Systems)
一、导读
1.1 本章学习目标
了解 Unix 操作系统的起源、发展及其对现代操作系统设计的深远影响
理解 Linux 内核的诞生背景以及 Linus Torvalds 创建 Linux 的动机
掌握 GNU 计划与开源运动的核心理念,理解 GPL 许可证的法律意义
熟悉 Linux 内核版本号的命名规则及版本演进的历史脉络
了解 Linux 内核社区的组织结构、开发流程与代码审查机制
理解 Unix 设计哲学(小即是美、模块化、文本流)如何体现在 Linux 内核设计中
认识 Linux 在服务器、嵌入式、移动设备(Android)等领域的广泛应用
1.2 为什么本章如此重要
学习 Linux 内核,不仅仅是学习一段代码,更是理解一种设计哲学和一种协作模式。Unix 诞生于 1969 年的贝尔实验室,由 Ken Thompson 和 Dennis Ritchie 共同开发。它的设计思想——"每个程序只做一件事并把它做好"、"一切皆文件"、"通过管道组合程序"——深刻影响了后续几乎所有操作系统的设计。Linux 内核正是这一哲学传统的继承者和发扬者。
Linux 的成功不仅仅是技术上的成功,更是开源协作模式的成功。1991 年,芬兰赫尔辛基大学的学生 Linus Torvalds 出于个人兴趣,开始编写一个类 Unix 的操作系统内核。他将源码发布到互联网上,吸引了全球数以万计的开发者参与贡献。这种"集市式"的开发模式(相对于传统的"大教堂式"开发),被 Eric Raymond 在《The Cathedral and the Bazaar》一书中详细阐述,成为开源运动的经典案例。
理解 Linux 的历史背景和社区文化,对于阅读内核源码至关重要。内核中的许多设计决策,都需要放在特定的历史语境中才能理解。例如,为什么内核代码风格如此严格?为什么某些看似过时的代码仍然存在?为什么社区对向后兼容性如此执着?这些问题的答案都藏在 Linux 的发展历程之中。
1.3 核心问题引导
Unix 操作系统最初是在什么硬件上开发的?它的可移植性是如何实现的?
GNU 计划与 Linux 内核之间的关系是什么?为什么说 Linux 严格来说应该叫 GNU/Linux?
GPL 许可证与 BSD 许可证的核心区别是什么?这对 Linux 的商业应用有何影响?
Linux 内核的版本号在 2.6.x 之后发生了什么变化?为什么取消了偶数/奇数的区分?
Linux 内核的维护者层级结构是怎样的?一个补丁从提交到合入需要经过哪些步骤?
Unix 的"管道"设计哲学如何影响了 Linux 内核的 I/O 子系统?
为什么 Linus Torvalds 选择 C 语言而不是汇编语言来编写 Linux 内核?
二、核心概念详解
2.1 Unix 的历史与设计哲学
Unix 的故事始于 1965 年的 Multics 项目,该项目由 MIT、GE 和贝尔实验室联合开发,旨在创建一个支持多用户、多任务的大型操作系统。Multics 虽然在技术上非常先进,但其复杂性最终导致了项目的失败。1969 年,贝尔实验室的 Ken Thompson 在 PDP-7 小型机上编写了 Unix 的原型,最初只是为了玩一个太空旅行游戏。Dennis Ritchie 随后发明了 C 语言(1972 年),并用 C 重写了 Unix,使其成为第一个可移植的操作系统。
Unix 的设计哲学可以概括为几条核心原则:第一,"小即是美"(Small is Beautiful),每个程序应该只做一件事并把它做好;第二,"一切皆文件",所有设备和服务都通过文件描述符接口访问;第三,通过管道(pipe)将小程序组合成复杂功能;第四,使用纯文本作为通用的数据交换格式。这些原则不仅影响了 Linux,也深刻塑造了整个软件工程的思维方式。
在 Unix 的发展过程中,出现了多个重要的分支:AT&T 的 System V、伯克利的 BSD(Berkeley Software Distribution)以及 DEC 的 Ultrix 等。这些分支之间的竞争和融合,形成了所谓的"Unix 战争"。最终,POSIX 标准试图统一这些分歧,而 Linux 在很大程度上遵循了 POSIX 规范。
2.2 Linux 的诞生与开源运动
1991 年 8 月 25 日,Linus Torvalds 在 comp.os.minix 新闻组发布了一条著名的消息:"Hello everybody out there using minix - I'm doing a (free) operating system (just a hobby, won't be big and professional like gnu)..."。这条消息标志着 Linux 内核项目的诞生。Linus 最初的目标是创建一个类似 Minix 的系统,但他很快决定将其发展为一个完整的、自由的操作系统内核。
Linux 的成功离不开 Richard Stallman 发起的 GNU 计划。GNU 计划始于 1983 年,目标是创建一个完全自由的类 Unix 操作系统。到 1991 年,GNU 已经完成了编译器(GCC)、编辑器(Emacs)、Shell(Bash)等关键工具,但缺少一个可用的内核(GNU Hurd 开发进展缓慢)。Linux 内核恰好填补了这一空白,与 GNU 工具链结合后形成了完整的操作系统。
开源运动的发展经历了几个重要阶段:1998 年,"Open Source"一词被正式提出,取代了带有意识形态色彩的"Free Software"说法,更容易被商业世界接受。2000 年代,IBM、Intel、Oracle 等大公司开始大规模投资 Linux 开发。2007 年,Android 的发布将 Linux 带入了移动设备领域。今天,Linux 运行在全球超过 96% 的服务器、所有超级计算机(TOP 500)以及数十亿台 Android 设备上。
2.3 内核版本管理与发布流程
Linux 内核的版本号经历了多次变化。早期(1.x 时代),奇数次版本号表示开发版本,偶数次表示稳定版本。2.6.x 时代取消了这一规则,所有 2.6.x 版本都可能是稳定版本。2011 年,Linus 宣布将版本号改为 3.x,主要是为了消除人们对"2.6.x 版本号越来越大"的困惑。目前(截至本书写作时),Linux 内核已经进入 6.x 时代。
内核的发布周期大约为每 9-10 周一个主版本。每个主版本发布后,会有一系列的稳定版本(stable)更新,修复 bug 和安全漏洞。长期支持版本(LTS)由 Greg Kroah-Hartman 等人维护,提供数年的安全更新。
内核的开发流程有着严格的层级结构。最顶层是 Linus Torvalds,他是最终的决策者。在他之下是各个子系统的维护者(Subsystem Maintainers),负责审查特定领域(如网络、文件系统、内存管理等)的补丁。补丁通常先发送到相关的邮件列表,经过社区讨论和审查后,由子系统维护者合入自己的树中,然后在合并窗口期间提交给 Linus。
2.4 Linux 内核许可证与法律框架
Linux 内核在 GPL v2(GNU General Public License version 2)许可证下发布。GPL v2 的核心要求是:任何分发基于 GPL 代码的衍生作品的行为,都必须同时提供源代码,并且衍生作品也必须以 GPL 许可证发布。这就是所谓的"传染性"或"Copyleft"特性。
对于内核开发者而言,理解 GPL 的实际影响非常重要。例如,内核模块是否算作衍生作品?这个问题在法律界仍有争议,但内核社区普遍认为,如果模块使用了内核的内部 API(而非稳定的导出接口),则应视为衍生作品,必须以 GPL 兼容许可证发布。这也是为什么内核中有 EXPORT_SYMBOL_GPL 宏,它只允许 GPL 兼容模块使用某些内核函数。
三、深入分析与讨论
3.1 Unix 设计哲学在内核中的体现
Unix 的设计哲学不仅体现在用户空间的工具链中,也深刻影响了内核的设计。"小即是美"的原则在内核中体现为模块化的子系统划分:内存管理、进程调度、文件系统、网络等子系统相对独立,通过清晰的接口交互。"一切皆文件"的理念直接体现在 VFS(虚拟文件系统)的设计中,设备、进程信息、内核参数都通过文件系统接口暴露给用户空间。
管道和组合的思想在内核中体现为分层架构。例如,网络子系统采用协议栈分层,每一层只负责特定的功能,通过标准接口与上下层交互。这种设计使得每一层可以独立替换和升级,而不会影响其他层。
3.2 开源协作模式的优势与挑战
Linux 内核的开发模式是软件工程史上的一个奇迹。数以万计的开发者,分布在不同的公司和时区,通过邮件列表进行异步协作,却能够产出世界上质量最高的软件之一。这种模式的成功依赖于几个关键因素:Linus Torvalds 的技术判断力和决策能力、严格的代码审查流程、邮件列表的透明讨论机制以及自动化测试基础设施。
然而,这种模式也面临挑战。邮件列表的门槛较高,新贡献者难以融入。内核社区的多样性问题也长期受到关注。近年来,社区在改进新贡献者体验方面做出了努力,如引入 lore.kernel.org 作为更友好的邮件列表归档界面。
四、实践案例
4.1 案例一:从一条补丁看内核开发流程
假设一位开发者想要修复网络子系统中的一个 bug。首先,他需要在本地编译内核并复现问题,然后编写修复代码。代码必须符合内核编码风格(使用 checkpatch.pl 脚本检查)。接着,他需要找到正确的维护者和邮件列表(使用 get_maintainer.pl 脚本),将补丁发送到邮件列表。维护者和社区成员会进行代码审查,提出修改意见。经过若干轮修改后,维护者将补丁合入自己的 git 树。在下一个合并窗口期间,维护者将这批补丁提交给 Linus。Linus 审查后合入主线,包含在下一个 rc(release candidate)版本中。
4.2 案例二:追踪 Linux 版本号的变迁
通过研究 Linux 版本号的变迁历史,可以清晰地看到项目从个人爱好到全球协作的演变。1.0(1994 年)是第一个正式版本,仅有约 17 万行代码。2.0(1996 年)引入了对多处理器的支持。2.6(2003 年)带来了 O(1) 调度器和新的设备模型。3.0(2011 年)主要是版本号的变化,技术上延续了 2.6.39。6.0(2022 年)则包含了大量的硬件支持和性能优化。每个大版本都标志着 Linux 在特定领域的重要突破。
五、常见误区与注意事项
误区:Linux 就是 GNU/Linux 的全部。实际上,Linux 仅指内核,一个完整的操作系统还需要 GNU 工具链、C 库、Shell 等用户空间组件。不过,在嵌入式领域,Linux 内核可能搭配非 GNU 的用户空间(如 musl libc + BusyBox)。
误区:开源意味着可以随意使用。GPL v2 对分发有严格要求,如果将 Linux 内核集成到商业产品中并分发,必须提供源代码。仅在内部使用(不分发)则不受此限制。
误区:Linus 一个人写了 Linux。实际上,Linus 的主要贡献是架构设计和代码审查,而非大量编写代码。Linux 内核是数以万计开发者共同贡献的结果。
注意:内核版本与发行版版本的区别。Ubuntu 22.04、RHEL 9 等发行版有自己的版本号,与内核版本号(如 5.15、6.1)是独立的概念。发行版会在其生命周期内升级或回移内核补丁。
六、本章小结
本章回顾了 Unix 和 Linux 的发展历程,从 1969 年贝尔实验室的 Unix 原型到 1991 年 Linus Torvalds 发起的 Linux 内核项目,再到今天运行在全球数十亿设备上的操作系统。Unix 的设计哲学——模块化、一切皆文件、小程序组合——深刻影响了 Linux 的内核架构。开源运动使得 Linux 能够汇聚全球开发者的智慧,形成了独特的社区驱动开发模式。内核版本管理从早期的简单编号发展到今天规范的发布周期,确保了稳定性和新特性的平衡。理解这些历史背景和文化因素,对于深入学习 Linux 内核的技术细节至关重要。
七、思考题与练习
比较 Unix 的设计哲学与 Windows 的设计哲学,分析它们各自的优势和适用场景。
为什么说 GPL 许可证是 Linux 成功的关键因素之一?如果没有 GPL,Linux 可能会如何发展?
研究 Linux 内核邮件列表(LKML)上最近讨论的一个技术话题,总结讨论的焦点和结论。
分析 Linux 内核开发模式与传统商业软件开发模式的异同,讨论各自的优缺点。
查阅 POSIX 标准的内容,说明 Linux 在哪些方面遵循了 POSIX 规范,在哪些方面有所偏离。
选择一个 Linux 内核子系统(如网络、文件系统、内存管理),研究其维护者是谁,最近有哪些重要的代码变更。
讨论"集市式"开发模式的质量保证机制:在没有集中测试团队的情况下,Linux 内核如何保持高质量?