HOWTO do Linux kernel developmen
这是关于这个话题的全部,最终的文件。 它包含有关如何成为Linux内核开发人员以及如何学习如何与Linux内核开发社区合作的说明。 它试图不包含与内核编程的技术方面有关的任何东西,但会帮助你指出正确的方向。
如果本文档中的任何内容过期,请将补丁发送给本文档底部列出的此文件的维护人员。
介绍
那么,你想学习如何成为Linux内核开发者? 或者您的经理已经告诉您“为此设备编写一个Linux驱动程序”。本文档的目标是通过描述您需要经过的过程向您介绍所需的一切信息,并提示如何实现这一目标 与社区合作。 它也将试图解释社区为什么像这样工作的一些原因。
内核主要用C语言编写,其中一些与构件相关的部分用汇编语言编写。 内核开发需要对C有一个很好的理解。 程序集(任何体系结构)不是必需的,除非你打算为该体系结构进行低级开发。 虽然他们不是一个坚实的C教育和/或多年的经验的好替代品,但下面的书是好的,如果有的话,可以参考:
- “The C Programming Language” by Kernighan and Ritchie [Prentice Hall]
- “Practical C Programming” by Steve Oualline [O’Reilly]
- “C: A Reference Manual” by Harbison and Steele [Prentice Hall]
内核是使用GNU C和GNU工具链编写的。 虽然它符合ISO C89标准,但它使用了许多标准中没有的扩展功能。 内核是一个独立的C环境,不依赖于标准C库,因此C标准的某些部分不被支持。 任意长分歧和浮点是不允许的。 有时难以理解内核对工具链和它所使用的扩展的假设,不幸的是没有明确的参考。 请检查gcc info pages(info gcc)的一些信息。
请记住,您正试图学习如何与现有的开发社区合作。 它是一个多元化的人群,具有高标准的编码,风格和程序。 随着时间的推移,这些标准已经被创造出来,基于他们发现对于这样一个地理上分散的大型团队来说最好的工作。 尽可能提前了解这些标准,因为这些标准是有据可查的; 不要指望人们适应你或你公司的做事方式。
法律问题
Linux内核源代码是在GPL下发布的。 有关许可证的详细信息,请参阅源代码树主目录中的COPYING文件。 如果您有关于许可证的进一步问题,请联系律师,而不要在Linux内核邮件列表上询问。 邮件列表上的人不是律师,你不应该依赖他们在法律事务上的陈述。
有关GPL的常见问题和答案,请参阅:
https://www.gnu.org/licenses/gpl-faq.html
文档
Linux内核源代码树有大量的文档,对于学习如何与内核社区交互是非常有价值的。 将新功能添加到内核时,建议添加新的文档文件,以解释如何使用该功能。 当内核更改导致内核暴露给用户空间的界面发生变化时,建议您在mtk.manpages@gmail.com和CC 列表linux-api@vger.kernel.org将手动页面的信息或补丁发送给手册页面维护人员。
以下是内核源代码树中需要读取的文件列表:
-
README
该文件给出了Linux内核的简短背景,并描述了配置和构建内核的必要步骤。 内核新手应该从这里开始。 -
Documentation/process/changes.rst
该文件给出了构建和运行内核所需的各种软件包的最低级别列表。 -
Documentation/process/coding-style.rst
这描述了Linux内核的编码风格,以及它背后的一些基本原理。 预计所有新代码将遵循本文档中的指导原则。 如果遵循这些规则,大多数维护人员只会接受补丁程序,而且许多人只有在正确的风格下才会审查代码。 -
Documentation/process/submitting-patches.rstandDocumentation/process/submitting-drivers.rst
这些文件详细描述了如何成功创建和发送补丁,包括(但不限于):- 电子邮件内容
- 电子邮件格式
- 发送给谁
遵循这些规则并不能保证成功(因为所有的补丁都受到内容和风格的审查),但不遵循这些规则几乎总是不会通过。
关于如何正确创建补丁的其他优秀描述如下:
“完美的补丁”:
https://www.ozlabs.org/~akpm/stuff/tpp.txt
“Linux内核补丁提交格式”:
http://linux.yyz.us/patch-format.html
-
Documentation/process/stable-api-nonsense.rst
这个文件描述了有意识决定在内核中没有一个稳定的API的基本原理,包括如下内容:- 子系统垫片层(兼容性?)
- 操作系统之间的驱动程序可移植
- 减轻内核源代码树中的快速变化(或防止快速变化)
本文档对于理解Linux开发理念至关重要,对于从其他操作系统开发人员转向Linux的人员非常重要。
-
Documentation/admin-guide/security-bugs.rst
如果您觉得在Linux内核中发现安全问题,请按照本文档中的步骤来帮助通知内核开发人员,并帮助解决问题。 -
Documentation/process/management-style.rst
本文档描述了Linux内核维护者如何操作以及他们方法背后的共同特征。 对于任何一个新的内核开发人员(或者只是对此感到好奇的人)来说,这是一个重要的阅读,因为它解决了很多关于内核维护人员独特行为的常见误解和困惑。 -
Documentation/process/stable-kernel-rules.rst
这个文件描述了稳定的内核释放如何发生的规则,以及如果你想要改变到这些版本之一该怎么做。 -
Documentation/process/kernel-docs.rst
与内核开发相关的外部文档列表。 如果在内核文档中找不到你要找的内容,请查阅这个列表。 -
Documentation/process/applying-patches.rst
一个很好的介绍,描述了一个补丁是什么以及如何将它应用到内核的不同开发分支。
内核也有大量的文件,可以从源代码本身或ReStructuredText标记(ReST)自动生成,就像这样。 这包括对内核API的完整描述,以及如何正确处理锁定的规则。
所有这些文件可以通过运行生成PDF或HTML:
make pdfdocs
make htmldocs
分别来自主内核源码目录。
使用ReST标记的文档将在文档/输出中生成。 它们也可以在LaTeX和ePub格式上生成:
make latexdocs
make epubdocs
目前,在DocBook上有一些正在转换为ReST的文档。 这些文档将在Documentation/DocBook/目录下创建,也可以通过运行生成为Postscript或手册页:
Becoming A Kernel Developer
如果你对Linux内核开发一无所知,你应该看看Linux KernelNewbies项目:
它包含一个有用的邮件列表,你几乎可以问任何类型的基本的内核开发问题(在问一些以前已经回答的问题之前,一定要首先搜索档案)。它还有一个IRC频道,你可以 用于实时提问,以及大量有用的文档,这对于学习Linux内核开发很有帮助。
该网站有关于代码组织,子系统和当前项目(树中和树外)的基本信息。 它还描述了一些基本的物流信息,比如如何编译内核和应用补丁。
如果你不知道你想从哪里开始,但是你想寻找一些开始加入到内核开发社区的任务,请转到Linux Kernel Janitor的项目:
https://kernelnewbies.org/KernelJanitors
这是一个很好的开始。 它描述了一个相对简单的问题清单,需要在Linux内核源码树中进行清理和修复。 与负责这个项目的开发人员一起工作,您将学习如何将您的补丁纳入Linux内核树的基础知识,如果您还没有任何想法,可能会指出接下来要做什么的方向。
如果你已经有了一段你想要放到内核树中的代码,但是需要一些帮助以正确的方式获得它,那么就创建一个kernel-mentors项目来帮助你解决这个问题。 这是一个邮件列表,可以在以下网址找到:
https://selenic.com/mailman/listinfo/kernel-mentors
在对Linux内核代码做任何实际的修改之前,理解代码是如何工作是非常重要的。 为此,没有什么比直接阅读(最棘手的部分评论得好),也许甚至在专门的工具的帮助下。 Linux交叉引用项目是一个特别推荐的工具,它能够以自引用索引的网页格式显示源代码。 一个优秀的最新的内核代码库可以在以下位置找到:
http://lxr.free-electrons.com/
开发过程
Linux内核开发过程目前由几个不同的主内核“分支”和许多不同的子系统特定的内核分支组成。 这些不同的分支是:
- main 4.x kernel tree
- 4.x.y -stable kernel tree
- 4.x -git kernel patches
- subsystem specific kernel trees and patches
- the 4.x -next kernel tree for integration tests
4.x kernel tree
4.x内核由Linus Torvalds维护,可以在pub/linux/kernel/v4.x/目录下的https://kernel.org上找到。其发展过程如下:
- 只要一个新的内核被发布,两个星期的窗口就会被打开,在这段时间里,维护者可以向Linus提交大的差异,通常是已经包含在-next内核中几个星期的补丁。提交重大更改的首选方法是使用git(内核的源代码管理工具,更多信息可以在https://git-scm.com/找到),但是普通的补丁也很好。
- 两个星期后,一个-rc1内核被释放,重点在于使得新内核尽可能坚如磐石。现在大部分补丁都应该修复一个回归。一直存在的错误不是回归,所以只有在重要的时候才推动这些修复。请注意,在-rc1之后可能会接受一个全新的驱动程序(或文件系统),因为只要更改是自包含的,并且不会影响代码之外的区域添加。在发布-rc1之后,可以使用git将修补程序发送给Linus,但是修补程序也需要发送到公共邮件列表以供审查。
- 每当Linus认为当前的git树处于一个合理稳定的状态,足以进行测试时,就会发布一个新的-rc。目标是每周发布一个新的-rc内核。
- 进程一直持续到内核被认为是“准备就绪”,这个过程应该持续大约6个星期。
值得一提的是Andrew Morton在linux-kernel邮件列表中关于内核版本的内容:
“Nobody knows when a kernel will be released, because it’s released according to perceived bug status, not according to a preconceived timeline.”
4.x.y -stable kernel tree
具有3部分版本的内核是稳定的内核。 它们包含相对较小和重要的安全问题修复或在给定的4.x内核中发现的显着回退。
对于那些想要最新的稳定内核并且对帮助测试开发/实验版本不感兴趣的用户,这是推荐的分支。
如果没有可用的4.x.y内核,则最高编号的4.x内核是当前稳定的内核。
4.x.y由“stable”团队stable@vger.kernel.org维护,并根据需要发布。 正常释放时间大约为两周,但如果没有紧迫问题,则可能会更长。 与安全相关的问题反而会导致发布几乎立即发生。
内核树中的Documentation/process/stable-kernel-rules.rst文件记录了-stable树可以接受哪些类型的更改以及发布过程如何工作。
4.x -git patches
这些是Linus内核树的每日快照,这些快照是在git存储库(因此得名)中管理的。这些补丁通常每天发布,代表Linus树的当前状态。 它们比-rc内核更具实验性,因为它们是自动生成的,不用粗略一眼就能看出它们是否理智。
Subsystem Specific kernel trees and patches
各种内核子系统的维护者(以及许多内核子系统开发者)在源代码库中公开了他们当前的开发状态。 这样,其他人可以看到内核的不同区域发生了什么。 在发展迅速的领域,可能会要求开发人员将其提交的内容基于子系统内核树,以避免提交与其他已经进行的工作之间的冲突。
这些仓库中的大部分都是git树,但也有其他SCM正在使用,或者补丁队列被发布为quilt系列。 这些子系统存储库的地址列在MAINTAINERS文件中。 他们中的许多人可以浏览https://git.kernel.org/。
在提议的补丁程序被提交给这样的子系统树之前,需要审查哪些主要发生在邮件列表上(参见下面的相应部分)。 对于几个内核子系统,这个评估过程是通过工具拼凑来跟踪的。 Patchwork提供一个Web界面,显示补丁发布,补丁上的任何评论或修改,维护人员可以将补丁标记为审阅,接受或拒绝。 大多数这些拼凑网站都列在https://patchwork.kernel.org/。
4.x -next kernel tree for integration tests
在子系统树更新合并到主线4.x树之前,需要对其进行集成测试。 为此,存在一个特殊的测试资源库,几乎所有的子系统树都几乎每天都被提取出来:
https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
这样,下一个内核就会给出一个总结性的展望,看看下一个合并期间将会进入主线内核的内容。 冒险的测试者非常欢迎运行时测试-next内核。
Bug Reporting
https://bugzilla.kernel.org是Linux内核开发者跟踪内核错误的地方。 鼓励用户报告他们在这个工具中找到的所有错误。 有关如何使用内核bugzilla的详细信息,请参阅:
https://bugzilla.kernel.org/page.cgi?id=faq.html
主内核源代码目录下的文件admin-guide / reporting-bugs.rst为如何报告可能的内核错误提供了一个很好的模板,并且详细说明了内核开发者需要什么样的信息来帮助跟踪这个问题。
Managing bug reports
实施黑客技能的最佳方法之一是修复其他人报告的错误。 不仅你会帮助内核更稳定,你将学习解决现实世界的问题,你会提高你的技能,其他开发人员会意识到你的存在。 修复错误是在其他开发人员中获得优势的最好方法之一,因为没有多少人浪费时间来修复其他人的错误。
要在已报告的错误报告中工作,请转到https://bugzilla.kernel.org。 如果您希望获得有关未来错误报告的建议,您可以订阅bugme-new邮件列表(仅邮寄新错误报告)或bugme-janitor邮件列表(bugzilla中的每个更改均会在此邮寄)
https://lists.linux-foundation.org/mailman/listinfo/bugme-new
https://lists.linux-foundation.org/mailman/listinfo/bugme-janitors
Mailing lists
正如上面的一些文档所描述的那样,大多数核心内核开发者都参与了Linux内核邮件列表。 有关如何订阅和取消订阅的详细信息,请访问:
http://vger.kernel.org/vger-lists.html#linux-kernel
在很多不同的地方都有网上邮件列表的存档。 使用搜索引擎来查找这些档案。 例如:
http://dir.gmane.org/gmane.linux.kernel
强烈建议您在将其发布到列表之前,搜索关于您想要调出的主题的档案。 很多已经详细讨论过的东西只能在邮件列表中记录下来。
大多数单独的内核子系统也都有自己的独立邮件列表,他们在这里进行开发工作。 请参阅MAINTAINERS文件以获取这些列表针对不同组的列表。
许多列表都在kernel.org上。 有关它们的信息可在以下网址找到:
http://vger.kernel.org/vger-lists.html
请记住在使用列表时要遵循良好的行为习惯。 尽管有点俗气,下面的URL有一些与列表(或任何列表)交互的简单指导:
http://www.albion.com/netiquette/
如果多人回复您的邮件,收件人列表可能会变得非常大。 不要从没有任何理由的CC:列表中删除任何人,也不要只回复列表地址。 习惯于接收邮件两次,一次来自发件人和一份来自列表的邮件,不要试图通过添加花哨的邮件头来调整邮件,人们不会喜欢它。
请记住保持您的回复的上下文和归属,并在回复顶部保留“John Kernelhacker writing ...:”行,并在各个引用部分之间添加您的语句,而不是写在邮件顶部。
如果您将修补程序添加到邮件中,请确保它们是可读的文本,如Documentation/process/submitting-patches.rst中所述。 内核开发人员不想处理附件或压缩补丁; 他们可能想对你的补丁的个别行发表评论,这只能用于这种方式。 确保你使用的邮件程序不会破坏空格和制表符。 一个好的第一个测试就是把邮件发送给自己,并尝试自己应用自己的补丁。 如果这不起作用,请修复您的邮件程序或更改它,直到它工作。
最重要的是,请记住尊重其他用户。
Working with the community
内核社区的目标是提供最好的内核。 当你提交一个可以接受的补丁的时候,将会对它的技术特性和那些单独的补丁进行评估。 那么,你应该期待什么?
- 批评
- 注释
- 要求改变
- 请求理由
- 安静
请记住,这是将你的补丁加入内核的一部分。 您必须能够对您的补丁进行批评和评论,在技术层面对其进行评估,并重新修补您的补丁或提供清晰,简明的推理,说明为什么不应该进行修改。 如果您的帖子没有回复,请等待几天再试一次,有时甚至会丢失大量的信息。
你不应该做什么?
- 希望您的补丁能够毫无疑问地被接受
- 变得防守
- 忽略评论
- 重新提交修补程序而不进行任何请求的更改
在一个正在寻求最佳技术解决方案的社区中,对于补丁的有效性总会有不同的看法。 你必须合作,并愿意适应你的想法,以适应内核。 或者至少愿意证明你的想法是值得的。 记住,只要你愿意努力寻找一个正确的解决方案,那么错误是可以接受的。
你的第一个补丁的答案可能仅仅是你应该纠正的十几件事情的列表,这是很正常的。 这并不意味着你的补丁不会被接受,这并不意味着对你个人不利。 只需更正针对您的修补程序提出的所有问题并重新发送。
内核社区和公司结构之间的差异
内核社区的工作方式与大多数传统企业开发环境不同。以下列出了您可以尝试避免的问题:
关于您提出的更改要说的很好:
- “这解决了很多问题。”
- “这删除了2000行代码。”
- “这是一个解释我想描述的东西的补丁。”
- “我测试了5种不同的架构......”
- “这是一系列的小补丁...”
- “这增加了典型机器的性能......”
不好的事情,你应该避免说:
- “我们在AIX/ptx/Solaris中这样做,所以它一定是好的...”
- “我已经这样做了20年了,所以......”
- “这是我的公司赚钱所需要的”
- “这是为我们的企业产品线”。
- “这是我的1000页的设计文件,描述了我的想法”
- “我已经为此工作了6个月......”
- “这是一个5000行补丁...”
- “我重写了当前所有的烂摊子,这里是......”
- “我有一个最后期限,现在需要应用这个补丁。”
内核社区与大多数传统的软件工程工作环境不同的另一种方式是交互的不露面本质。 使用电子邮件和irc作为沟通的主要形式的一个好处是没有基于性别或种族的歧视。 Linux内核的工作环境是接受女性和少数民族,因为你只是一个电子邮件地址。 国际方面也有助于平衡比赛场地,因为你不能根据一个人的名字来猜测性别。 一个男人可能被命名为安德烈,一个女人可能被命名为帕特。 大多数在Linux内核中工作并发表过意见的女性都有积极的经验。
语言障碍会给一些不习惯英语的人造成问题。 为了在邮件列表中正确地得到想法,需要掌握好语言,因此建议您在发送邮件之前检查您的邮件以确保它们有英文意义。
Break up your changes(细分你的改动)
Linux内核社区并不乐意同时接受大量的代码。 这些变化需要适当的介绍,讨论,并分解成微小的,单独的部分。 这几乎与公司习惯的做法完全相反。 您的建议也应该在开发过程中尽早介绍,以便您可以收到有关您正在进行的操作的反馈。 它也让社区觉得你正在与他们合作,而不是简单地把他们当作你的特征的倾倒地。 但是,不要一次发送50封电子邮件到邮件列表,你的补丁系列应该几乎全部都是小于这个时间的。
细分的理由如下:
-
小补丁增加了您的补丁应用的可能性,因为他们不需要太多时间或精力来验证正确性。 一个5线补丁可以由维护人员应用几乎一眼就可以看到。 但是,500行补丁可能需要几个小时来检查正确性(所花费的时间与补丁的大小成指数成比例)。
小的补丁也使得在出现问题时很容易进行调试。 一个接一个地退出补丁要比在一个补丁被应用之后解剖一个非常大的补丁容易得多(并且破坏了某些东西)。 -
发送小补丁很重要,而且在提交补丁前要重写和简化补丁(或简单地重新排序)。
这里是内核开发者Al Viro的一个类比:
“Think of a teacher grading homework from a math student. The teacher does not want to see the student’s trials and errors before they came up with the solution. They want to see the cleanest, most elegant answer. A good student knows this, and would never submit her intermediate work before the final solution.
The same is true of kernel development. The maintainers and reviewers do not want to see the thought process behind the solution to the problem one is solving. They want to see a simple and elegant solution.”
在提出一个优雅的解决方案和与社区一起工作并讨论你未完成的工作之间保持平衡可能是一个挑战。 因此,尽早获得反馈意见以改进工作是很好的做法,但是也可以将您的更改保留在可能已被接受的小块中,即使您的整个任务现在还没有准备好。
也意识到,发送补丁包括未完成的补丁是不可接受的,并且将在稍后“修复”。
验证修补
随着打破你的补丁,让你的Linux社区知道他们为什么要添加这个变化是非常重要的。 新功能必须被证明是必要和有用的。
记录您的更改
在发送补丁时,请特别注意您在电子邮件中的文字内容。 这些信息将成为修补程序的ChangeLog信息,并将保留给所有人看。 它应该完整地描述补丁,包含:
- 为什么改变是必要的
- 补丁中的整体设计方法
- 实施细节
- 测试结果
有关这应该是什么样子的更多细节,请参阅文档的ChangeLog部分:
所有这些东西有时候很难做到。 完善这些实践可能需要几年的时间(如果有的话)。 这是一个持续的改善过程,需要很多的耐心和决心。 但是不要放弃,这是可能的。 以前有很多人做过,每个人都必须从现在开始。
感谢Paolo Ciarrocchi,他允许“Development Process”(https://lwn.net/Articles/94386/)部分基于他写的文本,Randy Dunlap和Gerrit Huizenga提供了一些你所需要的东西 应该也不应该说。 也感谢Pat Mochel,Hanna Linder,Randy Dunlap,Kay Sievers,Vojtech Pavlik,Jan Kara,Josh Boyer,Kees Cook,Andrew Morton,Andi Kleen,Vadim Lobanov,Jesper Juhl,Adrian Bunk,Keri Harris,Frans Pop,David A Wheeler,Junio Hamano,Michael Kerrisk和Alex Shepard的评论,评论和贡献。 没有他们的帮助,这个文件是不可能的。
维护者:Greg Kroah-Hartman greg@kroah.com