1. 简介

1.1. 概要

本节的其余部分涵盖了内核开发流程的范围,以及开发人员及其雇主可能遇到的挫折。有很多原因说明为什么内核代码应该合并到官方(“主线”)内核中,包括自动提供给用户、多种形式的社区支持以及影响内核开发方向的能力。贡献给 Linux 内核的代码必须在 GPL 兼容许可下提供。

开发流程如何运作 介绍了开发流程、内核发布周期和合并窗口的机制。涵盖了补丁开发、审查和合并周期中的各个阶段。还讨论了一些工具和邮件列表。鼓励希望开始内核开发的开发人员将查找和修复错误作为初始练习。

早期阶段规划 涵盖了早期阶段的项目规划,重点是尽早让开发社区参与进来。

确保代码正确 介绍了编码过程;讨论了其他开发人员遇到的一些陷阱。涵盖了对补丁的一些要求,并介绍了可以帮助确保内核补丁正确的工具。

提交补丁 讨论了提交补丁以供审查的过程。为了得到开发社区的认真对待,补丁必须正确格式化和描述,并且必须发送到正确的位置。遵循本节中的建议应该有助于确保您的工作获得最好的反响。

后续跟进 介绍了提交补丁后会发生什么;那时工作远未完成。与审查人员合作是开发过程的关键部分;本节提供了一些关于如何避免在这个重要阶段出现问题的技巧。提醒开发人员不要认为补丁合并到主线后工作就完成了。

高级主题 介绍了两个“高级”主题:使用 git 管理补丁和审查其他人提交的补丁。

更多信息 在文档结尾处提供了更多关于内核开发信息的来源。

1.2. 本文档内容

Linux 内核拥有超过 800 万行代码,每次发布都有 1000 多名贡献者,是现存最大、最活跃的自由软件项目之一。自从 1991 年卑微的开始以来,这个内核已经发展成为最优秀的操作系统组件,它运行在口袋大小的数字音乐播放器、台式 PC、现有的最大的超级计算机以及介于两者之间的所有类型的系统上。它几乎在任何情况下都是一个强大、高效且可扩展的解决方案。

随着 Linux 的发展,希望参与其开发的开发人员(和公司)的数量也在增加。硬件供应商希望确保 Linux 能够很好地支持他们的产品,从而使这些产品对 Linux 用户有吸引力。使用 Linux 作为集成产品组件的嵌入式系统供应商希望 Linux 尽可能胜任且适合手头的任务。基于 Linux 的发行商和其他软件供应商对 Linux 内核的功能、性能和可靠性有明确的兴趣。最终用户也经常希望更改 Linux 以使其更好地满足他们的需求。

Linux 最引人注目的功能之一是开发人员可以访问它;任何具有必要技能的人都可以改进 Linux 并影响其发展方向。专有产品无法提供这种开放性,这是自由软件过程的特征。但是,如果说有什么不同的话,那就是内核比大多数其他自由软件项目更加开放。一个典型的三个月内核开发周期可能涉及 1000 多名开发人员为 100 多家不同的公司(或根本不为任何公司)工作。

与内核开发社区合作并不特别困难。但是,尽管如此,许多潜在的贡献者在尝试进行内核工作时都遇到了困难。内核社区已经发展出自己独特的运作方式,使其能够在每天都在更改数千行代码的环境中顺利运行(并生产高质量的产品)。因此,Linux 内核开发流程与专有开发方法大相径庭也就不足为奇了。

对于新的开发人员来说,内核的开发流程可能会显得陌生且令人生畏,但其背后有充分的理由和扎实的经验。不了解内核社区运作方式(或者更糟的是,试图蔑视或规避它们)的开发人员将会经历令人沮丧的体验。开发社区在帮助那些正在学习的人的同时,几乎没有时间顾及那些不听劝告或不关心开发过程的人。

希望那些阅读本文档的人能够避免这种令人沮丧的体验。这里有很多材料,但是阅读它所花费的精力很快就会得到回报。开发社区总是需要那些能够帮助改进内核的开发人员;以下文本应该可以帮助您或您的员工加入我们的社区。

1.3. 致谢

本文档由 Jonathan Corbet 编写,corbet@lwn.net。Johannes Berg、James Berry、Alex Chiang、Roland Dreier、Randy Dunlap、Jake Edge、Jiri Kosina、Matt Mackall、Arthur Marsh、Amanda McPherson、Andrew Morton、Andrew Price、Tsugikazu Shibata 和 Jochen Voß 的评论改进了本文档。

这项工作得到了 Linux 基金会的支持;特别感谢 Amanda McPherson,她看到了这项工作的价值并促成了这一切。

1.4. 将代码合并到主线的重要性

一些公司和开发人员有时会想,他们为什么要费心学习如何与内核社区合作,并将他们的代码合并到主线内核中(“主线”是指由 Linus Torvalds 维护并用作 Linux 发行版基础的内核)。从短期来看,贡献代码看起来像是可以避免的费用;直接保持代码分离并直接支持用户似乎更容易。事实是,保持代码分离(“树外”)是一种虚假的经济行为。

