Linux内核历史:哪些关键决策真正改变了服务器
从0.01到7.x,梳理Linux选择GPLv2、坚持单体内核、诞生Git与采用LTS模式的来龙去脉,并说明这些决策如何影响今天的服务器。
Linux 内核历史简述
Linux 内核的发展始于 1991 年 9 月发布的 0.01 版本,如今已发展到可在服务器上启动的 7.x 系列。版本发布列表并不是最值得关注的部分。少数几个决策塑造了 Linux 内核的整体形态,而每个决策至今仍会影响您今天租用的服务器。
本文中的日期和版本号来自 kernel.org 及其发布的版本历史。截至 2026 年 8 月,7.0 已于 2026 年 4 月 12 日发布,7.1 已于 2026 年 6 月 14 日发布,7.2 正处于候选发布阶段。
为什么 1992 年选择 GPL 至今仍然重要
0.01 版于 1991 年 9 月 17 日发布,采用的是 Torvalds 自行编写的许可证。该许可证要求分发源代码,并增加了一条更重要的规定:“不得收费分发,甚至不得收取‘处理’费用。”1991 年,软件通过软盘发布,而复制和邮寄软盘需要成本。这一条款使商业 Linux 发行版无法实现。
他后来修改了许可证。GNU General Public License(GPL)的采用在 1992 年 1 月的 0.12 版发行说明中宣布,并于 1992 年 2 月 1 日生效。1992 年 3 月发布的 0.95 版,是第一个采用该许可证发布的版本。此后建立在 Linux 之上的每项业务,都受益于这次变更。
内核仅采用 GPL version 2,且从未迁移到 version 3。Torvalds 在 2007 年拒绝迁移,主要原因是 GPLv3 中的反锁定规则。该规则要求,出货时包含 GPL 代码的设备也必须允许使用该代码的修改版本。他认为锁定硬件属于制造商自己的业务。2017 年,内核开发者发布了 Kernel Enforcement Statement,其中仍然借用了 GPLv3 的一项规定:收到侵权通知后修正问题的人可以保留其许可证,而不是在首次侵权时永久失去许可证。
这会对服务器产生两个后果。你启动的内核二进制文件附带获取对应源代码的权利,因此任何人都不能向你提供一个你无权检查或重新构建的 Linux 内核。内核中的版权声明还说明,该许可证不涵盖通过正常系统调用使用内核服务的用户程序。因此,专有数据库和监控代理可以为 Linux 发布,而不会因此违反许可证。宽松许可证会产生相反的约束。在选择平台前,理解这一差异很有价值:参见 Linux 和 FreeBSD 作为服务器平台。
实践中单体内核为何胜出
1992 年 1 月 29 日,Andrew Tanenbaum 在 comp.os.minix 新闻组发布了一条标题为“LINUX is obsolete”的消息。他提出了两项观点。单体内核让驱动程序和文件系统运行在同一个特权地址空间中,这是 1970 年代的设计;微内核则让这些组件作为普通进程运行,是未来的发展方向。Linux 还与 Intel 386 紧密绑定,因此永远无法移植到其他平台。
移植工作回应了可移植性问题。1995 年 3 月发布的 Version 1.2 增加了 Alpha、SPARC 和 MIPS 支持。1996 年 6 月发布的 Version 2.0 增加了 64 位 Alpha 移植版本。
折中方案回应了设计问题。Linux 从未变成微内核,而是获得了可加载内核模块:这些目标文件可以插入正在运行的内核,也可以再次移除,因此驱动程序可以独立于内核二进制文件发布。
lsmod | head
modinfo virtio_net | head -5lsmod 列出当前已加载的模块。modinfo 显示模块来源文件及其接受的参数。在虚拟服务器中,磁盘和网络路径上的大部分功能都由模块提供,因此同一个内核映像可以在它从未接触过的硬件上启动。
模块提供了这种灵活性,同时避免了微内核设计带来的成本。将驱动程序隔离到独立进程中后,每次调用都需要进行上下文切换并传递消息;在 1992 年,这种成本很高。
Linux 保留的成本才是需要重点规划的部分:模块拥有完整的内核权限,因此有缺陷的模块会导致整台机器宕机,而不是只影响一个进程。问题尤其常见于 out-of-tree 模块。未包含在 mainline 中的供应商驱动程序必须针对每个新内核重新构建。升级期间,DKMS 负责执行这项工作;如果构建失败,设备在重启后就会直接缺失。
SMP 花了 15 年才完成
1996 年 6 月发布的 Linux 2.0 是第一个支持对称多处理(SMP)的内核,即多个 CPU 运行同一个内核。最初的实现使用单个锁,即大内核锁(BKL),因此同一时间只能有一个处理器进入内核代码。第二个 CPU 因此可以改善主要在用户空间执行计算的工作负载,但对系统调用工作负载帮助很小,因为这些调用都会排在同一个锁后面。
移除这个锁花了 15 年。剩余使用点大多由 Arnd Bergmann 改为细粒度锁,BKL 最终在 2.6.39 中删除;该版本于 18 May 2011 发布。调度器的演进速度也同样缓慢:2.6.0 引入 O(1) 调度器,2007 年发布的 2.6.23 引入完全公平调度器(CFS),而 EEVDF 在 2023 年 10 月的 6.6 中取代了 CFS。
正因为这些工作,如今选择 4 vCPU 的方案已经很常见。但其中也有一个值得了解的限制。在共享虚拟服务器上,您的内核负责调度线程,而虚拟机监控程序负责调度您的内核。运行 top 并读取 %st 字段。窃取时间是指您的内核已经准备使用、但主机分配给其他客户机的 CPU 时间,因此在您的内核内部进行任何调优都无法取回这部分时间。
2.6 系列为何改变了内核构建方式
在 2.6 之前,版本号由两个部分组成。第二个数字为偶数表示稳定系列(2.4),为奇数表示开发系列(2.5)。2.4 于 2001 年 1 月 4 日发布,2.6 于 2003 年 12 月 17 日发布,因此用户等待下一个稳定系列将近 3 年。发行版无法等待这么久,因此会回移植补丁。两个厂商即使都发布“2.4”,所提供的内核也可能相差数千个补丁。
2.6 之后,这种划分被取消。主线内核现在会开启一个约 2 周的合并窗口,接收新的开发内容;随后持续发布候选版本,直到代码趋于稳定,然后每 9 到 10 周发布一个版本。这一节奏至今仍记录在 kernel.org 的文档中。该模型的另一部分于 2005 年 3 月 4 日出现:稳定树首次发布。它是针对 2.6.11 的仅修复更新,由 Greg Kroah-Hartman 和 Chris Wright 维护。稳定树接收修复,但不接收新功能。
这带来一个副作用:版本号不再代表明确承诺。3.0、4.0、5.0 和 7.0 都不是重写版本。当第二个数字变得足够大、令 Torvalds 感到不便时,他就会提高第一个数字。因此 7.0 于 2026 年 4 月继 6.19 之后发布。对于服务器而言,重要的是发行版跟踪哪个分支,以及该分支是否仍能获得修复。
2005 年 4 月 BitKeeper 事件如何催生 git
从 2002 年 2 月开始,内核使用 Larry McVoy 的公司 BitMover 开发的专有分布式版本控制系统 BitKeeper 进行开发,起始于 2.5 系列。BitMover 向内核开发者免费提供许可证,但附带条件:不得开发竞争性的版本控制工具,也不得对 BitKeeper 进行逆向工程。许多开发者不愿使用无法阅读其源代码的工具来开发自由内核。
2005 年 4 月,在 Andrew Tridgell 演示了一个可以与 BitKeeper 仓库通信的程序后,合作关系破裂。BitMover 认定这是逆向工程,并收回了免费许可证。内核在一个开发周期中途失去了版本控制系统。
git 于 2005 年 4 月 3 日开始开发。Torvalds 于 4 月 6 日宣布了它。4 月 7 日,git 已能自托管,也就是说,git 自身的历史已经由 git 保存。4 月 18 日,首次合并多个分支成功完成。2005 年 6 月,git 已用于管理 2.6.12 的发布。此后不久,Torvalds 将维护工作交给 Junio Hamano,自己回到内核开发中。
git 的设计直接源于这个问题:数千名贡献者,以及需要通过无人信任的网络相互拉取代码的维护者。每个对象都以其内容的哈希命名,因此修改旧历史中的一个字节,会改变其后的每个提交的名称。这就是为什么克隆结果是一种证据,而不是一种声明。每条部署流水线、每个配置仓库、大多数团队推送代码的代码托管平台以及您可以自行运行的 git 服务器,都源于一场围绕内核展开的许可证争议。
LTS 模型承诺什么,以及不承诺什么
Mainline 不是实际运行的版本。一个 mainline 版本会在 9 到 10 周后被后续版本取代。每次发布后,stable 树还会在几周内继续获得修复。Longterm 分支通常称为 LTS,会持续获得多年的修复,发行版基于这些分支构建。
2009 年 12 月发布的 2.6.32 证明了这种模型可行。RHEL 6、Debian 6、SUSE Linux Enterprise 11 SP1 和 Ubuntu 10.04 LTS 都发布了基于它的版本,该分支一直维护到 2016 年 2 月,也就是发布 6 年多以后。
这项承诺不止一次发生变化。最初是两年,后来部分分支延长到 6 年。2023 年,stable 维护者将默认期限缩短回两年,因为向旧树回移植修复会占用维护者时间,而且旧分支很少接受实际测试。2026 年 2 月 25 日,Greg Kroah-Hartman 与依赖这些分支的公司讨论后,再次公布了更长的预计维护期限;当前框架的期限为 3 到 6 年。
The data behind this chart
[
{
"kernel": "5.10",
"released": "2020-12-13",
"eol_projected": "Dec 2026",
"maintained_for": 6.0
},
{
"kernel": "5.15",
"released": "2021-10-31",
"eol_projected": "Dec 2026",
"maintained_for": 5.1
},
{
"kernel": "6.1",
"released": "2022-12-11",
"eol_projected": "Dec 2027",
"maintained_for": 5.0
},
{
"kernel": "6.6",
"released": "2023-10-29",
"eol_projected": "Dec 2027",
"maintained_for": 4.2
},
{
"kernel": "6.12",
"released": "2024-11-17",
"eol_projected": "Dec 2028",
"maintained_for": 4.1
},
{
"kernel": "6.18",
"released": "2025-11-30",
"eol_projected": "Dec 2028",
"maintained_for": 3.1
}
]截至 2026 年 8 月,kernel.org 列出了 6 个 longterm 分支。最旧的分支 5.10 结束维护时,已提供 6.0 年的修复,预计结束时间为 Dec 2026。最新的分支 6.18 预计维护到 Dec 2028,总计提供 3.1 年的修复。
应将这些日期视为最低期限,而不是合同承诺。6.6 和 6.12 的预计维护期限都在 2026 年 2 月延长过;相反,如果某个分支无人使用,也可能提前停止维护。发行版通常会替您做出选择:Debian 13 发布 6.12,Ubuntu 26.04 LTS 发布 7.0。这就是服务器上 LTS 与临时版本的选择问题的实际内容,也是将 Ubuntu 24.04 升级到 26.04时底层真正发生变化的部分。
这里还存在一个容易误判的问题。在 Ubuntu 24.04 上,uname -r 会输出类似 6.8.0-51-generic 的内容。这表示上游基础版本加上发行版自己的回移植修复,因此该数字只能说明分支从哪个版本开始,不能说明其中包含哪些修复。扫描器仅根据内核版本字符串判断时,会因此对发行版内核产生误报。
内核当前正在争论什么
目前有两项争论,核心都是由谁完成这项工作。
Rust 于 2022 年 12 月在 6.1 中作为基础设施引入。到了 7.0,实验性标签被移除,因此内核的核心语言包括 C、汇编和 Rust,构建过程也不再需要 nightly compiler。争论的焦点是维护责任。C 维护者修改接口时,可能会破坏自己并未查看的 Rust 绑定;现在争论的是由谁负责修复这些绑定。
第二项争论涉及 AI 贡献。随着机器辅助补丁数量增加并提交到邮件列表,Sasha Levin 于 2025 年 7 月提出了一项政策。该文档于 2025 年 12 月 23 日提交,如今位于内核自己的流程文档中:docs.kernel.org/process/coding-assistants.html。AI agent 不得添加 Signed-off-by 标签,因为该行用于证明 Developer Certificate of Origin (DCO),而只有人可以作出这一证明。使用辅助工具应通过 Assisted-by: 标签声明;该标签在审查期间由 Co-developed-by: 修改而来,因为工具不是作者。生成的代码必须兼容 GPL-2.0-only。提交补丁的人负责审查补丁,并对其承担责任。
推动这项政策的压力来自审查时间。生成补丁只需几秒,而维护者审查一个补丁可能需要整个下午。标签无法消除这种不平衡,但可以保留来源信息:历史记录会继续记录每项变更由谁签署,这正是 DCO 于 2004 年引入时要保护的属性。
这段历史对您租用的服务器意味着什么
- 许可证使您能够阅读和重新构建服务商启动的内核,也使专有软件仍能在其上运行。
- 单体设计意味着一个驱动程序错误就可能重启整台机器,也意味着每次升级内核时都必须重新构建树外模块。
- 发布模式意味着版本号提供的信息很少,而分支及其生命周期结束日期几乎决定了全部信息。
- 虚拟化类型决定了您能否执行某项操作:在 KVM 上,您可以启动自己的内核并加载模块;而在共享宿主机内核的容器虚拟化环境中,
uname -r显示宿主机的版本,modprobe会失败,并且多个 sysctl 参数为只读。
FAQ
为什么 Linux 内核仍使用 GPLv2,而不是 GPLv3?
Torvalds 在 2007 年决定不采用 GPLv3,主要原因是其反锁定条款。该条款要求发布 GPL 代码的设备同时接受该代码的修改版本。Torvalds 认为,锁定硬件属于制造商的业务范畴。实际上,重新许可也几乎不可能,因为内核的版权由数千名贡献者持有,而且没有可供依赖的版权转让协议。内核采用 GPL-2.0-only,因此不能合并仅以 GPLv3 提供的代码。
Linux 内核是单体内核还是微内核?
Linux 是带有可加载模块的单体内核。驱动程序和文件系统运行在内核地址空间中,lsmod 会显示当前已加载的模块。这样做一方面速度更快,另一方面故障影响范围更大:有缺陷的模块可能导致整台机器发生内核崩溃,而微内核通常只会丢失一个进程。自 1992 年以来,这种差异已经有所缩小,原因包括在用户空间运行的 FUSE 文件系统,以及内核在运行前会验证的 eBPF 程序。
mainline、stable 和 longterm 内核有什么区别?
mainline 是 Torvalds 的代码树,每 9 到 10 周发布一次,新功能会首先进入该分支。stable 基于最近的 mainline 版本,并在数周内接收错误修复。longterm 分支会持续多年接收修复,发行版通常基于这些分支构建内核。kernel.org 会列出当前的 longterm 分支,并为每个分支提供预计的生命周期结束日期。
Linux 内核是否接受 AI 编写的代码?
接受,但须遵循 2025 年 12 月确定的政策。必须在 Assisted-by: 标记中注明所使用的工具,AI 代理不得添加 Signed-off-by 行,并且生成的代码必须兼容 GPL-2.0-only。提交者必须进行签署确认,这表示其已审查补丁,并根据 Developer Certificate of Origin 对补丁承担责任。
服务器应运行哪个内核版本?
几乎所有情况下,都应运行发行版维护的版本。发行版内核由 longterm 分支、回移的修复以及厂商测试组成,也是服务提供商镜像和技术支持安排所依据的版本。只有在需要特定驱动程序或功能时,才应构建更新的 mainline 内核;在确定采用某个分支前,还应检查其生命周期结束日期。