操作系统那些事儿② GNU:那个坚持自由,却差点没有 Kernel 的项目
如果把操作系统的发展史比作《三国演义》,那么本文更像《三国演义》,而不是《三国志》。
本系列尝试用故事化的方式,讲述 Unix、Linux、BSD、GNU、Windows、macOS、Android 等操作系统背后的发展历程。
文中的人物、事件和技术演进都尽量参考公开资料,但为了让故事更容易理解,会适当简化一些历史细节,也会加入作者自己的理解。
它不是一篇学术论文,而是一段程序员视角的技术故事。
如果读完之后,你产生兴趣,愿意继续查阅官方资料,那这篇文章的目的就达到了。
引子:Unix 成功了,但程序员却开始失去自由
上一篇,我们讲到了 Unix。
Unix 从贝尔实验室走向大学。
又从大学走向商业公司。
它的影响越来越大。
使用它的人越来越多。
围绕 Unix 诞生的软件,也越来越丰富。
看起来:
一切都在向好的方向发展。
但是到了 20 世纪 80 年代,一个新的问题出现了。
过去,程序员之间经常交换代码。
谁遇到问题,就看看源代码。
发现 Bug,就顺手修一下。
写出新功能,也可以分享给别人。
但是后来:
软件开始成为商品。
源代码不再轻易公开。
程序员开始签署保密协议。
原本很自然的代码分享,逐渐变成了一件“不被允许的事情”。
就在这时,一个非常固执的程序员站了出来。
他的名字叫:
Richard Stallman。
他想做一件听起来近乎疯狂的事:
既然 Unix 不再自由,
那就重新写一个自由的 Unix。
这个项目叫:
GNU。

第一章:一个打印机引发的故事
Richard Stallman 当时工作在:
麻省理工学院人工智能实验室。
这里聚集着一群非常特别的程序员。
他们喜欢研究系统。
喜欢修改代码。
也喜欢把自己的成果分享给别人。
在那个年代,他们把自己称为:
Hacker。
这里的 Hacker,并不是今天新闻里入侵电脑的黑客。
而是:
喜欢探索技术。
喜欢解决问题。
喜欢把机器研究透的人。
据说,实验室里曾经有一台打印机。
这台打印机经常卡纸。
于是程序员修改了驱动程序。
当打印机卡住时,系统会自动提醒正在等待打印的人。
后来,实验室换了一台新打印机。
新打印机还是会卡纸。
但是这一次:
厂商不提供源代码。
Stallman 找到一个可能拥有驱动源码的人,希望对方给自己一份。
对方拒绝了。
因为:
他签署了保密协议。
这件事让 Stallman 非常震动。
在他看来:
一个程序员明明可以帮助另一个程序员。
却因为一份合同,不能分享代码。
问题已经不只是:
打印机为什么不提醒卡纸。
而是:
为什么程序员不能帮助程序员?