为了说明树外代码的成本,以下是内核开发流程的一些相关方面;其中大多数将在本文档的后面部分进行更详细的讨论。请考虑

  • 已合并到主线内核中的代码可供所有 Linux 用户使用。它将自动存在于所有启用它的发行版中。无需驱动程序磁盘、下载或支持多个发行版多个版本的麻烦;对于开发人员和用户来说,一切都只是正常运行。合并到主线中解决了大量的发行和支持问题。

  • 虽然内核开发人员努力维护用户空间的稳定接口,但内部内核 API 却在不断变化。缺乏稳定的内部接口是一个有意的设计决策;它允许随时进行根本性的改进,并产生更高质量的代码。但是,该策略的一个结果是,任何树外代码如果想与新内核一起工作,都需要不断维护。维护树外代码需要大量的工作才能使该代码正常工作。

    相反,主线中的代码不需要这项工作,因为有一个简单的规则,即任何进行 API 更改的开发人员也必须修复因该更改而中断的任何代码。因此,合并到主线中的代码的维护成本明显更低。

  • 除此之外,内核中的代码通常会由其他开发人员进行改进。赋予您的用户社区和客户改进您产品的权力可能会带来令人惊讶的结果。

  • 内核代码在合并到主线之前和之后都会进行审查。无论原始开发人员的技能有多强,这个审查过程总是能找到可以改进代码的地方。审查经常会发现严重的错误和安全问题。对于在封闭环境中开发的代码尤其如此;此类代码从外部开发人员的审查中获益良多。树外代码的质量较低。

  • 参与开发过程是您影响内核开发方向的方式。在场外抱怨的用户会被听到,但积极的开发人员拥有更强大的发言权,并且有能力实施更改,使内核更好地满足他们的需求。

  • 当代码被单独维护时,总是存在第三方贡献类似功能的不同实现的可能性。如果发生这种情况,您的代码合并将变得更加困难,甚至不可能。然后,您将面临不愉快的选择,要么 (1) 无限期地在树外维护一个非标准功能,要么 (2) 放弃您的代码并将您的用户迁移到树内版本。

  • 贡献代码是使整个过程运作的基本行动。通过贡献您的代码,您可以为内核添加新功能,并提供对其他内核开发人员有用的功能和示例。如果您为 Linux 开发了代码(或正在考虑这样做),那么您显然对这个平台的持续成功感兴趣;贡献代码是帮助确保成功的最佳方式之一。

以上所有推理都适用于任何树外内核代码,包括以专有的、仅二进制形式分发的代码。但是,在考虑任何类型的仅二进制内核代码分发之前,还应考虑其他因素。这些包括

  • 围绕专有内核模块分发的法律问题充其量是模糊不清的;很多内核版权持有人认为大多数仅二进制模块是内核的衍生产品,因此,它们的分发违反了 GNU 通用公共许可证(关于这一点将在下文详细说明)。您的作者不是律师,本文档中的任何内容都不能被视为法律建议。闭源模块的真正法律地位只能由法院确定。但是,困扰这些模块的不确定性始终存在。

  • 二进制模块大大增加了调试内核问题的难度,以至于大多数内核开发人员甚至不会尝试。因此,仅二进制模块的分发将使您的用户更难从社区获得支持。

  • 仅二进制模块的分销商也更难获得支持,他们必须为他们希望支持的每个发行版和每个内核版本提供模块版本。可能需要构建同一模块的数十个版本才能提供合理的全面覆盖,并且您的用户每次升级内核时都必须单独升级您的模块。

  • 上面关于代码审查的所有内容都双倍适用于闭源代码。由于此代码根本不可用,因此它不可能经过社区审查,并且毫无疑问会存在严重的问题。

特别是嵌入式系统的制造商可能会倾向于无视本节中的大部分内容,他们认为他们正在交付一个使用冻结内核版本且在发布后不需要更多开发的独立产品。这种论点忽略了广泛的代码审查的价值以及允许用户向您的产品添加功能的价值。但是,这些产品也有有限的商业寿命,之后必须发布新版本。届时,那些代码在主线中并得到良好维护的供应商将更有利于快速将新产品推向市场。

1.5. 许可

代码是在多个许可证下贡献给 Linux 内核的,但所有代码必须与 GNU 通用公共许可证 (GPLv2) 的第 2 版兼容,该许可证涵盖了整个内核发行版。实际上,这意味着所有代码贡献都受 GPLv2 覆盖(可以选择允许在更高版本的 GPL 下分发的语言)或三条款 BSD 许可证。任何不受兼容许可证覆盖的贡献都不会被内核接受。

对于贡献给内核的代码,不需要(或请求)版权转让。合并到主线内核的所有代码都保留其原始所有权;因此,内核现在有数千名所有者。

这种所有权结构的一个含义是,任何更改内核许可的尝试都注定会几乎肯定失败。在少数实际场景中,可以获得所有版权持有人的同意(或从内核中删除他们的代码)。因此,尤其是在可预见的未来,没有迁移到 GPL 第 3 版的前景。

必须保证所有贡献给内核的代码都是合法的自由软件。因此,不接受匿名(或假名)贡献者的代码。所有贡献者都需要“签署”他们的代码,声明该代码可以根据 GPL 与内核一起分发。未由其所有者许可为自由软件的代码,或可能为内核带来与版权相关的问题的代码(例如,来自缺乏适当保护的反向工程工作的代码)都不能被贡献。

关于与版权相关的问题在 Linux 开发邮件列表中很常见。此类问题通常会收到大量的答案,但应该记住,回答这些问题的人不是律师,无法提供法律建议。如果您有与 Linux 源代码相关的法律问题,那么与了解该领域的律师交谈是不可替代的。依赖从技术邮件列表中获得的答案是一件冒险的事情。