1. 引言¶
1.1. 执行摘要¶
本节其余部分介绍了内核开发过程的范围,以及开发人员及其雇主在该过程中可能遇到的种种挫折。将内核代码合并到官方(“主线”)内核中有许多极好的理由,包括用户可以自动获取、各种形式的社区支持,以及影响内核开发方向的能力。贡献给 Linux 内核的代码必须在兼容 GPL 的许可证下发布。
开发过程的工作原理 介绍了开发过程、内核发布周期以及合并窗口的机制。其中涵盖了补丁开发、审查和合并周期的各个阶段。还讨论了一些工具和邮件列表。鼓励想要开始内核开发的开发人员通过追踪和修复错误作为最初的练习。
早期规划 介绍了项目早期阶段的规划,并强调要尽早让开发社区参与进来。
编写正确的代码 讨论了编码过程;探讨了其他开发人员曾经遇到的一些陷阱。其中涵盖了对补丁的一些要求,并介绍了一些有助于确保内核补丁正确的工具。
发布补丁 讨论了发布补丁以供审查的过程。为了受到开发社区的重视,补丁必须经过规范的格式化和描述,并且必须发送到正确的地方。遵循本节中的建议将有助于确保您的工作获得最好的反响。
后续跟进 介绍了发布补丁后会发生的事情;此时工作远未结束。与审查者合作是开发过程至关重要的一部分;本节提供了许多关于如何在这一重要阶段避免问题的建议。开发人员需要注意,不要以为补丁合并到主线后工作就完成了。
进阶主题 介绍了几个“进阶”主题:使用 git 管理补丁以及审查其他人发布的补丁。
获取更多信息 通过指向有关内核开发的更多信息的来源链接,为本文档作结。
1.2. 本文档的内容¶
Linux 内核拥有超过 800 万行代码,每次发布都有远超 1000 名贡献者参与,是现存最大、最活跃的自由软件项目之一。自 1991 年初露锋芒以来,该内核已演变为同类中最优秀的操作系统组件,运行在袖珍数字音乐播放器、台式个人电脑、现存最大的超级计算机以及介于两者之间的所有类型的系统上。对于几乎任何情况,它都是一个强大、高效且可扩展的解决方案。
随着 Linux 的发展,希望参与其开发的开发人员(和公司)数量也在增加。硬件厂商希望确保 Linux 能够很好地支持他们的产品,从而使这些产品对 Linux 用户更具吸引力。将 Linux 用作集成产品组件的嵌入式系统厂商则希望 Linux 尽可能强大并最适合当前的任务。以 Linux 为产品基础的分销商和其他软件厂商对 Linux 内核的功能、性能和可靠性有着明确的兴趣。终端用户也经常希望修改 Linux,以使其更好地满足他们的需求。
Linux 最引人注目的特征之一是它对这些开发人员是开放的;任何具备必要技能的人都可以改进 Linux 并影响其开发方向。专有产品无法提供这种开放性,而这正是自由软件流程的特征。不过,如果要说的话,内核甚至比大多数其他自由软件项目更加开放。一个典型的为期三个月的内核开发周期可能会涉及来自 100 多个不同公司(或根本不属于任何公司)的 1000 多名开发人员。
与内核开发社区合作并不是特别困难。尽管如此,许多潜在的贡献者在尝试进行内核工作时仍然遇到了困难。内核社区已经发展出自己独特的运作方式,使其能够在每天有数千行代码被修改的环境中顺畅运作(并产出高质量的产品)。因此,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 通用公共许可证第 2 版(GPLv2)兼容。在实践中,这意味着所有代码贡献要么受 GPLv2 涵盖(可选地包含允许在 GPL 稍后版本下分发的语言),要么受三条款 BSD 许可证涵盖。任何不受兼容许可证涵盖的贡献都不会被内核接受。
贡献给内核的代码不需要(或被要求)转让版权。所有合并到主线内核的代码都保留其原始所有权;因此,内核现在拥有数千名所有者。
这种所有权结构的一个含义是,任何更改内核许可证的尝试几乎注定会失败。在极少数实际场景中,可以获得所有版权所有者的同意(或将他们的代码从内核中移除)。因此,特别是在可预见的未来,没有任何迁移到 GPL 第 3 版的前景。
贡献给内核的所有代码必须是合法的自由软件,这一点至关重要。因此,不接受身份不明的贡献者或匿名贡献者的代码。所有贡献者都必须在其代码上进行“签署(sign off)”,声明该代码可以根据 GPL 与内核一起分发。未被其所有者许可为自由软件的代码,或可能给内核带来版权相关问题的代码(例如缺乏适当保护措施的逆向工程努力派生出的代码),则不能被贡献。
关于版权相关问题的疑问在 Linux 开发邮件列表中很常见。此类问题通常不乏回答,但应当记住,回答这些问题的人不是律师,无法提供法律意见。如果您有与 Linux 源代码相关的法律问题,与懂该领域的律师交谈是无可替代的。依赖从技术邮件列表获取的答案是一件风险很高的事情。