第二章:过去的软件,是可以互相分享的
在早期计算机时代,硬件非常昂贵。
软件却还没有完全成为独立商品。
很多程序会随着机器一起提供。
程序员拿到源代码后,可以自己修改。
有时候:
一个实验室修改完程序。
会把代码复制给另一个实验室。
另一个实验室又会继续改进。
这很像今天的开源社区。
但是当时并没有 GitHub。
也没有 Pull Request。
甚至连“开源软件”这个词,都还没有流行起来。
大家只是觉得:
代码可以研究。
可以修改。
也可以分享。
但随着软件行业逐渐商业化,一切开始改变。
软件公司发现:
代码本身可以卖钱。
于是:
源代码被藏了起来。
许可证开始限制用户。
程序员也被要求承诺:
不能把代码交给别人。
对很多人来说,这只是商业发展的自然结果。
但对 Stallman 来说:
这是一种倒退。
第三章:既然没有自由的操作系统,那就自己写一个
1983 年。
Richard Stallman 宣布:
他要开发一套新的操作系统。
它需要满足两个条件。
第一:
像 Unix。
第二:
完全自由。
为什么要像 Unix?
因为 Unix 已经非常成熟。
大量程序员熟悉 Unix。
大量软件也围绕 Unix 开发。
如果新系统能够兼容 Unix:
原来的使用习惯可以保留。
很多程序也可以移植过去。
但是:
这个系统不能直接使用 Unix 的商业源代码。
它必须从头开始写。
于是:
GNU 项目诞生了。
GNU 的全称是:
GNU's Not Unix。
翻译过来就是:
GNU 不是 Unix。
这个名字有点奇怪。
因为解释 GNU 时,又会再次出现 GNU。
它像一个永远说不完的绕口令。
但这正是早期程序员喜欢的幽默。
第四章:GNU 的自由,不是不要钱
看到 Free Software,很多人第一反应是:
免费软件。
但 Stallman 所说的 Free,重点不是价格。
而是:
自由。
一份软件可以免费。
但如果用户不能查看源代码。
不能修改。
不能分享。
那么它依然可能不是自由软件。
反过来:
自由软件也可以收费。
开发者可以卖光盘。
可以提供技术支持。
也可以靠软件服务赚钱。
GNU 真正关心的问题是:
用户拿到程序之后,拥有什么权利?
你能不能运行它?
能不能研究它?
能不能修改它?
能不能分享给别人?
所以 Stallman 经常用一句话解释:
这里的 Free,
更像自由表达中的自由。
而不是免费啤酒中的免费。
第五章:GNU 想造的,不是几个命令,而是一整个系统
今天很多 Linux 用户,都使用过这些命令:
ls
cp
mv
rm
grep
sed
bash
gcc
gdb
make
很多人会自然地认为:
这些都是 Linux 命令。
但严格来说:
其中很多工具来自 GNU。
因为它们长期和 Linux 一起出现。
所以大家慢慢把整套东西都叫成了 Linux。
但 GNU 最初的目标,远远不只是写几个命令行工具。
它想创造的是:
一个完整的操作系统。
一套操作系统需要什么?
需要编辑器。
需要编译器。
需要调试器。
需要 Shell。
需要 C 语言库。
需要文件工具。
需要构建工具。
需要各种基础命令。
当然:
还需要内核。
于是 GNU 开始一件一件地写。
第六章:先造工具,再用工具造系统
GNU 的开发路线非常聪明。
想写操作系统:
先得有写代码的工具。
于是:
GNU Emacs 出现了。
程序员可以用它编辑代码。
但写完代码,还需要编译。
于是:
GCC 出现了。
程序出错,还要调试。
于是:
GDB 出现了。
程序越来越多,还需要自动构建。
于是:
GNU Make 出现了。
系统需要命令行环境。
于是:
Bash 出现了。
系统还需要大量基础命令。
于是:
GNU Coreutils 逐渐完善。
GNU 就这样:
先打造工具。
再用这些工具,继续打造自己的操作系统。
这像什么?
像一个人想建造一座城市。
但他没有起重机。
没有卡车。
没有水泥厂。
于是:
他先建工具厂。
再用工具厂生产出来的机器,继续建城市。
这个过程很慢。
但成果非常扎实。

第七章:GCC,后来帮助了另一个系统
GNU 项目中,有一个非常重要的工具:
GCC。
它最初是 GNU C Compiler。
后来逐渐支持更多语言,变成了 GNU Compiler Collection。
编译器有什么用?
简单来说:
程序员写的是源代码。
计算机真正运行的,是机器指令。
编译器负责把前者变成后者。
如果 GNU 没有自己的编译器:
那它就必须依赖其他公司的工具。
今天别人允许你使用。
明天可能修改许可证。
后天甚至可能停止提供。
所以:
一个自由的操作系统,最好也拥有自由的编译器。
GCC 的出现,让 GNU 有了自己的“兵工厂”。
GNU 可以用自由软件:
继续生产自由软件。
但是历史很有意思。
GNU 原本为自己的操作系统准备了 GCC。
后来:
GCC 却帮助 Linux 内核迅速成长。
GNU 辛辛苦苦打造的兵工厂。
最终先武装了另一支军队。
第八章:光是开放源代码,还不够
Stallman 很快发现一个问题。
假设:
GNU 把代码公开出来。
任何人都可以使用。
但有一家公司拿走代码。
修改之后。
再把修改版本变成闭源软件。
那么:
最初的代码虽然自由。
后来的版本,却可能再次被关起来。
于是 GNU 提出了一种很特别的思路:
Copyleft。
它显然是在模仿:
Copyright。
Copyright 是版权。
Copyleft 则可以理解为:
把版权反过来使用。
它的规则大致是:
你可以使用代码。
可以修改代码。
也可以分享代码。
但是当你把修改后的版本继续发布时:
也要把同样的自由留给下一个用户。
这种思想后来体现在:
GPL。
也就是:
GNU General Public License。
GPL 并不是不要版权。
恰恰相反:
它需要利用版权法,保证代码在传播过程中继续保持自由。
简单来说:
别人把自由给了你。
你不能拿走自由之后,再把门锁上。
第九章:GNU 什么都有了,唯独缺一颗心脏
经过多年开发。
GNU 的工具越来越完整。
编辑器有了。
编译器有了。
调试器有了。
Shell 有了。
C 语言库也有了。
各种基础命令越来越丰富。
GNU 距离完整操作系统,似乎只剩最后一步。
但这最后一步,却是最关键的一步:
Kernel。
内核负责什么?
管理 CPU。
管理内存。
管理进程。
管理硬盘和设备。
为上层程序提供系统调用。
没有内核:
GNU 的工具再多,也只能运行在其他操作系统上。
这就像:
汽车已经造好了方向盘。
座椅。
车灯。
轮胎。
变速箱。
甚至车载工具箱。
唯独没有发动机。
第十章:GNU 没想造普通发动机
GNU 当然知道自己需要内核。
但 GNU 并不想简单地复制传统 Unix 的设计。
他们想做一个更先进的内核。
当时,操作系统领域流行一种很有吸引力的思想:
微内核。
传统内核通常把很多功能放在一个大内核里。
进程管理。
内存管理。
设备驱动。
文件系统。
网络。
全都在内核空间运行。
这样的设计通常被称为:
单体内核。
微内核则不同。
它希望内核本身只保留最基础的功能。
其他服务:
尽量放到用户空间。
这样做的好处听起来非常美好。
系统更加模块化。
某个服务崩溃,不一定拖垮整个系统。
文件系统可以替换。
服务可以独立升级。
权限也可以更加灵活。
于是 GNU 选择:
基于 Mach 微内核,开发自己的系统。
它的名字叫:
Hurd。
第十一章:Hurd 的理想很丰满
Hurd 并不只是一个普通内核。
它更像一群相互协作的服务。
文件系统是一种服务。
网络是一种服务。
认证也是一种服务。
传统 Unix 中,很多事情必须由系统管理员完成。
而 Hurd 希望:
普通用户也能在自己的权限范围内,运行一些系统服务。
例如:
用户可以挂载自己的文件系统。
可以替换一些服务。
可以拥有更多控制权。
这种设计非常符合 GNU 的理念。
不仅软件应该自由。
操作系统里的权力,也不应该全部集中在一个巨大内核手中。
从设计上看:
Hurd 很先进。
很优雅。
也很有理想主义色彩。
但是:
它太难写了。
第十二章:越优雅的设计,有时越难落地
微内核理论上很美。
实际开发时,却会带来很多复杂问题。
原本内核内部的一次函数调用。
拆分服务之后:
可能变成进程之间的通信。
服务更多。
边界更多。
通信更多。
调试也更加困难。
而且:
Hurd 依赖 Mach。
底层微内核的问题,也会影响 Hurd。
GNU 不只是想让系统能够启动。
它还希望:
-
架构先进;
-
权限灵活;
-
兼容 Unix;
-
性能可靠;
-
最终还能让普通人使用。
每增加一个目标:
开发难度就上升一层。
于是:
Hurd 一直在开发。
一直在改进。
也确实能够运行。
但是:
它迟迟没有成为成熟的主流系统。
GNU 什么都有了。
却一直等不到自己的内核真正长大。

第十三章:就在 GNU 苦等内核时,一个大学生出现了
时间来到:
1991 年。
芬兰有一个大学生:
Linus Torvalds。
他想给自己的 386 电脑,写一个能够使用的类 Unix 系统。
一开始:
这只是一个个人项目。
他没有打算发动一场软件自由运动。
也没有打算创造一个改变世界的商业平台。
他只是觉得:
现有系统不够好用。
那就自己写一个。
这个新项目后来有了一个名字:
Linux。
需要注意:
Linux 最初只是一个 Kernel。
它有内核。
但缺少大量系统工具。
它需要编译器。
需要 Shell。
需要 C 语言库。
需要基础命令。
需要调试工具。
而这些东西:
GNU 已经写了很多年。
第十四章:一个有身体,一个有心脏
当 Linux 出现时:
GNU 已经拥有了大量成熟工具。
却缺少一个真正可用的内核。
Linux 则相反:
它有了正在快速成长的内核。
却缺少完整的用户空间。
于是:
两个项目相遇了。
Linux Kernel
加上 GNU 工具
再加上其他自由软件
终于组成了一个真正能够使用的类 Unix 系统。
这像什么?
GNU 花了很多年:
造好了车身。
方向盘。
轮胎。
仪表盘。
座椅。
甚至连维修工具都准备好了。
但发动机迟迟没有完成。
就在这时:
Linux 推来了一台发动机。
虽然最初还有点粗糙。
但它真的能够转。
于是:
这辆车终于开了起来。

第十五章:后来,大家把整辆车都叫成了 Linux
这个组合迅速发展。
越来越多开发者加入。
越来越多硬件得到支持。
越来越多软件可以运行。
发行版开始出现。
服务器开始使用。
互联网公司开始采用。
后来:
超级计算机。
云计算。
嵌入式设备。
Android 手机。
都和 Linux 产生了联系。
但是一个有趣的问题出现了。
这套系统里:
内核叫 Linux。
大量基础工具来自 GNU。
那么:
整个系统应该叫什么?
大多数人说:
Linux。
因为简单。
好记。
而且已经形成了习惯。
但 Stallman 认为:
Linux 只是内核。
完整系统中,大量关键部分来自 GNU。
所以应该叫:
GNU/Linux。
这场争论持续了很多年。
支持 GNU/Linux 的人认为:
这个名称能够提醒大家:
GNU 和自由软件运动作出了巨大贡献。
而支持直接叫 Linux 的人则认为:
现代发行版不只有 GNU。
还有很多其他项目。
如果所有项目都写进名字:
系统名称可能长得像一份软件清单。
第十六章:Linux 还是 GNU/Linux?
这个问题很难有一个让所有人满意的答案。
严格来说:
Linux 是内核。
GNU 提供了大量基础工具。
现代 Linux 发行版,则由成百上千个项目共同组成。
所以从技术上说:
把整个系统都等同于 Linux,并不完全准确。
但从现实使用来说:
Linux 已经成为最普遍的名称。
今天人们说:
Linux 服务器。
Linux 桌面。
Linux 发行版。
大家通常都知道:
说的是一套完整系统,而不只是 Kernel。
至于你喜欢叫 Linux。
还是 GNU/Linux。
其实都没有太大问题。
但至少应该知道:
当你打开终端,输入:
bash
gcc
gdb
grep
ls
你使用的不只是 Linux。
GNU 一直都在。
第十七章:GNU 失败了吗?
如果按照最初目标来看:
GNU 想创造一套完整的自由操作系统。
它希望:
工具是自己的。
用户空间是自己的。
内核也是自己的。
最后:
Hurd 没有成为主流。
让 GNU 工具真正走向世界的内核,是 Linux。
从这个角度看:
GNU 似乎没有完全实现最初计划。
但是如果换一个角度:
GNU 又取得了巨大的成功。
GCC 成为重要的编译器。
GDB 成为经典调试器。
Bash 成为广泛使用的 Shell。
GNU 工具进入无数服务器。
GPL 影响了整个开源软件世界。
更重要的是:
GNU 让人们开始认真讨论一个问题。
软件到底只是商品,
还是一种用户应该拥有控制权的工具?
第十八章:自由软件与开源软件,不完全是一回事
后来:
Open Source,也就是开源软件,逐渐成为更流行的说法。
很多公司喜欢开源。
因为开源意味着:
更多人参与开发。
更多人帮助测试。
代码迭代更快。
生态也更容易扩大。
这些都很实际。
也很容易被商业世界接受。
但 Stallman 始终认为:
开源和自由软件,重点并不完全一样。
开源更关心:
这种开发模式是不是高效。
自由软件更关心:
用户是不是拥有应有的权利。
对开源支持者来说:
开放代码,通常能带来更好的软件。
对 Stallman 来说:
即使自由软件有时候不够方便。
自由本身也依然重要。
这也是为什么:
GNU 经常显得非常固执。
它不是只想做更好的软件。
它想改变软件世界的规则。
写在最后:它没有等来自己的 Kernel,却改变了整个时代
回头看 GNU 的故事:
它带着强烈的理想主义色彩。
Richard Stallman 看到程序员失去分享代码的自由。
于是:
他决定重新创造一个自由的 Unix。
GNU 写出了:
-
编辑器;
-
编译器;
-
调试器;
-
Shell;
-
C 语言库;
-
基础命令;
-
软件许可证;
-
一整套自由软件思想。
但最关键的内核:
Hurd。
却一直没有真正成熟。
就在 GNU 苦苦等待的时候:
Linux 出现了。
于是:
GNU 提供了工具和用户空间。
Linux 提供了 Kernel。
两个原本目标并不相同的项目,意外组成了一个改变世界的系统。
后来:
大多数人把它叫成 Linux。
GNU 的名字,反而逐渐隐藏在系统背后。
但它从来没有真正消失。
每一次使用 Bash。
每一次运行 GCC。
每一次输入 grep。
甚至每一次讨论开源许可证。
GNU 都在提醒我们:
软件不只是代码。
它也代表着:
谁拥有控制权。
谁可以研究它。
谁可以修改它。
谁又有权把它分享给别人。
GNU 没有等来自己理想中的 Kernel。
但它推动了自由软件的发展。
也为 Linux 的崛起,提前准备好了几乎整个世界。
如果把现代操作系统看成一片森林。
Unix 是那棵古老的大树。
GNU 则像一个坚持改变森林规则的人。
它没能亲手种出最大的一棵树。
但后来长成参天大树的 Linux:
使用了它准备的工具。
吸收了它推动的思想。
也继承了它对自由的坚持。
下一回:
一个芬兰大学生即将登场。
他原本只是想给自己的电脑写一个小内核。
但这个小项目最后却进入了服务器、云计算、超级计算机和几十亿部手机。
它的名字叫:
Linux。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)