From 575fbfa69e50d8fec61b16e384034cb1ffc4c033 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:26:02 +0800 Subject: docs/zh_CN: Improve zh_CN/process/index.rst Improve language and grammar of zh_CN/process/index.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/aace391070859555c0378f93506e46fcdb8dbf93.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/process/index.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/index.rst b/Documentation/translations/zh_CN/process/index.rst index 8051a7b322c5..39e9c88fbaa6 100644 --- a/Documentation/translations/zh_CN/process/index.rst +++ b/Documentation/translations/zh_CN/process/index.rst @@ -13,11 +13,11 @@ 与Linux 内核社区一起工作 ======================== -那么你想成为Linux内核开发人员? 欢迎! 不但从技术意义上讲有很多关于内核的知识 -需要学,而且了解我们社区的工作方式也很重要。 阅读这些文章可以让您以更轻松地, -麻烦最少的方式将更改合并到内核。 +你想成为Linux内核开发人员吗?欢迎之至!在学习许多关于内核的技术知识的同时, +了解我们社区的工作方式也很重要。阅读这些文档可以让您以更轻松的、麻烦更少的 +方式将更改合并到内核。 -以下是每位开发人员应阅读的基本指南。 +以下是每位开发人员都应阅读的基本指南: .. toctree:: :maxdepth: 1 @@ -47,7 +47,7 @@ management-style embargoed-hardware-issues -这些是一些总体技术指南,由于缺乏更好的地方,现在已经放在这里 +这些是一些总体性技术指南,由于不大好分类而放在这里: .. toctree:: :maxdepth: 1 -- cgit v1.2.3 From 72d85e3bf0b1932b9b78b3657bb448bbcbf4a944 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:26:24 +0800 Subject: docs/zh_CN: Improve zh_CN/process/1.Intro.rst Improve language and grammar of zh_CN/process/1.Intro.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/ed025a9071811f354b53d4b6e8e1d0976b34f34a.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/1.Intro.rst | 195 +++++++++++---------- 1 file changed, 102 insertions(+), 93 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/1.Intro.rst b/Documentation/translations/zh_CN/process/1.Intro.rst index 10a15f3dc282..4f9284cbe33b 100644 --- a/Documentation/translations/zh_CN/process/1.Intro.rst +++ b/Documentation/translations/zh_CN/process/1.Intro.rst @@ -1,162 +1,170 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/1.Intro.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_process_intro: -介绍 +引言 ==== -执行摘要 +内容提要 -------- -本节的其余部分涵盖了内核开发过程的范围,以及开发人员及其雇主在这方面可能遇 -到的各种挫折。内核代码应该合并到正式的(“主线”)内核中有很多原因,包括对用 -户的自动可用性、多种形式的社区支持以及影响内核开发方向的能力。提供给Linux -内核的代码必须在与GPL兼容的许可证下可用。 +本节的其余部分涵盖了内核开发的过程,以及开发人员及其雇主在这方面可能遇到的 +各种问题。有很多原因使内核代码应被合并到正式的(“主线”)内核中,包括对用户 +的自动可用性、多种形式的社区支持以及影响内核开发方向的能力。提供给Linux内核 +的代码必须在与GPL兼容的许可证下可用。 :ref:`cn_development_process` 介绍了开发过程、内核发布周期和合并窗口的机制。 -涵盖了补丁开发、审查和合并周期中的各个阶段。有一些关于工具和邮件列表的讨论。 -鼓励希望开始内核开发的开发人员作为初始练习跟踪并修复bug。 +涵盖了补丁开发、审查和合并周期中的各个阶段。还有一些关于工具和邮件列表的讨论? +鼓励希望开始内核开发的开发人员跟踪并修复缺陷以作为初步练习。 -:ref:`cn_development_early_stage` 包括早期项目规划,重点是尽快让开发社区参与 +:ref:`cn_development_early_stage` 包括项目的早期规划,重点是尽快让开发社区 +参与进来。 -:ref:`cn_development_coding` 是关于编码过程的;讨论了其他开发人员遇到的几个 -陷阱。对补丁的一些要求已经涵盖,并且介绍了一些工具,这些工具有助于确保内核 +:ref:`cn_development_coding` 是关于编程过程的;介绍了其他开发人员遇到的几个 +陷阱。也涵盖了对补丁的一些要求,并且介绍了一些工具,这些工具有助于确保内核 补丁是正确的。 -:ref:`cn_development_posting` 讨论发布补丁以供评审的过程。为了让开发社区 -认真对待,补丁必须正确格式化和描述,并且必须发送到正确的地方。遵循本节中的 -建议有助于确保为您的工作提供最好的接纳。 +:ref:`cn_development_posting` 描述发布补丁以供评审的过程。为了让开发社区能 +认真对待,补丁必须被正确格式化和描述,并且必须发送到正确的地方。遵循本节中的 +建议有助于确保您的工作能被较好地接纳。 -:ref:`cn_development_followthrough` 介绍了发布补丁之后发生的事情;该工作 -在这一点上还远远没有完成。与审阅者一起工作是开发过程中的一个重要部分;本节 -提供了一些关于如何在这个重要阶段避免问题的提示。当补丁被合并到主线中时, -开发人员要注意不要假定任务已经完成。 +:ref:`cn_development_followthrough` 介绍了发布补丁之后发生的事情;工作在这时 +还远远没有完成。与审阅者一起工作是开发过程中的一个重要部分;本节提供了一些 +关于如何在这个重要阶段避免问题的提示。当补丁被合并到主线中时,开发人员要注意 +不要假定任务已经完成。 -:ref:`cn_development_advancedtopics` 介绍了两个“高级”主题: -使用Git管理补丁和查看其他人发布的补丁。 +:ref:`cn_development_advancedtopics` 介绍了两个“高级”主题:使用Git管理补丁 +和查看其他人发布的补丁。 -:ref:`cn_development_conclusion` 总结了有关内核开发的更多信息,附带有带有 -指向资源的链接. +:ref:`cn_development_conclusion` 总结了有关内核开发的更多信息,附带有相关资源 +链接。 -这个文件是关于什么的 +这个文档是关于什么的 -------------------- -Linux内核有超过800万行代码,每个版本的贡献者超过1000人,是现存最大、最活跃 -的免费软件项目之一。从1991年开始,这个内核已经发展成为一个最好的操作系统 -组件,运行在袖珍数字音乐播放器、台式PC、现存最大的超级计算机以及所有类型的 -系统上。它是一种适用于几乎任何情况的健壮、高效和可扩展的解决方案。 +Linux内核有超过800万行代码,每个版本的贡献者超过1000人,是现存最大、最活跃的 +免费软件项目之一。从1991年开始,这个内核已经发展成为一个最好的操作系统组件, +运行在袖珍数字音乐播放器、台式电脑、现存最大的超级计算机以及所有类型的系统上。 +它是一种适用于几乎任何情况的健壮、高效和可扩展的解决方案。 随着Linux的发展,希望参与其开发的开发人员(和公司)的数量也在增加。硬件供应商 希望确保Linux能够很好地支持他们的产品,使这些产品对Linux用户具有吸引力。嵌入 式系统供应商使用Linux作为集成产品的组件,希望Linux能够尽可能地胜任手头的任务。 -分销商和其他基于Linux的软件供应商对Linux内核的功能、性能和可靠性有着明确的 -兴趣。最终用户也常常希望修改Linux,使之更好地满足他们的需求。 +分销商和其他基于Linux的软件供应商切实关心Linux内核的功能、性能和可靠性。最终 +用户也常常希望修改Linux,使之能更好地满足他们的需求。 Linux最引人注目的特性之一是这些开发人员可以访问它;任何具备必要技能的人都可以 改进Linux并影响其开发方向。专有产品不能提供这种开放性,这是自由软件的一个特点。 -但是,如果有什么不同的话,内核比大多数其他自由软件项目更开放。一个典型的三个月 -内核开发周期可以涉及1000多个开发人员,他们为100多个不同的公司 -(或者根本没有公司)工作。 +如果有什么不同的话,那就是内核比大多数其他自由软件项目更开放。一个典型的三个 +月内核开发周期可以涉及1000多个开发人员,他们为100多个不同的公司(或者根本不 +隶属公司)工作。 -与内核开发社区合作并不是特别困难。但是,尽管如此,许多潜在的贡献者在尝试做 -内核工作时遇到了困难。内核社区已经发展了自己独特的操作方式,使其能够在每天 +与内核开发社区合作并不是特别困难。但尽管如此,仍有许多潜在的贡献者在尝试做 +内核工作时遇到了困难。内核社区已经发展出自己独特的操作方式,使其能够在每天 都要更改数千行代码的环境中顺利运行(并生成高质量的产品)。因此,Linux内核开发 -过程与专有的开发方法有很大的不同也就不足为奇了。 +过程与专有的开发模式有很大的不同也就不足为奇了。 -对于新开发人员来说,内核的开发过程可能会让人感到奇怪和恐惧,但这个背后有充分的 -理由和坚实的经验。一个不了解内核社区的方式的开发人员(或者更糟的是,他们试图 -抛弃或规避内核社区的方式)会有一个令人沮丧的体验。开发社区, 在帮助那些试图学习 -的人的同时,没有时间帮助那些不愿意倾听或不关心开发过程的人。 +对于新开发人员来说,内核的开发过程可能会让人感到奇怪和恐惧,但这背后有充分的 +理由和坚实的经验。一个不了解内核社区工作方式的开发人员(或者更糟的是,他们 +试图抛弃或规避之)会得到令人沮丧的体验。开发社区在帮助那些试图学习的人的同时, +没有时间帮助那些不愿意倾听或不关心开发过程的人。 -希望阅读本文的人能够避免这种令人沮丧的经历。这里有很多材料,但阅读时所做的 +希望阅读本文的人能够避免这种令人沮丧的经历。这些材料很长,但阅读它们时所做的 努力会在短时间内得到回报。开发社区总是需要能让内核变更好的开发人员;下面的 -文本应该帮助您或为您工作的人员加入我们的社区。 +文字应该帮助您或为您工作的人员加入我们的社区。 致谢 ---- -本文件由Jonathan Corbet撰写,corbet@lwn.net。以下人员的建议使之更为完善: +本文档由Jonathan Corbet 撰写。以下人员的建议使之更为完善: 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ß. +Andrew Morton, Andrew Price, Tsugikazu Shibata 和 Jochen Voß 。 这项工作得到了Linux基金会的支持,特别感谢Amanda McPherson,他看到了这项工作 -的价值并把它变成现实。 +的价值并将其变成现实。 代码进入主线的重要性 -------------------- 有些公司和开发人员偶尔会想,为什么他们要费心学习如何与内核社区合作,并将代码 放入主线内核(“主线”是由Linus Torvalds维护的内核,Linux发行商将其用作基础)。 -在短期内,贡献代码看起来像是一种可以避免的开销;仅仅将代码分开并直接支持用户 +在短期内,贡献代码看起来像是一种可以避免的开销;维护独立代码并直接支持用户 似乎更容易。事实上,保持代码独立(“树外”)是在经济上是错误的。 -作为说明树外代码成本的一种方法,下面是内核开发过程的一些相关方面;本文稍后将 -更详细地讨论其中的大部分内容。考虑: +为了说明树外代码成本,下面给出内核开发过程的一些相关方面;本文稍后将更详细地 +讨论其中的大部分内容。请考虑: - 所有Linux用户都可以使用合并到主线内核中的代码。它将自动出现在所有启用它的 - 发行版上。不需要驱动程序磁盘、下载,也不需要为多个发行版的多个版本提供支持; - 对于开发人员和用户来说,这一切都是可行的。并入主线解决了大量的分布和支持问题 + 发行版上。无需驱动程序磁盘、额外下载,也不需要为多个发行版的多个版本提供 + 支持;这一切将方便所有开发人员和用户。并入主线解决了大量的分发和支持问题。 -- 当内核开发人员努力维护一个稳定的用户空间接口时,内部内核API处于不断变化之中. - 缺乏一个稳定的内部接口是一个深思熟虑的设计决策;它允许在任何时候进行基本的改 - 进,并产生更高质量的代码。但该策略的一个结果是,如果要使用新的内核,任何树外 - 代码都需要持续的维护。维护树外代码需要大量的工作才能使代码保持工作状态。 +- 当内核开发人员努力维护一个稳定的用户空间接口时,内核内部API处于不断变化之中。 + 不维持稳定的内部接口是一个慎重的设计决策;它允许在任何时候进行基本的改进, + 并产出更高质量的代码。但该策略导致结果是,若要使用新的内核,任何树外代码都 + 需要持续的维护。维护树外代码会需要大量的工作才能使代码保持正常运行。 - 相反,位于主线中的代码不需要这样做,因为一个简单的规则要求进行API更改的任何 - 开发人员也必须修复由于该更改而破坏的任何代码。因此,合并到主线中的代码大大 - 降低了维护成本。 + 相反,位于主线中的代码不需要这样做,因为基本规则要求进行API更改的任何开发 + 人员也必须修复由于该更改而破坏的任何代码。因此,合并到主线中的代码大大降低 + 了维护成本。 -- 除此之外,内核中的代码通常会被其他开发人员改进。令人惊讶的结果可能来自授权 - 您的用户社区和客户改进您的产品。 +- 除此之外,内核中的代码通常会被其他开发人员改进。您授权的用户社区和客户对您 + 产品的改进可能会令人惊喜。 -- 内核代码在合并到主线之前和之后都要经过审查。不管原始开发人员的技能有多强, +- 内核代码在合并到主线之前和之后都要经过审查。无论原始开发人员的技能有多强, 这个审查过程总是能找到改进代码的方法。审查经常发现严重的错误和安全问题。 - 这对于在封闭环境中开发的代码尤其如此;这种代码从外部开发人员的审查中获益 - 匪浅。树外代码是低质量代码。 + 对于在封闭环境中开发的代码尤其如此;这种代码从外部开发人员的审查中获益匪浅。 + 树外代码是低质量代码。 - 参与开发过程是您影响内核开发方向的方式。旁观者的抱怨会被听到,但是活跃的 开发人员有更强的声音——并且能够实现使内核更好地满足其需求的更改。 - 当单独维护代码时,总是存在第三方为类似功能提供不同实现的可能性。如果发生 - 这种情况,合并代码将变得更加困难——甚至到了不可能的地步。然后,您将面临以下 - 令人不快的选择:(1)无限期地维护树外的非标准特性,或(2)放弃代码并将用户 - 迁移到树内版本。 + 这种情况,合并代码将变得更加困难——甚至成为不可能。之后,您将面临以下令人 + 不快的选择:(1)无限期地维护树外的非标准特性,或(2)放弃代码并将用户迁移 + 到树内版本。 -- 代码的贡献是使整个过程工作的根本。通过贡献代码,您可以向内核添加新功能,并 - 提供其他内核开发人员使用的功能和示例。如果您已经为Linux开发了代码(或者 - 正在考虑这样做),那么您显然对这个平台的持续成功感兴趣;贡献代码是确保成功 - 的最好方法之一。 +- 代码的贡献是使整个流程工作的根本。通过贡献代码,您可以向内核添加新功能,并 + 提供其他内核开发人员使用的功能和示例。如果您已经为Linux开发了代码(或者正在 + 考虑这样做),那么您显然对这个平台的持续成功感兴趣;贡献代码是确保成功的 + 最好方法之一。 上述所有理由都适用于任何树外内核代码,包括以专有的、仅二进制形式分发的代码。 -然而,在考虑任何类型的纯二进制内核代码分布之前,还需要考虑其他因素。这些包括: +然而,在考虑任何类型的纯二进制内核代码分布之前,还需要考虑其他因素。包括: -- 围绕专有内核模块分发的法律问题充其量是模糊的;相当多的内核版权所有者认为, - 大多数仅限二进制的模块是内核的派生产品,因此,它们的分发违反了GNU通用公共 - 许可证(下面将详细介绍)。您的作者不是律师,本文档中的任何内容都不可能被 +- 围绕专有内核模块分发的法律问题其实较为模糊;相当多的内核版权所有者认为, + 大多数仅二进制的模块是内核的派生产品,因此,它们的分发违反了GNU通用公共 + 许可证(下面将详细介绍)。本文作者不是律师,本文档中的任何内容都不可能被 视为法律建议。封闭源代码模块的真实法律地位只能由法院决定。但不管怎样,困扰 这些模块的不确定性仍然存在。 - 二进制模块大大增加了调试内核问题的难度,以至于大多数内核开发人员甚至都不会 尝试。因此,只分发二进制模块将使您的用户更难从社区获得支持。 -- 对于只支持二进制的模块的发行者来说,支持也更加困难,他们必须为他们希望支持 - 的每个发行版和每个内核版本提供一个版本的模块。为了提供相当全面的覆盖范围, +- 对于仅二进制的模块的发行者来说,支持也更加困难,他们必须为他们希望支持的 + 每个发行版和每个内核版本提供不同版本的模块。为了提供较为全面的覆盖范围, 可能需要一个模块的几十个构建,并且每次升级内核时,您的用户都必须单独升级 - 您的模块。 + 这些模块。 -- 上面提到的关于代码评审的所有问题都更加存在于封闭源代码。由于该代码根本不可 - 用,因此社区无法对其进行审查,毫无疑问,它将存在严重问题。 +- 上面提到的关于代码评审的所有问题都更加存在于封闭源代码中。由于该代码根本 + 不可得,因此社区无法对其进行审查,毫无疑问,它将存在严重问题。 -尤其是嵌入式系统的制造商,可能会倾向于忽视本节中所说的大部分内容,因为他们 +尤其是嵌入式系统的制造商,可能会倾向于忽视本节中所说的大部分内容;因为他们 相信自己正在商用一种使用冻结内核版本的独立产品,在发布后不需要再进行开发。 这个论点忽略了广泛的代码审查的价值以及允许用户向产品添加功能的价值。但这些 -产品也有有限的商业寿命,之后必须发布新版本的产品。在这一点上,代码在主线上 -并得到良好维护的供应商将能够更好地占位,以使新产品快速上市。 +产品的商业寿命有限,之后必须发布新版本的产品。在这一点上,代码在主线上并得到 +良好维护的供应商将能够更好地占位,以使新产品快速上市。 许可 ---- @@ -164,23 +172,24 @@ Andrew Morton, Andrew Price, Tsugikazu Shibata, 和 Jochen Voß. 代码是根据一些许可证提供给Linux内核的,但是所有代码都必须与GNU通用公共许可 证(GPLV2)的版本2兼容,该版本是覆盖整个内核分发的许可证。在实践中,这意味 着所有代码贡献都由GPLv2(可选地,语言允许在更高版本的GPL下分发)或3子句BSD -许可(New BSD License, 译者注)覆盖。任何不包含在兼容许可证中的贡献都不会 +许可(New BSD License,译者注)覆盖。任何不包含在兼容许可证中的贡献都不会 被接受到内核中。 贡献给内核的代码不需要(或请求)版权分配。合并到主线内核中的所有代码都保留 其原始所有权;因此,内核现在拥有数千个所有者。 -这种所有权结构的一个暗示是,任何改变内核许可的尝试都注定会失败。很少有实际 -的场景可以获得所有版权所有者的同意(或者从内核中删除他们的代码)。因此,特 -别是,在可预见的将来,不可能迁移到GPL的版本3。 +这种所有权结构也暗示着,任何改变内核许可的尝试都注定会失败。很少有实际情况 +可以获得所有版权所有者的同意(或者从内核中删除他们的代码)。因此,尤其是在 +可预见的将来,许可证不大可能迁移到GPL的版本3。 -所有贡献给内核的代码都必须是合法的免费软件。因此,不接受匿名(或匿名)贡献 -者的代码。所有贡献者都需要在他们的代码上“sign off”,声明代码可以在GPL下与内 -核一起分发。无法提供未被其所有者许可为免费软件的代码,或可能为内核造成版权 -相关问题的代码(例如,由缺乏适当保护的反向工程工作派生的代码)不能被接受。 +所有贡献给内核的代码都必须是合法的免费软件。因此,不接受匿名(或化名)贡献 +者的代码。所有贡献者都需要在他们的代码上“sign off(签发)”,声明代码可以 +在GPL下与内核一起分发。无法提供未被其所有者许可为免费软件的代码,或可能为 +内核造成版权相关问题的代码(例如,由缺乏适当保护的反向工程工作派生的代码) +不能被接受。 -有关版权相关问题的问题在Linux开发邮件列表中很常见。这样的问题通常会得到不少 -答案,但要记住,回答这些问题的人不是律师,不能提供法律咨询。如果您有关于 -Linux源代码的法律问题,那么与了解该领域的律师交流是无法替代的。依靠从技术 -邮件列表中获得的答案是一件冒险的事情。 +有关版权问题的提问在Linux开发邮件列表中很常见。这样的问题通常会得到不少答案, +但请记住,回答这些问题的人不是律师,不能提供法律咨询。如果您有关于Linux源代码 +的法律问题,没有什么可以代替咨询了解这一领域的律师。依赖从技术邮件列表中获得 +的答案是一件冒险的事情。 -- cgit v1.2.3 From 25236a4a93964579c842657a5efecaf46386a1c6 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:26:41 +0800 Subject: docs/zh_CN: Improve zh_CN/process/2.Process.rst Sync and improve language & grammar of zh_CN/process/2.Process.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/526409b6a93af6d14e0bb14b630fced9a9ffe98d.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/2.Process.rst | 345 +++++++++++---------- 1 file changed, 175 insertions(+), 170 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/2.Process.rst b/Documentation/translations/zh_CN/process/2.Process.rst index ebe2e0254b3e..229629e305ca 100644 --- a/Documentation/translations/zh_CN/process/2.Process.rst +++ b/Documentation/translations/zh_CN/process/2.Process.rst @@ -1,17 +1,24 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/2.Process.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_process: -开发流程如何工作 +开发流程如何进行 ================ -90年代早期的Linux内核开发是一件相当松散的事情,涉及的用户和开发人员相对较 -少。由于拥有数以百万计的用户群,并且在一年的时间里有大约2000名开发人员参与 -进来,内核因此必须发展许多流程来保持开发的顺利进行。要成为流程的有效组成 -部分,需要对流程的工作方式有一个扎实的理解。 +90年代早期的Linux内核开发是一件相当松散的事情,涉及的用户和开发人员相对较少。 +由于拥有数以百万计的用户群,且每年有大约2000名开发人员参与进来,内核因此必须 +发展出许多既定流程来保证开发的顺利进行。要参与到流程中来,需要对此流程的进行 +方式有一个扎实的理解。 总览 ---- @@ -20,112 +27,113 @@ 内核版本。最近的发布历史记录如下: ====== ================= - 4.11 四月 30, 2017 - 4.12 七月 2, 2017 - 4.13 九月 3, 2017 - 4.14 十一月 12, 2017 - 4.15 一月 28, 2018 - 4.16 四月 1, 2018 + 5.0 2019年3月3日 + 5.1 2019年5月5日 + 5.2 2019年7月7日 + 5.3 2019年9月15日 + 5.4 2019年11月24日 + 5.5 2020年1月6日 ====== ================= -每4.x版本都是一个主要的内核版本,具有新特性、内部API更改等等。一个典型的4.x -版本包含大约13000个变更集,变更了几十万行代码。因此,4.x是Linux内核开发的前 +每个5.x版本都是一个主要的内核版本,具有新特性、内部API更改等等。一个典型的5.x +版本包含大约13000个变更集,变更了几十万行代码。因此,5.x是Linux内核开发的前 沿;内核使用滚动开发模型,不断集成重大变化。 -对于每个版本的补丁合并,遵循一个相对简单的规则。在每个开发周期的开始,“合并 -窗口”被打开。当时,被认为足够稳定(并且被开发社区接受)的代码被合并到主线内 +对于每个版本的补丁合并,遵循一个相对简单的规则。在每个开发周期的开头,“合并 +窗口”被打开。这时,被认为足够稳定(并且被开发社区接受)的代码被合并到主线内 核中。在这段时间内,新开发周期的大部分变更(以及所有主要变更)将以接近每天 1000次变更(“补丁”或“变更集”)的速度合并。 -(顺便说一句,值得注意的是,合并窗口期间集成的更改并不是凭空产生的;它们是 -提前收集、测试和分级的。稍后将详细描述该过程的工作方式)。 +(顺便说一句,值得注意的是,合并窗口期间集成的更改并不是凭空产生的;它们是经 +提前收集、测试和分级的。稍后将详细描述该过程的工作方式。) 合并窗口持续大约两周。在这段时间结束时,LinusTorvalds将声明窗口已关闭,并 -释放第一个“rc”内核。例如,对于目标为4.14的内核,在合并窗口结束时发生的释放 -将被称为4.14-rc1。RC1版本是一个信号,表示合并新特性的时间已经过去,稳定下一 -个内核的时间已经开始。 +释放第一个“rc”内核。例如,对于目标为5.6的内核,在合并窗口结束时发生的释放 +将被称为5.6-rc1。-rc1 版本是一个信号,表示合并新特性的时间已经过去,稳定下一 +个内核的时间已经到来。 在接下来的6到10周内,只有修复问题的补丁才应该提交给主线。有时会允许更大的 -更改,但这种情况很少发生;试图在合并窗口外合并新功能的开发人员往往会受到不 +更改,但这种情况很少发生;试图在合并窗口外合并新功能的开发人员往往受不到 友好的接待。一般来说,如果您错过了给定特性的合并窗口,最好的做法是等待下一 -个开发周期。(对于以前不支持的硬件,偶尔会对驱动程序进行例外;如果它们不 -改变已有代码,则不会导致回归,并且应该可以随时安全地添加)。 +个开发周期。(偶尔会对未支持硬件的驱动程序进行例外;如果它们不改变已有代码, +则不会导致回归,应该可以随时被安全地加入)。 随着修复程序进入主线,补丁速度将随着时间的推移而变慢。Linus大约每周发布一次 -新的-rc内核;一个正常的系列将在-rc6和-rc9之间,内核被认为足够稳定并最终发布。 +新的-rc内核;在内核被认为足够稳定并最终发布前,一般会达到-rc6到-rc9之间。 然后,整个过程又重新开始了。 -例如,这里是4.16的开发周期进行情况(2018年的所有日期): +例如,这里是5.4的开发周期进行情况(2019年): ============== ============================== - 一月 28 4.15 稳定版发布 - 二月 11 4.16-rc1, 合并窗口关闭 - 二月 18 4.16-rc2 - 二月 25 4.16-rc3 - 三月 4 4.16-rc4 - 三月 11 4.16-rc5 - 三月 18 4.16-rc6 - 三月 25 4.16-rc7 - 四月 1 4.16 稳定版发布 + 九月 15 5.3 稳定版发布 + 九月 30 5.4-rc1 合并窗口关闭 + 十月 6 5.4-rc2 + 十月 13 5.4-rc3 + 十月 20 5.4-rc4 + 十月 27 5.4-rc5 + 十一月 3 5.4-rc6 + 十一月 10 5.4-rc7 + 十一月 17 5.4-rc8 + 十一月 24 5.4 稳定版发布 ============== ============================== -开发人员如何决定何时结束开发周期并创建稳定的版本?使用的最重要的指标是以前 -版本的回归列表。不欢迎出现任何错误,但是那些破坏了以前能工作的系统的错误被 -认为是特别严重的。因此,导致回归的补丁是不受欢迎的,很可能在稳定期内删除。 +开发人员如何决定何时结束开发周期并创建稳定版本?最重要的指标是以前版本的 +回归列表。不欢迎出现任何错误,但是那些破坏了以前能工作的系统的错误被认为是 +特别严重的。因此,导致回归的补丁是不受欢迎的,很可能在稳定期内删除。 开发人员的目标是在稳定发布之前修复所有已知的回归。在现实世界中,这种完美是 -很难实现的;在这种规模的项目中,变量太多了。有一点,延迟最终版本只会使问题 -变得更糟;等待下一个合并窗口的一堆更改将变大,从而在下次创建更多的回归错误。 -因此,大多数4.x内核都有一些已知的回归错误,不过,希望没有一个是严重的。 +很难实现的;在这种规模的项目中,变数太多了。需要说明的是,延迟最终版本只会 +使问题变得更糟;等待下一个合并窗口的更改将变多,导致下次出现更多的回归错误。 +因此,大多数5.x内核都有一些已知的回归错误,不过,希望没有一个是严重的。 -一旦一个稳定的版本发布,它正在进行的维护工作就被移交给“稳定团队”,目前由 -Greg Kroah-Hartman组成。稳定团队将使用4.x.y编号方案不定期的发布稳定版本的更 -新。要加入更新版本,补丁程序必须(1)修复一个重要的bug,(2)已经合并到 -下一个开发主线中。内核通常会在超过其初始版本的一个以上的开发周期内接收稳定 -的更新。例如,4.13内核的历史如下 +一旦一个稳定的版本发布,它的持续维护工作就被移交给“稳定团队”,目前由 +Greg Kroah-Hartman领导。稳定团队将使用5.x.y编号方案不定期地发布稳定版本的 +更新。要合入更新版本,补丁必须(1)修复一个重要的缺陷,且(2)已经合并到 +下一个开发版本主线中。内核通常会在其初始版本后的一个以上的开发周期内收到 +稳定版更新。例如,5.2内核的历史如下(2019年): ============== =============================== - 九月 3 4.13 稳定版发布 - 九月 13 4.13.1 - 九月 20 4.13.2 - 九月 27 4.13.3 - 十月 5 4.13.4 - 十月 12 4.13.5 + 七月 7 5.2 稳定版发布 + 七月 13 5.2.1 + 七月 21 5.2.2 + 七月 26 5.2.3 + 七月 28 5.2.4 + 七月 31 5.2.5 ... ... - 十一月 24 4.13.16 + 十月 11 5.2.21 ============== =============================== -4.13.16是4.13版本的最终稳定更新。 +5.2.21是5.2版本的最终稳定更新。 有些内核被指定为“长期”内核;它们将得到更长时间的支持。在本文中,当前的长期 内核及其维护者是: - ====== ====================== ============================== - 3.16 Ben Hutchings (长期稳定内核) - 4.1 Sasha Levin - 4.4 Greg Kroah-Hartman (长期稳定内核) - 4.9 Greg Kroah-Hartman - 4.14 Greg Kroah-Hartman - ====== ====================== ============================== + ====== ================================ ================ + 3.16 Ben Hutchings (长期稳定内核) + 4.4 Greg Kroah-Hartman & Sasha Levin (长期稳定内核) + 4.9 Greg Kroah-Hartman & Sasha Levin + 4.14 Greg Kroah-Hartman & Sasha Levin + 4.19 Greg Kroah-Hartman & Sasha Levin + 5.4 Greg Kroah-Hartman & Sasha Levin + ====== ================================ ================ -为长期支持选择内核纯粹是维护人员有必要和时间来维护该版本的问题。目前还没有 -为即将发布的任何特定版本提供长期支持的已知计划。 +长期支持内核的选择纯粹是维护人员是否有需求和时间来维护该版本的问题。 +目前还没有为即将发布的任何特定版本提供长期支持的已知计划。 补丁的生命周期 -------------- 补丁不会直接从开发人员的键盘进入主线内核。相反,有一个稍微复杂(如果有些非 正式)的过程,旨在确保对每个补丁进行质量审查,并确保每个补丁实现了一个在主线 -中需要的更改。对于小的修复,这个过程可能会很快发生,或者,在大的和有争议的 -变更的情况下,会持续数年。许多开发人员的挫折来自于对这个过程缺乏理解或者 -试图绕过它。 +中需要的更改。对于小的修复,这个过程可能会很快完成,,而对于较大或有争议的 +变更,可能会持续数年。许多开发人员的沮丧来自于对这个过程缺乏理解或者试图绕过它。 -为了减少这种挫折感,本文将描述补丁如何进入内核。下面是一个介绍,它以某种 -理想化的方式描述了这个过程。更详细的过程将在后面的章节中介绍。 +为了减少这种挫败,本文将描述补丁如何进入内核。下面的介绍以一种较为理想化的 +方式描述了这个过程。更详细的过程将在后面的章节中介绍。 -补丁程序经历的阶段通常是: +补丁通常要经历以下阶段: -- 设计。这就是补丁的真正需求——以及满足这些需求的方式——的所在。设计工作通常 +- 设计。这就是补丁的真正需求——以及满足这些需求的方式——所在。设计工作通常 是在不涉及社区的情况下完成的,但是如果可能的话,最好是在公开的情况下完成 这项工作;这样可以节省很多稍后再重新设计的时间。 @@ -134,53 +142,51 @@ Greg Kroah-Hartman组成。稳定团队将使用4.x.y编号方案不定期的发 - 更广泛的评审。当补丁接近准备好纳入主线时,它应该被相关的子系统维护人员 接受——尽管这种接受并不能保证补丁会一直延伸到主线。补丁将出现在维护人员的 - 子系统树中,并进入 -next 树(如下所述)。当流程工作时,此步骤将导致对补丁 - 进行更广泛的审查,并发现由于将此补丁与其他人所做的工作集成而导致的任何 + 子系统树中,并进入 -next 树(如下所述)。当流程进行时,此步骤将会对补丁 + 进行更广泛的审查,并发现由于将此补丁与其他人所做的工作合并而导致的任何 问题。 -- 请注意,大多数维护人员也有日常工作,因此合并补丁可能不是他们的最高优先级。 - 如果您的补丁程序得到了关于所需更改的反馈,那么您应该进行这些更改,或者为 - 不应该进行这些更改的原因辩护。如果您的补丁没有评审意见,但没有被其相应的 - 子系统或驱动程序维护者接受,那么您应该坚持不懈地将补丁更新到当前内核,使 - 其干净地应用,并不断地将其发送以供审查和合并。 +- 请注意,大多数维护人员也有日常工作,因此合并补丁可能不是他们的最优先工作。 + 如果您的补丁得到了需要更改的反馈,那么您应该进行这些更改,或者解释为何 + 不应该进行这些更改。如果您的补丁没有评审意见,也没有被其相应的子系统或 + 驱动程序维护者接受,那么您应该坚持不懈地将补丁更新到当前内核使其可被正常 + 应用,并不断地发送它以供审查和合并。 - 合并到主线。最终,一个成功的补丁将被合并到由LinusTorvalds管理的主线存储库 - 中。此时可能会出现更多的评论和/或问题;开发人员应对这些问题并解决出现的 - 任何问题很重要。 + 中。此时可能会出现更多的评论和/或问题;对开发人员来说应对这些问题并解决 + 出现的任何问题仍很重要。 -- 稳定版发布。可能受补丁影响的用户数量现在很大,因此可能再次出现新的问题。 +- 稳定版发布。大量用户可能受此补丁影响,因此可能再次出现新的问题。 - 长期维护。虽然开发人员在合并代码后可能会忘记代码,但这种行为往往会给开发 - 社区留下不良印象。合并代码消除了一些维护负担,因为其他代码将修复由API - 更改引起的问题。但是,如果代码要长期保持有用,原始开发人员应该继续为 - 代码负责。 + 社区留下不良印象。合并代码消除了一些维护负担,因为其他人将修复由API更改 + 引起的问题。但是,如果代码要长期保持可用,原始开发人员应该继续为代码负责。 -内核开发人员(或他们的雇主)犯的最大错误之一是试图将流程简化为一个 -“合并到主线”步骤。这种方法总是会让所有相关人员感到沮丧。 +内核开发人员(或他们的雇主)犯的最大错误之一是试图将流程简化为一个“合并到 +主线”步骤。这种方法总是会让所有相关人员感到沮丧。 补丁如何进入内核 ---------------- 只有一个人可以将补丁合并到主线内核存储库中:LinusTorvalds。但是,在进入 2.6.38内核的9500多个补丁中,只有112个(大约1.3%)是由Linus自己直接选择的。 -内核项目已经发展到一个规模,没有一个开发人员可以在没有支持的情况下检查和 -选择每个补丁。内核开发人员处理这种增长的方式是通过使用围绕信任链构建的 -助理系统。 +内核项目已经发展到一个没有一个开发人员可以在没有支持的情况下检查和选择每个 +补丁的规模。内核开发人员处理这种增长的方式是使用围绕信任链构建的助理系统。 -内核代码库在逻辑上被分解为一组子系统:网络、特定的体系结构支持、内存管理、 -视频设备等。大多数子系统都有一个指定的维护人员,开发人员对该子系统中的代码 -负有全部责任。这些子系统维护者(松散地)是他们所管理的内核部分的守护者; -他们(通常)会接受一个补丁以包含到主线内核中。 +内核代码库在逻辑上被分解为一组子系统:网络、特定体系结构支持、内存管理、视 +频设备等。大多数子系统都有一个指定的维护人员,其总体负责该子系统中的代码。 +这些子系统维护者(松散地)是他们所管理的内核部分的“守门员”;他们(通常) +会接受一个补丁以包含到主线内核中。 -子系统维护人员每个人都使用git源代码管理工具管理自己版本的内核源代码树。Git -等工具(以及Quilt或Mercurial等相关工具)允许维护人员跟踪补丁列表,包括作者 +子系统维护人员每个人都管理着自己版本的内核源代码树,通常(并非总是)使用Git。 +Git等工具(以及Quilt或Mercurial等相关工具)允许维护人员跟踪补丁列表,包括作者 信息和其他元数据。在任何给定的时间,维护人员都可以确定他或她的存储库中的哪 些补丁在主线中找不到。 -当合并窗口打开时,顶级维护人员将要求Linus从其存储库中“拉出”他们为合并选择 +当合并窗口打开时,顶级维护人员将要求Linus从存储库中“拉出”他们为合并选择 的补丁。如果Linus同意,补丁流将流向他的存储库,成为主线内核的一部分。 -Linus对拉操作中接收到的特定补丁的关注程度各不相同。很明显,有时他看起来很 -关注。但是,作为一般规则,Linus相信子系统维护人员不会向上游发送坏补丁。 +Linus对拉取中接收到的特定补丁的关注程度各不相同。很明显,有时他看起来很 +关注。但是一般来说,Linus相信子系统维护人员不会向上游发送坏补丁。 子系统维护人员反过来也可以从其他维护人员那里获取补丁。例如,网络树是由首先 在专用于网络设备驱动程序、无线网络等的树中积累的补丁构建的。此存储链可以 @@ -195,26 +201,26 @@ Next 树 子系统树链引导补丁流到内核,但它也提出了一个有趣的问题:如果有人想查看为 下一个合并窗口准备的所有补丁怎么办?开发人员将感兴趣的是,还有什么其他的 -更改有待解决,以查看是否存在需要担心的冲突;例如,更改核心内核函数原型的 +更改有待解决,以了解是否存在需要担心的冲突;例如,更改核心内核函数原型的 修补程序将与使用该函数旧形式的任何其他修补程序冲突。审查人员和测试人员希望 -在所有这些变更到达主线内核之前,能够访问它们的集成形式中的变更。您可以从所有 -有趣的子系统树中提取更改,但这将是一项大型且容易出错的工作。 +在所有这些变更到达主线内核之前,能够访问它们的集成形式的变更。您可以从所有 +相关的子系统树中提取更改,但这将是一项复杂且容易出错的工作。 -答案以-next树的形式出现,在这里子系统树被收集以供测试和审查。Andrew Morton -维护的这些旧树被称为“-mm”(用于内存管理,这就是它的启动名字)。-mm 树集成了 -一长串子系统树中的补丁;它还包含一些旨在帮助调试的补丁。 +解决方案以-next树的形式出现,在这里子系统树被收集以供测试和审查。这些树中 +由Andrew Morton维护的较老的一个,被称为“-mm”(用于内存管理,创建时为此)。 +-mm 树集成了一长串子系统树中的补丁;它还包含一些旨在帮助调试的补丁。 除此之外,-mm 还包含大量由Andrew直接选择的补丁。这些补丁可能已经发布在邮件 -列表上,或者它们可能应用于内核中没有指定子系统树的部分。结果,-mm 作为一种 -最后手段的子系统树运行;如果没有其他明显的路径可以让补丁进入主线,那么它很 -可能以-mm 结束。累积在-mm 中的各种补丁最终将被转发到适当的子系统树,或者直接 +列表上,或者它们可能应用于内核中未指定子系统树的部分。同时,-mm 作为最后 +手段的子系统树;如果没有其他明显的路径可以让补丁进入主线,那么它很可能最 +终选择-mm 树。累积在-mm 中的各种补丁最终将被转发到适当的子系统树,或者直接 发送到Linus。在典型的开发周期中,大约5-10%的补丁通过-mm 进入主线。 -当前-mm 补丁可在“mmotm”(-mm of the moment)目录中找到,地址: +当前-mm 补丁可在“mmotm”(-mm of the moment)目录中找到: https://www.ozlabs.org/~akpm/mmotm/ -然而,使用mmotm树可能是一种令人沮丧的体验;它甚至可能无法编译。 +然而,使用MMOTM树可能会十分令人头疼;它甚至可能无法编译。 下一个周期补丁合并的主要树是linux-next,由Stephen Rothwell 维护。根据设计 linux-next 是下一个合并窗口关闭后主线的快照。linux-next树在Linux-kernel 和 @@ -228,49 +234,48 @@ Linux-next 已经成为内核开发过程中不可或缺的一部分;在一个 Staging 树 ---------- -内核源代码树包含drivers/staging/directory,其中有许多驱动程序或文件系统的 -子目录正在被添加到内核树中。它们然需要更多的工作的时候可以保留在 -driver/staging目录中;一旦完成,就可以将它们移到内核中。这是一种跟踪不符合 -Linux内核编码或质量标准的驱动程序的方法,但人们可能希望使用它们并跟踪开发。 +内核源代码树包含drivers/staging/目录,其中有许多驱动程序或文件系统的子目录 +正在被添加到内核树中。它们在仍然需要更多的修正的时候可以保留在driver/staging/ +目录中;一旦完成,就可以将它们移到内核中。这是一种跟踪不符合Linux内核编码或 +质量标准的驱动程序的方法,人们可能希望使用它们并跟踪开发。 -Greg Kroah Hartman 目前负责维护staging 树。仍需要工作的驱动程序将发送给他, +Greg Kroah Hartman 目前负责维护staging 树。仍需要修正的驱动程序将发送给他, 每个驱动程序在drivers/staging/中都有自己的子目录。除了驱动程序源文件之外, -目录中还应该有一个TODO文件。todo文件列出了驱动程序需要接受的挂起的工作, +目录中还应该有一个TODO文件。TODO文件列出了驱动程序需要接受的暂停的工作, 以及驱动程序的任何补丁都应该抄送的人员列表。当前的规则要求,staging的驱动 程序必须至少正确编译。 -Staging 是一种相对容易的方法,可以让新的驱动程序进入主线,幸运的是,他们会 -引起其他开发人员的注意,并迅速改进。然而,进入staging并不是故事的结尾; -staging中没有看到常规进展的代码最终将被删除。经销商也倾向于相对不愿意使用 -staging驱动程序。因此,在成为一名合适的主线驱动的路上,staging 充其量只是 -一个停留。 +Staging 是一种让新的驱动程序进入主线的相对容易的方法,它们会幸运地引起其他 +开发人员的注意,并迅速改进。然而,进入staging并不是故事的结尾;staging中 +没有看到常规进展的代码最终将被删除。经销商也倾向于相对不愿意使用staging驱动 +程序。因此,在成为一个合适的主线驱动的路上,staging 仅是一个中转站。 工具 ---- 从上面的文本可以看出,内核开发过程在很大程度上依赖于在不同方向上聚集补丁的 能力。如果没有适当强大的工具,整个系统将无法在任何地方正常工作。关于如何使用 -这些工具的教程远远超出了本文档的范围,但是还是有一些指南的空间。 +这些工具的教程远远超出了本文档的范围,但还是用一点篇幅介绍一些关键点。 到目前为止,内核社区使用的主要源代码管理系统是git。Git是在自由软件社区中开发 的许多分布式版本控制系统之一。它非常适合内核开发,因为它在处理大型存储库和 -大量补丁时性能非常好。它还有一个难以学习和使用的名声,尽管随着时间的推移它 -变得更好了。对于内核开发人员来说,对Git的某种熟悉几乎是一种要求;即使他们不 -将它用于自己的工作,他们也需要Git来跟上其他开发人员(以及主线)正在做的事情。 +大量补丁时性能非常好。它也以难以学习和使用而著称,尽管随着时间的推移它变得 +更好了。对于内核开发人员来说,对Git的某种熟悉几乎是一种要求;即使他们不将它 +用于自己的工作,他们也需要Git来跟上其他开发人员(以及主线)正在做的事情。 -现在几乎所有的Linux发行版都打包了Git。主页位于: +现在几乎所有的Linux发行版都打包了Git。Git主页位于: https://git-scm.com/ -那个页面有指向文档和教程的指针。 +此页面包含了文档和教程的链接。 -在不使用git的内核开发人员中,最流行的选择几乎肯定是mercurial: +在不使用git的内核开发人员中,最流行的选择几乎肯定是Mercurial: http://www.seleric.com/mercurial/ Mercurial与Git共享许多特性,但它提供了一个界面,许多人觉得它更易于使用。 -另一个值得了解的工具是quilt: +另一个值得了解的工具是Quilt: https://savannah.nongnu.org/projects/quilt @@ -282,79 +287,79 @@ Quilt 是一个补丁管理系统,而不是源代码管理系统。它不会 邮件列表 -------- -大量的Linux内核开发工作是通过邮件列表完成的。如果不在某个地方加入至少一个列表, -就很难成为社区中一个功能完备的成员。但是,Linux邮件列表对开发人员来说也是一个 -潜在的危险,他们可能会被一堆电子邮件淹没,违反Linux列表上使用的约定,或者 -两者兼而有之。 +大量的Linux内核开发工作是通过邮件列表完成的。如果不加入至少一个某个列表, +就很难成为社区中的一个“全功能”成员。但是,Linux邮件列表对开发人员来说也是 +一个潜在的危险,他们可能会被一堆电子邮件淹没、违反Linux列表上使用的约定, +或者两者兼而有之。 大多数内核邮件列表都在vger.kernel.org上运行;主列表位于: http://vger.kernel.org/vger-lists.html -不过,也有一些列表托管在别处;其中一些列表位于lists.redhat.com。 +不过,也有一些列表托管在别处;其中一些列表位于 +redhat.com/mailman/listinfo。 -当然,内核开发的核心邮件列表是linux-kernel。这个名单是一个令人生畏的地方; -每天的信息量可以达到500条,噪音很高,谈话技术性很强,参与者并不总是表现出 +当然,内核开发的核心邮件列表是linux-kernel。这个列表是一个令人生畏的地方: +每天的信息量可以达到500条,噪音很高,谈话技术性很强,且参与者并不总是表现出 高度的礼貌。但是,没有其他地方可以让内核开发社区作为一个整体聚集在一起; -避免使用此列表的开发人员将错过重要信息。 +不使用此列表的开发人员将错过重要信息。 -有一些提示可以帮助在linux-kernel生存: +以下一些提示可以帮助在linux-kernel生存: -- 将邮件转移到单独的文件夹,而不是主邮箱。我们必须能够持续地忽略洪流。 +- 将邮件转移到单独的文件夹,而不是主邮箱文件夹。我们必须能够持续地忽略洪流。 -- 不要试图跟踪每一次谈话-其他人都不会。重要的是要对感兴趣的主题(尽管请 - 注意,长时间的对话可以在不更改电子邮件主题行的情况下偏离原始主题)和参与 - 的人进行筛选。 +- 不要试图跟上每一次谈话——没人会这样。重要的是要筛选感兴趣的主题(但请注意 + 长时间的对话可能会偏离原来的主题,尽管未改变电子邮件的主题)和参与的人。 -- 不要挑事。如果有人试图激起愤怒的反应,忽略他们。 +- 不要回复挑事的人。如果有人试图激起愤怒,请忽略他们。 -- 当响应Linux内核电子邮件(或其他列表上的电子邮件)时,请为所有相关人员保留 - cc:header。如果没有强有力的理由(如明确的请求),则不应删除收件人。一定要 - 确保你要回复的人在cc:list中。这个惯例也使你不必在回复邮件时明确要求被抄送。 +- 当回复Linux内核电子邮件(或其他列表上的电子邮件)时,请为所有相关人员保留 + Cc: 抄送头。如果没有确实的理由(如明确的请求),则不应删除收件人。一定要 + 确保你要回复的人在抄送列表中。这个惯例也使你不必在回复邮件时明确要求被抄送。 -- 在提出问题之前,搜索列表档案(和整个网络)。有些开发人员可能会对那些显然 +- 在提出问题之前,搜索列表存档(和整个网络)。有些开发人员可能会对那些显然 没有完成家庭作业的人感到不耐烦。 -- 避免贴顶帖(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难 +- 避免顶部回复(把你的答案放在你要回复的引文上面的做法)。这会让你的回答更难 理解,印象也很差。 -- 询问正确的邮件列表。linux-kernel 可能是通用的讨论点,但它不是从所有子系统 - 中寻找开发人员的最佳场所。 +- 在正确的邮件列表发问。linux-kernel 可能是通用的讨论场所,但它不是寻找所有 + 子系统开发人员的最佳场所。 -最后一点——找到正确的邮件列表——是开发人员出错的常见地方。在Linux内核上提出与 -网络相关的问题的人几乎肯定会收到一个礼貌的建议,转而在netdev列表上提出, -因为这是大多数网络开发人员经常出现的列表。还有其他列表可用于scsi、 -video4linux、ide、filesystem等子系统。查找邮件列表的最佳位置是与内核源代码 -一起打包的MAINTAINERS文件。 +最后一点——找到正确的邮件列表——是开发人员常出错的地方。在linux-kernel上 +提出与网络相关的问题的人几乎肯定会收到一个礼貌的建议,转到netdev列表上提出, +因为这是大多数网络开发人员经常出现的列表。还有其他列表可用于scsi、video4linux、 +ide、filesystem等子系统。查找邮件列表的最佳位置是与内核源代码一起打包的 +MAINTAINERS文件。 开始内核开发 ------------ -关于如何开始内核开发过程的问题很常见——来自个人和公司。同样常见的是错误,这 -使得关系的开始比必须的更困难。 +关于如何开始内核开发过程的问题很常见——个人和公司皆然。同样常见的是失误,这 +使得关系的开始比本应的更困难。 公司通常希望聘请知名的开发人员来启动开发团队。实际上,这是一种有效的技术。 -但它也往往是昂贵的,而且没有增长经验丰富的内核开发人员储备。考虑到时间的 -投入,可以让内部开发人员加快Linux内核的开发速度。花这个时间可以让雇主拥有 -一批了解内核和公司的开发人员,他们也可以帮助培训其他人。从中期来看,这往往 -是更有利可图的方法。 +但它也往往是昂贵的,而且对增加有经验的内核开发人员的数量没有多大帮助。考 +虑到时间投入,可以让内部开发人员加快Linux内核的开发速度。利用这段时间可以 +让雇主拥有一批既了解内核又了解公司的开发人员,还可以帮助培训其他人。从中期 +来看,这通常是更有利可图的方法。 可以理解的是,单个开发人员往往对起步感到茫然。从一个大型项目开始可能会很 -吓人;人们往往想先用一些较小的东西来测试水域。这是一些开发人员开始创建修补 -拼写错误或轻微编码风格问题的补丁的地方。不幸的是,这样的补丁会产生一定程度 -的噪音,这会分散整个开发社区的注意力,因此,越来越多的人看不起它们。希望向 -社区介绍自己的新开发人员将无法通过这些方式获得他们想要的那种接待。 +吓人;人们往往想先用一些较小的东西来试试水。由此,一些开发人员开始创建修补 +拼写错误或轻微编码风格问题的补丁。不幸的是,这样的补丁会产生一定程度的噪音, +这会分散整个开发社区的注意力,因此,它们越来越被人不看重。希望向社区介绍 +自己的新开发人员将无法通过这些方式获得他们期待的反响。 -Andrew Morton 为有抱负的内核开发人员提供了这个建议 +Andrew Morton 为有抱负的内核开发人员提供了如下建议 :: - 所有内核初学者的No.1项目肯定是“确保内核在所有的机器上,你可以触摸 - 到的,始终运行良好" 通常这样做的方法是与其他人一起解决问题(这 - 可能需要坚持!)但这很好——这是内核开发的一部分 + 所有内核开发者的第一个项目肯定应该是“确保内核在您可以操作的所有 + 机器上始终完美运行”。通常的方法是和其他人一起解决问题(这可能需 + 要坚持!),但就是如此——这是内核开发的一部分。 (http://lwn.net/articles/283982/) -在没有明显问题需要解决的情况下,建议开发人员查看当前的回归和开放式错误列表. -解决需要修复的问题没有任何缺点;通过解决这些问题,开发人员将获得处理过程的 -经验,同时与开发社区的其他人建立尊重。 +在没有明显问题需要解决的情况下,通常建议开发人员查看当前的回归和开放缺陷 +列表。从来都不缺少需要解决的问题;通过解决这些问题,开发人员将从该过程获得 +经验,同时与开发社区的其他成员建立相互尊重。 -- cgit v1.2.3 From 84e13b01fb4450b04241befe3beaea048ce835b6 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:27:04 +0800 Subject: docs/zh_CN: Improve zh_CN/process/3.Early-stage.rst Improve language and grammar of zh_CN/process/3.Early-stage.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/501394c36239abe67966529595e10fa1aea22cd0.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/3.Early-stage.rst | 139 +++++++++++---------- 1 file changed, 73 insertions(+), 66 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/3.Early-stage.rst b/Documentation/translations/zh_CN/process/3.Early-stage.rst index b8676aec6005..de53dd12e911 100644 --- a/Documentation/translations/zh_CN/process/3.Early-stage.rst +++ b/Documentation/translations/zh_CN/process/3.Early-stage.rst @@ -1,7 +1,14 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/3.Early-stage.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_early_stage: @@ -9,45 +16,45 @@ ======== 当考虑一个Linux内核开发项目时,很可能会直接跳进去开始编码。然而,与任何重要 -的项目一样,成功的许多基础最好是在第一行代码编写之前就做好了。在早期计划和 -沟通中花费一些时间可以节省更多的时间。 +的项目一样,许多成功的基础最好是在第一行代码编写之前就打下。在早期计划和 +沟通中花费一些时间可以在之后节省更多的时间。 -详述问题 +搞清问题 -------- -与任何工程项目一样,成功的内核增强从要解决的问题的清晰描述开始。在某些情况 -下,这个步骤很容易:例如,当某个特定硬件需要驱动程序时。不过,在其他方面, -将实际问题与建议的解决方案混淆是很有诱惑力的,这可能会导致困难。 +与任何工程项目一样,成功的内核改善从清晰描述要解决的问题开始。在某些情况 +下,这个步骤很容易:例如当某个特定硬件需要驱动程序时。不过,在其他情况下, +很容易将实际问题与建议的解决方案混在一起,这可能会导致麻烦。 -举个例子:几年前,使用Linux音频的开发人员寻求一种方法来运行应用程序,而不因 -系统延迟过大而导致退出或其他工件。他们得到的解决方案是一个内核模块,旨在连 -接到Linux安全模块(LSM)框架中;这个模块可以配置为允许特定的应用程序访问 -实时调度程序。这个模块被实现并发送到Linux内核邮件列表,在那里它立即遇到问题。 +举个例子:几年前,Linux音频的开发人员寻求一种方法来运行应用程序,而不会因 +系统延迟过大而导致退出或其他问题。他们得到的解决方案是一个连接到Linux安全 +模块(LSM)框架中的内核模块;这个模块可以配置为允许特定的应用程序访问实时 +调度程序。这个模块被实现并发到linux-kernel邮件列表,在那里它立即遇到了麻烦。 对于音频开发人员来说,这个安全模块足以解决他们当前的问题。但是,对于更广泛的 内核社区来说,这被视为对LSM框架的滥用(LSM框架并不打算授予他们原本不具备的 进程特权),并对系统稳定性造成风险。他们首选的解决方案包括短期的通过rlimit 机制进行实时调度访问,以及长期的减少延迟的工作。 -然而,音频社区看不到他们实施的特定解决方案的过去;他们不愿意接受替代方案。 +然而,音频社区无法超越他们实施的特定解决方案来看问题;他们不愿意接受替代方案。 由此产生的分歧使这些开发人员对整个内核开发过程感到失望;其中一个开发人员返回 -到音频列表并发布了以下内容: +到audio列表并发布了以下内容: - 有很多非常好的Linux内核开发人员,但他们往往会被一群傲慢的傻瓜所压倒。 - 试图向这些人传达用户需求是浪费时间。他们太“聪明”了,根本听不到少数人 - 的话。 + 有很多非常好的Linux内核开发人员,但他们往往会被一群傲慢的傻瓜所压倒。 + 试图向这些人传达用户需求是浪费时间。他们太“聪明”了,根本听不到少数 + 人的话。 (http://lwn.net/articles/131776/) -实际情况不同;与特定模块相比,内核开发人员更关心系统稳定性、长期维护以及找到 -正确的问题解决方案。这个故事的寓意是把重点放在问题上——而不是具体的解决方案 -上——并在投入创建代码之前与开发社区讨论这个问题。 +实际情况却是不同的;与特定模块相比,内核开发人员更关心系统稳定性、长期维护 +以及找到问题的正确解决方案。这个故事的寓意是把重点放在问题上——而不是具体的 +解决方案上——并在开始编写代码之前与开发社区讨论这个问题。 因此,在考虑一个内核开发项目时,我们应该得到一组简短问题的答案: - - 究竟需要解决的问题是什么? + - 需要解决的问题究竟是什么? - - 受此问题影响的用户是谁?解决方案应该解决哪些用例? + - 受此问题影响的用户有哪些?解决方案应该解决哪些使用案例? - 内核现在为何没能解决这个问题? @@ -62,100 +69,100 @@ - 很可能问题是由内核以您不理解的方式解决的。Linux内核很大,具有许多不明显 的特性和功能。并不是所有的内核功能都像人们所希望的那样有文档记录,而且很 - 容易遗漏一些东西。你的作者发出了一个完整的驱动程序,复制了一个新作者不 - 知道的现有驱动程序。重新设计现有轮子的代码不仅浪费,而且不会被接受到主线 + 容易遗漏一些东西。某作者发布了一个完整的驱动程序,重复了一个其不 + 知道的现有驱动程序。重新发明现有轮子的代码不仅浪费,而且不会被接受到主线 内核中。 - - 建议的解决方案中可能有一些元素不适用于主线合并。在编写代码之前,最好先 - 了解这样的问题。 + - 建议的解决方案中可能有一些要素不适合并入主线。在编写代码之前,最好先了解 + 这样的问题。 - 其他开发人员完全有可能考虑过这个问题;他们可能有更好的解决方案的想法,并且 可能愿意帮助创建这个解决方案。 在内核开发社区的多年经验给了我们一个明确的教训:闭门设计和开发的内核代码总是 有一些问题,这些问题只有在代码发布到社区中时才会被发现。有时这些问题很严重, -需要数月或数年的努力才能使代码达到内核社区的标准。一些例子包括: +需要数月或数年的努力才能使代码达到内核社区的标准。例如: - 设计并实现了单处理器系统的DeviceScape网络栈。只有使其适合于多处理器系统, - 才能将其合并到主线中。在代码中改装锁等等是一项困难的任务;因此,这段代码 + 才能将其合并到主线中。在代码中修改锁等等是一项困难的任务;因此,这段代码 (现在称为mac80211)的合并被推迟了一年多。 - Reiser4文件系统包含许多功能,核心内核开发人员认为这些功能应该在虚拟文件 系统层中实现。它还包括一些特性,这些特性在不将系统暴露于用户引起的死锁的 - 情况下是不容易实现的。这些问题的最新发现——以及对其中一些问题的拒绝——已经 - 导致Reiser4远离了主线内核。 + 情况下是不容易实现的。这些问题过迟发现——以及拒绝处理其中一些问题——已经 + 导致Reiser4置身主线内核之外。 - Apparmor安全模块以被认为不安全和不可靠的方式使用内部虚拟文件系统数据结构。 - 这种担心(包括其他)使Apparmor多年不在主线上。 + 这种担心(包括其他)使Apparmor多年来无法进入主线。 -在每一种情况下,通过与内核开发人员的早期讨论,可以避免大量的痛苦和额外的工作。 +在这些情况下,与内核开发人员的早期讨论,可以避免大量的痛苦和额外的工作。 -找谁交流 --------- +找谁交流? +---------- 当开发人员决定公开他们的计划时,下一个问题是:我们从哪里开始?答案是找到正确 的邮件列表和正确的维护者。对于邮件列表,最好的方法是在维护者(MAINTAINERS)文件 -中查找要发布的相关位置。如果有一个合适的子系统列表,那么发布它通常比在Linux -内核上发布更可取;您更有可能接触到在相关子系统中具有专业知识的开发人员,并且 -环境可能具支持性。 +中查找要发布的相关位置。如果有一个合适的子系统列表,那么其上发布通常比在 +linux-kernel上发布更可取;您更有可能接触到在相关子系统中具有专业知识的开发 +人员,并且环境可能具支持性。 -找到维护人员可能会有点困难。同样,维护者文件是开始的地方。但是,该文件往往不总 -是最新的,并且并非所有子系统都在那里表示。实际上,维护者文件中列出的人员可能 +找到维护人员可能会有点困难。同样,维护者文件是开始的地方。但是,该文件往往不 +是最新的,并且并非所有子系统都在那里显示。实际上,维护者文件中列出的人员可能 不是当前实际担任该角色的人员。因此,当对联系谁有疑问时,一个有用的技巧是使用 -git(尤其是“git-log”)查看感兴趣的子系统中当前活动的用户。看看谁在写补丁, -如果有人的话,谁会在这些补丁上加上用线签名的。这些人将是帮助新开发项目的最佳 -人选。 +git(尤其是“git-log”)查看感兴趣的子系统中当前活动的用户。看看谁在写补丁、 +谁会在这些补丁上加上Signed-off-by行签名(如有)。这些人将是帮助新开发项目的 +最佳人选。 -找到合适的维护者的任务有时是非常具有挑战性的,以至于内核开发人员添加了一个 -脚本来简化过程: +找到合适的维护者有时是非常具有挑战性的,以至于内核开发人员添加了一个脚本来 +简化这个过程: :: .../scripts/get_maintainer.pl -当给定“-f”选项时,此脚本将返回给定文件或目录的当前维护者。如果在命令行上传递 -了一个补丁,它将列出可能接收补丁副本的维护人员。有许多选项可以调节 -get_maintainer.pl搜索维护者的难易程度;请小心使用更具攻击性的选项,因为最终 +当给定“-f”选项时,此脚本将返回指定文件或目录的当前维护者。如果在命令行上 +给出了一个补丁,它将列出可能接收补丁副本的维护人员。有许多选项可以调节 +get_maintainer.pl搜索维护者的严格程度;请小心使用更激进的选项,因为最终结果 可能会包括对您正在修改的代码没有真正兴趣的开发人员。 -如果所有其他方法都失败了,那么与Andrew Morton交谈可以成为一种有效的方法来跟踪 -特定代码段的维护人员。 +如果所有其他方法都失败了,那么与Andrew Morton交流是跟踪特定代码段维护人员 +的一种有效方法。 何时邮寄? ---------- -如果可能的话,在早期阶段发布你的计划只会有帮助。描述正在解决的问题以及已经 +如果可能的话,在早期阶段发布你的计划只会更有帮助。描述正在解决的问题以及已经 制定的关于如何实施的任何计划。您可以提供的任何信息都可以帮助开发社区为项目 提供有用的输入。 -在这个阶段可能发生的一件令人沮丧的事情不是敌对的反应,而是很少或根本没有 -反应。可悲的事实是:(1)内核开发人员往往很忙;(2)不缺少有宏伟计划和很少 -代码(甚至代码前景)支持他们的人;(3)没有人有义务审查或评论别人发表的 -想法。除此之外,高级设计常常隐藏一些问题,这些问题只有在有人真正尝试实现 -这些设计时才会被发现;因此,内核开发人员宁愿看到代码。 +在这个阶段可能发生的一件令人沮丧的事情不是得到反对意见,而是很少或根本没有 +反馈。令人伤心的事实是:(1)内核开发人员往往很忙;(2)不缺少有宏伟计划但 +代码(甚至代码设想)很少的人去支持他们;(3)没有人有义务审查或评论别人发表 +的想法。除此之外,高层级的设计常常隐藏着一些问题,这些问题只有在有人真正尝试 +实现这些设计时才会被发现;因此,内核开发人员宁愿看到代码。 -如果发表评论的请求在评论的方式上没有什么效果,不要假设这意味着对项目没有 -兴趣。不幸的是,你也不能假设你的想法没有问题。在这种情况下,最好的做法是 -继续进行,把你的进展随时通知社区。 +如果发布请求评论(RFC)并没得到什么有用的评论,不要以为这意味着无人对此项目 +有兴趣,同时你也不能假设你的想法没有问题。在这种情况下,最好的做法是继续进 +行,把你的进展随时通知社区。 获得官方认可 ----------------------- -如果您的工作是在公司环境中完成的,就像大多数Linux内核工作一样,显然,在您将 -公司的计划或代码发布到公共邮件列表之前,必须获得适当授权的经理的许可。发布 -不确定是否兼容GPL的代码可能是有特别问题的;公司的管理层和法律人员越早能够就 -发布内核开发项目达成一致,对参与的每个人都越好。 +如果您的工作是在公司环境中完成的,就像大多数Linux内核工作一样;显然,在您将 +公司的计划或代码发布到公共邮件列表之前,必须获得有适当权利经理的许可。发布 +不确定是否兼容GPL的代码尤其会带来问题;公司的管理层和法律人员越早能够就发布 +内核开发项目达成一致,对参与的每个人都越好。 一些读者可能会认为他们的核心工作是为了支持还没有正式承认存在的产品。将雇主 的计划公布在公共邮件列表上可能不是一个可行的选择。在这种情况下,有必要考虑 保密是否真的是必要的;通常不需要把开发计划关在门内。 -也就是说,有些情况下,一家公司在开发过程的早期就不能合法地披露其计划。拥有 -经验丰富的内核开发人员的公司可以选择以开环的方式进行,前提是他们以后能够避免 +的确,有些情况下一家公司在开发过程的早期无法合法地披露其计划。拥有经验丰富 +的内核开发人员的公司可能选择以开环的方式进行开发,前提是他们以后能够避免 严重的集成问题。对于没有这种内部专业知识的公司,最好的选择往往是聘请外部 -开发商根据保密协议审查计划。Linux基金会运行了一个NDA程序,旨在帮助解决这种 -情况; +开发者根据保密协议审查计划。Linux基金会运行了一个NDA程序,旨在帮助解决这种 +情况;更多信息参见: - http://www.linuxfoundation.org/en/NDA_program + http://www.linuxfoundation.org/nda/ 这种审查通常足以避免以后出现严重问题,而无需公开披露项目。 -- cgit v1.2.3 From 34c27e7a4ef5cfa5f6cda749b2e7ecd3654c9780 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:27:24 +0800 Subject: docs/zh_CN: Improve zh_CN/process/4.Coding.rst Improve language and grammar of zh_CN/process/4.Coding.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/66d6ec99bdd0f41c91951d33eb0fa7c4748019a4.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/4.Coding.rst | 279 +++++++++++---------- 1 file changed, 141 insertions(+), 138 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/4.Coding.rst b/Documentation/translations/zh_CN/process/4.Coding.rst index 66cd8ee07606..94f7f866f103 100644 --- a/Documentation/translations/zh_CN/process/4.Coding.rst +++ b/Documentation/translations/zh_CN/process/4.Coding.rst @@ -1,155 +1,160 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/4.Coding.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_coding: 使代码正确 ====================== -虽然对于一个坚实的、面向社区的设计过程有很多话要说,但是任何内核开发项目的 -证明都在生成的代码中。它是将由其他开发人员检查并合并(或不合并)到主线树中 +虽然一个坚实的、面向社区的设计过程有很多值得说道的,但是任何内核开发项目工作 +的证明都反映在代码中。它是将由其他开发人员检查并合并(或不合并)到主线树中 的代码。所以这段代码的质量决定了项目的最终成功。 -本节将检查编码过程。我们将从内核开发人员出错的几种方式开始。然后重点将转移 -到正确的事情和可以帮助这个任务的工具上。 +本节将检查编码过程。我们将从内核开发人员常犯的几种错误开始。然后重点将转移 +到正确的做法和相关有用的工具上。 陷阱 ---- -编码风格 +代码风格 ******** -内核长期以来都有一种标准的编码风格,如 +内核长期以来都有其标准的代码风格,如 :ref:`Documentation/translations/zh_CN/process/coding-style.rst ` -中所述。在大部分时间里,该文件中描述的政策被认为至多是建议性的。因此,内核 -中存在大量不符合编码风格准则的代码。代码的存在会给内核开发人员带来两个独立 -的危害。 - -首先,要相信内核编码标准并不重要,也不强制执行。事实上,如果没有按照标准对代 -码进行编码,那么向内核添加新代码是非常困难的;许多开发人员甚至会在审查代码之 -前要求对代码进行重新格式化。一个与内核一样大的代码库需要一些统一的代码,以使 -开发人员能够快速理解其中的任何部分。所以已经没有空间来存放奇怪的格式化代码了。 - -偶尔,内核的编码风格会与雇主的强制风格发生冲突。在这种情况下,内核的风格必须 -在代码合并之前获胜。将代码放入内核意味着以多种方式放弃一定程度的控制权——包括 -控制代码的格式化方式。 - -另一个陷阱是假定已经在内核中的代码迫切需要编码样式的修复。开发人员可能会开始 -生成重新格式化补丁,作为熟悉过程的一种方式,或者作为将其名称写入内核变更日志 -的一种方式,或者两者兼而有之。但是纯编码风格的修复被开发社区视为噪音;它们往 -往受到冷遇。因此,最好避免使用这种类型的补丁。由于其他原因,在处理一段代码的 -同时修复它的样式是很自然的,但是编码样式的更改不应该仅为了更改而进行。 - -编码风格的文档也不应该被视为绝对的法律,这是永远不会被违反的。如果有一个很好 -的理由反对这种样式(例如,如果拆分为适合80列限制的行,那么它的可读性就会大大 -降低),那么就这样做。 - -请注意,您还可以使用 ``clang-format`` 工具来帮助您处理这些规则,自动重新格式 -化部分代码,并查看完整的文件,以发现编码样式错误、拼写错误和可能的改进。它还 -可以方便地进行排序,包括对齐变量/宏、回流文本和其他类似任务。有关详细信息,请 -参阅文件 :ref:`Documentation/process/clang-format.rst ` +中所述。在多数时候,该文档中描述的准则至多被认为是建议性的。因此,内核中存在 +大量不符合代码风格准则的代码。这种代码的存在会给内核开发人员带来两方面的危害。 + +首先,相信内核代码标准并不重要,也不强制执行。但事实上,如果没有按照标准 +编写代码,那么新代码将很难加入到内核中;许多开发人员甚至会在审查代码之前要求 +对代码进行重新格式化。一个像内核这么大的代码库需要一些统一格式的代码,以使 +开发人员能够快速理解其中的任何部分。所以再也经不起奇怪格式的代码的折腾了。 + +内核的代码风格偶尔会与雇主的强制风格发生冲突。在这种情况下,必须在代码合并 +之前遵从内核代码风格。将代码放入内核意味着以多种方式放弃一定程度的控制权—— +包括控制代码样式。 + +另一个危害是认为已经在内核中的代码迫切需要修复代码样式。开发者可能会开始编写 +重新格式化补丁,作为熟悉开发过程的一种方式,或者作为将其名字写入内核变更日志 +的一种方式,或者两者兼而有之。但是纯代码风格的修复被开发社区视为噪音,它们往 +往受到冷遇。因此,最好避免编写这种类型的补丁。在由于其他原因处理一段代码的 +同时顺带修复其样式是很自然的,但是不应该仅为了更改代码样式而更改之。 + +代码风格文档也不应该被视为绝对不可违反的规则。如果有一个足够的理由反对这种 +样式(例如为了80列限制拆分行会导致可读性大大降低),那么就这样做吧。 + +注意您还可以使用 ``clang-format`` 工具来帮助您处理这些规则,快速自动重新格式 +化部分代码,和审阅完整的文件以发现代码样式错误、拼写错误和可能的改进。它还 +可以方便地排序 ``#includes`` 、对齐变量/宏、重排文本和其他类似任务。有关详细 +信息,请参阅文档 :ref:`Documentation/process/clang-format.rst ` 抽象层 ****** 计算机科学教授教学生以灵活性和信息隐藏的名义广泛使用抽象层。当然,内核广泛 -地使用了抽象;任何涉及数百万行代码的项目都不能做到这一点并存活下来。但经验 -表明,过度或过早的抽象可能和过早的优化一样有害。抽象应用于所需的级别, +地使用了抽象;任何涉及数百万行代码的项目都必须做到这一点以存续下来。但经验 +表明,过度或过早的抽象可能和过早的优化一样有害。抽象应用在适当层级, 不要过度。 -在一个简单的级别上,考虑一个函数的参数,该参数总是由所有调用方作为零传递。 -我们可以保留这个论点: 以防有人最终需要使用它提供的额外灵活性。不过,到那时, -实现这个额外参数的代码很有可能以某种从未被注意到的微妙方式被破坏——因为它从 -未被使用过。或者,当需要额外的灵活性时,它不会以符合程序员早期期望的方式来 -这样做。内核开发人员通常会提交补丁来删除未使用的参数;一般来说,首先不应该 -添加这些参数。 +简单点,先考虑一个调用时始终只有一个参数且总为零的函数。我们可以保留这个参数, +以在需要使用它时提供的额外灵活性。不过,在那时实现了这个额外参数的代码很有 +可能以某种从未被注意到的微妙方式被破坏——因为它从未被使用过。或者当需要额外 +的灵活性时,它并未以符合程序员当初期望的方式来实现。内核开发人员通常会提交 +补丁来删除未使用的参数;一般来说,一开始就不应该添加这些参数。 -隐藏硬件访问的抽象层——通常允许大量的驱动程序在多个操作系统中使用——尤其不受 +隐藏硬件访问的抽象层——通常为了允许大量的驱动程序兼容多个操作系统——尤其不受 欢迎。这样的层使代码变得模糊,可能会造成性能损失;它们不属于Linux内核。 -另一方面,如果您发现自己从另一个内核子系统复制了大量的代码,那么现在是时候 -问一下,事实上,将这些代码中的一些提取到单独的库中,或者在更高的层次上实现 -这些功能是否有意义。在整个内核中复制相同的代码没有价值。 +另一方面,如果您发现自己从另一个内核子系统复制了大量的代码,那么是时候 +了解一下:是否需要将这些代码中的部分提取到单独的库中,或者在更高的层次上 +实现这些功能。在整个内核中复制相同的代码没有价值。 #ifdef 和预处理 *************** -C预处理器似乎给一些C程序员带来了强大的诱惑,他们认为它是一种有效地将大量灵 -活性编码到源文件中的方法。但是预处理器不是C,大量使用它会导致代码对其他人来 -说更难读取,对编译器来说更难检查正确性。大量的预处理器几乎总是代码需要一些 +C预处理器似乎给一些C程序员带来了强大的诱惑,他们认为它是一种将大量灵活性加入 +源代码中的方法。但是预处理器不是C,大量使用它会导致代码对其他人来说更难阅读, +对编译器来说更难检查正确性。使用了大量预处理器几乎总是代码需要一些 清理工作的标志。 -使用ifdef的条件编译实际上是一个强大的功能,它在内核中使用。但是很少有人希望 -看到代码被大量地撒上ifdef块。作为一般规则,ifdef的使用应尽可能限制在头文件 -中。有条件编译的代码可以限制函数,如果代码不存在,这些函数就会变成空的。然后 -编译器将悄悄地优化对空函数的调用。结果是代码更加清晰,更容易理解。 +使用#ifdef的条件编译实际上是一个强大的功能,它在内核中使用。但是很少有人希望 +看到代码被铺满#ifdef块。一般规定,ifdef的使用应尽可能限制在头文件中。条件 +编译代码可以限制函数,如果代码不存在,这些函数就直接变成空的。然后编译器将 +悄悄地优化对空函数的调用。使得代码更加清晰,更容易理解。 -C预处理器宏存在许多危险,包括可能对具有副作用且没有类型安全性的表达式进行多 -重评估。如果您试图定义宏,请考虑创建一个内联函数。结果相同的代码,但是内联 -函数更容易读取,不会多次计算其参数,并且允许编译器对参数和返回值执行类型检查。 +C预处理器宏存在许多危险性,包括可能对具有副作用且没有类型安全的表达式进行多 +重评估。如果您试图定义宏,请考虑创建一个内联函数替代。结果相同的代码,内联 +函数更容易阅读,不会多次计算其参数,并且允许编译器对参数和返回值执行类型检查。 内联函数 ******** 不过,内联函数本身也存在风险。程序员可以倾心于避免函数调用和用内联函数填充源 文件所固有的效率。然而,这些功能实际上会降低性能。因为它们的代码在每个调用站 -点都被复制,所以它们最终会增加编译内核的大小。反过来,这会对处理器的内存缓存 -造成压力,从而大大降低执行速度。通常,内联函数应该非常小,而且相对较少。毕竟, -函数调用的成本并不高;大量内联函数的创建是过早优化的典型例子。 +点都被复制一遍,所以最终会增加编译内核的大小。此外,这也对处理器的内存缓存 +造成压力,从而大大降低执行速度。通常内联函数应该非常小,而且相对较少。毕竟 +函数调用的成本并不高;大量创建内联函数是过早优化的典型例子。 -一般来说,内核程序员会忽略缓存效果,这会带来危险。在开始的数据结构课程中,经 -典的时间/空间权衡通常不适用于当代硬件。空间就是时间,因为一个大的程序比一个 +一般来说,内核程序员会自冒风险忽略缓存效果。在数据结构课程开头中的经典 +时间/空间权衡通常不适用于当代硬件。空间 *就是* 时间,因为一个大的程序比一个 更紧凑的程序运行得慢。 -最近的编译器在决定一个给定函数是否应该被内联方面扮演着越来越积极的角色。 -因此,“inline”关键字的自由放置可能不仅仅是过度的,它也可能是无关的。 +较新的编译器越来越激进地决定一个给定函数是否应该内联。因此,随意放置使用 +“inline”关键字可能不仅仅是过度的,也可能是无用的。 锁 ** -2006年5月,“deviceescape”网络堆栈在GPL下发布,并被纳入主线内核。这是一个受 -欢迎的消息;对Linux中无线网络的支持充其量被认为是不合格的,而deviceescape -堆栈提供了修复这种情况的承诺。然而,直到2007年6月(2.6.22),这段代码才真 +2006年5月,“deviceescape”网络堆栈在前呼后拥下以GPL发布,并被纳入主线内核。 +这是一个受欢迎的消息;Linux中对无线网络的支持充其量被认为是不合格的,而 +Deviceescape堆栈承诺修复这种情况。然而直到2007年6月(2.6.22),这段代码才真 正进入主线。发生了什么? -这段代码显示了许多闭门造车的迹象。但一个特别大的问题是,它并不是设计用于多 -处理器系统。在合并这个网络堆栈(现在称为mac80211)之前,需要对其进行一个锁 -方案的改造。 +这段代码出现了许多闭门造车的迹象。但一个大麻烦是,它并不是为多处理器系统而 +设计。在合并这个网络堆栈(现在称为mac80211)之前,需要对其进行一个锁方案的 +改造。 曾经,Linux内核代码可以在不考虑多处理器系统所带来的并发性问题的情况下进行 -开发。然而,现在,这个文件是写在双核笔记本电脑上的。即使在单处理器系统上, +开发。然而现在,这个文档就是在双核笔记本电脑上写的。即使在单处理器系统上, 为提高响应能力所做的工作也会提高内核内的并发性水平。编写内核代码而不考虑锁 -的日子已经过去很长了。 +的日子早已远去。 可以由多个线程并发访问的任何资源(数据结构、硬件寄存器等)必须由锁保护。新 -的代码应该记住这一要求;事后改装锁是一项相当困难的任务。内核开发人员应该花 -时间充分了解可用的锁原语,以便为作业选择正确的工具。显示对并发性缺乏关注的 -代码进入主线将很困难。 +的代码应该谨记这一要求;事后修改锁是一项相当困难的任务。内核开发人员应该花 +时间充分了解可用的锁原语,以便为工作选择正确的工具。对并发性缺乏关注的代码 +很难进入主线。 回归 **** -最后一个值得一提的危险是:它可能会引起改变(这可能会带来很大的改进),从而 -导致现有用户的某些东西中断。这种变化被称为“回归”,回归已经成为主线内核最不 -受欢迎的。除少数例外情况外,如果回归不能及时修正,会导致回归的变化将被取消。 -最好首先避免回归。 +最后一个值得一提的危险是回归:它可能会引起导致现有用户的某些东西中断的改变 +(这也可能会带来很大的改进)。这种变化被称为“回归”,回归已经成为主线内核 +最不受欢迎的问题。除了少数例外情况,如果回归不能及时修正,会导致回归的修改 +将被取消。最好首先避免回归发生。 -人们常常争论,如果回归让更多人可以工作,远超过产生问题,那么回归是合理的。 -如果它破坏的一个系统却为十个系统带来新的功能,为什么不进行更改呢?2007年7月, +人们常常争论,如果回归带来的功能远超过产生的问题,那么回归是否为可接受的。 +如果它破坏了一个系统却为十个系统带来新的功能,为何不改改态度呢?2007年7月, Linus对这个问题给出了最佳答案: :: - 所以我们不会通过引入新问题来修复错误。那样的谎言很疯狂,没有人知道 - 你是否真的有进展。是前进两步,后退一步,还是向前一步,向后两步? + + 所以我们不会通过引入新问题来修复错误。这种方式是靠不住的,没人知道 + 是否真的有进展。是前进两步、后退一步,还是前进一步、后退两步? (http://lwn.net/articles/243460/) -一种特别不受欢迎的回归类型是用户空间ABI的任何变化。一旦接口被导出到用户空间, +特别不受欢迎的一种回归类型是用户空间ABI的任何变化。一旦接口被导出到用户空间, 就必须无限期地支持它。这一事实使得用户空间接口的创建特别具有挑战性:因为它们 -不能以不兼容的方式进行更改,所以必须第一次正确地进行更改。因此,用户空间界面 -总是需要大量的思考、清晰的文档和广泛的审查。 +不能以不兼容的方式进行更改,所以必须一次就对。因此,用户空间接口总是需要大量 +的思考、清晰的文档和广泛的审查。 代码检查工具 @@ -157,13 +162,13 @@ Linus对这个问题给出了最佳答案: 至少目前,编写无错误代码仍然是我们中很少人能达到的理想状态。不过,我们希望做 的是,在代码进入主线内核之前,尽可能多地捕获并修复这些错误。为此,内核开发人 -员已经组装了一系列令人印象深刻的工具,可以自动捕获各种各样的模糊问题。计算机 +员已经提供了一系列令人印象深刻的工具,可以自动捕获各种各样的隐藏问题。计算机 发现的任何问题都是一个以后不会困扰用户的问题,因此,只要有可能,就应该使用 自动化工具。 -第一步只是注意编译器产生的警告。当代版本的GCC可以检测(并警告)大量潜在错误。 -通常,这些警告都指向真正的问题。提交以供审阅的代码通常不会产生任何编译器警告。 -在消除警告时,注意了解真正的原因,并尽量避免“修复”,使警告消失而不解决其原因。 +第一步是注意编译器产生的警告。当前版本的GCC可以检测(并警告)大量潜在错误。 +通常,这些警告都指向真正的问题。提交以供审阅的代码一般不会产生任何编译器警告。 +在消除警告时,注意了解真正的原因,并尽量避免仅“修复”使警告消失而不解决其原因。 请注意,并非所有编译器警告都默认启用。使用“make KCFLAGS=-W”构建内核以 获得完整集合。 @@ -172,45 +177,43 @@ Linus对这个问题给出了最佳答案: 子菜单中。对于任何用于开发或测试目的的内核,都应该启用其中几个选项。特别是, 您应该打开: - - 启用 ENABLE_MUST_CHECK and FRAME_WARN 以获得一组额外的警告,以解决使用不 - 推荐使用的接口或忽略函数的重要返回值等问题。这些警告生成的输出可能是冗长 - 的,但您不必担心来自内核其他部分的警告。 + - FRAME_WARN 获取大于给定数量的堆栈帧的警告。 + 这些警告生成的输出可能比较冗长,但您不必担心来自内核其他部分的警告。 - - DEBUG_OBJECTS 将添加代码,以跟踪内核创建的各种对象的生存期,并在出现问题时 - 发出警告。如果要添加创建(和导出)自己的复杂对象的子系统,请考虑添加对对象 - 调试基础结构的支持。 + - DEBUG_OBJECTS 将添加代码以跟踪内核创建的各种对象的生命周期,并在出现问题 + 时发出警告。如果你要添加创建(和导出)关于其自己的复杂对象的子系统,请 + 考虑打开对象调试基础结构的支持。 - DEBUG_SLAB 可以发现各种内存分配和使用错误;它应该用于大多数开发内核。 - - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP and DEBUG_MUTEXES 会发现许多常见的 - 锁定错误. + - DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP 和 DEBUG_MUTEXES 会发现许多常见的 + 锁错误。 -还有很多其他调试选项,其中一些将在下面讨论。其中一些具有显著的性能影响,不应 -一直使用。但是,在学习可用选项上花费的一些时间可能会在短期内得到多次回报。 +还有很多其他调试选项,其中一些将在下面讨论。其中一些有显著的性能影响,不应 +一直使用。在学习可用选项上花费一些时间,可能会在短期内得到许多回报。 -其中一个较重的调试工具是锁定检查器或“lockdep”。该工具将跟踪系统中每个锁 +其中一个较重的调试工具是锁检查器或“lockdep”。该工具将跟踪系统中每个锁 (spinlock或mutex)的获取和释放、获取锁的相对顺序、当前中断环境等等。然后, -它可以确保总是以相同的顺序获取锁,相同的中断假设适用于所有情况,等等。换句话 -说,lockdep可以找到许多场景,在这些场景中,系统很少会死锁。在部署的系统中, -这种问题可能会很痛苦(对于开发人员和用户而言);LockDep允许提前以自动方式 -发现问题。具有任何类型的非普通锁定的代码在提交包含前应在启用lockdep的情况 -下运行。 +它可以确保总是以相同的顺序获取锁,相同的中断假设适用于所有情况等等。换句话 +说,lockdep可以找到许多导致系统死锁的场景。在部署的系统中,这种问题可能会 +很痛苦(对于开发人员和用户而言);LockDep允许提前以自动方式发现问题。具有 +任何类型的非普通锁的代码在提交合并前应在启用lockdep的情况下运行测试。 作为一个勤奋的内核程序员,毫无疑问,您将检查任何可能失败的操作(如内存分配) -的返回状态。然而,事实上,最终的故障恢复路径可能完全没有经过测试。未测试的 -代码往往会被破坏;如果所有这些错误处理路径都被执行了几次,那么您可能对代码 +的返回状态。然而,事实上,最终的故障复现路径可能完全没有经过测试。未测试的 +代码往往会出问题;如果所有这些错误处理路径都被执行了几次,那么您可能对代码 更有信心。 内核提供了一个可以做到这一点的错误注入框架,特别是在涉及内存分配的情况下。 -启用故障注入后,内存分配的可配置百分比将失败;这些失败可以限制在特定的代码 +启用故障注入后,内存分配的可配置失败的百分比;这些失败可以限定在特定的代码 范围内。在启用了故障注入的情况下运行,程序员可以看到当情况恶化时代码如何响 应。有关如何使用此工具的详细信息,请参阅 Documentation/fault-injection/fault-injection.rst。 -使用“sparse”静态分析工具可以发现其他类型的错误。对于sparse,可以警告程序员 -用户空间和内核空间地址之间的混淆、big endian和small endian数量的混合、在需 -要一组位标志的地方传递整数值等等。sparse必须单独安装(如果您的分发服务器没 -有将其打包,可以在 https://sparse.wiki.kernel.org/index.php/Main_page)找到, +“sparse”静态分析工具可以发现其他类型的错误。sparse可以警告程序员用户空间 +和内核空间地址之间的混淆、大端序与小端序的混淆、在需要一组位标志的地方传递 +整数值等等。sparse必须单独安装(如果您的分发服务器没有将其打包, +可以在 https://sparse.wiki.kernel.org/index.php/Main_page 找到), 然后可以通过在make命令中添加“C=1”在代码上运行它。 “Coccinelle”工具 :ref:`http://coccinelle.lip6.fr/ ` @@ -221,8 +224,8 @@ scripts/coccinelle目录下已经打包了相当多的内核“语义补丁” 其他类型的可移植性错误最好通过为其他体系结构编译代码来发现。如果没有S/390系统 -或Blackfin开发板,您仍然可以执行编译步骤。可以在以下位置找到一组用于x86系统的 -大型交叉编译器: +或Blackfin开发板,您仍然可以执行编译步骤。可以在以下位置找到一大堆用于x86系统的 +交叉编译器: https://www.kernel.org/pub/tools/crosstool/ @@ -233,22 +236,22 @@ scripts/coccinelle目录下已经打包了相当多的内核“语义补丁” 文档通常比内核开发规则更为例外。即便如此,足够的文档将有助于简化将新代码合并 到内核中的过程,使其他开发人员的生活更轻松,并对您的用户有所帮助。在许多情况 -下,文件的添加已基本上成为强制性的。 +下,添加文档已基本上是强制性的。 任何补丁的第一个文档是其关联的变更日志。日志条目应该描述正在解决的问题、解决 方案的形式、处理补丁的人员、对性能的任何相关影响,以及理解补丁可能需要的任何 -其他内容。确保changelog说明了为什么补丁值得应用;大量开发人员未能提供这些信息。 +其他内容。确保变更日志说明了*为什么*补丁值得应用;大量开发者未能提供这些信息。 -任何添加新用户空间界面的代码(包括新的sysfs或/proc文件)都应该包含该界面的 -文档,该文档使用户空间开发人员能够知道他们在使用什么。请参阅 -Documentation/ABI/README,了解如何格式化此文档以及需要提供哪些信息。 +任何添加新用户空间接口的代码——包括新的sysfs或/proc文件——都应该包含该接口 +的文档,该文档使用户空间开发人员能够知道他们在使用什么。请参阅 +Documentation/ABI/README,了解如何此文档格式以及需要提供哪些信息。 -文件 :ref:`Documentation/admin-guide/kernel-parameters.rst ` -描述了内核的所有引导时间参数。任何添加新参数的补丁都应该向该文件添加适当的 +文档 :ref:`Documentation/admin-guide/kernel-parameters.rst ` +描述了内核的所有引导时间参数。任何添加新参数的补丁都应该向该文档添加适当的 条目。 -任何新的配置选项都必须附有帮助文本,帮助文本清楚地解释了这些选项以及用户可能 -希望何时选择它们。 +任何新的配置选项都必须附有帮助文本,帮助文本需清楚地解释这些选项以及用户可能 +希望何时使用它们。 许多子系统的内部API信息通过专门格式化的注释进行记录;这些注释可以通过 “kernel-doc”脚本以多种方式提取和格式化。如果您在具有kerneldoc注释的子系统中 @@ -257,31 +260,31 @@ Documentation/ABI/README,了解如何格式化此文档以及需要提供哪 来说是一个有用的活动。这些注释的格式以及如何创建kerneldoc模板的一些信息可以在 :ref:`Documentation/doc-guide/ ` 上找到。 -任何阅读大量现有内核代码的人都会注意到,注释的缺失往往是最值得注意的。再一次, -对新代码的期望比过去更高;合并未注释的代码将更加困难。这就是说,人们几乎不希望 -用语言注释代码。代码本身应该是可读的,注释解释了更微妙的方面。 +任何阅读大量现有内核代码的人都会注意到,注释的缺失往往是最值得注意的。同时, +对新代码的要求比过去更高;合并未注释的代码将更加困难。这就是说,人们并不期望 +详细注释的代码。代码本身应该是自解释的,注释阐释了更微妙的方面。 某些事情应该总是被注释。使用内存屏障时,应附上一行文字,解释为什么需要设置内存 -屏障。数据结构的锁定规则通常需要在某个地方解释。一般来说,主要数据结构需要全面 -的文档。应该指出单独代码位之间不明显的依赖性。任何可能诱使代码看门人进行错误的 -“清理”的事情都需要一个注释来说明为什么要这样做。等等。 +屏障。数据结构的锁规则通常需要在某个地方解释。一般来说,主要数据结构需要全面 +的文档。应该指出代码中分立的位之间不明显的依赖性。任何可能诱使代码管理人进行 +错误的“清理”的事情都需要一个注释来说明为什么要这样做。等等。 内部API更改 ----------- -内核提供给用户空间的二进制接口不能被破坏,除非在最严重的情况下。相反,内核的 -内部编程接口是高度流动的,当需要时可以更改。如果你发现自己不得不处理一个内核 -API,或者仅仅因为它不满足你的需求而不使用特定的功能,这可能是API需要改变的一 -个标志。作为内核开发人员,您有权进行此类更改。 +内核提供给用户空间的二进制接口不能被破坏,除非逼不得已。而内核的内部编程接口 +是高度流动的,当需要时可以更改。如果你发现自己不得不处理一个内核API,或者仅 +仅因为它不满足你的需求导致无法使用特定的功能,这可能是API需要改变的一个标志。 +作为内核开发人员,您有权进行此类更改。 -当然, 可以进行API更改,但它们必须是合理的。因此,任何进行内部API更改的补丁都 -应该附带一个关于更改内容和必要原因的描述。这种变化也应该分解成一个单独的补丁, -而不是埋在一个更大的补丁中。 +的确可以进行API更改,但更改必须是合理的。因此任何进行内部API更改的补丁都应该 +附带关于更改内容和必要原因的描述。这种变化也应该拆分成一个单独的补丁,而不是 +埋在一个更大的补丁中。 另一个要点是,更改内部API的开发人员通常要负责修复内核树中被更改破坏的任何代码。 -对于一个广泛使用的函数,这个职责可以导致成百上千的变化,其中许多变化可能与其他 -开发人员正在做的工作相冲突。不用说,这可能是一项大工作,所以最好确保理由是 +对于一个广泛使用的函数,这个责任可以导致成百上千的变化,其中许多变化可能与其他 +开发人员正在做的工作相冲突。不用说,这可能是一项大工程,所以最好确保理由是 可靠的。请注意,coccinelle工具可以帮助进行广泛的API更改。 在进行不兼容的API更改时,应尽可能确保编译器捕获未更新的代码。这将帮助您确保找 -- cgit v1.2.3 From 75cc66836d9eea2c00aefc6730893adb97e41b18 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:27:48 +0800 Subject: docs/zh_CN: Improve zh_CN/process/5.Posting.rst Improve language and grammar of zh_CN/process/5.Posting.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/e2e8e109c7709ebbed9f536cbe49f6f56f38d5bf.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/5.Posting.rst | 243 +++++++++++---------- 1 file changed, 125 insertions(+), 118 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/5.Posting.rst b/Documentation/translations/zh_CN/process/5.Posting.rst index 9ff9945f918c..b0c65614844d 100644 --- a/Documentation/translations/zh_CN/process/5.Posting.rst +++ b/Documentation/translations/zh_CN/process/5.Posting.rst @@ -1,150 +1,157 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/5.Posting.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_posting: 发布补丁 ======== -迟早,当您的工作准备好提交给社区进行审查,并最终包含到主线内核中时。不出所料, +您的工作迟早会准备好提交给社区进行审查,并最终包含到主线内核中。毫不稀奇, 内核开发社区已经发展出一套用于发布补丁的约定和过程;遵循这些约定和过程将使 -参与其中的每个人的生活更加轻松。本文件将试图合理详细地涵盖这些期望;更多信息 -也可在以下文件中找到 -:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst `, -:ref:`Documentation/process/submitting-drivers.rst ` -和 :ref:`Documentation/translations/zh_CN/process/submit-checklist.rst `. +参与其中的每个人的生活更加轻松。本文档试图描述这些约定的部分细节;更多信息 +也可在以下文档中找到 +:ref:`Documentation/translations/zh_CN/process/submitting-patches.rst `, +:ref:`Documentation/translations/zh_CN/process/submitting-drivers.rst ` +和 :ref:`Documentation/translations/zh_CN/process/submit-checklist.rst `。 何时邮寄 -------- -在补丁完全“准备好”之前,有一个不断的诱惑来避免发布补丁。对于简单的补丁, -这不是问题。但是,如果正在完成的工作很复杂,那么在工作完成之前从社区获得 -反馈就可以获得很多好处。因此,您应该考虑发布正在进行的工作,甚至使Git树 -可用,以便感兴趣的开发人员可以随时赶上您的工作。 +在补丁完全“准备好”之前,避免发布补丁是一种持续的诱惑。对于简单的补丁,这 +不是问题。但是如果正在完成的工作很复杂,那么在工作完成之前从社区获得反馈就 +可以获得很多好处。因此,您应该考虑发布正在进行的工作,甚至维护一个可用的Git +树,以便感兴趣的开发人员可以随时赶上您的工作。 -当发布还没有准备好包含的代码时,最好在发布本身中这样说。还应提及任何有待完成 -的主要工作和任何已知问题。很少有人会看到那些被认为是半生不熟的补丁,但是那些 -人会想到他们可以帮助你把工作推向正确的方向。 +当发布中有尚未准备好被包含的代码,最好在发布中说明。还应提及任何有待完成的 +主要工作和任何已知问题。很少有人会愿意看那些被认为是半生不熟的补丁,但是 +那些愿意的人会带着他们的点子来一起帮助你把工作推向正确的方向。 创建补丁之前 ------------ -在考虑将补丁发送到开发社区之前,有许多事情应该做。这些包括: +在考虑将补丁发送到开发社区之前,有许多事情应该做。包括: - - 尽可能地测试代码。利用内核的调试工具,确保内核使用所有合理的配置选项组合 - 进行构建,使用跨编译器为不同的体系结构进行构建等。 + - 尽可能地测试代码。利用内核的调试工具,确保内核使用了所有可能的配置选项组合 + 进行构建,使用交叉编译器为不同的体系结构进行构建等。 - - 确保您的代码符合内核编码风格指南。 + - 确保您的代码符合内核代码风格指南。 - 您的更改是否具有性能影响?如果是这样,您应该运行基准测试来显示您的变更的 影响(或好处);结果的摘要应该包含在补丁中。 - 确保您有权发布代码。如果这项工作是为雇主完成的,雇主对这项工作具有所有权, - 并且必须同意根据GPL对其进行放行。 + 并且必须同意根据GPL对其进行发布。 一般来说,在发布代码之前进行一些额外的思考,几乎总是能在短时间内得到回报。 补丁准备 -------- -准备发布补丁可能是一个惊人的工作量,但再次尝试节省时间在这里通常是不明智的, -即使在短期内。 +准备补丁发布的工作量可能很惊人,但在此尝试节省时间通常是不明智的,即使在短期 +内亦然。 -必须针对内核的特定版本准备补丁。作为一般规则,补丁程序应该基于Linus的Git树中 -的当前主线。当以主线为基础时,从一个众所周知的发布点开始——一个稳定的或RC的 -发布——而不是在一个主线分支任意点。 +必须针对内核的特定版本准备补丁。一般来说,补丁应该基于Linus的Git树中的当前 +主线。当以主线为基础时,请从一个众所周知的发布点开始——如稳定版本或 -rc +版本发布点——而不是在一个任意的主线分支点。 -但是,可能需要针对-mm、linux-next或子系统树生成版本,以便于更广泛的测试和审查。 -根据补丁的区域以及其他地方的情况,针对这些其他树建立补丁可能需要大量的工作来 +也可能需要针对-mm、linux-next或子系统树生成版本,以便于更广泛的测试和审查。 +根据补丁的区域以及其他地方的情况,针对其他树建立的补丁可能需要大量的工作来 解决冲突和处理API更改。 只有最简单的更改才应格式化为单个补丁;其他所有更改都应作为一系列逻辑更改进行。 分割补丁是一门艺术;一些开发人员花了很长时间来弄清楚如何按照社区期望的方式来 -做。然而,有一些经验法则可以大大帮助: +分割。不过,这些经验法则也许有帮助: - - 您发布的补丁程序系列几乎肯定不会是工作系统中的一系列更改。相反,您所做的 - 更改需要在最终形式中加以考虑,然后以有意义的方式进行拆分。开发人员对离散的、 - 自包含的更改感兴趣,而不是您获取这些更改的路径。 + - 您发布的补丁系列几乎肯定不会是开发过程中版本控制系统中的一系列更改。相反, + 需要对您所做更改的最终形式加以考虑,然后以有意义的方式进行拆分。开发人员对 + 离散的、自包含的更改感兴趣,而不是您创造这些更改的原始路径。 - - 每个逻辑上独立的变更都应该格式化为单独的补丁。这些更改可以是小的(“向此 - 结构添加字段”)或大的(例如,添加一个重要的新驱动程序),但它们在概念上 - 应该是小的,并且可以接受一行描述。每个补丁都应该做一个特定的更改,可以单独 - 检查并验证它所做的事情。 + - 每个逻辑上独立的变更都应该格式化为单独的补丁。这些更改可以是小的(如“向 + 此结构体添加字段”)或大的(如添加一个重要的新驱动程序),但它们在概念上 + 应该是小的,并且可以在一行内简述。每个补丁都应该做一个特定的、可以单独 + 检查并验证它所做的事情的更改。 - - 作为重申上述准则的一种方法:不要在同一补丁中混合不同类型的更改。如果一个 - 补丁修复了一个关键的安全漏洞,重新排列了一些结构,并重新格式化了代码,那么 - 很有可能它会被忽略,而重要的修复将丢失。 + - 换种方式重申上述准则,也就是说:不要在同一补丁中混合不同类型的更改。如果 + 一个补丁修复了一个关键的安全漏洞,又重新排列了一些结构,还重新格式化了代 + 码,那么它很有可能会被忽略,从而导致重要的修复丢失。 - - 每个补丁都应该产生一个内核,它可以正确地构建和运行;如果补丁系列在中间被 - 中断,那么结果应该仍然是一个工作的内核。补丁系列的部分应用是使用 - “git bisct”工具查找回归的一个常见场景;如果结果是一个损坏的内核,那么对于 - 那些从事追踪问题的高尚工作的开发人员和用户来说,将使他们的生活更加艰难。 + - 每个补丁都应该能创建一个可以正确地构建和运行的内核;如果补丁系列在中间被 + 断开,那么结果仍应是一个正常工作的内核。部分应用一系列补丁是使用 + “git bisct”工具查找回归的一个常见场景;如果结果是一个损坏的内核,那么将使 + 那些从事追踪问题的高尚工作的开发人员和用户的生活更加艰难。 - - 不过,不要过分。一位开发人员曾经将一组编辑内容作为500个单独的补丁发布到一个 - 文件中,这并没有使他成为内核邮件列表中最受欢迎的人。一个补丁可以相当大, - 只要它仍然包含一个单一的逻辑变更。 + - 不要过分分割。一位开发人员曾经将一组针对单个文件的编辑分成500个单独的补丁 + 发布,这并没有使他成为内核邮件列表中最受欢迎的人。一个补丁可以相当大, + 只要它仍然包含一个单一的 *逻辑* 变更。 - - 用一系列补丁添加一个全新的基础设施是很有诱惑力的,但是在系列中的最后一个 - 补丁启用整个补丁之前,该基础设施是不使用的。如果可能的话,应该避免这种 - 诱惑;如果这个系列增加了回归,那么二分法将指出最后一个补丁是导致问题的 - 补丁,即使真正的bug在其他地方。只要有可能,添加新代码的补丁程序应该立即 - 激活该代码。 + - 用一系列补丁添加一个全新的基础设施,但是该设施在系列中的最后一个补丁启用 + 整个变更之前不能使用,这看起来很诱人。如果可能的话,应该避免这种诱惑; + 如果这个系列增加了回归,那么二分法将指出最后一个补丁是导致问题的补丁, + 即使真正的bug在其他地方。只要有可能,添加新代码的补丁程序应该立即激活该 + 代码。 -创建完美补丁系列的工作可能是一个令人沮丧的过程,在完成“真正的工作”之后需要花费 -大量的时间和思考。但是,如果做得好,这是一段很好的时间。 +创建完美补丁系列的工作可能是一个令人沮丧的过程,在完成“真正的工作”之后需要 +花费大量的时间和思考。但是如果做得好,花费的时间就是值得的。 补丁格式和更改日志 ------------------ 所以现在你有了一系列完美的补丁可以发布,但是这项工作还没有完成。每个补丁都 -需要被格式化成一条消息,它可以快速而清晰地将其目的传达给世界其他地方。为此, +需要被格式化成一条消息,以快速而清晰地将其目的传达到世界其他地方。为此, 每个补丁将由以下部分组成: - - 命名补丁作者的可选“from”行。只有当你通过电子邮件传递别人的补丁时,这一行 - 才是必要的,但是如果有疑问,添加它不会有任何伤害。 + - 可选的“From”行,表明补丁作者。只有当你通过电子邮件发送别人的补丁时,这一行 + 才是必须的,但是为防止疑问加上它也不会有什么坏处。 - - 一行描述补丁的作用。对于没有其他上下文的读者来说,此消息应该足够了解补丁 - 的范围;这是将在“短格式”变更日志中显示的行。此消息通常首先用相关的子系统 - 名称格式化,然后是补丁的目的。例如: + - 一行描述,说明补丁的作用。对于在没有其他上下文的情况下看到该消息的读者来说, + 该消息应足以确定修补程序的范围;此行将显示在“short form(简短格式)”变更 + 日志中。此消息通常需要先加上子系统名称前缀,然后是补丁的目的。例如: - :: + :: - gpio: fix build on CONFIG_GPIO_SYSFS=n + gpio: fix build on CONFIG_GPIO_SYSFS=n - - 一个空白行,后面是补丁内容的详细描述。这个描述可以是必需的;它应该说明补丁 + - 一行空白,后接补丁内容的详细描述。此描述可以是任意需要的长度;它应该说明补丁 的作用以及为什么它应该应用于内核。 - - 一个或多个标记行,至少有一个由补丁作者的:signed-off-by 签名。签名将在下面 - 更详细地描述。 + - 一个或多个标记行,至少有一个由补丁作者的 Signed-off-by 签名。标记将在下面 + 详细描述。 -上面的项目一起构成补丁的变更日志。写一篇好的变更日志是一门至关重要但常常被 -忽视的艺术;值得花一点时间来讨论这个问题。当你写一个变更日志时,你应该记住 -有很多不同的人会读你的话。其中包括子系统维护人员和审查人员,他们需要决定是否 -应该包括补丁,分销商和其他维护人员试图决定是否应该将补丁反向移植到其他内核, -bug搜寻人员想知道补丁是否负责他们正在追查的问题,想知道内核如何变化的用户。 -等等。一个好的变更日志以最直接和最简洁的方式向所有这些人传达所需的信息。 +上面的项目一起构成补丁的变更日志。写一则好的变更日志是一门至关重要但常常被 +忽视的艺术;值得花一点时间来讨论这个问题。当你编写变更日志时,你应该记住有 +很多不同的人会读你的话。其中包括子系统维护人员和审查人员,他们需要决定是否 +应该合并补丁,分销商和其他维护人员试图决定是否应该将补丁反向移植到其他内核, +缺陷搜寻人员想知道补丁是否导致他们正在追查的问题,以及想知道内核如何变化的 +用户等等。一个好的变更日志以最直接和最简洁的方式向所有这些人传达所需的信息。 -为此,总结行应该描述变更的影响和动机,以及在一行约束条件下可能发生的变化。 +在结尾,总结行应该描述变更的影响和动机,以及在一行约束条件下可能发生的变化。 然后,详细的描述可以详述这些主题,并提供任何需要的附加信息。如果补丁修复了 -一个bug,请引用引入该bug的commit(如果可能,请在引用commits时同时提供commit id -和标题)。如果某个问题与特定的日志或编译器输出相关联,请包含该输出以帮助其他 -人搜索同一问题的解决方案。如果更改是为了支持以后补丁中的其他更改,那么就这么 -说。如果更改了内部API,请详细说明这些更改以及其他开发人员应该如何响应。一般 -来说,你越能把自己放在每个阅读你的changelog的人的位置上,changelog(和内核 +一个缺陷,请引用引入该缺陷的提交(如果可能,请在引用提交时同时提供其 id 和 +标题)。如果某个问题与特定的日志或编译器输出相关联,请包含该输出以帮助其他 +人搜索同一问题的解决方案。如果更改是为了支持以后补丁中的其他更改,那么应当 +说明。如果更改了内部API,请详细说明这些更改以及其他开发人员应该如何响应。 +一般来说,你越把自己放在每个阅读你变更日志的人的位置上,变更日志(和内核 作为一个整体)就越好。 -不用说,变更日志应该是将变更提交到修订控制系统时使用的文本。接下来是: +不消说,变更日志是将变更提交到版本控制系统时使用的文本。接下来将是: - - 补丁本身,采用统一的(“-u”)补丁格式。将“-p”选项用于diff将使函数名与更改 - 相关联,从而使结果补丁更容易被其他人读取。 + - 补丁本身,采用统一的(“-u”)补丁格式。使用“-p”选项来diff将使函数名与 + 更改相关联,从而使结果补丁更容易被其他人读取。 -您应该避免在补丁中包括对不相关文件(例如,由构建过程生成的文件或编辑器 -备份文件)的更改。文档目录中的文件“dontdiff”在这方面有帮助;使用“-X”选项将 +您应该避免在补丁中包括与更改不相关文件(例如,构建过程生成的文件或编辑器 +备份文件)。文档目录中的“dontdiff”文件在这方面有帮助;使用“-X”选项将 其传递给diff。 -上面提到的标签用于描述各种开发人员如何与这个补丁的开发相关联。 +上面提到的标签(tag)用于描述各种开发人员如何与这个补丁的开发相关联。 :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst ` 文档中对它们进行了详细描述;下面是一个简短的总结。每一行的格式如下: @@ -154,87 +161,87 @@ bug搜寻人员想知道补丁是否负责他们正在追查的问题,想知 常用的标签有: - - Signed-off-by: 这是一个开发人员的证明,他或她有权提交补丁以包含到内核中。 - 这是开发来源认证协议,其全文可在 + - Signed-off-by: 这是一个开发人员的证明,证明他或她有权提交补丁以包含到内核 + 中。这表明同意开发者来源认证协议,其全文见 :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst ` - 中找到,如果没有适当的签字,则不能合并到主线中。 + 如果没有合适的签字,则不能合并到主线中。 - Co-developed-by: 声明补丁是由多个开发人员共同创建的;当几个人在一个补丁上 - 工作时,它用于将属性赋予共同作者(除了 From: 所赋予的作者之外)。因为 - Co-developed-by: 表示作者身份,所以每个共同开发人, 必须紧跟在相关合作作者 - 的签名之后。具体内容和示例可以在以下文件中找到 + 工作时,它用于给出共同作者(除了 From: 所给出的作者之外)。由于 + Co-developed-by: 表示作者身份,所以每个共同开发人,必须紧跟在相关合作作者 + 的Signed-off-by之后。具体内容和示例见以下文件 :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst ` - Acked-by: 表示另一个开发人员(通常是相关代码的维护人员)同意补丁适合包含 在内核中。 - - Tested-by: 声明指定的人已经测试了补丁并发现它可以工作。 + - Tested-by: 声明某人已经测试了补丁并确认它可以工作。 - - Reviewed-by: 指定的开发人员已经审查了补丁的正确性;有关详细信息,请参阅 + - Reviewed-by: 表示某开发人员已经审查了补丁的正确性;有关详细信息,请参阅 :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst ` - - Reported-by: 指定报告此补丁修复的问题的用户;此标记用于提供感谢。 + - Reported-by: 指定报告此补丁修复的问题的用户;此标记用于表示感谢。 - - Cc:指定的人收到了补丁的副本,并有机会对此发表评论。 + - Cc:指定某人收到了补丁的副本,并有机会对此发表评论。 -在补丁中添加标签时要小心:只有cc:才适合在没有指定人员明确许可的情况下添加。 +在补丁中添加标签时要小心:只有Cc:才适合在没有指定人员明确许可的情况下添加。 发送补丁 -------- -在邮寄补丁之前,您还需要注意以下几点: +在寄出补丁之前,您还需要注意以下几点: - - 您确定您的邮件发送程序不会损坏补丁吗?有免费的空白更改或由邮件客户端 - 执行的行包装的补丁不会在另一端复原,并且通常不会进行任何详细检查。如果有 - 任何疑问,把补丁寄给你自己,让你自己相信它是完好无损的。 + - 您确定您的邮件发送程序不会损坏补丁吗?被邮件客户端更改空白或修饰了行的补丁 + 无法被另一端接受,并且通常不会进行任何详细检查。如果有任何疑问,先把补丁寄 + 给你自己,让你自己确定它是完好无损的。 :ref:`Documentation/translations/zh_CN/process/email-clients.rst ` - 提供了一些有用的提示,可以让特定的邮件客户机工作以发送补丁。 + 提供了一些有用的提示,可以让特定的邮件客户端正常发送补丁。 - - 你确定你的补丁没有愚蠢的错误吗?您应该始终通过scripts/checkpatch.pl运行 - 补丁程序,并解决它提出的投诉。请记住,checkpatch.pl虽然是大量思考内核 - 补丁应该是什么样子的体现,但它并不比您聪明。如果修复checkpatch.pl投诉会 + - 你确定你的补丁没有荒唐的错误吗?您应该始终通过scripts/checkpatch.pl检查 + 补丁程序,并解决它提出的问题。请记住,checkpatch.pl,虽然体现了对内核补丁 + 应该是什么样的大量思考,但它并不比您聪明。如果修复checkpatch.pl给的问题会 使代码变得更糟,请不要这样做。 补丁应始终以纯文本形式发送。请不要将它们作为附件发送;这使得审阅者在答复中更难 引用补丁的部分。相反,只需将补丁直接放到您的消息中。 -邮寄补丁时,重要的是将副本发送给任何可能感兴趣的人。与其他一些项目不同,内核 -鼓励人们错误地发送过多的副本;不要假定相关人员会看到您在邮件列表中的发布。 +寄出补丁时,重要的是将副本发送给任何可能感兴趣的人。与其他一些项目不同,内核 +鼓励人们甚至错误地发送过多的副本;不要假定相关人员会看到您在邮件列表中的发布。 尤其是,副本应发送至: - - 受影响子系统的维护人员。如前所述,维护人员文件是查找这些人员的第一个地方。 + - 受影响子系统的维护人员。如前所述,维护人员文件是查找这些人员的首选地方。 - 其他在同一领域工作的开发人员,尤其是那些现在可能在那里工作的开发人员。使用 git查看还有谁修改了您正在处理的文件,这很有帮助。 - - 如果您对错误报告或功能请求做出响应,也可以抄送原始发送人。 + - 如果您对某错误报告或功能请求做出响应,也可以抄送原始发送人。 - - 将副本发送到相关邮件列表,或者,如果没有其他应用,则发送到Linux内核列表。 + - 将副本发送到相关邮件列表,或者若无相关列表,则发送到linux-kernel列表。 - - 如果您正在修复一个bug,请考虑该修复是否应进入下一个稳定更新。如果是这样, - stable@vger.kernel.org 应该得到补丁的副本。另外,在补丁本身的标签中添加 - 一个“cc:stable@vger.kernel.org”;这将使稳定团队在修复进入主线时收到通知。 + - 如果您正在修复一个缺陷,请考虑该修复是否应进入下一个稳定更新。如果是这样, + 补丁副本也应发到stable@vger.kernel.org 。另外,在补丁本身的标签中添加一个 + “Cc: stable@vger.kernel.org”;这将使稳定版团队在修复进入主线时收到通知。 -当为一个补丁选择接收者时,最好知道你认为谁最终会接受这个补丁并将其合并。虽然 -可以将补丁直接发送给LinusTorvalds并让他合并,但通常情况下不会这样做。Linus -很忙,并且有子系统维护人员负责监视内核的特定部分。通常您会希望维护人员合并您 -的补丁。如果没有明显的维护人员,Andrew Morton通常是最后的补丁目标。 +当为一个补丁选择接收者时,最好清楚你认为谁最终会接受这个补丁并将其合并。虽然 +可以将补丁直接发给Linus Torvalds并让他合并,但通常情况下不会这样做。Linus很 +忙,并且有子系统维护人员负责监视内核的特定部分。通常您会希望维护人员合并您的 +补丁。如果没有明显的维护人员,Andrew Morton通常是最后的补丁接收者。 -补丁需要好的主题行。补丁程序行的规范格式如下: +补丁需要好的主题行。补丁主题行的规范格式如下: :: [PATCH nn/mm] subsys: one-line description of the patch -其中“nn”是补丁的序号,“mm”是系列中补丁的总数,“subsys”是受影响子系统的名称。 -显然,一个单独的补丁可以省略nn/mm。 +其中“nn”是补丁的序号,“mm”是系列中补丁的总数,“subsys”是受影响子系统的 +名称。当然,一个单独的补丁可以省略nn/mm。 -如果您有一系列重要的补丁,那么通常将介绍性描述作为零部分发送。不过,这种约定 -并没有得到普遍遵循;如果您使用它,请记住简介中的信息不会使它进入内核变更日志。 +如果您有一系列重要的补丁,那么通常发送一个简介作为第〇部分。不过,这个约定 +并没有得到普遍遵循;如果您使用它,请记住简介中的信息不会进入内核变更日志。 因此,请确保补丁本身具有完整的变更日志信息。 一般来说,多部分补丁的第二部分和后续部分应作为对第一部分的回复发送,以便它们 在接收端都连接在一起。像git和coilt这样的工具有命令,可以通过适当的线程发送 -一组补丁。但是,如果您有一个长系列,并且正在使用git,请远离–chain reply-to -选项,以避免创建异常深的嵌套。 +一组补丁。但是,如果您有一长串补丁,并正使用git,请不要使用–-chain-reply-to +选项,以避免创建过深的嵌套。 -- cgit v1.2.3 From 1ba336902c7413f7dc6f45ab50fd87445d16c964 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:28:07 +0800 Subject: docs/zh_CN: Improve zh_CN/process/6.Followthrough Improve language and grammar of zh_CN/process/6.Followthrough.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/2024bbd647208fcb1c8b3db036e6f492bbdb2464.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/6.Followthrough.rst | 165 +++++++++++---------- 1 file changed, 86 insertions(+), 79 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/6.Followthrough.rst b/Documentation/translations/zh_CN/process/6.Followthrough.rst index f509e077e1cb..2a127e737b6a 100644 --- a/Documentation/translations/zh_CN/process/6.Followthrough.rst +++ b/Documentation/translations/zh_CN/process/6.Followthrough.rst @@ -1,145 +1,152 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/6.Followthrough.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_followthrough: 跟进 ==== -在这一点上,您已经遵循了到目前为止给出的指导方针,并且,随着您自己的工程技能 -的增加,已经发布了一系列完美的补丁。即使是经验丰富的内核开发人员也能犯的最大 -错误之一是,认为他们的工作现在已经完成了。事实上,发布补丁意味着进入流程的下 -一个阶段,可能还需要做很多工作。 +此时,您已经遵循了到目前为止给出的指导方针,并且,随着您自己的工程技能的增加, +已经发布了一系列完美的补丁。即使是经验丰富的内核开发人员也能犯的最大错误之一 +是,认为他们的工作现在已经完成了。事实上,发布补丁意味着进入流程的下一个阶段, +可能还需要做很多工作。 -一个补丁在第一次发布时就非常出色,没有改进的余地,这是很罕见的。内核开发流程 -认识到这一事实,因此,它非常注重对已发布代码的改进。作为代码的作者,您应该与 +一个补丁在首次发布时就非常出色、没有改进的余地,这是很罕见的。内核开发流程已 +认识到这一事实,因此它非常注重对已发布代码的改进。作为代码的作者,您应该与 内核社区合作,以确保您的代码符合内核的质量标准。如果不参与这个过程,很可能会 -阻止将补丁包含到主线中。 +无法将补丁合并到主线中。 与审阅者合作 ------------ 任何意义上的补丁都会导致其他开发人员在审查代码时发表大量评论。对于许多开发 -人员来说,与审查人员合作可能是内核开发过程中最令人生畏的部分。但是,如果你 +人员来说,与审阅人员合作可能是内核开发过程中最令人生畏的部分。但是如果你 记住一些事情,生活会变得容易得多: - - 如果你已经很好地解释了你的补丁,评论人员会理解它的价值,以及为什么你会 - 费尽心思去写它。但是这个并不能阻止他们提出一个基本的问题:五年或十年后 - 用这个代码维护一个内核会是什么感觉?你可能被要求做出的许多改变——从编码风格 - 的调整到大量的重写——都来自于对Linux的理解,即从现在起十年后,Linux仍将在 - 开发中。 + - 如果你已经很好地解释了你的补丁,审阅人员会理解它的价值,以及为什么你会 + 费尽心思去写它。但是这个并不能阻止他们提出一个基本的问题:在五年或十年后 + 维护含有此代码的内核会怎么样?你可能被要求做出的许多改变——从编码风格的 + 调整到大量的重写——都来自于对Linux的理解,即从现在起十年后,Linux仍将 + 在开发中。 - 代码审查是一项艰苦的工作,这是一项相对吃力不讨好的工作;人们记得谁编写了 - 内核代码,但对于那些审查它的人来说,几乎没有什么持久的名声。因此,评论 + 内核代码,但对于那些审查它的人来说,几乎没有什么长久的名声。因此,审阅 人员可能会变得暴躁,尤其是当他们看到同样的错误被一遍又一遍地犯下时。如果 - 你得到了一个看起来愤怒、侮辱或完全冒犯你的评论,抵制以同样方式回应的冲动。 - 代码审查是关于代码的,而不是关于人的,代码审查人员不会亲自攻击您。 + 你得到了一个看起来愤怒、侮辱或完全冒犯你的评论,请抑制以同样方式回应的冲动。 + 代码审查是关于代码的,而不是关于人的,代码审阅人员不会亲自攻击您。 - - 同样,代码审查人员也不想以牺牲你雇主的利益为代价来宣传他们雇主的议程。 + - 同样,代码审阅人员也不想以牺牲你雇主的利益为代价来宣传他们雇主的议程。 内核开发人员通常希望今后几年能在内核上工作,但他们明白他们的雇主可能会改 变。他们真的,几乎毫无例外地,致力于创造他们所能做到的最好的内核;他们并 没有试图给雇主的竞争对手造成不适。 -所有这些归根结底都是,当审阅者向您发送评论时,您需要注意他们正在进行的技术 -观察。不要让他们的表达方式或你自己的骄傲阻止这种事情的发生。当你在一个补丁 -上得到评论时,花点时间去理解评论人想说什么。如果可能的话,请修复审阅者要求 -您修复的内容。然后回复审稿人:谢谢他们,并描述你将如何回答他们的问题。 +所有这些归根结底就是,当审阅者向您发送评论时,您需要注意他们正在进行的技术 +评论。不要让他们的表达方式或你自己的骄傲阻止此事。当你在一个补丁上得到评论 +时,花点时间去理解评论人想说什么。如果可能的话,请修复审阅者要求您修复的内 +容。然后回复审阅者:谢谢他们,并描述你将如何回答他们的问题。 请注意,您不必同意审阅者建议的每个更改。如果您认为审阅者误解了您的代码,请 解释到底发生了什么。如果您对建议的更改有技术上的异议,请描述它并证明您对该 -问题的解决方案是正确的。如果你的解释有道理,审稿人会接受的。不过,如果你的 -解释不能证明是有说服力的,尤其是当其他人开始同意审稿人的观点时,请花些时间 -重新考虑一下。你很容易对自己解决问题的方法视而不见,以至于你没有意识到某个 -问题根本是错误的,或者你甚至没有解决正确的问题。 +问题的解决方案是正确的。如果你的解释有道理,审阅者会接受的。不过,如果你的 +解释证明缺乏说服力,尤其是当其他人开始同意审稿人的观点时,请花些时间重新考虑 +一下。你很容易对自己解决问题的方法视而不见,以至于你没有意识到某些东西完全 +是错误的,或者你甚至没有解决正确的问题。 -Andrew Morton建议,每一条不会导致代码更改的评论都应该导致额外的代码注释; -这可以帮助未来的评论人员避免出现第一次出现的问题。 +Andrew Morton建议,每一个不会导致代码更改的审阅评论都应该产生一个额外的代码 +注释;这可以帮助未来的审阅人员避免第一次出现的问题。 -一个致命的错误是忽视评论,希望它们会消失。他们不会走的。如果您在没有对之前 -收到的注释做出响应的情况下重新发布代码,那么很可能会发现补丁毫无用处。 +一个致命的错误是忽视评论,希望它们会消失。它们不会走的。如果您在没有对之前 +收到的评论做出响应的情况下重新发布代码,那么很可能会发现补丁毫无用处。 说到重新发布代码:请记住,审阅者不会记住您上次发布的代码的所有细节。因此, -提醒审查人员以前提出的问题以及您如何处理这些问题总是一个好主意;补丁变更 +提醒审阅人员以前提出的问题以及您如何处理这些问题总是一个好主意;补丁变更 日志是提供此类信息的好地方。审阅者不必搜索列表档案来熟悉上次所说的内容; -如果您帮助他们开始运行,当他们重新访问您的代码时,他们的心情会更好。 +如果您帮助他们直接开始,当他们重新查看您的代码时,心情会更好。 如果你已经试着做正确的事情,但事情仍然没有进展呢?大多数技术上的分歧都可以 -通过讨论来解决,但有时人们只需要做出决定。如果你真的认为这个决定对你不利, -你可以试着向更高的权力上诉。在这篇文章中,更高的权力倾向于Andrew Morton。 -Andrew在内核开发社区中受i很大的尊重;他经常为似乎被绝望地阻塞事情清障。 -尽管如此,对Andrew的呼吁不应轻而易举,也不应在所有其他替代方案都被探索之前 -使用。当然,记住,他也可能不同意你的意见。 +通过讨论来解决,但有时人们仍需要做出决定。如果你真的认为这个决定对你不利, +你可以试着向有更高权力的人上诉。对于本文,更高权力的人是 Andrew Morton 。 +Andrew 在内核开发社区中非常受尊敬;他经常为似乎被绝望阻塞的事情清障。尽管 +如此,不应轻易就直接找 Andrew ,也不应在所有其他替代方案都被尝试之前找他。 +当然,记住,他也可能不同意你的意见。 接下来会发生什么 ---------------- -如果一个补丁被认为是添加到内核中的一件好事,并且一旦大多数审查问题得到解决, -下一步通常是进入子系统维护人员的树中。工作方式因子系统而异;每个维护人员都 -有自己的工作方式。特别是,可能有不止一棵树——一棵树,也许,专门用于计划下一 -个合并窗口的补丁,另一棵树用于长期工作。 +如果一个补丁被认为适合添加到内核中,并且大多数审查问题得到解决,下一步通常 +是进入子系统维护人员的树中。工作方式因子系统而异;每个维护人员都有自己的 +工作方式。特别是可能有不止一棵树——也许一棵树专门用于计划下一个合并窗口的 +补丁,另一棵树用于长期工作。 -对于应用于没有明显子系统树(例如内存管理修补程序)的区域的修补程序,默认树 -通常以-mm结尾。影响多个子系统的补丁也可以最终通过-mm树。 +对于应用到不属于明显子系统树(例如内存管理修补程序)的区域的修补程序,默认树 +通常上溯到-mm。影响多个子系统的补丁也可以最终进入-mm树。 包含在子系统树中可以提高补丁的可见性。现在,使用该树的其他开发人员将默认获 得补丁。子系统树通常也为Linux提供支持,使其内容对整个开发社区可见。在这一点 上,您很可能会从一组新的审阅者那里得到更多的评论;这些评论需要像上一轮那样 -得到回答。 +得到回应。 -在这一点上也会发生什么,这取决于你的补丁的性质,是与其他人正在做的工作发生 +在这时也会发生点什么,这取决于你的补丁的性质,是否与其他人正在做的工作发生 冲突。在最坏的情况下,严重的补丁冲突可能会导致一些工作被搁置,以便剩余的补丁 可以成形并合并。另一些时候,冲突解决将涉及到与其他开发人员合作,可能还会 在树之间移动一些补丁,以确保所有的应用都是干净的。这项工作可能是一件痛苦的 -事情,但要计算您的福祉:在Linux下一棵树出现之前,这些冲突通常只在合并窗口 -中出现,必须迅速解决。现在可以在合并窗口打开之前,在空闲时解决这些问题。 +事情,但也需庆幸现在的幸福:在linux-next树出现之前,这些冲突通常只在合并窗口 +中出现,必须迅速解决。现在可以在合并窗口打开之前的空闲时间解决这些问题。 有朝一日,如果一切顺利,您将登录并看到您的补丁已经合并到主线内核中。祝贺你! -然而,一旦庆祝活动完成(并且您已经将自己添加到维护人员文件中),就值得记住 -一个重要的小事实:工作仍然没有完成。并入主线带来了自身的挑战。 +然而,一旦庆祝完了(并且您已经将自己添加到维护人员文件中),就一定要记住 +一个重要的小事实:工作仍然没有完成。并入主线也带来了它的挑战。 -首先,补丁的可见性再次提高。可能会有新一轮的开发者评论,他们以前不知道这 -个补丁。忽略它们可能很有诱惑力,因为您的代码不再存在任何被合并的问题。但是, -要抵制这种诱惑,您仍然需要对有问题或建议的开发人员作出响应。 +首先,补丁的可见性再次提高。可能会有以前不知道这个补丁的开发者的新一轮评论。 +忽略它们可能很有诱惑力,因为您的代码不再存在任何被合并的问题。但是,要抵制 +这种诱惑,您仍然需要对有问题或建议的开发人员作出响应。 -不过,更重要的是:将代码包含在主线中会将代码交给更大的一组测试人员。即使您 -为尚未提供的硬件提供了驱动程序,您也会惊讶于有多少人会将您的代码构建到内核 -中。当然,如果有测试人员,也会有错误报告。 +不过,更重要的是:将代码包含在主线中会将代码交给更多的一些测试人员。即使您 +为尚未可用的硬件提供了驱动程序,您也会惊讶于有多少人会将您的代码构建到内核 +中。当然,如果有测试人员,也可能会有错误报告。 -最糟糕的错误报告是回归。如果你的补丁导致回归,你会发现很多不舒服的眼睛盯着 -你;回归需要尽快修复。如果您不愿意或无法修复回归(其他人都不会为您修复), +最糟糕的错误报告是回归。如果你的补丁导致回归,你会发现多到让你不舒服的眼睛盯 +着你;回归需要尽快修复。如果您不愿意或无法修复回归(其他人都不会为您修复), 那么在稳定期内,您的补丁几乎肯定会被移除。除了否定您为使补丁进入主线所做的 -所有工作之外,如果由于未能修复回归而取消补丁,很可能会使将来的工作更难合并。 +所有工作之外,如果由于未能修复回归而取消补丁,很可能会使将来的工作更难被合并。 -在处理完任何回归之后,可能还有其他普通的bug需要处理。稳定期是修复这些错误并 -确保代码在主线内核版本中的首次发布尽可能可靠的最好机会。所以,请回答错误 +在处理完任何回归之后,可能还有其他普通缺陷需要处理。稳定期是修复这些错误并 +确保代码在主线内核版本中的首次发布尽可能可靠的最好机会。所以,请回应错误 报告,并尽可能解决问题。这就是稳定期的目的;一旦解决了旧补丁的任何问题,就 -可以开始创建酷的新补丁。 +可以开始尽情创建新补丁。 -别忘了,还有其他里程碑也可能会创建bug报告:下一个主线稳定版本,当著名的发行 -商选择包含补丁的内核版本时,等等。继续响应这些报告是您工作的基本骄傲。但是, -如果这不是足够的动机,那么也值得考虑的是,开发社区会记住那些在合并后对代码 -失去兴趣的开发人员。下一次你发布补丁时,他们会以你以后不会在身边维护它为假 -设来评估它。 +别忘了,还有其他节点也可能会创建缺陷报告:下一个主线稳定版本,当著名的发行 +商选择包含您补丁的内核版本时等等。继续响应这些报告是您工作的基本素养。但是 +如果这不能提供足够的动机,那么也需要考虑:开发社区会记住那些在合并后对代码 +失去兴趣的开发人员。下一次你发布补丁时,他们会以你以后不会持续维护它为前提 +来评估它。 其他可能发生的事情 ------------------ -有一天,你可以打开你的邮件客户端,看到有人给你寄了一个代码补丁。毕竟,这是 +某天,当你打开你的邮件客户端时,看到有人给你寄了一个代码补丁。毕竟,这是 让您的代码公开存在的好处之一。如果您同意这个补丁,您可以将它转发给子系统 -维护人员(确保包含一个正确的From:行,这样属性是正确的,并添加一个您自己 -的签准),或者回复一个Acked-by,让原始发送者向上发送它。 +维护人员(确保包含一个正确的From:行,这样属性是正确的,并添加一个您自己的 +signoff ),或者回复一个 Acked-by: 让原始发送者向上发送它。 -如果您不同意补丁,请发送一个礼貌的回复,解释原因。如果可能的话,告诉作者需要 -做哪些更改才能让您接受补丁。对于代码的编写者和维护者所反对的合并补丁,存在着 -一定的阻力,但仅此而已。如果你被认为不必要的阻碍了好的工作,那么这些补丁最 -终会经过你身边并进入主线。在Linux内核中,没有人对任何代码拥有绝对的否决权。 -除了Linus。 +如果您不同意补丁,请礼貌地回复,解释原因。如果可能的话,告诉作者需要做哪些 +更改才能让您接受补丁。合并代码的编写者和维护者所反对的补丁的确存在着一定的 +阻力,但仅此而已。如果你被认为不必要的阻碍了好的工作,那么这些补丁最终会 +绕过你并进入主线。在Linux内核中,没有人对任何代码拥有绝对的否决权。可能除 +了Linus。 在非常罕见的情况下,您可能会看到完全不同的东西:另一个开发人员发布了针对您 -的问题的不同解决方案。在这一点上,两个补丁中的一个可能不会合并,“我的在这里 -是第一个”不被认为是一个令人信服的技术论据。如果有人的补丁取代了你的补丁而进 -入了主线,那么只有一种方法可以回应你:高兴你的问题得到解决,继续你的工作。 -以这种方式把一个人的工作推到一边可能会伤害和气馁,但是在他们忘记了谁的补丁 -真正被合并很久之后,社区会记住你的反应。 +的问题的不同解决方案。在这时,两个补丁之一可能不会被合并,“我的补丁首先 +发布”不被认为是一个令人信服的技术论据。如果有别人的补丁取代了你的补丁而进 +入了主线,那么只有一种方法可以回应你:很高兴你的问题解决了,请继续工作吧。 +以这种方式把某人的工作推到一边可能导致伤心和气馁,但是社区会记住你的反应, +即使很久以后他们已经忘记了谁的补丁真正被合并。 -- cgit v1.2.3 From dc4bdca8c365522da49b941d8f67ab0714952f7d Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:28:26 +0800 Subject: docs/zh_CN: Improve zh_CN/process/7.AdvancedTopics Improve language and grammar of zh_CN/process/7.AdvancedTopics.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/e1579cfc77eb0cc31fb7402e8742dbc364b9086e.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../zh_CN/process/7.AdvancedTopics.rst | 141 +++++++++++---------- 1 file changed, 75 insertions(+), 66 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/7.AdvancedTopics.rst b/Documentation/translations/zh_CN/process/7.AdvancedTopics.rst index 2f0ef750746f..6d0dadae13b1 100644 --- a/Documentation/translations/zh_CN/process/7.AdvancedTopics.rst +++ b/Documentation/translations/zh_CN/process/7.AdvancedTopics.rst @@ -1,7 +1,14 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/7.AdvancedTopics.rst ` -:Translator: Alex Shi + +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_advancedtopics: @@ -15,110 +22,112 @@ --------------- 内核使用分布式版本控制始于2002年初,当时Linus首次开始使用专有的Bitkeeper应用 -程序。虽然bitkeeper存在争议,但它所体现的软件版本管理方法却肯定不是。分布式 -版本控制可以立即加速内核开发项目。在当前的时代,有几种免费的比特保持器替代品。 -无论好坏,内核项目都将Git作为其选择的工具。 +程序。虽然BitKeeper存在争议,但它所体现的软件版本管理方法却肯定不是。分布式 +版本控制可以立即加速内核开发项目。现在有好几种免费的BitKeeper替代品。 +但无论好坏,内核项目都已经选择了Git作为其工具。 -使用Git管理补丁可以使开发人员的生活更加轻松,尤其是随着补丁数量的增加。Git -也有其粗糙的边缘和一定的危险,它是一个年轻和强大的工具,仍然在其开发人员完善 +使用Git管理补丁可以使开发人员的生活更加轻松,尤其是随着补丁数量的增长。Git也 +有其粗糙的边角和一定的危险性,它是一个年轻和强大的工具,仍然在其开发人员完善 中。本文档不会试图教会读者如何使用git;这会是个巨长的文档。相反,这里的重点 -将是Git如何特别适合内核开发过程。想要加快Git的开发人员可以在以下网站上找到 -更多信息: +将是Git如何特别适合内核开发过程。想要加快用Git速度的开发人员可以在以下网站上 +找到更多信息: https://git-scm.com/ https://www.kernel.org/pub/software/scm/git/docs/user-manual.html -在尝试使用它使补丁可供其他人使用之前,第一要务是阅读上述站点,对Git的工作 -方式有一个扎实的了解。使用Git的开发人员应该能够获得主线存储库的副本,探索 -修订历史,提交对树的更改,使用分支等。了解Git用于重写历史的工具(如Rebase) -也很有用。Git有自己的术语和概念;Git的新用户应该了解refs、远程分支、索引、 -快进合并、推拉、分离头等。一开始可能有点吓人,但这些概念不难通过一点学习来 +同时网上也能找到各种各样的教程。 + +在尝试使用它生成补丁供他人使用之前,第一要务是阅读上述网页,对Git的工作方式 +有一个扎实的了解。使用Git的开发人员应能进行拉取主线存储库的副本,查询修订 +历史,提交对树的更改,使用分支等操作。了解Git用于重写历史的工具(如rebase) +也很有用。Git有自己的术语和概念;Git的新用户应该了解引用、远程分支、索引、 +快进合并、推拉、游离头等。一开始可能有点吓人,但这些概念不难通过一点学习来 理解。 使用git生成通过电子邮件提交的补丁是提高速度的一个很好的练习。 -当您准备好开始安装Git树供其他人查看时,您当然需要一个可以从中提取的服务器。 -如果您有一个可以访问Internet的系统,那么使用git守护进程设置这样的服务器相 -对简单。否则,免费的公共托管网站(例如github)开始出现在网络上。成熟的开发 -人员可以在kernel.org上获得一个帐户,但这些帐户并不容易找到;有关更多信息, -请参阅 https://kernel.org/faq/ +当您准备好开始建立Git树供其他人查看时,无疑需要一个可以从中拉取的服务器。 +如果您有一个可以访问因特网的系统,那么使用git-daemon设置这样的服务器相对 +简单。同时,免费的公共托管网站(例如github)也开始出现在网络上。成熟的开发 +人员可以在kernel.org上获得一个帐户,但这些帐户并不容易得到;更多有关信息, +请参阅 https://kernel.org/faq/ 。 正常的Git工作流程涉及到许多分支的使用。每一条开发线都可以分为单独的“主题 -分支”,并独立维护。Git的分支机构很便宜,没有理由不免费使用它们。而且,在 -任何情况下,您都不应该在任何您打算让其他人从中受益的分支中进行开发。应该 -小心地创建公开可用的分支;当它们处于完整的形式并准备好运行时(而不是之前), -合并开发分支的补丁。 +分支”,并独立维护。Git的分支很容易使用,没有理由不使用它们。而且,在任何 +情况下,您都不应该在任何您打算让其他人从中拉取的分支中进行开发。应该小心地 +创建公开可用的分支;当开发分支处于完整状态并已准备好时(而不是之前)才合并 +开发分支的补丁。 Git提供了一些强大的工具,可以让您重写开发历史。一个不方便的补丁(比如说, 一个打破二分法的补丁,或者有其他一些明显的缺陷)可以在适当的位置修复,或者 -完全从历史中消失。一个补丁系列可以被重写,就好像它是在今天的主线之上写的 -一样,即使你已经花了几个月的时间在写它。可以透明地将更改从一个分支转移到另 -一个分支。等等。明智地使用git修改历史的能力可以帮助创建问题更少的干净补丁集。 +完全从历史中消失。一个补丁系列可以被重写,就好像它是在今天的主线上写的一样, +即使你已经花了几个月的时间在写它。可以透明地将更改从一个分支转移到另一个 +分支。等等。明智地使用git修改历史的能力可以帮助创建问题更少的干净补丁集。 -然而,过度使用这种能力可能会导致其他问题,而不仅仅是对创建完美项目历史的 -简单痴迷。重写历史将重写该历史中包含的更改,将经过测试(希望)的内核树变 -为未经测试的内核树。但是,除此之外,如果开发人员没有对项目历史的共享视图, -他们就无法轻松地协作;如果您重写了其他开发人员拉入他们存储库的历史,您将 -使这些开发人员的生活更加困难。因此,这里有一个简单的经验法则:被导出到其他 -人的历史在此后通常被认为是不可变的。 +然而,过度使用这种功能可能会导致其他问题,而不仅仅是对创建完美项目历史的 +简单痴迷。重写历史将重写该历史中包含的更改,将经过测试(希望如此)的内核树 +变为未经测试的内核树。除此之外,如果开发人员没有共享项目历史,他们就无法 +轻松地协作;如果您重写了其他开发人员拉入他们存储库的历史,您将使这些开发 +人员的生活更加困难。因此,这里有一个简单的经验法则:被导出到其他地方的历史 +在此后通常被认为是不可变的。 因此,一旦将一组更改推送到公开可用的服务器上,就不应该重写这些更改。如果您 -尝试强制进行不会导致快进合并(即不共享同一历史记录的更改)的更改,Git将尝 -试强制执行此规则。可以重写此检查,有时可能需要重写导出的树。在树之间移动变 -更集以避免Linux-next中的冲突就是一个例子。但这种行为应该是罕见的。这就是为 -什么开发应该在私有分支中进行(必要时可以重写)并且只有在公共分支处于合理的 -高级状态时才转移到公共分支中的原因之一。 +尝试强制进行无法快进合并的更改(即不共享同一历史记录的更改),Git将尝试强制 +执行此规则。这可能覆盖检查,有时甚至需要重写导出的树。在树之间移动变更集以 +避免linux-next中的冲突就是一个例子。但这种行为应该是罕见的。这就是为什么 +开发应该在私有分支中进行(必要时可以重写)并且只有在公共分支处于合理的较新 +状态时才转移到公共分支中的原因之一。 当主线(或其他一组变更所基于的树)前进时,很容易与该树合并以保持领先地位。 对于一个私有的分支,rebasing 可能是一个很容易跟上另一棵树的方法,但是一旦 -一棵树被导出到全世界,rebasing就不是一个选项。一旦发生这种情况,就必须进行 -完全合并(merge)。合并有时是很有意义的,但是过于频繁的合并会不必要地扰乱 -历史。在这种情况下,建议的技术是不经常合并,通常只在特定的发布点(如主线-rc -发布)合并。如果您对特定的更改感到紧张,则可以始终在私有分支中执行测试合并。 -在这种情况下,git rerere 工具很有用;它记住合并冲突是如何解决的,这样您就 -不必重复相同的工作。 +一棵树被导出到外界,rebasing就不可取了。一旦发生这种情况,就必须进行完全 +合并(merge)。合并有时是很有意义的,但是过于频繁的合并会不必要地扰乱历史。 +在这种情况下建议的做法是不要频繁合并,通常只在特定的发布点(如主线-rc发布) +合并。如果您对特定的更改感到紧张,则可以始终在私有分支中执行测试合并。在 +这种情况下,git“rerere”工具很有用;它能记住合并冲突是如何解决的,这样您 +就不必重复相同的工作。 关于Git这样的工具的一个最大的反复抱怨是:补丁从一个存储库到另一个存储库的 大量移动使得很容易陷入错误建议的变更中,这些变更避开审查雷达进入主线。当内 -核开发人员看到这种情况发生时,他们往往会感到不高兴;在Git树上放置未查看或 -主题外的补丁可能会影响您将来获取树的能力。引用Linus: +核开发人员看到这种情况发生时,他们往往会感到不高兴;在Git树上放置未审阅或 +主题外的补丁可能会影响您将来让树被拉取的能力。引用Linus的话: :: - 你可以给我发补丁,但要我从你哪里取一个Git补丁,我需要知道你知道 - 你在做什么,我需要能够相信事情而不去检查每个个人改变。 + 你可以给我发补丁,但当我从你那里拉取一个Git补丁时,我需要知道你清楚 + 自己在做什么,我需要能够相信事情而 *无需* 手动检查每个单独的更改。 (http://lwn.net/articles/224135/)。 为了避免这种情况,请确保给定分支中的所有补丁都与相关主题紧密相关;“驱动程序 修复”分支不应更改核心内存管理代码。而且,最重要的是,不要使用Git树来绕过 -审查过程。不时的将树的摘要发布到相关的列表中,当时间合适时,请求 -Linux-next 中包含该树。 +审查过程。不时的将树的摘要发布到相关的列表中,在合适时候请求linux-next中 +包含该树。 -如果其他人开始发送补丁以包含到您的树中,不要忘记查看它们。还要确保您维护正确 -的作者信息; ``git am`` 工具在这方面做得最好,但是如果它通过第三方转发给您, -您可能需要在补丁中添加“From:”行。 +如果其他人开始发送补丁以包含到您的树中,不要忘记审阅它们。还要确保您维护正确 +的作者信息; git “am”工具在这方面做得最好,但是如果补丁通过第三方转发给您, +您可能需要在补丁中添加“From:”行。 -请求pull操作时,请务必提供所有相关信息:树的位置、要拉的分支以及拉操作将导致 -的更改。在这方面,git request pull 命令非常有用;它将按照其他开发人员的预期 -格式化请求,并检查以确保您记住了将这些更改推送到公共服务器。 +请求拉取时,请务必提供所有相关信息:树的位置、要拉取的分支以及拉取将导致的 +更改。在这方面 git request-pull 命令非常有用;它将按照其他开发人员所期望的 +格式化请求,并检查以确保您已记得将这些更改推送到公共服务器。 -审查补丁 +审阅补丁 -------- -一些读者当然会反对将本节与“高级主题”放在一起,因为即使是刚开始的内核开发人员 -也应该检查补丁。当然,学习如何在内核环境中编程没有比查看其他人发布的代码更好 -的方法了。此外,审阅者永远供不应求;通过查看代码,您可以对整个流程做出重大贡献。 +一些读者显然会反对将本节与“高级主题”放在一起,因为即使是刚开始的内核开发人员 +也应该审阅补丁。当然,没有比查看其他人发布的代码更好的方法来学习如何在内核环境 +中编程了。此外,审阅者永远供不应求;通过审阅代码,您可以对整个流程做出重大贡献。 -审查代码可能是一个令人生畏的前景,特别是对于一个新的内核开发人员来说,他们 +审查代码可能是一副令人生畏的图景,特别是对一个新的内核开发人员来说,他们 可能会对公开询问代码感到紧张,而这些代码是由那些有更多经验的人发布的。不过, -即使是最有经验的开发人员编写的代码也可以得到改进。也许对评审员(所有评审员) -最好的建议是:把评审评论当成问题而不是批评。询问“在这条路径中如何释放锁?” +即使是最有经验的开发人员编写的代码也可以得到改进。也许对(所有)审阅者最好 +的建议是:把审阅评论当成问题而不是批评。询问“在这条路径中如何释放锁?” 总是比说“这里的锁是错误的”更好。 -不同的开发人员将从不同的角度审查代码。一些主要关注的是编码样式以及代码行是 -否有尾随空格。其他人将主要关注补丁作为一个整体实现的变更是否对内核有好处。 -然而,其他人会检查是否存在锁定问题、堆栈使用过度、可能的安全问题、在其他 -地方发现的代码重复、足够的文档、对性能的不利影响、用户空间ABI更改等。所有 -类型的检查,如果它们导致更好的代码进入内核,都是受欢迎和值得的。 +不同的开发人员将从不同的角度审查代码。部分人会主要关注代码风格以及代码行是 +否有尾随空格。其他人会主要关注补丁作为一个整体实现的变更是否对内核有好处。 +同时也有人会检查是否存在锁问题、堆栈使用过度、可能的安全问题、在其他地方 +发现的代码重复、足够的文档、对性能的不利影响、用户空间ABI更改等。所有类型 +的检查,只要它们能引导更好的代码进入内核,都是受欢迎和值得的。 -- cgit v1.2.3 From 6dbc975f4845d0326cfc82fc8b0246ce97bf84f8 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Fri, 5 Mar 2021 13:28:48 +0800 Subject: docs/zh_CN: Improve zh_CN/process/8.Conclusion.rst Improve language and grammar of zh_CN/process/8.Conclusion.rst Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/8311d04c5528442ecae241062fbb1a7eded0b4f6.1614920267.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/process/8.Conclusion.rst | 60 ++++++++++++---------- 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/process/8.Conclusion.rst b/Documentation/translations/zh_CN/process/8.Conclusion.rst index 90cec3de6106..71c3e30efc6f 100644 --- a/Documentation/translations/zh_CN/process/8.Conclusion.rst +++ b/Documentation/translations/zh_CN/process/8.Conclusion.rst @@ -1,7 +1,13 @@ .. include:: ../disclaimer-zh_CN.rst :Original: :ref:`Documentation/process/8.Conclusion.rst ` -:Translator: Alex Shi +:Translator: + + 时奎亮 Alex Shi + +:校译: + + 吴想成 Wu XiangCheng .. _cn_development_conclusion: @@ -9,56 +15,56 @@ ======== 关于Linux内核开发和相关主题的信息来源很多。首先是在内核源代码分发中找到的 -文档目录。顶级 :ref:`Documentation/translations/zh_CN/process/howto.rst ` -文件是一个重要的起点 +文档目录。顶级 +:ref:`Documentation/translations/zh_CN/process/howto.rst ` +文件是一个重要的起点; :ref:`Documentation/translations/zh_CN/process/submitting-patches.rst ` -和 :ref:`process/submitting-drivers.rst ` +和 :ref:`Documentation/transaltions/zh_CN/process/submitting-drivers.rst ` 也是所有内核开发人员都应该阅读的内容。许多内部内核API都是使用kerneldoc机制 -记录的;“make htmldocs”或“make pdfdocs”可用于以HTML或PDF格式生成这些文档( -尽管某些发行版提供的tex版本会遇到内部限制,无法正确处理文档)。 +记录的;“make htmldocs”或“make pdfdocs”可用于以HTML或PDF格式生成这些文档 +(尽管某些发行版提供的tex版本会遇到内部限制,无法正确处理文档)。 -不同的网站在各个细节层次上讨论内核开发。您的作者想谦虚地建议用 https://lwn.net/ -作为来源;有关许多特定内核主题的信息可以通过以下网址的lwn内核索引找到: +不同的网站在各个细节层次上讨论内核开发。本文作者想谦虚地建议用 https://lwn.net/ +作为来源;有关许多特定内核主题的信息可以通过以下网址的 LWN 内核索引找到: - http://lwn.net/kernel/index/ + http://lwn.net/kernel/index/ 除此之外,内核开发人员的一个宝贵资源是: - https://kernelnewbies.org/ + https://kernelnewbies.org/ -当然,我们不应该忘记 https://kernel.org/ 这是内核发布信息的最终位置。 +当然,也不应该忘记 https://kernel.org/ ,这是内核发布信息的最终位置。 关于内核开发有很多书: - Linux设备驱动程序,第三版(Jonathan Corbet、Alessandro Rubini和Greg Kroah Hartman)。 - 在线:http://lwn.net/kernel/ldd3/ + 《Linux设备驱动程序》第三版(Jonathan Corbet、Alessandro Rubini和Greg Kroah Hartman) + 线上版本在 http://lwn.net/kernel/ldd3/ - Linux内核开发(Robert Love)。 + 《Linux内核设计与实现》(Robert Love) - 了解Linux内核(Daniel Bovet和Marco Cesati)。 + 《深入理解Linux内核》(Daniel Bovet和Marco Cesati) -然而,所有这些书都有一个共同的缺点:当它们上架时,它们往往有些过时,而且它们 -已经上架一段时间了。不过,在那里还可以找到相当多的好信息。 +然而,所有这些书都有一个共同的缺点:它们上架时就往往有些过时,而且已经上架 +一段时间了。不过,在那里还是可以找到相当多的好信息。 有关git的文档,请访问: - https://www.kernel.org/pub/software/scm/git/docs/ + https://www.kernel.org/pub/software/scm/git/docs/ - https://www.kernel.org/pub/software/scm/git/docs/user-manual.html + https://www.kernel.org/pub/software/scm/git/docs/user-manual.html 结论 ==== -祝贺所有通过这篇冗长的文件的人。希望它能够帮助您理解Linux内核是如何开发的, +祝贺所有通过这篇冗长的文档的人。希望它能够帮助您理解Linux内核是如何开发的, 以及您如何参与这个过程。 -最后,重要的是参与。任何开源软件项目都不超过其贡献者投入其中的总和。Linux内核 -的发展速度和以前一样快,因为它得到了大量开发人员的帮助,他们都在努力使它变得 -更好。内核是一个主要的例子,说明当成千上万的人为了一个共同的目标一起工作时, -可以做些什么。 +最后,重要的是参与。任何开源软件项目都不会超过其贡献者投入其中的总和。Linux +内核的发展速度和以前一样快,因为它得到了大量开发人员的帮助,他们都在努力使它 +变得更好。内核是一个最成功的例子,说明了当成千上万的人为了一个共同的目标一起 +工作时,可以做出什么。 -不过,内核总是可以从更大的开发人员基础中获益。总有更多的工作要做。但是,同样 +不过,内核总是可以从更大的开发人员基础中获益。总有更多的工作要做。但是同样 重要的是,Linux生态系统中的大多数其他参与者可以通过为内核做出贡献而受益。使 代码进入主线是提高代码质量、降低维护和分发成本、提高对内核开发方向的影响程度 -等的关键。这是一种人人都赢的局面。踢开你的编辑,来加入我们吧,你会非常受 -欢迎的。 +等的关键。这是一种共赢的局面。启动你的编辑器,来加入我们吧;你会非常受欢迎的。 -- cgit v1.2.3 From 4eba99315c9fb3c684a054a4a33dfb15709598b5 Mon Sep 17 00:00:00 2001 From: hjh Date: Thu, 4 Mar 2021 17:45:55 +0800 Subject: PATCH Documentation translations:translate sound/hd-audio/controls to chinese Signed-off-by: hjh Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210304094556.5858-1-huangjianghui@uniontech.com Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/index.rst | 1 + .../translations/zh_CN/sound/hd-audio/controls.rst | 102 +++++++++++++++++++++ .../translations/zh_CN/sound/hd-audio/index.rst | 14 +++ Documentation/translations/zh_CN/sound/index.rst | 22 +++++ 4 files changed, 139 insertions(+) create mode 100644 Documentation/translations/zh_CN/sound/hd-audio/controls.rst create mode 100644 Documentation/translations/zh_CN/sound/hd-audio/index.rst create mode 100644 Documentation/translations/zh_CN/sound/index.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst index be6f11176200..2767dacfe86d 100644 --- a/Documentation/translations/zh_CN/index.rst +++ b/Documentation/translations/zh_CN/index.rst @@ -20,6 +20,7 @@ process/index filesystems/index arm64/index + sound/index 目录和表格 ---------- diff --git a/Documentation/translations/zh_CN/sound/hd-audio/controls.rst b/Documentation/translations/zh_CN/sound/hd-audio/controls.rst new file mode 100644 index 000000000000..54c028ab9a40 --- /dev/null +++ b/Documentation/translations/zh_CN/sound/hd-audio/controls.rst @@ -0,0 +1,102 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Chinese translator: Huang Jianghui +--------------------------------------------------------------------- +.. include:: ../../disclaimer-zh_CN.rst +以下为正文 +--------------------------------------------------------------------- +====================================== +高清音频编解码器特定混音器控件 +====================================== + + +此文件解释特定于编解码器的混音器控件. + +瑞昱编解码器 +------------ + +声道模式 + 这是一个用于更改环绕声道设置的枚举控件,仅在环绕声道打开时显示出现。 + 它给出要使用的通道数:"2ch","4ch","6ch",和"8ch"。根据配置,这还控 + 制多I/O插孔的插孔重分配。 + +自动静音模式 + 这是一个枚举控件,用于更改耳机和线路输出插孔的自动静音行为。如果内 + 置扬声器、耳机和/或线路输出插孔在机器上可用,则显示该控件。当只有 + 耳机或者线路输出的时候,它给出”禁用“和”启用“状态。当启用后,插孔插 + 入后扬声器会自动静音。 + + 当耳机和线路输出插孔都存在时,它给出”禁用“、”仅扬声器“和”线路输出+扬 + 声器“。当”仅扬声器“被选择,插入耳机或者线路输出插孔可使扬声器静音, + 但不会使线路输出静音。当线路输出+扬声器被选择,插入耳机插孔会同时使扬 + 声器和线路输出静音。 + + +矽玛特编解码器 +-------------- + +模拟环回 + 此控件启用/禁用模拟环回电路。只有在编解码器提示中将”lookback“设置为真 + 时才会出现(见HD-Audio.txt)。请注意,在某些编解码器上,模拟环回和正常 + PCM播放是独占的,即当此选项打开时,您将听不到任何PCM流。 + +交换中置/低频 + 交换中置和低频通道顺序,通常情况下,左侧对应中置,右侧对应低频,启动此 + 项后,左边低频,右边中置。 + +耳机作为线路输出 + 当此控制开启时,将耳机视为线路输出插孔。也就是说,耳机不会自动静音其他 + 线路输出,没有耳机放大器被设置到引脚上。 + +麦克风插口模式、线路插孔模式等 + 这些枚举控制输入插孔引脚的方向和偏置。根据插孔类型,它可以设置为”麦克风 + 输入“和”线路输入“以确定输入偏置,或者当引脚是环绕声道的多I/O插孔时,它 + 可以设置为”线路输出“。 + + +威盛编解码器 +------------ + +智能5.1 + 一个枚举控件,用于为环绕输出重新分配多个I/O插孔的任务。当它打开时,相应 + 的输入插孔(通常是线路输入和麦克风输入)被切换为环绕和中央低频输出插孔。 + +独立耳机 + 启用此枚举控制时,耳机输出从单个流(第三个PCM,如hw:0,2)而不是主流路由。 + 如果耳机DAC与侧边或中央低频通道DAC共享,则DAC将自动切换到耳机。 + +环回混合 + 一个用于确定是否启动了模拟环回路由的枚举控件。当它启用后,模拟环回路由到 + 前置通道。同样,耳机与扬声器输出也采用相同的路径。作为一个副作用,当设置 + 此模式后,单个音量控制将不再适用于耳机和扬声器,因为只有一个DAC连接到混 + 音器小部件。 + +动态电源控制 + 此控件决定是否启动每个插孔的动态电源控制检测。启用时,根据插孔的插入情况 + 动态更改组件的电源状态(D0/D3)以节省电量消耗。但是,如果您的系统没有提 + 供正确的插孔检测,这将无法工作;在这种情况下,请关闭此控件。 + +插孔检测 + 此控件仅为VT1708编解码器提供,它不会为每个插孔插拔提供适当的未请求事件。 + 当此控件打开,驱动将轮询插孔检测,以便耳机自动静音可以工作,而关闭此控 + 件将降低功耗。 + + +科胜讯编解码器 +-------------- + +自动静音模式 + 见瑞昱解码器 + + + +模拟编解码器 +------------ + +通道模式 + 这是一个用于更改环绕声道设置的枚举控件,仅在环绕声道可用时显示。它提供了能 + 被使用的通道数:”2ch“、”4ch“和”6ch“。根据配置,这还控制多I/O插孔的插孔重 + 分配。 + +独立耳机 + 启动此枚举控制后,耳机输出从单个流(第三个PCM,如hw:0,2)而不是主流路由。 diff --git a/Documentation/translations/zh_CN/sound/hd-audio/index.rst b/Documentation/translations/zh_CN/sound/hd-audio/index.rst new file mode 100644 index 000000000000..d9885d53b069 --- /dev/null +++ b/Documentation/translations/zh_CN/sound/hd-audio/index.rst @@ -0,0 +1,14 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../../disclaimer-zh_CN.rst + +:Original: :doc:`../../../../sound/hd-audio/index` +:Translator: Huang Jianghui + + +高清音频 +======== + +.. toctree:: + :maxdepth: 2 + + controls diff --git a/Documentation/translations/zh_CN/sound/index.rst b/Documentation/translations/zh_CN/sound/index.rst new file mode 100644 index 000000000000..28d5dca34a63 --- /dev/null +++ b/Documentation/translations/zh_CN/sound/index.rst @@ -0,0 +1,22 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../sound/index` +:Translator: Huang Jianghui + + +==================== +Linux 声音子系统文档 +==================== + +.. toctree:: + :maxdepth: 2 + + hd-audio/index + +.. only:: subproject and html + + Indices + ======= + + * :ref:`genindex` -- cgit v1.2.3 From 550c8399d0175e200794938ec2a5f227b3dc43ec Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 4 Mar 2021 16:01:32 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/README.rst Add translation zh_CN/admin-guide/README.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210304080131.GA16539@mipc Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/README.rst | 347 +++++++++++++++++++++ .../translations/zh_CN/admin-guide/index.rst | 6 +- 2 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/README.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/README.rst b/Documentation/translations/zh_CN/admin-guide/README.rst new file mode 100644 index 000000000000..939aee115e48 --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/README.rst @@ -0,0 +1,347 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :ref:`Documentation/admin-guide/README.rst ` + +:译者: + + 吴想成 Wu XiangCheng + +Linux内核5.x版本 +========================================= + +以下是Linux版本5的发行注记。仔细阅读它们, +它们会告诉你这些都是什么,解释如何安装内核,以及遇到问题时该如何做。 + +什么是Linux? +--------------- + + Linux是Unix操作系统的克隆版本,由Linus Torvalds在一个松散的网络黑客 + (Hacker,无贬义)团队的帮助下从头开始编写。它旨在实现兼容POSIX和 + 单一UNIX规范。 + + 它具有在现代成熟的Unix中应当具有的所有功能,包括真正的多任务处理、虚拟内存、 + 共享库、按需加载、共享的写时拷贝(COW)可执行文件、恰当的内存管理以及包括 + IPv4和IPv6在内的复合网络栈。 + + Linux在GNU通用公共许可证,版本2(GNU GPLv2)下分发,详见随附的COPYING文件。 + +它能在什么样的硬件上运行? +----------------------------- + + 虽然Linux最初是为32位的x86 PC机(386或更高版本)开发的,但今天它也能运行在 + (至少)Compaq Alpha AXP、Sun SPARC与UltraSPARC、Motorola 68000、PowerPC、 + PowerPC64、ARM、Hitachi SuperH、Cell、IBM S/390、MIPS、HP PA-RISC、Intel + IA-64、DEC VAX、AMD x86-64 Xtensa和ARC架构上。 + + Linux很容易移植到大多数通用的32位或64位体系架构,只要它们有一个分页内存管理 + 单元(PMMU)和一个移植的GNU C编译器(gcc;GNU Compiler Collection,GCC的一 + 部分)。Linux也被移植到许多没有PMMU的体系架构中,尽管功能显然受到了一定的 + 限制。 + Linux也被移植到了其自己上。现在可以将内核作为用户空间应用程序运行——这被 + 称为用户模式Linux(UML)。 + +文档 +----- +因特网上和书籍上都有大量的电子文档,既有Linux专属文档,也有与一般UNIX问题相关 +的文档。我建议在任何Linux FTP站点上查找LDP(Linux文档项目)书籍的文档子目录。 +本自述文件并不是关于系统的文档:有更好的可用资源。 + + - 因特网上和书籍上都有大量的(电子)文档,既有Linux专属文档,也有与普通 + UNIX问题相关的文档。我建议在任何有LDP(Linux文档项目)书籍的Linux FTP + 站点上查找文档子目录。本自述文件并不是关于系统的文档:有更好的可用资源。 + + - 文档/子目录中有各种自述文件:例如,这些文件通常包含一些特定驱动程序的 + 内核安装说明。请阅读 + :ref:`Documentation/process/changes.rst ` 文件,它包含了升级内核 + 可能会导致的问题的相关信息。 + +安装内核源代码 +--------------- + + - 如果您要安装完整的源代码,请把内核tar档案包放在您有权限的目录中(例如您 + 的主目录)并将其解包:: + + xz -cd linux-5.x.tar.xz | tar xvf - + + 将“X”替换成最新内核的版本号。 + + 【不要】使用 /usr/src/linux 目录!这里有一组库头文件使用的内核头文件 + (通常是不完整的)。它们应该与库匹配,而不是被内核的变化搞得一团糟。 + + - 您还可以通过打补丁在5.x版本之间升级。补丁以xz格式分发。要通过打补丁进行 + 安装,请获取所有较新的补丁文件,进入内核源代码(linux-5.x)的目录并 + 执行:: + + xz -cd ../patch-5.x.xz | patch -p1 + + 请【按顺序】替换所有大于当前源代码树版本的“x”,这样就可以了。您可能想要 + 删除备份文件(文件名类似xxx~ 或 xxx.orig),并确保没有失败的补丁(文件名 + 类似xxx# 或 xxx.rej)。如果有,不是你就是我犯了错误。 + + 与5.x内核的补丁不同,5.x.y内核(也称为稳定版内核)的补丁不是增量的,而是 + 直接应用于基本的5.x内核。例如,如果您的基本内核是5.0,并且希望应用5.0.3 + 补丁,则不应先应用5.0.1和5.0.2的补丁。类似地,如果您运行的是5.0.2内核, + 并且希望跳转到5.0.3,那么在应用5.0.3补丁之前,必须首先撤销5.0.2补丁 + (即patch -R)。更多关于这方面的内容,请阅读 + :ref:`Documentation/process/applying-patches.rst ` 。 + + 或者,脚本 patch-kernel 可以用来自动化这个过程。它能确定当前内核版本并 + 应用找到的所有补丁:: + + linux/scripts/patch-kernel linux + + 上面命令中的第一个参数是内核源代码的位置。补丁是在当前目录应用的,但是 + 可以将另一个目录指定为第二个参数。 + + - 确保没有过时的 .o 文件和依赖项:: + + cd linux + make mrproper + + 现在您应该已经正确安装了源代码。 + +软件要求 +--------- + + 编译和运行5.x内核需要各种软件包的最新版本。请参考 + :ref:`Documentation/process/changes.rst ` + 来了解最低版本要求以及如何升级软件包。请注意,使用过旧版本的这些包可能会 + 导致很难追踪的间接错误,因此不要以为在生成或操作过程中出现明显问题时可以 + 只更新包。 + +为内核建立目录 +--------------- + + 编译内核时,默认情况下所有输出文件都将与内核源代码放在一起。使用 + ``make O=output/dir`` 选项可以为输出文件(包括 .config)指定备用位置。 + 例如:: + + kernel source code: /usr/src/linux-5.x + build directory: /home/name/build/kernel + + 要配置和构建内核,请使用:: + + cd /usr/src/linux-5.x + make O=/home/name/build/kernel menuconfig + make O=/home/name/build/kernel + sudo make O=/home/name/build/kernel modules_install install + + 请注意:如果使用了 ``O=output/dir`` 选项,那么它必须用于make的所有调用。 + +配置内核 +--------- + + 即使只升级一个小版本,也不要跳过此步骤。每个版本中都会添加新的配置选项, + 如果配置文件没有按预定设置,就会出现奇怪的问题。如果您想以最少的工作量 + 将现有配置升级到新版本,请使用 ``makeoldconfig`` ,它只会询问您新配置 + 选项的答案。 + + - 其他配置命令包括:: + + "make config" 纯文本界面。 + + "make menuconfig" 基于文本的彩色菜单、选项列表和对话框。 + + "make nconfig" 增强的基于文本的彩色菜单。 + + "make xconfig" 基于Qt的配置工具。 + + "make gconfig" 基于GTK+的配置工具。 + + "make oldconfig" 基于现有的 ./.config 文件选择所有选项,并询问 + 新配置选项。 + + "make olddefconfig" + 类似上一个,但不询问直接将新选项设置为默认值。 + + "make defconfig" 根据体系架构,使用arch/$arch/defconfig或 + arch/$arch/configs/${PLATFORM}_defconfig中的 + 默认选项值创建./.config文件。 + + "make ${PLATFORM}_defconfig" + 使用arch/$arch/configs/${PLATFORM}_defconfig中 + 的默认选项值创建一个./.config文件。 + 用“makehelp”来获取您体系架构中所有可用平台的列表。 + + "make allyesconfig" + 通过尽可能将选项值设置为“y”,创建一个 + ./.config文件。 + + "make allmodconfig" + 通过尽可能将选项值设置为“m”,创建一个 + ./.config文件。 + + "make allnoconfig" 通过尽可能将选项值设置为“n”,创建一个 + ./.config文件。 + + "make randconfig" 通过随机设置选项值来创建./.config文件。 + + "make localmodconfig" 基于当前配置和加载的模块(lsmod)创建配置。禁用 + 已加载的模块不需要的任何模块选项。 + + 要为另一台计算机创建localmodconfig,请将该计算机 + 的lsmod存储到一个文件中,并将其作为lsmod参数传入。 + + 此外,通过在参数LMC_KEEP中指定模块的路径,可以将 + 模块保留在某些文件夹或kconfig文件中。 + + target$ lsmod > /tmp/mylsmod + target$ scp /tmp/mylsmod host:/tmp + + host$ make LSMOD=/tmp/mylsmod \ + LMC_KEEP="drivers/usb:drivers/gpu:fs" \ + localmodconfig + + 上述方法在交叉编译时也适用。 + + "make localyesconfig" 与localmodconfig类似,只是它会将所有模块选项转换 + 为内置(=y)。你可以同时通过LMC_KEEP保留模块。 + + "make kvmconfig" 为kvm客体内核支持启用其他选项。 + + "make xenconfig" 为xen dom0客体内核支持启用其他选项。 + + "make tinyconfig" 配置尽可能小的内核。 + + 更多关于使用Linux内核配置工具的信息,见文档 + Documentation/kbuild/kconfig.rst。 + + - ``make config`` 注意事项: + + - 包含不必要的驱动程序会使内核变大,并且在某些情况下会导致问题: + 探测不存在的控制器卡可能会混淆其他控制器。 + + - 如果存在协处理器,则编译了数学仿真的内核仍将使用协处理器:在 + 这种情况下,数学仿真永远不会被使用。内核会稍微大一点,但不管 + 是否有数学协处理器,都可以在不同的机器上工作。 + + - “kernel hacking”配置细节通常会导致更大或更慢的内核(或两者 + 兼而有之),甚至可以通过配置一些例程来主动尝试破坏坏代码以发现 + 内核问题,从而降低内核的稳定性(kmalloc())。因此,您可能应该 + 用于研究“开发”、“实验”或“调试”特性相关问题。 + +编译内核 +--------- + + - 确保您至少有gcc 4.9可用。 + 有关更多信息,请参阅 :ref:`Documentation/process/changes.rst ` 。 + + 请注意,您仍然可以使用此内核运行a.out用户程序。 + + - 执行 ``make`` 来创建压缩内核映像。如果您安装了lilo以适配内核makefile, + 那么也可以进行 ``makeinstall`` ,但是您可能需要先检查特定的lilo设置。 + + 实际安装必须以root身份执行,但任何正常构建都不需要。 + 无须徒然使用root身份。 + + - 如果您将内核的任何部分配置为模块,那么还必须执行 ``make modules_install`` 。 + + - 详细的内核编译/生成输出: + + 通常,内核构建系统在相当安静的模式下运行(但不是完全安静)。但是有时您或 + 其他内核开发人员需要看到编译、链接或其他命令的执行过程。为此,可使用 + “verbose(详细)”构建模式。 + 向 ``make`` 命令传递 ``V=1`` 来实现,例如:: + + make V=1 all + + 如需构建系统也给出内个目标重建的愿意,请使用 ``V=2`` 。默认为 ``V=0`` 。 + + - 准备一个备份内核以防出错。对于开发版本尤其如此,因为每个新版本都包含 + 尚未调试的新代码。也要确保保留与该内核对应的模块的备份。如果要安装 + 与工作内核版本号相同的新内核,请在进行 ``make modules_install`` 安装 + 之前备份modules目录。 + + 或者,在编译之前,使用内核配置选项“LOCALVERSION”向常规内核版本附加 + 一个唯一的后缀。LOCALVERSION可以在“General Setup”菜单中设置。 + + - 为了引导新内核,您需要将内核映像(例如编译后的 + .../linux/arch/x86/boot/bzImage)复制到常规可引导内核的位置。 + + - 不再支持在没有LILO等启动装载程序帮助的情况下直接从软盘引导内核。 + + 如果从硬盘引导Linux,很可能使用LILO,它使用/etc/lilo.conf文件中 + 指定的内核映像文件。内核映像文件通常是/vmlinuz、/boot/vmlinuz、 + /bzImage或/boot/bzImage。使用新内核前,请保存旧映像的副本,并复制 + 新映像覆盖旧映像。然后您【必须重新运行LILO】来更新加载映射!否则, + 将无法启动新的内核映像。 + + 重新安装LILO通常需要运行/sbin/LILO。您可能希望编辑/etc/lilo.conf + 文件为旧内核映像指定一个条目(例如/vmlinux.old)防止新的不能正常 + 工作。有关更多信息,请参阅LILO文档。 + + 重新安装LILO之后,您应该就已经准备好了。关闭系统,重新启动,尽情 + 享受吧! + + 如果需要更改内核映像中的默认根设备、视频模式等,请在适当的地方使用 + 启动装载程序的引导选项。无需重新编译内核即可更改这些参数。 + + - 使用新内核重新启动并享受它吧。 + +若遇到问题 +----------- + + - 如果您发现了一些可能由于内核缺陷所导致的问题,请检查MAINTAINERS(维护者) + 文件看看是否有人与令您遇到麻烦的内核部分相关。如果无人在此列出,那么第二 + 个最好的方案就是把它们发给我(torvalds@linux-foundation.org),也可能发送 + 到任何其他相关的邮件列表或新闻组。 + + - 在所有的缺陷报告中,【请】告诉我们您在说什么内核,如何复现问题,以及您的 + 设置是什么的(使用您的常识)。如果问题是新的,请告诉我;如果问题是旧的, + 请尝试告诉我您什么时候首次注意到它。 + + - 如果缺陷导致如下消息:: + + unable to handle kernel paging request at address C0000010 + Oops: 0002 + EIP: 0010:XXXXXXXX + eax: xxxxxxxx ebx: xxxxxxxx ecx: xxxxxxxx edx: xxxxxxxx + esi: xxxxxxxx edi: xxxxxxxx ebp: xxxxxxxx + ds: xxxx es: xxxx fs: xxxx gs: xxxx + Pid: xx, process nr: xx + xx xx xx xx xx xx xx xx xx xx + + 或者类似的内核调试信息显示在屏幕上或在系统日志里,请【如实】复制它。 + 可能对你来说转储(dump)看起来不可理解,但它确实包含可能有助于调试问题的 + 信息。转储上方的文本也很重要:它说明了内核转储代码的原因(在上面的示例中, + 是由于内核指针错误)。更多关于如何理解转储的信息,请参见 + Documentation/admin-guide/bug-hunting.rst。 + + - 如果使用 CONFIG_KALLSYMS 编译内核,则可以按原样发送转储,否则必须使用 + ``ksymoops`` 程序来理解转储(但通常首选使用CONFIG_KALLSYMS编译)。 + 此实用程序可从 + https://www.kernel.org/pub/linux/utils/kernel/ksymoops/ 下载。 + 或者,您可以手动执行转储查找: + + - 在调试像上面这样的转储时,如果您可以查找EIP值的含义,这将非常有帮助。 + 十六进制值本身对我或其他任何人都没有太大帮助:它会取决于特定的内核设置。 + 您应该做的是从EIP行获取十六进制值(忽略 ``0010:`` ),然后在内核名字列表 + 中查找它,以查看哪个内核函数包含有问题的地址。 + + 要找到内核函数名,您需要找到与显示症状的内核相关联的系统二进制文件。就是 + 文件“linux/vmlinux”。要提取名字列表并将其与内核崩溃中的EIP进行匹配, + 请执行:: + + nm vmlinux | sort | less + + 这将为您提供一个按升序排序的内核地址列表,从中很容易找到包含有问题的地址 + 的函数。请注意,内核调试消息提供的地址不一定与函数地址完全匹配(事实上, + 这是不可能的),因此您不能只“grep”列表:不过列表将为您提供每个内核函数 + 的起点,因此通过查找起始地址低于你正在搜索的地址,但后一个函数的高于的 + 函数,你会找到您想要的。实际上,在您的问题报告中加入一些“上下文”可能是 + 一个好主意,给出相关的上下几行。 + + 如果您由于某些原因无法完成上述操作(如您使用预编译的内核映像或类似的映像), + 请尽可能多地告诉我您的相关设置信息,这会有所帮助。有关详细信息请阅读 + ‘Documentation/admin-guide/reporting-issues.rst’。 + + - 或者,您可以在正在运行的内核上使用gdb(只读的;即不能更改值或设置断点)。 + 为此,请首先使用-g编译内核;适当地编辑arch/x86/Makefile,然后执行 ``make + clean`` 。您还需要启用CONFIG_PROC_FS(通过 ``make config`` )。 + + 使用新内核重新启动后,执行 ``gdb vmlinux /proc/kcore`` 。现在可以使用所有 + 普通的gdb命令。查找系统崩溃点的命令是 ``l *0xXXXXXXXX`` (将xxx替换为EIP + 值)。 + + 用gdb无法调试一个当前未运行的内核是由于gdb(错误地)忽略了编译内核的起始 + 偏移量。 diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index 48bbd3ebad48..e7d8d43e4d4f 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -13,9 +13,13 @@ Linux 内核用户和管理员指南 这个初始部分包含总体信息,包括描述内核的README, 关于内核参数的文档等。 -Todolist: +.. toctree:: + :maxdepth: 1 README + +Todolist: + kernel-parameters devices sysctl/index -- cgit v1.2.3 From 0e2c578cba9d83663cce1abe584d65364408f0b5 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 4 Mar 2021 16:01:50 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/unicode.rst Add translation zh_CN/admin-guide/unicode.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210304080148.GA16612@mipc Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/index.rst | 2 +- .../translations/zh_CN/admin-guide/unicode.rst | 170 +++++++++++++++++++++ 2 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/unicode.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index e7d8d43e4d4f..a716a48c8018 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -60,6 +60,7 @@ Todolist: clearing-warn-once cpu-load + unicode Todolist: @@ -115,7 +116,6 @@ Todolist: sysrq thunderbolt ufs - unicode vga-softcursor video-output xfs diff --git a/Documentation/translations/zh_CN/admin-guide/unicode.rst b/Documentation/translations/zh_CN/admin-guide/unicode.rst new file mode 100644 index 000000000000..ef7f3cb2c02e --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/unicode.rst @@ -0,0 +1,170 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :ref:`Documentation/admin-guide/unicode.rst` + +:译者: + + 吴想成 Wu XiangCheng + +Unicode(统一码)支持 +====================== + + (英文版)上次更新:2005-01-17,版本号 1.4 + +此文档由H. Peter Anvin 管理,是Linux注册名称与编号管理局 +(Linux Assigned Names And Numbers Authority,LANANA)项目的一部分。 +现行版本请见: + + http://www.lanana.org/docs/unicode/admin-guide/unicode.rst + +简介 +----- + +Linux内核代码已被重写以使用Unicode来将字符映射到字体。下载一个Unicode到字体 +(Unicode-to-font)表,八位字符集与UTF-8模式都将改用此字体来显示。 + +这微妙地改变了八位字符表的语义。现在的四个字符表是: + +=============== =============================== ================ +映射代号 映射名称 Escape代码 (G0) +=============== =============================== ================ +LAT1_MAP Latin-1 (ISO 8859-1) ESC ( B +GRAF_MAP DEC VT100 pseudographics ESC ( 0 +IBMPC_MAP IBM code page 437 ESC ( U +USER_MAP User defined ESC ( K +=============== =============================== ================ + +特别是 ESC ( U 不再是“直通字体”,因为字体可能与IBM字符集完全不同。 +例如,即使加载了一个Latin-1字体,也允许使用块图形(block graphics)。 + +请注意,尽管这些代码与ISO 2022类似,但这些代码及其用途都与ISO 2022不匹配; +Linux有两个八位代码(G0和G1),而ISO 2022有四个七位代码(G0-G3)。 + +根据Unicode标准/ISO 10646,U+F000到U+F8FF被保留用于操作系统范围内的分配 +(Unicode标准将其称为“团体区域(Corporate Zone)”,因为这对于Linux是不准确 +的,所以我们称之为“Linux区域”)。选择U+F000作为起点,因为它允许直接映射 +区域以2的大倍数开始(以防需要1024或2048个字符的字体)。这就留下U+E000到 +U+EFFF作为最终用户区。 + +[v1.2]:Unicodes范围从U+F000到U+F7FF已经被硬编码为直接映射到加载的字体, +绕过了翻译表。用户定义的映射现在默认为U+F000到U+F0FF,模拟前述行为。实际上, +此范围可能较短;例如,vgacon只能处理256字符(U+F000..U+F0FF)或512字符 +(U+F000..U+F1FF)字体。 + +Linux 区域中定义的实际字符 +--------------------------- + +此外,还定义了Unicode 1.1.4中不存在的以下字符;这些字符由DEC VT图形映射使用。 +[v1.2]此用法已过时,不应再使用;请参见下文。 + +====== ====================================== +U+F800 DEC VT GRAPHICS HORIZONTAL LINE SCAN 1 +U+F801 DEC VT GRAPHICS HORIZONTAL LINE SCAN 3 +U+F803 DEC VT GRAPHICS HORIZONTAL LINE SCAN 7 +U+F804 DEC VT GRAPHICS HORIZONTAL LINE SCAN 9 +====== ====================================== + +DEC VT220使用6x10字符矩阵,这些字符在DEC VT图形字符集中形成一个平滑的过渡。 +我省略了扫描5行,因为它也被用作块图形字符,因此被编码为U+2500 FORMS LIGHT +HORIZONTAL。 + +[v1.3]:这些字符已正式添加到Unicode 3.2.0中;它们在U+23BA、U+23BB、U+23BC、 +U+23BD处添加。Linux现在使用新值。 + +[v1.2]:添加了以下字符来表示常见的键盘符号,这些符号不太可能被添加到Unicode +中,因为它们非常讨厌地取决于特定供应商。当然,这是糟糕设计的一个好例子。 + +====== ====================================== +U+F810 KEYBOARD SYMBOL FLYING FLAG +U+F811 KEYBOARD SYMBOL PULLDOWN MENU +U+F812 KEYBOARD SYMBOL OPEN APPLE +U+F813 KEYBOARD SYMBOL SOLID APPLE +====== ====================================== + +克林贡(Klingon)语支持 +------------------------ + +1996年,Linux是世界上第一个添加对人工语言克林贡支持的操作系统,克林贡是由 +Marc Okrand为《星际迷航》电视连续剧创造的。这种编码后来被征募Unicode注册表 +(ConScript Unicode Registry,CSUR)采用,并建议(但最终被拒绝)纳入Unicode +平面一。不过,它仍然是Linux区域中的Linux/CSUR私有分配。 + +这种编码已经得到克林贡语言研究所(Klingon Language Institute)的认可。 +有关更多信息,请联系他们: + + http://www.kli.org/ + +由于Linux CZ开头部分的字符大多是dingbats/symbols/forms类型,而且这是一种 +语言,因此根据标准Unicode惯例,我将它放置在16单元的边界上。 + +.. note:: + + 这个范围现在由征募Unicode注册表正式管理。规范性引用文件为: + + https://www.evertype.com/standards/csur/klingon.html + +克林贡语有一个26个字符的字母表,一个10位数的位置数字书写系统,从左到右 +,从上到下书写。 + +克林贡字母的几种字形已经被提出。但是由于这组符号看起来始终是一致的,只有实际 +的形状不同,因此按照标准Unicode惯例,这些差异被认为是字体变体。 + +====== ======================================================= +U+F8D0 KLINGON LETTER A +U+F8D1 KLINGON LETTER B +U+F8D2 KLINGON LETTER CH +U+F8D3 KLINGON LETTER D +U+F8D4 KLINGON LETTER E +U+F8D5 KLINGON LETTER GH +U+F8D6 KLINGON LETTER H +U+F8D7 KLINGON LETTER I +U+F8D8 KLINGON LETTER J +U+F8D9 KLINGON LETTER L +U+F8DA KLINGON LETTER M +U+F8DB KLINGON LETTER N +U+F8DC KLINGON LETTER NG +U+F8DD KLINGON LETTER O +U+F8DE KLINGON LETTER P +U+F8DF KLINGON LETTER Q + - Written in standard Okrand Latin transliteration +U+F8E0 KLINGON LETTER QH + - Written in standard Okrand Latin transliteration +U+F8E1 KLINGON LETTER R +U+F8E2 KLINGON LETTER S +U+F8E3 KLINGON LETTER T +U+F8E4 KLINGON LETTER TLH +U+F8E5 KLINGON LETTER U +U+F8E6 KLINGON LETTER V +U+F8E7 KLINGON LETTER W +U+F8E8 KLINGON LETTER Y +U+F8E9 KLINGON LETTER GLOTTAL STOP + +U+F8F0 KLINGON DIGIT ZERO +U+F8F1 KLINGON DIGIT ONE +U+F8F2 KLINGON DIGIT TWO +U+F8F3 KLINGON DIGIT THREE +U+F8F4 KLINGON DIGIT FOUR +U+F8F5 KLINGON DIGIT FIVE +U+F8F6 KLINGON DIGIT SIX +U+F8F7 KLINGON DIGIT SEVEN +U+F8F8 KLINGON DIGIT EIGHT +U+F8F9 KLINGON DIGIT NINE + +U+F8FD KLINGON COMMA +U+F8FE KLINGON FULL STOP +U+F8FF KLINGON SYMBOL FOR EMPIRE +====== ======================================================= + +其他虚构和人工字母 +------------------- + +自从分配了克林贡Linux Unicode块之后,John Cowan +和 Michael Everson 建立了一个虚构和人工字母的注册表。 +征募Unicode注册表请访问: + + https://www.evertype.com/standards/csur/ + +所使用的范围位于最终用户区域的低端,因此无法进行规范化分配,但建议希望对虚构 +字母进行编码的人员使用这些代码,以实现互操作性。对于克林贡语,CSUR采用了Linux +编码。CSUR的人正在推动将Tengwar和Cirth添加到Unicode平面一;将克林贡添加到 +Unicode平面一被拒绝,因此上述编码仍然是官方的。 -- cgit v1.2.3 From d619afd344463c2c9b7e994fd798a957cec5f019 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Mon, 1 Mar 2021 03:10:51 +0800 Subject: docs/zh_CN:add riscv boot-image-header.rst translation This patch translates Documentation/riscv/boot-image-header.rst intoChinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210228191054.6048-2-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/riscv/boot-image-header.rst | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/translations/zh_CN/riscv/boot-image-header.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/riscv/boot-image-header.rst b/Documentation/translations/zh_CN/riscv/boot-image-header.rst new file mode 100644 index 000000000000..241bf9c1bcbe --- /dev/null +++ b/Documentation/translations/zh_CN/riscv/boot-image-header.rst @@ -0,0 +1,67 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../riscv/boot-image-header` +:Translator: Yanteng Si + +.. _cn_boot-image-header.rst: + + +========================== +RISC-V Linux启动镜像文件头 +========================== + +:Author: Atish Patra +:Date: 20 May 2019 + +此文档仅描述RISC-V Linux 启动文件头的详情。 + +TODO: + 写一个完整的启动指南。 + +在解压后的Linux内核镜像中存在以下64字节的文件头:: + + u32 code0; /* Executable code */ + u32 code1; /* Executable code */ + u64 text_offset; /* Image load offset, little endian */ + u64 image_size; /* Effective Image size, little endian */ + u64 flags; /* kernel flags, little endian */ + u32 version; /* Version of this header */ + u32 res1 = 0; /* Reserved */ + u64 res2 = 0; /* Reserved */ + u64 magic = 0x5643534952; /* Magic number, little endian, "RISCV" */ + u32 magic2 = 0x05435352; /* Magic number 2, little endian, "RSC\x05" */ + u32 res3; /* Reserved for PE COFF offset */ + +这种头格式与PE/COFF文件头兼容,并在很大程度上受到ARM64文件头的启发。因此,ARM64 +和RISC-V文件头可以在未来合并为一个共同的头。 + +注意 +==== + +- 将来也可以复用这个文件头,用来对RISC-V的EFI桩提供支持。为了使内核镜像如同一个 + EFI应用程序一样加载,EFI规范中规定在内核镜像的开始需要PE/COFF镜像文件头。为了 + 支持EFI桩,应该用“MZ”魔术字符替换掉code0,并且res3(偏移量未0x3c)应指向PE/COFF + 文件头的其余部分. + +- 表示文件头版本号的Drop-bit位域 + + ========== ========== + Bits 0:15 次要 版本 + Bits 16:31 主要 版本 + ========== ========== + + 这保持了新旧版本之间的兼容性。 + 当前版本被定义为0.2。 + +- 从版本0.2开始,结构体成员“magic”就已经被弃用,在之后的版本中,可能会移除掉它。 + 最初,该成员应该与ARM64头的“magic”成员匹配,但遗憾的是并没有。 + “magic2”成员代替“magic”成员与ARM64头相匹配。 + +- 在当前的文件头,标志位域只剩下了一个位。 + + ===== ============================== + Bit 0 内核字节序。1 if BE, 0 if LE. + ===== ============================== + +- 对于引导加载程序加载内核映像来说,image_size成员对引导加载程序而言是必须的,否 + 则将引导失败。 -- cgit v1.2.3 From cb07e0977a6271472cec1e50dad4b5a8035c353d Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Mon, 1 Mar 2021 03:10:52 +0800 Subject: docs/zh_CN: add riscv patch-acceptance.rst translation This patch translates Documentation/riscv/patch-acceptance.rst into Chineae. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210228191054.6048-3-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/riscv/patch-acceptance.rst | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Documentation/translations/zh_CN/riscv/patch-acceptance.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/riscv/patch-acceptance.rst b/Documentation/translations/zh_CN/riscv/patch-acceptance.rst new file mode 100644 index 000000000000..9fd1c8216763 --- /dev/null +++ b/Documentation/translations/zh_CN/riscv/patch-acceptance.rst @@ -0,0 +1,31 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../riscv/patch-acceptance` +:Translator: Yanteng Si + +.. _cn_riscv_patch-acceptance: + + +arch/riscv 开发者维护指南 +========================= + +概述 +---- +RISC-V指令集体系结构是公开开发的: +正在进行的草案可供所有人查看和测试实现。新模块或者扩展草案可能会在开发过程中发 +生更改---有时以不兼容的方式对以前的草案进行更改。这种灵活性可能会给RISC-V Linux +维护者带来挑战。Linux开发过程更喜欢经过良好检查和测试的代码,而不是试验代码。我 +们希望推广同样的规则到即将被内核合并的RISC-V相关代码。 + +附加的提交检查单 +---------------- +我们仅接受相关标准已经被RISC-V基金会标准为“已批准”或“已冻结”的扩展或模块的补丁。 +(开发者当然可以维护自己的Linux内核树,其中包含所需代码扩展草案的代码。) + +此外,RISC-V规范允许爱好者创建自己的自定义扩展。这些自定义拓展不需要通过RISC-V +基金会的任何审核或批准。为了避免将爱好者一些特别的RISC-V拓展添加进内核代码带来 +的维护复杂性和对性能的潜在影响,我们将只接受RISC-V基金会正式冻结或批准的的扩展 +补丁。(开发者当然可以维护自己的Linux内核树,其中包含他们想要的任何自定义扩展 +的代码。) -- cgit v1.2.3 From b52e2a6e662b6bf7bd2f024e62cf8471eda8fcdc Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Mon, 1 Mar 2021 03:10:53 +0800 Subject: docs/zh_CN: add riscv pmu.rst translation This patch translates Documentation/riscv/pmu.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210228191054.6048-4-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/riscv/pmu.rst | 233 +++++++++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 Documentation/translations/zh_CN/riscv/pmu.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/riscv/pmu.rst b/Documentation/translations/zh_CN/riscv/pmu.rst new file mode 100644 index 000000000000..22dcf3a9ca6e --- /dev/null +++ b/Documentation/translations/zh_CN/riscv/pmu.rst @@ -0,0 +1,233 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../riscv/pmu` +:Translator: Yanteng Si + +.. _cn_riscv_pmu: + + +======================== +RISC-V平台上对PMUs的支持 +======================== + +Alan Kao , Mar 2018 + +简介 +------------ + +截止本文撰写时,在The RISC-V ISA Privileged Version 1.10中提到的 perf_event +相关特性如下: +(详情请查阅手册) + +* [m|s]counteren +* mcycle[h], cycle[h] +* minstret[h], instret[h] +* mhpeventx, mhpcounterx[h] + +仅有以上这些功能,移植perf需要做很多工作,究其原因是缺少以下通用架构的性能 +监测特性: + +* 启用/停用计数器 + 在我们这里,计数器一直在自由运行。 +* 计数器溢出引起的中断 + 规范中没有这种功能。 +* 中断指示器 + 不可能所有的计数器都有很多的中断端口,所以需要一个中断指示器让软件来判断 + 哪个计数器刚好溢出。 +* 写入计数器 + 由于内核不能修改计数器,所以会有一个SBI来支持这个功能[1]。 另外,一些厂商 + 考虑实现M-S-U型号机器的硬件扩展来直接写入计数器。 + +这篇文档旨在为开发者提供一个在内核中支持PMU的简要指南。下面的章节简要解释了 +perf' 机制和待办事项。 + +你可以在这里查看以前的讨论[1][2]。 另外,查看附录中的相关内核结构体可能会有 +帮助。 + + +1. 初始化 +--------- + +*riscv_pmu* 是一个类型为 *struct riscv_pmu* 的全局指针,它包含了根据perf内部 +约定的各种方法和PMU-specific参数。人们应该声明这样的实例来代表PMU。 默认情况 +下, *riscv_pmu* 指向一个常量结构体 *riscv_base_pmu* ,它对基准QEMU模型有非常 +基础的支持。 + + +然后他/她可以将实例的指针分配给 *riscv_pmu* ,这样就可以利用已经实现的最小逻 +辑,或者创建他/她自己的 *riscv_init_platform_pmu* 实现。 + +换句话说,现有的 *riscv_base_pmu* 源只是提供了一个参考实现。 开发者可以灵活地 +决定多少部分可用,在最极端的情况下,他们可以根据自己的需要定制每一个函数。 + + +2. Event Initialization +----------------------- + +当用户启动perf命令来监控一些事件时,首先会被用户空间的perf工具解释为多个 +*perf_event_open* 系统调用,然后进一步调用上一步分配的 *event_init* 成员函数 +的主体。 在 *riscv_base_pmu* 的情况下,就是 *riscv_event_init* 。 + +该功能的主要目的是将用户提供的事件翻译成映射图,从而可以直接对HW-related的控 +制寄存器或计数器进行操作。该翻译基于 *riscv_pmu* 中提供的映射和方法。 + +注意,有些功能也可以在这个阶段完成: + +(1) 中断设置,这个在下一节说; +(2) 特限级设置(仅用户空间、仅内核空间、两者都有); +(3) 析构函数设置。 通常应用 *riscv_destroy_event* 即可; +(4) 对非采样事件的调整,这将被函数应用,如 *perf_adjust_period* ,通常如下:: + + if (!is_sampling_event(event)) { + hwc->sample_period = x86_pmu.max_period; + hwc->last_period = hwc->sample_period; + local64_set(&hwc->period_left, hwc->sample_period); + } + + +在 *riscv_base_pmu* 的情况下,目前只提供了(3)。 + + +3. 中断 +------- + +3.1. 中断初始化 + +这种情况经常出现在 *event_init* 方案的开头。通常情况下,这应该是一个代码段,如:: + + int x86_reserve_hardware(void) + { + int err = 0; + + if (!atomic_inc_not_zero(&pmc_refcount)) { + mutex_lock(&pmc_reserve_mutex); + if (atomic_read(&pmc_refcount) == 0) { + if (!reserve_pmc_hardware()) + err = -EBUSY; + else + reserve_ds_buffers(); + } + if (!err) + atomic_inc(&pmc_refcount); + mutex_unlock(&pmc_reserve_mutex); + } + + return err; + } + +而神奇的是 *reserve_pmc_hardware* ,它通常做原子操作,使实现的IRQ可以从某个全局函 +数指针访问。 而 *release_pmc_hardware* 的作用正好相反,它用在上一节提到的事件分配 +器中。 + + (注:从所有架构的实现来看,*reserve/release* 对总是IRQ设置,所以 *pmc_hardware* + 似乎有些误导。 它并不处理事件和物理计数器之间的绑定,这一点将在下一节介绍。) + +3.2. IRQ结构体 + +基本上,一个IRQ运行以下伪代码:: + + for each hardware counter that triggered this overflow + + get the event of this counter + + // following two steps are defined as *read()*, + // check the section Reading/Writing Counters for details. + count the delta value since previous interrupt + update the event->count (# event occurs) by adding delta, and + event->hw.period_left by subtracting delta + + if the event overflows + sample data + set the counter appropriately for the next overflow + + if the event overflows again + too frequently, throttle this event + fi + fi + + end for + + 然而截至目前,没有一个RISC-V的实现为perf设计了中断,所以具体的实现要在未来完成。 + +4. Reading/Writing 计数 +----------------------- + +它们看似差不多,但perf对待它们的态度却截然不同。 对于读,在 *struct pmu* 中有一个 +*read* 接口,但它的作用不仅仅是读。 根据上下文,*read* 函数不仅要读取计数器的内容 +(event->count),还要更新左周期到下一个中断(event->hw.period_left)。 + + 但 perf 的核心不需要直接写计数器。 写计数器隐藏在以下两点的抽象化之后, + 1) *pmu->start* ,从字面上看就是开始计数,所以必须把计数器设置成一个合适的值,以 + 便下一次中断; + 2)在IRQ里面,应该把计数器设置成同样的合理值。 + +在RISC-V中,读操作不是问题,但写操作就需要费些力气了,因为S模式不允许写计数器。 + + +5. add()/del()/start()/stop() +----------------------------- + +基本思想: add()/del() 向PMU添加/删除事件,start()/stop() 启动/停止PMU中某个事件 +的计数器。 所有这些函数都使用相同的参数: *struct perf_event *event* 和 *int flag* 。 + +把 perf 看作一个状态机,那么你会发现这些函数作为这些状态之间的状态转换过程。 +定义了三种状态(event->hw.state): + +* PERF_HES_STOPPED: 计数停止 +* PERF_HES_UPTODATE: event->count是最新的 +* PERF_HES_ARCH: 依赖于体系结构的用法,。。。我们现在并不需要它。 + +这些状态转换的正常流程如下: + +* 用户启动一个 perf 事件,导致调用 *event_init* 。 +* 当被上下文切换进来的时候,*add* 会被 perf core 调用,并带有一个标志 PERF_EF_START, + 也就是说事件被添加后应该被启动。 在这个阶段,如果有的话,一般事件会被绑定到一个物 + 理计数器上。当状态变为PERF_HES_STOPPED和PERF_HES_UPTODATE,因为现在已经停止了, + (软件)事件计数不需要更新。 + + - 然后调用 *start* ,并启用计数器。 + 通过PERF_EF_RELOAD标志,它向计数器写入一个适当的值(详细情况请参考上一节)。 + 如果标志不包含PERF_EF_RELOAD,则不会写入任何内容。 + 现在状态被重置为none,因为它既没有停止也没有更新(计数已经开始)。 + +*当被上下文切换出来时被调用。 然后,它检查出PMU中的所有事件,并调用 *stop* 来更新它们 + 的计数。 + + - *stop* 被 *del* 和perf核心调用,标志为PERF_EF_UPDATE,它经常以相同的逻辑和 *read* + 共用同一个子程序。 + 状态又一次变为PERF_HES_STOPPED和PERF_HES_UPTODATE。 + + - 这两对程序的生命周期: *add* 和 *del* 在任务切换时被反复调用;*start* 和 *stop* 在 + perf核心需要快速停止和启动时也会被调用,比如在调整中断周期时。 + +目前的实现已经足够了,将来可以很容易地扩展到功能。 + +A. 相关结构体 +------------- + +* struct pmu: include/linux/perf_event.h +* struct riscv_pmu: arch/riscv/include/asm/perf_event.h + + 两个结构体都被设计为只读。 + + *struct pmu* 定义了一些函数指针接口,它们大多以 *struct perf_event* 作为主参数,根据 + perf的内部状态机处理perf事件(详情请查看kernel/events/core.c)。 + + *struct riscv_pmu* 定义了PMU的具体参数。 命名遵循所有其它架构的惯例。 + +* struct perf_event: include/linux/perf_event.h +* struct hw_perf_event + + 表示 perf 事件的通用结构体,以及硬件相关的细节。 + +* struct riscv_hw_events: arch/riscv/include/asm/perf_event.h + + 保存事件状态的结构有两个固定成员。 + 事件的数量和事件的数组。 + +参考文献 +-------- + +[1] https://github.com/riscv/riscv-linux/pull/124 + +[2] https://groups.google.com/a/groups.riscv.org/forum/#!topic/sw-dev/f19TmCNP6yA -- cgit v1.2.3 From 5af38859efc3f5419a9f7478a30af098f863c603 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Mon, 1 Mar 2021 03:10:54 +0800 Subject: docs/zh_CN: add riscv index.rst translation This patch translates Documentation/riscv/index.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210228191054.6048-5-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/riscv/index.rst | 28 ++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Documentation/translations/zh_CN/riscv/index.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/riscv/index.rst b/Documentation/translations/zh_CN/riscv/index.rst new file mode 100644 index 000000000000..db13b1101490 --- /dev/null +++ b/Documentation/translations/zh_CN/riscv/index.rst @@ -0,0 +1,28 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../riscv/index` +:Translator: Yanteng Si + +.. _cn_riscv_index: + + +=============== +RISC-V 体系结构 +=============== + +.. toctree:: + :maxdepth: 1 + + boot-image-header + pmu + patch-acceptance + + +.. only:: subproject and html + + 目录 + ==== + + * :ref:`genindex` -- cgit v1.2.3 From d0c4c07e7b38113796aeb7ec57c9f0bb4c3503b0 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Mon, 15 Mar 2021 13:10:53 -0600 Subject: docs/zh_cn: Fix a couple of reference warnings Just put in the relevant file names and let automarkup handle the rest. Fixes: 550c8399d017 ("docs/zh_CN: Add zh_CN/admin-guide/README.rst") Reported-by: Stephen Rothwell Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/admin-guide/README.rst | 2 +- Documentation/translations/zh_CN/admin-guide/unicode.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/README.rst b/Documentation/translations/zh_CN/admin-guide/README.rst index 939aee115e48..669a022f6817 100644 --- a/Documentation/translations/zh_CN/admin-guide/README.rst +++ b/Documentation/translations/zh_CN/admin-guide/README.rst @@ -1,6 +1,6 @@ .. include:: ../disclaimer-zh_CN.rst -:Original: :ref:`Documentation/admin-guide/README.rst ` +:Original: Documentation/admin-guide/README.rst :译者: diff --git a/Documentation/translations/zh_CN/admin-guide/unicode.rst b/Documentation/translations/zh_CN/admin-guide/unicode.rst index ef7f3cb2c02e..b0b08d2b6eb7 100644 --- a/Documentation/translations/zh_CN/admin-guide/unicode.rst +++ b/Documentation/translations/zh_CN/admin-guide/unicode.rst @@ -1,6 +1,6 @@ .. include:: ../disclaimer-zh_CN.rst -:Original: :ref:`Documentation/admin-guide/unicode.rst` +:Original: Documentation/admin-guide/unicode.rst :译者: -- cgit v1.2.3 From c3fa459b69bc55c10efb53160c5b933648477209 Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Mon, 8 Mar 2021 08:57:01 +0100 Subject: docs/kokr: make sections on bug reporting match practice Translate this commit to Korean: cf6d6fc27936 ("docs: process/howto.rst: make sections on bug reporting match practice") Signed-off-by: SeongJae Park Link: https://lore.kernel.org/r/20210308075701.23411-1-sj38.park@gmail.com Signed-off-by: Jonathan Corbet --- Documentation/translations/ko_KR/howto.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/ko_KR/howto.rst b/Documentation/translations/ko_KR/howto.rst index 787f1e85f8a0..a2bdd564c907 100644 --- a/Documentation/translations/ko_KR/howto.rst +++ b/Documentation/translations/ko_KR/howto.rst @@ -339,14 +339,8 @@ Andrew Morton의 글이 있다. 버그 보고 --------- -https://bugzilla.kernel.org 는 리눅스 커널 개발자들이 커널의 버그를 추적하는 -곳이다. 사용자들은 발견한 모든 버그들을 보고하기 위하여 이 툴을 사용할 것을 -권장한다. kernel bugzilla를 사용하는 자세한 방법은 다음을 참조하라. - - https://bugzilla.kernel.org/page.cgi?id=faq.html - 메인 커널 소스 디렉토리에 있는 'Documentation/admin-guide/reporting-issues.rst' -파일은 커널 버그라고 생각되는 것을 보고하는 방법에 관한 좋은 템플릿이며 문제를 +파일은 커널 버그라고 생각되는 것을 어떻게 보고하면 되는지, 그리고 문제를 추적하기 위해서 커널 개발자들이 필요로 하는 정보가 무엇들인지를 상세히 설명하고 있다. @@ -362,8 +356,14 @@ https://bugzilla.kernel.org 는 리눅스 커널 개발자들이 커널의 버 점수를 얻을 수 있는 가장 좋은 방법중의 하나이다. 왜냐하면 많은 사람들은 다른 사람들의 버그들을 수정하기 위하여 시간을 낭비하지 않기 때문이다. -이미 보고된 버그 리포트들을 가지고 작업하기 위해서 https://bugzilla.kernel.org -를 참조하라. +이미 보고된 버그 리포트들을 가지고 작업하기 위해서는 여러분이 관심있는 +서브시스템을 찾아라. 해당 서브시스템의 버그들이 어디로 리포트 되는지 +MAINTAINERS 파일을 체크하라; 그건 대부분 메일링 리스트이고, 가끔은 버그 추적 +시스템이다. 그 장소에 있는 최근 버그 리포트 기록들을 검색하고 여러분이 보기에 +적합하다 싶은 것을 도와라. 여러분은 버그 리포트를 위해 +https://bugzilla.kernel.org 를 체크하고자 할 수도 있다; 소수의 커널 +서브시스템들만이 버그 신고와 추적을 위해 해당 시스템을 실제로 사용하고 있지만, +전체 커널의 버그들이 그곳에 정리된다. 메일링 리스트들 -- cgit v1.2.3 From 3501c960dfda9153c7d3d26921f14bcb107ccb73 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Tue, 23 Mar 2021 17:16:52 +0800 Subject: docs/zh_CN: Add translations in zh_CN/kernel-hacking/ Add new translations * Documentation/translations/zh_CN/kernel-hacking/index.rst * Documentation/translations/zh_CN/kernel-hacking/hacking.rst And link them to zh_CN/index.rst. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210323091651.GA23904@mipc Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/index.rst | 1 + .../translations/zh_CN/kernel-hacking/hacking.rst | 708 +++++++++++++++++++++ .../translations/zh_CN/kernel-hacking/index.rst | 22 + 3 files changed, 731 insertions(+) create mode 100644 Documentation/translations/zh_CN/kernel-hacking/hacking.rst create mode 100644 Documentation/translations/zh_CN/kernel-hacking/index.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/index.rst b/Documentation/translations/zh_CN/index.rst index 2767dacfe86d..4fdd57417ffb 100644 --- a/Documentation/translations/zh_CN/index.rst +++ b/Documentation/translations/zh_CN/index.rst @@ -18,6 +18,7 @@ admin-guide/index process/index + kernel-hacking/index filesystems/index arm64/index sound/index diff --git a/Documentation/translations/zh_CN/kernel-hacking/hacking.rst b/Documentation/translations/zh_CN/kernel-hacking/hacking.rst new file mode 100644 index 000000000000..ab974faddecf --- /dev/null +++ b/Documentation/translations/zh_CN/kernel-hacking/hacking.rst @@ -0,0 +1,708 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/kernel-hacking/hacking.rst + +:译者: + + 吴想成 Wu XiangCheng + +============== +内核骇客指北 +============== + +:作者: Rusty Russell + +引言 +===== + +欢迎咱优雅的读者们来阅读Rusty的非常不靠谱的Linux内核骇客(Hacking)指南。本文 +描述了内核代码的常见例程和一般要求:其目标是引导有经验的C程序员入门Linux内核 +开发。我回避了实现细节:这是代码要做的,也忽略了很多有用的例程。 + +在你读这篇文章之前,请理解我从来没有想过要写这篇文章,因为我的资历太低了; +但我一直想读这样的文章,自己写是唯一的方法。我希望它能成长为一个最佳实践、 +通用起点和其他信息的汇编。 + +玩家 +======= + +在任何时候,系统中的每个CPU都可以: + +- 与任何进程无关,服务于硬件中断; + +- 与任何进程无关,服务于软件中断(softirq)或子任务(tasklet); + +- 运行于内核空间中,与进程(用户上下文)相关联; + +- 在用户空间中运行进程。 + +它们之间有优先级顺序。最下面的两个可以互相抢占,但上面为严格的层次结构: +每个层级只能被上方的抢占。例如,当一个软中断在CPU上运行时,没有其他软中断 +会抢占它,但是硬件中断可以抢占它。不过,系统中的任何其他CPU都是独立执行的。 + +我们将会看到许多方法,用户上下文可以阻止中断,从而成为真正的不可抢占。 + +用户上下文 +------------ + +用户上下文是指当您从系统调用或其他陷阱进入时:就像用户空间一样,您可以被更 +重要的任务和中断抢占。您可以通过调用 :c:func:`schedule()` 进行睡眠。 + +.. note:: + + 在模块加载和卸载以及块设备层上的操作时,你始终处于用户上下文中。 + +在用户上下文中,当前 ``current`` 指针(指示我们当前正在执行的任务)是有效的, +且 :c:func:`in_interrupt()` ( ``include/linux/preempt.h`` )值为非(false)。 + +.. warning:: + + 请注意,如果您禁用了抢占或软中断(见下文),:c:func:`in_interrupt()` 会 + 返回假阳性。 + +硬件中断(Hard IRQs) +---------------------- + +像定时器、网卡和键盘等都是可能在任意时刻产生中断的真实硬件。内核运行中断 +处理程序,为硬件提供服务。内核确保处理程序永远不会重入:如果相同的中断到达, +它将被排队(或丢弃)。因为它会关闭中断,所以处理程序必须很快:通常它只是 +确认中断,标记一个“软件中断”以执行并退出。 + +您可以通过 :c:func:`in_irq()` 返回真来判断您处于硬件中断状态。 + +.. warning:: + + 请注意,如果中断被禁用,这将返回假阳性(见下文)。 + +软件中断上下文:软中断(Softirqs)与子任务(Tasklets) +------------------------------------------------------- + +当系统调用即将返回用户空间或硬件中断处理程序退出时,任何标记为挂起(通常通 +过硬件中断)的“软件中断”将运行( ``kernel/softirq.c`` )。 + +此处完成了许多真正的中断处理工作。在向SMP过渡的早期,只有“bottom halves下半 +部”(BHs)机制,无法利用多个CPU的优势。在从那些一团糟的就电脑切换过来后不久, +我们放弃了这个限制,转而使用“软中断”。 + +``include/linux/interrupt.h`` 列出了不同的软中断。定时器软中断是一个非常重要 +的软中断( ``include/linux/timer.h`` ):您可以注册它以在给定时间后为您调用 +函数。 + +软中断通常是一个很难处理的问题,因为同一个软中断将同时在多个CPU上运行。因此, +子任务( ``include/linux/interrupt.h`` )更常用:它们是动态可注册的(意味着 +您可以拥有任意数量),并且它们还保证任何子任务都只能在一个CPU上运行,不同的 +子任务也可以同时运行。 + +.. warning:: + + “tasklet”这个名字是误导性的:它们与“任务”无关,可能更多与当时 + 阿列克谢·库兹涅佐夫享用的糟糕伏特加有关。 + +你可以使用 :c:func:`in_softirq()` 宏( ``include/linux/preempt.h`` )来确认 +是否处于软中断(或子任务)中。 + +.. warning:: + + 注意,如果持有 :ref:`bottom half lock ` 锁,这将返回 + 假阳性。 + +一些基本规则 +================ + +缺少内存保护 + 如果你损坏了内存,无论是在用户上下文还是中断上下文中,整个机器都会崩溃。 + 你确定你不能在用户空间里做你想做的事吗? + +缺少浮点或MMX + FPU上下文不会被保存;即使在用户上下文中,FPU状态也可能与当前进程不一致: + 您会弄乱某些用户进程的FPU状态。如果真的要这样做,就必须显式地保存/恢复 + 完整的FPU状态(并避免上下文切换)。这通常不是个好主意;请优先用定点算法。 + +严格的堆栈限制 + 对于大多数32位体系结构,根据配置选项的不同内核堆栈大约为3K到6K;对于大 + 多数64位机器,内核堆栈大约为14K,并且经常与中断共享,因此你无法使用全部。 + 应避免深度递归和栈上的巨型本地数组(用动态分配它们来代替)。 + +Linux内核是可移植的 + 就这样吧。您的代码应该是纯64位的,并且不依赖于字节序(endian)。您还应该 + 尽量减少CPU特定的东西,例如内联汇编(inline assembly)应该被干净地封装和 + 最小化以便于移植。一般来说,它应该局限于内核树中有体系结构依赖的部分。 + +输入输出控制(ioctls):避免编写新的系统调用 +============================================== + +系统调用(system call)通常看起来像这样:: + + asmlinkage long sys_mycall(int arg) + { + return 0; + } + + +首先,在大多数情况下,您无需创建新的系统调用。创建一个字符设备并为其实现适当 +的输入输出控制(ioctls)。这比系统调用灵活得多,不必写进每个体系结构的 +``include/asm/unistd.h`` 和 ``arch/kernel/entry.S`` 文件里,而且更容易被Linus +接受。 + +如果您的程序所做的只是读取或写入一些参数,请考虑实现 :c:func:`sysfs()` 接口。 + +在输入输出控制中,您处于进程的用户上下文。出现错误时,返回一个负的错误参数 +(errno,请参阅 ``include/uapi/asm-generic/errno-base.h`` 、 +``include/uapi/asm-generic/errno.h`` 和 ``include/linux/errno.h`` ),否则返 +回0。 + +在睡眠之后,您应该检查是否出现了信号:Unix/Linux处理信号的方法是暂时退出系统 +调用,并返回 ``-ERESTARTSYS`` 错误。系统调用入口代码将切换回用户上下文,处理 +信号处理程序,然后系统调用将重新启动(除非用户禁用了该功能)。因此,您应该准 +备好处理重新启动,例如若您处理某些数据结构到一半。 + +:: + + if (signal_pending(current)) + return -ERESTARTSYS; + + +如果你要做更长时间的计算:优先考虑用户空间。如果你真的想在内核中做这件事,你 +应该定期检查你是否需要让出CPU(请记得每个CPU都有协作多任务)。 +习惯用法:: + + cond_resched(); /* Will sleep */ + + +接口设计的小注释:UNIX系统调用的格言是“提供机制而不是策略 +Provide mechanism not policy”。 + +死锁的“配方” +==================== + +您不能调用任何可能睡眠的程序,除非: + +- 您处于用户上下文中。 + +- 你未拥有任何自旋锁。 + +- 您已经启用中断(实际上,Andi Kleen说调度代码将为您启用它们,但这可能不是 + 您想要的)。 + +注意,有些函数可能隐式地睡眠:常见的是用户空间访问函数(\*_user)和没有 +``GFP_ATOMIC`` 的内存分配函数。 + +您应该始终打开 ``CONFIG_DEBUG_ATOMIC_SLEEP`` 项来编译内核,如果您违反这些 +规则,它将警告您。如果你 **真的** 违反了规则,你最终会锁住你的电脑。 + +真的会这样。 + + +常用函数/程序 +=============== + +:c:func:`printk()` +------------------ + +定义于 ``include/linux/printk.h`` + +:c:func:`printk()` 将内核消息提供给控制台、dmesg和syslog守护进程。它对于调 +试和报告错误很有用,并且可以在中断上下文中使用,但是使用时要小心:如果机器 +的控制台中充斥着printk消息则会无法使用。它使用与ANSI C printf基本兼容的格式 +字符串,并通过C字符串串联为其提供第一个“优先”参数:: + + printk(KERN_INFO "i = %u\n", i); + + +参见 ``include/linux/kern_levels.h`` ;了解其他 ``KERN_`` 值;syslog将这些值 +解释为级别。特殊用法:打印IP地址使用:: + + __be32 ipaddress; + printk(KERN_INFO "my ip: %pI4\n", &ipaddress); + + +:c:func:`printk()` 内部使用的1K缓冲区,不捕获溢出。请确保足够使用。 + +.. note:: + + 当您开始在用户程序中将printf打成printk时,就知道自己是真正的内核程序员了 + :) + +.. note:: + + 另一个注释:最初的unix第六版源代码在其printf函数的顶部有一个注释:“printf + 不应该用于叽叽喳喳”。你也应该遵循此建议。 + +:c:func:`copy_to_user()` / :c:func:`copy_from_user()` / :c:func:`get_user()` / :c:func:`put_user()` +--------------------------------------------------------------------------------------------------- + +定义于 ``include/linux/uaccess.h`` / ``asm/uaccess.h`` + +**[睡眠]** + +:c:func:`put_user()` 和 :c:func:`get_user()` 用于从用户空间中获取和向用户空 +间中传出单个值(如int、char或long)。指向用户空间的指针永远不应该直接取消 +引用:应该使用这些程序复制数据。两者都返回 ``-EFAULT`` 或 0。 + +:c:func:`copy_to_user()` 和 :c:func:`copy_from_user()` 更通用:它们从/向用户 +空间复制任意数量的数据。 + +.. warning:: + + 与 :c:func:`put_user()` 和 :c:func:`get_user()` 不同,它们返回未复制的 + 数据量(即0仍然意味着成功)。 + +【是的,这个愚蠢的接口真心让我尴尬。火爆的口水仗大概每年都会发生。 +—— Rusty Russell】 + +这些函数可以隐式睡眠。它不应该在用户上下文之外调用(没有意义)、调用时禁用中断 +或获得自旋锁。 + +:c:func:`kmalloc()`/:c:func:`kfree()` +------------------------------------- + +定义于 ``include/linux/slab.h`` + +**[可能睡眠:见下]** + +这些函数用于动态请求指针对齐的内存块,类似用户空间中的malloc和free,但 +:c:func:`kmalloc()` 需要额外的标志词。重要的值: + +``GFP_KERNEL`` + 可以睡眠和交换以释放内存。只允许在用户上下文中使用,但这是分配内存最可靠 + 的方法。 + +``GFP_ATOMIC`` + 不会睡眠。较 ``GFP_KERNEL`` 更不可靠,但可以从中断上下文调用。你 **应该** + 有一个很好的内存不足错误处理策略。 + +``GFP_DMA`` + 分配低于16MB的ISA DMA。如果你不知道那是什么,那你就不需要了。非常不可靠。 + +如果您看到一个从无效上下文警告消息调用的睡眠的函数,那么您可能在没有 +``GFP_ATOMIC`` 的情况下从中断上下文调用了一个睡眠的分配函数。你必须立即修复, +快点! + +如果你要分配至少 ``PAGE_SIZE`` ( ``asm/page.h`` 或 ``asm/page_types.h`` ) +字节,请考虑使用 :c:func:`__get_free_pages()` ( ``include/linux/gfp.h`` )。 +它采用顺序参数(0表示页面大小,1表示双页,2表示四页……)和与上述相同的内存 +优先级标志字。 + +如果分配的字节数超过一页,可以使用 :c:func:`vmalloc()` 。它将在内核映射中分 +配虚拟内存。此块在物理内存中不是连续的,但是MMU(内存管理单元)使它看起来像 +是为您准备好的连续空间(因此它只是看起来对cpu连续,对外部设备驱动程序则不然)。 +如果您真的需要为一些奇怪的设备提供大量物理上连续的内存,那么您就会遇到问题: +Linux对此支持很差,因为正在运行的内核中的内存碎片化会使它变得很困难。最好的 +方法是在引导过程的早期通过 :c:func:`alloc_bootmem()` 函数分配。 + +在创建自己的常用对象缓存之前,请考虑使用 ``include/linux/slab.h`` 中的slab +缓存。 + +:c:macro:`current` +------------------ + +定义于 ``include/asm/current.h`` + +此全局变量(其实是宏)包含指向当前任务结构(task structure)的指针,因此仅在 +用户上下文中有效。例如,当进程进行系统调用时,这将指向调用进程的任务结构。 +在中断上下文中不为空(**not NULL**)。 + +:c:func:`mdelay()`/:c:func:`udelay()` +------------------------------------- + +定义于 ``include/asm/delay.h`` / ``include/linux/delay.h`` + +:c:func:`udelay()` 和 :c:func:`ndelay()` 函数可被用于小暂停。不要对它们使用 +大的值,因为这样会导致溢出——帮助函数 :c:func:`mdelay()` 在这里很有用,或者 +考虑 :c:func:`msleep()`。 + +:c:func:`cpu_to_be32()`/:c:func:`be32_to_cpu()`/:c:func:`cpu_to_le32()`/:c:func:`le32_to_cpu()` +----------------------------------------------------------------------------------------------- + +定义于 ``include/asm/byteorder.h`` + +:c:func:`cpu_to_be32()` 系列函数(其中“32”可以替换为64或16,“be”可以替换为 +“le”)是在内核中进行字节序转换的常用方法:它们返回转换后的值。所有的变体也 +提供反向转换函数: +:c:func:`be32_to_cpu()` 等。 + +这些函数有两个主要的变体:指针变体,例如 :c:func:`cpu_to_be32p()` ,它获取 +指向给定类型的指针,并返回转换后的值。另一个变体是“in-situ”系列,例如 +:c:func:`cpu_to_be32s()` ,它转换指针引用的值,并返回void。 + +:c:func:`local_irq_save()`/:c:func:`local_irq_restore()` +-------------------------------------------------------- + +定义于 ``include/linux/irqflags.h`` + + +这些程序禁用本地CPU上的硬中断,并还原它们。它们是可重入的;在其一个 +``unsigned long flags`` 参数中保存以前的状态。如果您知道中断已启用,那么可 +直接使用 :c:func:`local_irq_disable()` 和 :c:func:`local_irq_enable()`。 + +.. _local_bh_disable_zh: + +:c:func:`local_bh_disable()`/:c:func:`local_bh_enable()` +-------------------------------------------------------- + +定义于 ``include/linux/bottom_half.h`` + + +这些程序禁用本地CPU上的软中断,并还原它们。它们是可重入的;如果之前禁用了 +软中断,那么在调用这对函数之后仍然会禁用它们。它们阻止软中断和子任务在当前 +CPU上运行。 + +:c:func:`smp_processor_id()` +---------------------------- + +定义于 ``include/linux/smp.h`` + +:c:func:`get_cpu()` 禁用抢占(这样您就不会突然移动到另一个cpu)并返回当前 +处理器号,介于0和 ``NR_CPUS`` 之间。请注意,CPU编号不一定是连续的。完成后, +使用 :c:func:`put_cpu()` 再次返回。 + +如果您知道您不能被另一个任务抢占(即您处于中断上下文中,或已禁用抢占),您 +可以使用 :c:func:`smp_processor_id()`。 + +``__init``/``__exit``/``__initdata`` +------------------------------------ + +定义于 ``include/linux/init.h`` + +引导之后,内核释放一个特殊的部分;用 ``__init`` 标记的函数和用 ``__initdata`` +标记的数据结构在引导完成后被丢弃:同样地,模块在初始化后丢弃此内存。 +``__exit`` 用于声明只在退出时需要的函数:如果此文件未编译为模块,则该函数将 +被删除。请参阅头文件以使用。请注意,使用 :c:func:`EXPORT_SYMBOL()` 或 +:c:func:`EXPORT_SYMBOL_GPL()` 将标记为 ``__init`` 的函数导出到模块是没有意义 +的——这将出问题。 + + +:c:func:`__initcall()`/:c:func:`module_init()` +---------------------------------------------- + +定义于 ``include/linux/init.h`` / ``include/linux/module.h`` + +内核的许多部分都作为模块(内核的可动态加载部分)良好服务。使用 +:c:func:`module_init()` 和 :c:func:`module_exit()` 宏可以简化代码编写,无需 +``#ifdef`` ,即可以作为模块运行或内置在内核中。 + +:c:func:`module_init()` 宏定义在模块插入时(如果文件编译为模块)或在引导时 +调用哪个函数:如果文件未编译为模块,:c:func:`module_init()` 宏将等效于 +:c:func:`__initcall()` ,它通过链接器的魔力确保在引导时调用该函数。 + +该函数可以返回一个错误值,以导致模块加载失败(不幸的是,如果将模块编译到内核 +中,则此操作无效)。此函数在启用中断的用户上下文中调用,因此可以睡眠。 + +:c:func:`module_exit()` +----------------------- + + +定义于 ``include/linux/module.h`` + +这个宏定义了在模块删除时要调用的函数(如果是编译到内核中的文件,则无用武之地)。 +只有在模块使用计数到零时才会调用它。这个函数也可以睡眠,但不能失败:当它返回 +时,所有的东西都必须清理干净。 + +注意,这个宏是可选的:如果它不存在,您的模块将不可移除(除非 ``rmmod -f`` )。 + +:c:func:`try_module_get()`/:c:func:`module_put()` +------------------------------------------------- + +定义于 ``include/linux/module.h`` + +这些函数会操作模块使用计数,以防止删除(如果另一个模块使用其导出的符号之一, +则无法删除模块,参见下文)。在调用模块代码之前,您应该在该模块上调用 +:c:func:`try_module_get()` :若失败,那么该模块将被删除,您应该将其视为不存在。 +若成功,您就可以安全地进入模块,并在完成后调用模块 :c:func:`module_put()` 。 + +大多数可注册结构体都有所有者字段,例如在 +:c:type:`struct file_operations ` 结构体中,此字段应设置为 +宏 ``THIS_MODULE`` 。 + +等待队列 ``include/linux/wait.h`` +==================================== + +**[睡眠]** + +等待队列用于等待某程序在条件为真时唤醒另一程序。必须小心使用,以确保没有竞争 +条件。先声明一个 :c:type:`wait_queue_head_t` ,然后对希望等待该条件的进程声明 +一个关于它们自己的 :c:type:`wait_queue_entry_t` ,并将其放入队列中。 + +声明 +----- + +使用 :c:func:`DECLARE_WAIT_QUEUE_HEAD()` 宏声明一个 ``wait_queue_head_t`` , +或者在初始化代码中使用 :c:func:`init_waitqueue_head()` 程序。 + +排队 +----- + +将自己放在等待队列中相当复杂,因为你必须在检查条件之前将自己放入队列中。有一 +个宏可以来执行此操作: :c:func:`wait_event_interruptible()` +( ``include/linux/wait.h`` )第一个参数是等待队列头,第二个参数是计算的表达 +式;当该表达式为true时宏返回0,或者在接收到信号时返回 ``-ERESTARTSYS`` 。 +:c:func:`wait_event()` 版本会忽略信号。 + +唤醒排队任务 +------------- + +调用 :c:func:`wake_up()` ( ``include/linux/wait.h`` ),它将唤醒队列中的所有 +进程。例外情况:如果有一个进程设置了 ``TASK_EXCLUSIVE`` ,队列的其余部分将不 +会被唤醒。这个基本函数的其他变体也可以在同一个头文件中使用。 + +原子操作 +========= + +某些操作在所有平台上都有保证。第一类为操作 :c:type:`atomic_t` +( ``include/asm/atomic.h`` )的函数;它包含一个有符号整数(至少32位长), +您必须使用这些函数来操作或读取 :c:type:`atomic_t` 变量。 +:c:func:`atomic_read()` 和 :c:func:`atomic_set()` 获取并设置计数器,还有 +:c:func:`atomic_add()` ,:c:func:`atomic_sub()` ,:c:func:`atomic_inc()` , +:c:func:`atomic_dec()` 和 :c:func:`atomic_dec_and_test()` (如果递减为零, +则返回true)。 + +是的。它在原子变量为零时返回true(即!=0)。 + +请注意,这些函数比普通的算术运算速度慢,因此不应过度使用。 + +第二类原子操作是在 ``unsigned long`` ( ``include/linux/bitops.h`` )上的 +原子位操作。这些操作通常采用指向位模式(bit pattern)的指针,第0位是最低有效 +位。:c:func:`set_bit()`,:c:func:`clear_bit()` 和 :c:func:`change_bit()` 设置、 +清除和更改给定位。:c:func:`test_and_set_bit()` ,:c:func:`test_and_clear_bit()` +和 :c:func:`test_and_change_bit()` 执行相同的操作,但如果之前设置了位,则返回 +true;这些对于原子设置标志特别有用。 + +可以使用大于 ``BITS_PER_LONG`` 位的位索引调用这些操作。但结果在大端序平台上 +不太正常,所以最好不要这样做。 + +符号 +===== + +在内核内部,正常的链接规则仍然适用(即除非用static关键字将符号声明为文件范围, +否则它可以在内核中的任何位置使用)。但是对于模块,会保留一个特殊可导出符号表, +该表将入口点限制为内核内部。模块也可以导出符号。 + +:c:func:`EXPORT_SYMBOL()` +------------------------- + +定义于 ``include/linux/export.h`` + +这是导出符号的经典方法:动态加载的模块将能够正常使用符号。 + +:c:func:`EXPORT_SYMBOL_GPL()` +----------------------------- + +定义于 ``include/linux/export.h`` + + +类似于 :c:func:`EXPORT_SYMBOL()`,只是 :c:func:`EXPORT_SYMBOL_GPL()` 导出的 +符号只能由具有由 :c:func:`MODULE_LICENSE()` 指定GPL兼容许可证的模块看到。这 +意味着此函数被认为是一个内部实现问题,而不是一个真正的接口。一些维护人员和 +开发人员在添加一些新的API或功能时可能却需要导出 EXPORT_SYMBOL_GPL()。 + +:c:func:`EXPORT_SYMBOL_NS()` +---------------------------- + +定义于 ``include/linux/export.h`` + +这是 ``EXPORT_SYMBOL()`` 的变体,允许指定符号命名空间。符号名称空间记录于 +Documentation/core-api/symbol-namespaces.rst 。 + +:c:func:`EXPORT_SYMBOL_NS_GPL()` +-------------------------------- + +定义于 ``include/linux/export.h`` + +这是 ``EXPORT_SYMBOL_GPL()`` 的变体,允许指定符号命名空间。符号名称空间记录于 +Documentation/core-api/symbol-namespaces.rst 。 + +程序与惯例 +=========== + +双向链表 ``include/linux/list.h`` +----------------------------------- + +内核头文件中曾经有三组链表程序,但这一组是赢家。如果你对一个单链表没有特别迫切的 +需求,那么这是一个不错的选择。 + +通常 :c:func:`list_for_each_entry()` 很有用。 + +返回值惯例 +------------ + +对于在用户上下文中调用的代码,违背C语言惯例是很常见的,即返回0表示成功,返回 +负错误值(例如 ``-EFAULT`` )表示失败。这在一开始可能是不直观的,但在内核中 +相当普遍。 + +使用 :c:func:`ERR_PTR()` ( ``include/linux/err.h`` )将负错误值编码到指针中, +然后使用 :c:func:`IS_ERR()` 和 :c:func:`PTR_ERR()` 将其再取出:避免为错误值 +使用单独的指针参数。挺讨厌的,但的确是个好方式。 + +破坏编译 +---------- + +Linus和其他开发人员有时会更改开发内核中的函数或结构体名称;这样做不仅是为了 +让每个人都保持警惕,还反映了一个重大的更改(例如,不能再在打开中断的情况下 +调用,或者执行额外的检查,或者不执行以前捕获的检查)。通常这会附带一个linux +内核邮件列表中相当全面的注释;请搜索存档以查看。简单地对文件进行全局替换通常 +会让事情变得 **更糟** 。 + +初始化结构体成员 +------------------ + +初始化结构体的首选方法是使用指定的初始化器,如ISO C99所述。 +例如:: + + static struct block_device_operations opt_fops = { + .open = opt_open, + .release = opt_release, + .ioctl = opt_ioctl, + .check_media_change = opt_media_change, + }; + + +这使得很容易查找(grep),并且可以清楚地看到设置了哪些结构字段。你应该这样做, +因为它看起来很酷。 + +GNU 扩展 +---------- + +Linux内核中明确允许GNU扩展。请注意,由于缺乏通用性,一些更复杂的版本并没有 +得到很好的支持,但以下内容被认为是标准的(有关更多详细信息,请参阅GCC info页 +的“C 扩展”部分——是的,实际上是info页,手册页只是info中内容的简短摘要)。 + +- 内联函数 + +- 语句表达式(Statement expressions)(即({ 和 })结构)。 + + +- 声明函数/变量/类型的属性(__attribute__) + +- typeof + +- 零长度数组 + +- 宏变量 + +- 空指针运算 + +- 非常量(Non-Constant)初始化程序 + +- 汇编程序指令(在 arch/ 和 include/asm/ 之内) + +- 字符串函数名(__func__)。 + +- __builtin_constant_p() + +在内核中使用long long时要小心,gcc为其生成的代码非常糟糕:除法和乘法在i386上 +不能工作,因为内核环境中缺少用于它的gcc运行时函数。 + +C++ +--- + +在内核中使用C++通常是个坏主意,因为内核不提供必要的运行时环境,并且不为其 +测试包含文件。不过这仍然是可能的,但不建议。如果你真的想这么做,至少别用 +异常处理(exceptions)。 + +#if +--- + +通常认为,在头文件(或.c文件顶部)中使用宏来抽象函数比在源代码中使用“if”预 +处理器语句更干净。 + +把你的东西放进内核里 +====================== + +为了让你的东西更正式、补丁更整洁,还有一些工作要做: + +- 搞清楚你在谁的地界儿上干活。查看源文件的顶部、 ``MAINTAINERS`` 文件以及 + ``CREDITS`` 文件的最后一部分。你应该和此人协调,确保你没有重新发明轮子, + 或者尝试一些已经被拒绝的东西。 + + 确保你把你的名字和电子邮件地址放在你创建或修改的任何文件的顶部。当人们发 + 现一个缺陷,或者想要做出修改时,这是他们首先会看的地方。 + +- 通常你需要一个配置选项来支持你的内核编程。在适当的目录中编辑 ``Kconfig`` 。 + 配置语言很容易通过剪切和粘贴来使用,在 + Documentation/kbuild/kconfig-language.rst 中有完整的文档。 + + 在您对选项的描述中,请确保同时照顾到了专家用户和对此功能一无所知的用户。 + 在此说明任何不兼容和问题。结尾一定要写上“如有疑问,就选N”(或者是“Y”); + 这是针对那些看不懂你在说什么的人的。 + +- 编辑 ``Makefile`` :配置变量在这里导出,因此通常你只需添加一行 + “obj-$(CONFIG_xxx) += xxx.o”。语法记录在 + Documentation/kbuild/makefiles.rst 。 + +- 如果你做了一些有意义的事情,那可以把自己放进 ``CREDITS`` ,通常不止一个 + 文件(无论如何你的名字都应该在源文件的顶部)。维护人员意味着您希望在对 + 子系统进行更改时得到询问,并了解缺陷;这意味着对某部分代码做出更多承诺。 + +- 最后,别忘记去阅读 Documentation/process/submitting-patches.rst , + 也许还有 Documentation/process/submitting-drivers.rst 。 + +Kernel 仙女棒 +=============== + +浏览源代码时的一些收藏。请随意添加到此列表。 + +``arch/x86/include/asm/delay.h``:: + + #define ndelay(n) (__builtin_constant_p(n) ? \ + ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ + __ndelay(n)) + + +``include/linux/fs.h``:: + + /* + * Kernel pointers have redundant information, so we can use a + * scheme where we can return either an error code or a dentry + * pointer with the same return value. + * + * This should be a per-architecture thing, to allow different + * error and pointer decisions. + */ + #define ERR_PTR(err) ((void *)((long)(err))) + #define PTR_ERR(ptr) ((long)(ptr)) + #define IS_ERR(ptr) ((unsigned long)(ptr) > (unsigned long)(-1000)) + +``arch/x86/include/asm/uaccess_32.h:``:: + + #define copy_to_user(to,from,n) \ + (__builtin_constant_p(n) ? \ + __constant_copy_to_user((to),(from),(n)) : \ + __generic_copy_to_user((to),(from),(n))) + + +``arch/sparc/kernel/head.S:``:: + + /* + * Sun people can't spell worth damn. "compatibility" indeed. + * At least we *know* we can't spell, and use a spell-checker. + */ + + /* Uh, actually Linus it is I who cannot spell. Too much murky + * Sparc assembly will do this to ya. + */ + C_LABEL(cputypvar): + .asciz "compatibility" + + /* Tested on SS-5, SS-10. Probably someone at Sun applied a spell-checker. */ + .align 4 + C_LABEL(cputypvar_sun4m): + .asciz "compatible" + + +``arch/sparc/lib/checksum.S:``:: + + /* Sun, you just can't beat me, you just can't. Stop trying, + * give up. I'm serious, I am going to kick the living shit + * out of you, game over, lights out. + */ + + +致谢 +===== + +感谢Andi Kleen提出点子,回答我的问题,纠正我的错误,充实内容等帮助。 +感谢Philipp Rumpf做了许多拼写和清晰度修复,以及一些优秀的不明显的点。 +感谢Werner Almesberger对 :c:func:`disable_irq()` 做了一个很好的总结, +Jes Sorensen和Andrea Arcangeli补充了一些注意事项。 +感谢Michael Elizabeth Chastain检查并补充了配置部分。 +感谢Telsa Gwynne教我DocBook。 diff --git a/Documentation/translations/zh_CN/kernel-hacking/index.rst b/Documentation/translations/zh_CN/kernel-hacking/index.rst new file mode 100644 index 000000000000..df530de2278d --- /dev/null +++ b/Documentation/translations/zh_CN/kernel-hacking/index.rst @@ -0,0 +1,22 @@ +.. _kernel_hacking_zh: + +.. include:: ../disclaimer-zh_CN.rst + +:Original: Documentation/kernel-hacking/index.rst + +:译者: + + 吴想成 Wu XiangCheng + +============= +内核骇客指南 +============= + +.. toctree:: + :maxdepth: 2 + + hacking + +TODO + +- locking -- cgit v1.2.3 From d5d444d0ea860a9b58741b78c3e8be9585ccd83f Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 18 Mar 2021 15:19:17 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/reporting-issues Add translation zh_CN/admin-guide/reporting-issues.rst, and link it to zh_CN/admin-guide/index.rst. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/13d126d5a210988728c76398436c62f1fb25fb0c.1616050069.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/index.rst | 5 + .../zh_CN/admin-guide/reporting-issues.rst | 1269 ++++++++++++++++++++ 2 files changed, 1274 insertions(+) create mode 100644 Documentation/translations/zh_CN/admin-guide/reporting-issues.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index a716a48c8018..fe2abc3fec86 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -32,6 +32,11 @@ Todolist: 下面的一组文档,针对的是试图跟踪问题和bug的用户。 +.. toctree:: + :maxdepth: 1 + + reporting-issues + Todolist: reporting-bugs diff --git a/Documentation/translations/zh_CN/admin-guide/reporting-issues.rst b/Documentation/translations/zh_CN/admin-guide/reporting-issues.rst new file mode 100644 index 000000000000..2805c1a03cd5 --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/reporting-issues.rst @@ -0,0 +1,1269 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR CC-BY-4.0) +.. + If you want to distribute this text under CC-BY-4.0 only, please use 'The + Linux kernel developers' for author attribution and link this as source: + https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/Documentation/admin-guide/reporting-issues.rst +.. + Note: Only the content of this RST file as found in the Linux kernel sources + is available under CC-BY-4.0, as versions of this text that were processed + (for example by the kernel's build system) might contain content taken from + files which use a more restrictive license. + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../admin-guide/reporting-issues` + +:译者: + + 吴想成 Wu XiangCheng + +.. important:: + + 本文档将取代“Documentation/admin-guide/reporting-bugs.rst”。主要的工作 + 已经完成,你可以自由地按照其指示来向Linux内核开发者报告问题。但请留意, + 下面的文字还需要一些润色和校审。现阶段它被合并到Linux内核源代码中,以使 + 这个过程更容易,并增加文本的可见性。 + + 因此,任何文本改进或其他反馈都是非常受欢迎的。请将它发送到“Thorsten + Leemhuis ”和“Jonathan Corbet ”, + 最好抄送“Linux内核邮件列表(LKML) ”和 + “Linux内核文档列表 ”。 + + 文本中仍需改进或讨论的区域包含了指出剩余问题的提示;它们都以“FIXME”开头, + 这样更容易找到。 + + +报告问题 ++++++++++ + + +简明指南(亦即 太长不看) +========================== + +如果您同时面临多个Linux内核的问题,请分别向开发人员报告每个问题。请尽力尝试 +猜测哪个内核部分可能导致问题。查看 :ref:`MAINTAINERS ` 文件, +了解开发人员希望如何被告知有关问题。请注意 `bugzilla.kernel.org +`_ 很少用到,因为几乎在所有情况下,报告都需要 +通过电子邮件发送! + +请彻底检查目标是否已有此报告;也请搜索LKML(内核邮件列表)档案和网络。如果 +找到匹配的,请加入现有的讨论。如果没有找到,请安装 `最新的Linux主线内核 +`_ 。确保其是纯净的,也就是没有打补丁或使用附加的内核 +模块。还要确保内核运行在一个正常的环境中,并且在问题发生之前没有受到污染。 + +如果您可以用主线内核复现您的问题,那么请向您之前确定的目标发送一个报告。确 +保它包括所有相关信息,在导致回归(regression)的情况下应该提到导致它的变化, +这通常可以通过二分法找到。还要确保报告能够送达给所有需要了解它的人,例如 +安全团队、稳定版维护者或导致回归的补丁开发人员。一旦发送报告,请回答可能出 +现的任何问题,并尽可能提供帮助。这包括继续工作:每次发布新的rc1主线内核时, +检查这个问题是否仍然存在,并在初始报告中添加状态更新。 + +如果你无法在主线内核中复现这个问题,那么请考虑继续使用它;如果您想使用较旧 +的版本线,并希望看到它在那里得到修复,那么首先要确定它仍受支持。将其最新版 +本安装为纯净内核。如果你不能在那里复现这个问题,试着在主线中或之前的任何讨 +论中找到修复它的提交:这些讨论经常会提到是否有计划支持或认为支持太复杂。如 +果没有讨论支持,可询问是否有可能。如果您没有发现任何提交或之前的讨论,请参 +阅Linux-stable邮件列表存档中现有的报告,因为它可能是特定版本线的回归。如果 +是,就像在主线中报告问题一样报告它(包括二分结果)。 + +如果仍没有解决方案,请在子系统的邮件列表中寻求建议。 + + +如何向内核维护人员报告问题的逐步指南 +===================================== + +上面的简明指南概述了如何向Linux内核开发人员报告问题。对于已经熟悉向自由和开 +源软件(FLOSS)项目报告问题的人来说,这可能是他们所需要的全部内容。对于其他 +人,本部分更为详细,并一步一步地描述。为了便于阅读,它仍然尽量简洁,并省略 +了许多细节;这些在逐步指南后的参考章节中进行了描述,该章节更详细地解释了每 +个步骤。 + +注意:本节涉及的方面比简明指南多,顺序也稍有不同。这符合你的利益,以确保您 +尽早意识到看起来像Linux内核毛病的问题可能实际上是由其他原因引起的。这些步骤 +可以确保你最终不会觉得在这一过程中投入的时间是浪费: + + * 停止阅读本文档并将问题报告给您的供应商,除非您已经运行了最新的主线内核或 + 愿意安装它。这个内核不能以任何方式被修改或增强,因此被认为是“纯净的”。 + + * 看看你正在处理的问题是否为回归问题、安全问题或非常严重的问题:这些都是需 + 要在接下来的一些步骤中特别处理的“高优先级问题”。 + + * 当问题发生时,检查您的内核是否被“污染”,因为使内核设置这个标志的事件可能 + 会导致您面临的问题。 + + * 定位可能引起问题的驱动程序或内核子系统。找出其开发人员期望的报告的方式和 + 位置。注意:大多数情况下不会是 bugzilla.kernel.org,因为问题通常需要通 + 过邮件发送给维护人员和公共邮件列表。 + + * 在缺陷追踪器或问题相关邮件列表的存档中彻底搜索可能与您的问题匹配的报告。 + 还要检查您是否能在您喜爱的网络搜索引擎或Linux内核邮件列表(LKML)存档中 + 找到一些信息。如果您发现了什么,请加入讨论,而不是发送新的报告。 + + * 创建一个新的备份,并将系统修复和恢复工具放在手边。 + + * 确保您的系统不会通过动态构建额外的内核模块来增强其内核,像DKMS这样的解决 + 方案可能在您不知情的情况下就在本地进行了这样的工作。 + + * 确保不是内核环境导致了您面临的问题。 + + * 粗略地写下如何重现这个问题。如果您同时处理多个问题,请为每个问题单独写注 + 释,并确保它们在新启动的系统上独立出现。这是必要的,因为每个问题都需要分 + 别报告给内核开发人员,除非它们严重纠缠在一起。 + +在完成这些准备之后,你将进入主要部分: + + * 安装最新的Linux主线内核:这是所有问题首先得到修复的地方,因为它是内核开 + 发人员主要关注的版本线。在某些情况下,使用最新的Linux稳定版内核进行测试 + 和报告也是一个可以接受的替代方案,例如在合并窗口期间;但在这段时间里,你 + 可能想要暂停努力直到它结束。 + + * 确保您刚刚安装的内核在运行时不会“污染”自己。 + + * 在您刚刚安装的内核中复现这个问题。如果它没有出现,请查看只发生在稳定版和 + 长期支持内核的问题的说明。 + + * 优化你的笔记:试着找到并写出最直接的复现问题的方法。确保最终结果包含所有 + 重要的细节,同时让第一次听说的人容易阅读和理解。如果您在此过程中学到了一 + 些东西,请考虑再次搜索关于该问题的现有报告。 + + * 如果失败包含堆栈转储(stack dump),例如Oops所做的,则请考虑对其进行解码 + 以找到出错的代码行。 + + * 如果您的问题是回归问题,请尽可能缩小引入问题时的范围。 + + * 通过详细描述问题来开始编写报告。记得包括以下条目:您为复现而安装的最新内 + 核版本、使用的Linux发行版以及关于如何复现该问题的说明。如果可能,将内核 + 构建配置(.config)和 ``dmesg`` 的输出放在网上的某个地方,并链接到它。包 + 含或上传所有其他可能相关的信息,如Oops的输出/截图或来自 ``lspci`` 的输出 + 。一旦你写完了这个主要部分,请在上方插入一个正常长度的段落快速概述问题和 + 影响。再在此之上添加一个简单描述问题的句子,以得到人们的阅读。现在给出一 + 个更短的描述性标题或主题。然后就可以像MAINTAINERS文件告诉你的那样发送或 + 提交报告了,除非你在处理一个“高优先级问题”:它们需要按照下面“高优先级问 + 题的特殊处理”所述特别关照。 + + * 等待别人的反应,继续推进事情,直到你能够接受这样或那样的结果。因此,请公 + 开和及时地回应任何询问。测试提出的修复。积极地测试:至少重新测试每个新主 + 线版本的首个候选版本(RC),并报告你的结果。如果出现拖延,就友好地提醒一 + 下。如果你没有得到任何帮助或者未能满意,请试着自己帮助自己。 + + +报告只发生在较旧内核版本线的问题 +---------------------------------- + +如果您尝试了如上所述的最新主线内核,但未能重现您的问题,那么本节是为您准备 +的;若您同时希望看到在旧版本线或定期根据新的稳定或长期发行版重新编写的供应 +商内核中修复这个问题,请遵循以下步骤: + + * 请做好准备,接下来的几个步骤可能无法在旧版本中解决问题:修复可能太大或太 + 冒险,无法移植到那里。 + + * 检查内核开发人员是否仍然维护你关心的Linux内核版本线:去 `kernel.org + `_ 的首页,确保此特定版本线的最新版没有“[EOL]”标记。 + + * 检查Linux稳定版邮件列表中的现有报告。 + + * 从特定的版本线安装最新版本作为纯净内核。确保这个内核没有被污染,并且仍然 + 存在问题,因为问题可能已经在那里被修复了。 + + * 在Linux内核版本控制系统中搜索修复主线问题的更改,因为它的提交消息可能会 + 告诉你修复是否已经计划好了支持。如果你没有找到,搜索适当的邮件列表,寻找 + 讨论此类问题或同行评议可能修复的帖子;然后检查讨论是否认为修复不适合支持。 + 如果支持根本不被考虑,加入最新的讨论,询问是否有可能。 + + * 通过安装您所关心的版本线的首个发行版,检查您是否正在处理主线中从未出现过 + 的回归。如果这个问题没有出现,你基本上需要用此版本来报告这个问题,就像你 + 用主线报告一个问题一样(见上面)。理想情况下,在该主题和两个相关提交ID的 + 帮助下,通过对网上现有报告的搜索,将能二分问题。如果还是一无所获,那就写 + 份报告;将报告抄送或转发给稳定版维护者、稳定版邮件列表和编写更改的人。如 + 果您发现了导致问题的更改,请包含缩短的提交ID。 + + * 前面的步骤之一应该会给出一个解决方案。如果仍未能成功,请向可能引起问题的 + 子系统的维护人员询问建议;抄送特定子系统的邮件列表以及稳定版邮件列表 + + +参考章节:向内核维护者报告问题 +=============================== + +上面的详细指南简要地列出了所有主要步骤,这对大多数人来说应该足够了。但有时, +即使是有经验的用户也可能想知道如何实际执行这些步骤之一。这就是本节的目的, +因为它将提供关于上述每个步骤的更多细节。请将此作为参考文档:可以从头到尾 +阅读它。但它主要是为了浏览和查找如何实际执行这些步骤的详细信息。 + +在深入挖掘细节之前,我想先给你一些一般性建议: + + * Linux内核开发人员很清楚这个过程很复杂,比其他的FLOSS项目要求更多。我们很 + 希望让它更简单。但这需要在不同的地方以及一些基础设施上付诸努力,这些基础 + 设施需要持续的维护;尚未有人站出来做这些工作,所以目前情况就是这样。 + + * 与某些供应商签订的保证或支持合同并不能使您有权要求上游Linux内核社区的开 + 发人员进行修复:这样的合同完全在Linux内核、其开发社区和本文档的范围之外。 + 这就是为什么在这种情况下,你不能要求任何契约保证,即使开发人员处理的问 + 题对供应商有效。如果您想主张您的权利,使用供应商的支持渠道代替。当这样做 + 的时候,你可能想提出你希望看到这个问题在上游Linux内核中修复;可以这是确 + 保最终修复将被纳入所有Linux发行版的唯一方法来鼓励他们。 + + * 如果您从未向FLOSS项目报告过任何问题,那么您应该考虑阅读 `如何有效地报告 + 缺陷 `_ , `如何 + 以明智的方式提问 `_ , + 和 `如何提出好问题 `_ 。 + +解决这些问题之后,可以在下面找到如何正确地向Linux内核报告问题的详细信息。 + + +确保您使用的是上游Linux内核 +---------------------------- + + *停止阅读本文档,并将问题报告给您的供应商,除非您已经运行了最新的主线内 + 核或愿意安装它。这个内核不能以任何方式被修改或增强,因此被认为是“纯净的”。* + +像大多数程序员一样,Linux内核开发人员不喜欢花时间处理他们维护的源代码中根本 +不会发生的问题的报告:这只会浪费每个人的时间,包括您的时间。这就是为什么你 +之后必须用最新的“纯净”内核来测试你的问题:一个直接从 `kernel.org +`_ 上获取的Linux源代码构建的内核,没有以任何方式进行修 +改或增强。 + +从内核开发的角度来看,几乎所有设备(计算机、笔记本电脑、智能手机、路由器……) +使用的内核和大多数Linux发行版提供的内核都很古老,并且经过了大量修改。因此, +它们不具备向Linux内核开发人员报告问题的资格:您在此类内核中面临的问题可能 +已经修复,或者是由更改或添加引起的,即使它们看起来很小或完全不相关。这就是 +为什么这些内核的问题需要报告给分发它的供应商。它的开发人员应该查看报告,如 +若发现是上游问题,直接向上游修复它或在那里报告它。在实践中,这有时行不通。 +如果是这种情况,您可能想要绕过供应商,自己安装最新的主线内核,并报告本文档 +中概述的问题;只是要确保使用真正新鲜的内核(见下文)。 + + +.. note:: + + FIXME:我们应该接受与“纯净内核”映像非常接近的问题报告吗?但是什么时候它 + 们足够接近,又该如何用文字表达呢?也许像这样? + + *注意:一些Linux内核开发人员接受来自已知接近上游的供应商内核的报告。例 + 如Debian GNU/Linux Sid或Fedora Rawhide的内核,它们通常紧跟主线,只携带 + 几个补丁。因此,其中之一的报告可能会被需要处理它的开发人员所接受。但如 + 果他们真的这么做了,很大程度上取决于单个开发人员和手头的问题。这就是为 + 什么安装主线纯净内核是安全的选择。* + + *Arch Linux,其他Fedora发行版,以及openSUSE Tumbleweed通常使用非常接近 + 上游的稳定版内核。一些开发人员也会从他们那里接受缺陷报告。但请注意,通 + 常应该避免使用稳定版内核来报告问题,而应使用主线内核(见下文)。* + + 还有其他主要的Linux发行版应该在这里提到吗? + + +高优先级的问题? +----------------- + + *看看你正在处理的问题是否是回归问题、安全问题或非常严重的问题:这些都是 + 需要在接下来的一些步骤中特别处理的“高优先级问题”。* + +Linus Torvalds和主要的Linux内核开发人员希望看到一些问题尽快得到解决,因此在 +报告过程中有一些“高优先级问题”的处理略有不同。有三种情况符合条件:回归、安全 +问题和非常严重的问题。 + +如果在旧版本的Linux内核中工作的东西不能在新版本的Linux内核中工作,或者某种 +程度上在新版本的Linux内核中工作得更差,那么你就需要处理“回归”。因此,当一个 +在Linux 5.7中表现良好的WiFi驱动程序在5.8中表现不佳或根本不能工作时,这是一 +种回归。如果应用程序在新的内核中出现不稳定的现象,这也是一种回归,这可能是 +由于内核和用户空间之间的接口(如procfs和sysfs)发生不兼容的更改造成的。显著 +的性能降低或功耗增加也可以称为回归。但是请记住:新内核需要使用与旧内核相似的 +配置来构建(参见下面如何实现这一点)。这是因为内核开发人员在实现新特性时有 +时无法避免不兼容性;但是为了避免回归,这些特性必须在构建配置期间显式地启用。 + +什么是安全问题留给您自己判断。在继续之前,请考虑阅读 +“Documentation/admin-guide/security-bugs.rst”,因为它提供了如何最恰当地处理 +安全问题的额外细节。 + +当发生了完全无法接受的糟糕事情时,此问题就是一个“非常严重的问题”。例如, +Linux内核破坏了它处理的数据或损坏了它运行的硬件。当内核突然显示错误消息 +(“kernel panic”)并停止工作,或者根本没有任何停止信息时,您也在处理一个严重 +的问题。注意:不要混淆“panic”(内核停止自身的致命错误)和“Oops”(可恢复错误), +因为显示后者之后内核仍然在运行。 + + +检查“污染”标志 +---------------- + + *当问题发生时,检查您的内核是否被“污染”,因为使内核设置这个标志的事件可 + 能会导致您面临的问题。* + +当某些可能会导致看起来完全不相关的后续错误的事情发生时,内核会用“污染 +(taint)”标志标记自己。如果您的内核受到污染,那么您面临的可能是这样的错误。 +因此在投入更多时间到这个过程中之前,尽早排除此情况可能对你有好处。这是这个 +步骤出现在这里的唯一原因,因为这个过程稍后会告诉您安装最新的主线内核;然后 +您将需要再次检查污染标志,因为当它出问题的时候内核报告会关注它。 + +在正在运行的系统上检查内核是否污染非常容易:如果 ``cat /proc/sys/kernel/tainted`` +返回“0”,那么内核没有被污染,一切正常。在某些情况下无法检查该文件;这就是 +为什么当内核报告内部问题(“kernel bug”)、可恢复错误(“kernel Oops”)或停止 +操作前不可恢复的错误(“kernel panic”)时,它也会提到污染状态。当其中一个错 +误发生时,查看打印的错误消息的顶部,搜索以“CPU:”开头的行。如果发现问题时内 +核未被污染,那么它应该以“Not infected”结束;如果你看到“Tainted:”且后跟一些 +空格和字母,那就被污染了。 + +如果你的内核被污染了,请阅读“Documentation/admin-guide/tainted-kernels.rst” +以找出原因。设法消除污染因素。通常是由以下三种因素之一引起的: + + 1. 发生了一个可恢复的错误(“kernel Oops”),内核污染了自己,因为内核知道在 + 此之后它可能会出现奇怪的行为错乱。在这种情况下,检查您的内核或系统日志, + 并寻找以下列文字开头的部分:: + + Oops: 0000 [#1] SMP + + 如方括号中的“#1”所示,这是自启动以来的第一次Oops。每个Oops和此后发生的 + 任何其他问题都可能是首个Oops的后续问题,即使这两个问题看起来完全不相关。 + 通过消除首个Oops的原因并在之后复现该问题,可以排除这种情况。有时仅仅 + 重新启动就足够了,有时更改配置后重新启动可以消除Oops。但是在这个流程中 + 不要花费太多时间在这一点上,因为引起Oops的原因可能已经在您稍后将按流程 + 安装的新Linux内核版本中修复了。 + + 2. 您的系统使用的软件安装了自己的内核模块,例如Nvidia的专有图形驱动程序或 + VirtualBox。当内核从外部源(即使它们是开源的)加载此类模块时,它会污染 + 自己:它们有时会在不相关的内核区域导致错误,从而可能导致您面临的问题。 + 因此,当您想要向Linux内核开发人员报告问题时,您必须阻止这些模块加载。 + 大多数情况下最简单的方法是:临时卸载这些软件,包括它们可能已经安装的任 + 何模块。之后重新启动。 + + 3. 当内核加载驻留在Linux内核源代码staging树中的模块时,它也会污染自身。这 + 是一个特殊的区域,代码(主要是驱动程序)还没有达到正常Linux内核的质量 + 标准。当您报告此种模块的问题时,内核受到污染显然是没有问题的;只需确保 + 问题模块是造成污染的唯一原因。如果问题发生在一个不相关的区域,重新启动 + 并通过指定 ``foo.blacklist=1`` 作为内核参数临时阻止该模块被加载(用有 + 问题的模块名替换“foo”)。 + + +定位导致问题的内核区域 +------------------------ + + *定位可能引起问题的驱动程序或内核子系统。找出其开发人员期望的报告的方式 + 和位置。注意:大多数情况下不会是bugzilla.kernel.org,因为问题通常需要通 + 过邮件发送给维护人员和公共邮件列表。* + +将报告发送给合适的人是至关重要的,因为Linux内核是一个大项目,大多数开发人员 +只熟悉其中的一小部分。例如,相当多的程序员只关心一个驱动程序,比如一个WiFi +芯片驱动程序;它的开发人员可能对疏远的或不相关的“子系统”(如TCP堆栈、 +PCIe/PCI子系统、内存管理或文件系统)的内部知识了解很少或完全不了解。 + +问题在于:Linux内核缺少一个,可以简单地将问题归档并让需要了解它的开发人员了 +解它的,中心化缺陷跟踪器。这就是为什么你必须找到正确的途径来自己报告问题。 +您可以在脚本的帮助下做到这一点(见下文),但它主要针对的是内核开发人员和专 +家。对于其他人来说,MAINTAINERS(维护人员)文件是更好的选择。 + +如何阅读MAINTAINERS维护者文件 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +为了说明如何使用 :ref:`MAINTAINERS ` 文件,让我们假设您的笔记 +本电脑中的WiFi在更新内核后突然出现了错误行为。这种情况下可能是WiFi驱动的问 +题。显然,它也可能由于驱动基于的某些代码,但除非你怀疑有这样的东西会附着在 +驱动程序上。如果真的是其他的问题,驱动程序的开发人员会让合适的人参与进来。 + +遗憾的是,没有通用且简单的办法来检查哪个代码驱动了特定硬件组件。 + +在WiFi驱动出现问题的情况下,你可能想查看 ``lspci -k`` 的输出,因为它列出了 +PCI/PCIe总线上的设备和驱动它的内核模块:: + + [user@something ~]$ lspci -k + [...] + 3a:00.0 Network controller: Qualcomm Atheros QCA6174 802.11ac Wireless Network Adapter (rev 32) + Subsystem: Bigfoot Networks, Inc. Device 1535 + Kernel driver in use: ath10k_pci + Kernel modules: ath10k_pci + [...] + +但如果你的WiFi芯片通过USB或其他内部总线连接,这种方法就行不通了。在这种情况 +下,您可能需要检查您的WiFi管理器或 ``ip link`` 的输出。寻找有问题的网络接口 +的名称,它可能类似于“wlp58s0”。此名称可以用来找到驱动它的模块:: + + [user@something ~]$ realpath --relative-to=/sys/module//sys/class/net/wlp58s0/device/driver/module + ath10k_pci + +如果这些技巧不能进一步帮助您,请尝试在网上搜索如何缩小相关驱动程序或子系统 +的范围。如果你不确定是哪一个:试着猜一下,即使你猜得不好,也会有人会帮助你 +的。 + +一旦您知道了相应的驱动程序或子系统,您就希望在MAINTAINERS文件中搜索它。如果 +是“ath10k_pci”,您不会找到任何东西,因为名称太具体了。有时你需要在网上寻找 +帮助;但在此之前,请尝试使用一个稍短或修改过的名称来搜索MAINTAINERS文件,因 +为这样你可能会发现类似这样的东西:: + + QUALCOMM ATHEROS ATH10K WIRELESS DRIVER + Mail: A. Some Human + Mailing list: ath10k@lists.infradead.org + Status: Supported + Web-page: https://wireless.wiki.kernel.org/en/users/Drivers/ath10k + SCM: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git + Files: drivers/net/wireless/ath/ath10k/ + +注意:如果您阅读在Linux源代码树的根目录中找到的原始维护者文件,则行描述将是 +缩写。例如,“Mail:(邮件)”将是“M:”,“Mailing list:(邮件列表)”将是“L”, +“Status:(状态)”将是“S:”。此文件顶部有一段解释了这些和其他缩写。 + +首先查看“Status”状态行。理想情况下,它应该得到“Supported(支持)”或 +“Maintained(维护)”。如果状态为“Obsolete(过时的)”,那么你在使用一些过时的 +方法,需要转换到新的解决方案上。有时候,只有在感到有动力时,才会有人为代码 +提供“Odd Fixes”。如果碰见“Orphan”,你就完全不走运了,因为再也没有人关心代码 +了,只剩下这些选项:准备好与问题共存,自己修复它,或者找一个愿意修复它的程序员。 + +检查状态后,寻找以“bug:”开头的一行:它将告诉你在哪里可以找到子系统特定的缺 +陷跟踪器来提交你的问题。上面的例子没有此行。大多数部分都是这样,因为 Linux +内核的开发完全是由邮件驱动的。很少有子系统使用缺陷跟踪器,且其中只有一部分 +依赖于 bugzilla.kernel.org。 + + +.. note:: + + FIXME: 旧的文本对 bugzilla.kernel.org 采取了完全不同的方法,因为提到它是 + 发布人们不知道如何联系相关人员的问题的地方。新的文本很少提到它;而当它像 + 这里一样提到时,是为了警告用户这往往是一个错误的地方。 + + 之所以选择这种方法,是因为本文的主要作者注意到有不少(甚至很多?)用户在 + bugzilla 上提交的 bug 没有得到回复。这也是意料之中的事情,因为不少(很多? + 大多数?)维护者甚至在他们的子系统有报告提交时都没有得到通知。而报告得 + 不到任何回复让用户非常烦恼,甚至可能会让他们生气。改进 bugzilla.k.o 确实 + 是一个选择,但在 2017 年的内核和维护者峰会上,大家一致同意先走这条路(很 + 抱歉花了这么长时间):这更容易实现,争议也更小,因为给已经超负荷工作的维 + 护者增加额外的负担不太可能得到好的效果。 + + +在这种情况下,你必须寻找以“Mail:”开头的行。这些行提到了特定代码的维护者的名 +字和电子邮件地址。也可以查找以“Mailing list:”开头的行,它告诉你开发代码的公 +共邮件列表。你的报告之后需要通过邮件发到这些地址。另外,对于所有通过电子邮 +件发送的问题报告,一定要抄送 Linux Kernel Mailing List(LKML) +。在以后通过邮件发送问题报告时,不要遗漏任何 +一个邮件列表!维护者都是大忙人,可能会把一些工作留给子系统特定列表上的其他开 +发者;而 LKML 很重要,因为需要一个可以找到所有问题报告的地方。 + + +.. note:: + + FIXME: 上面一节告诉用户一定要抄送 LKML。如今,它是一种“万能的”列表,几乎 + 没有人密切关注它。因此,似乎应该“全入”,让人们把他们的报告发到这里来,因 + 为所有的东西(报告、修正......)都可以在同一个地方找到(至少对于所有通过 + 邮件发送的报告和所有抄送 LKML 的子系统)。 + + 相关信息:我们是否应该建立一个类似“linux-issues@vger.kernel.org”的邮件列 + 表,并告诉上述的用户在报告问题时一定要抄送?这样一来,报告者就可以在一个 + 中心化的位置搜索现有的报告(至少是通过邮件报告的问题),而不会把常规的 + LKML 流量混入结果中。 + + +借助脚本找到维护者 +~~~~~~~~~~~~~~~~~~~~ + +对于手头有Linux源码的人来说,有第二个可以找到合适的报告地点的选择:脚本 +“scripts/get_maintainer.pl”,它尝试找到所有要联系的人。它会查询MAINTAINERS +文件,并需要用相关源代码的路径来调用。对于编译成模块的驱动程序,经常可以用 +这样的命令找到:: + + $ modinfo ath10k_pci | grep filename | sed 's!/lib/modules/.*/kernel/!!; s!filename:!!; s!\.ko\(\|\.xz\)!!' + drivers/net/wireless/ath/ath10k/ath10k_pci.ko + +将其中的部分内容传递给脚本:: + + $ ./scripts/get_maintainer.pl -f drivers/net/wireless/ath/ath10k* + Some Human (supporter:QUALCOMM ATHEROS ATH10K WIRELESS DRIVER) + Another S. Human (maintainer:NETWORKING DRIVERS) + ath10k@lists.infradead.org (open list:QUALCOMM ATHEROS ATH10K WIRELESS DRIVER) + linux-wireless@vger.kernel.org (open list:NETWORKING DRIVERS (WIRELESS)) + netdev@vger.kernel.org (open list:NETWORKING DRIVERS) + linux-kernel@vger.kernel.org (open list) + +不要把你的报告发给所有的人。发送给维护者,脚本称之为“supporter:”;另外抄送 +代码最相关的邮件列表,以及 Linux 内核邮件列表(LKML)。在此例中,你需要将报 +告发送给 “Some Human ” ,并抄送 +“ath10k@lists.infradead.org”和“linux-kernel@vger.kernel.org”。 + +注意:如果你用 git 克隆了 Linux 源代码,你可能需要用--git 再次调用 +get_maintainer.pl。脚本会查看提交历史,以找到最近哪些人参与了相关代码的编写, +因为他们可能会提供帮助。但要小心使用这些结果,因为它很容易让你误入歧途。 +例如,这种情况常常会发生在很少被修改的地方(比如老旧的或未维护的驱动程序): +有时这样的代码会在树级清理期间被根本不关心此驱动程序的开发者修改。 + + +搜索现有报告 +------------- + + *在缺陷追踪器或问题相关邮件列表的存档中彻底搜索可能与您的问题匹配的报告。 + 还要检查您是否能在您喜爱的网络搜索引擎或Linux内核邮件列表(LKML)存档 + 中找到一些信息。如果您发现了什么,请加入讨论,而不是发送新的报告。* + +报告一个别人已经提出的问题,对每个人来说都是浪费时间,尤其是作为报告人的你。 +所以彻底检查是否有人已经报告了这个问题,这对你自己是有利的。因此,不要草 +草完成报告过程中的这一步。请先花 30 到 60 分钟甚至更多的时间,来为你和他人 +节省更多时间和减少麻烦麻烦。 + +搜索的最佳之处是缺陷跟踪器或者你需要提交报告的邮件列表。你可以在 +`lore.kernel.org `_ 上找到很多这样的列表,但是有 +些在其他的地方。例如上一步中使用的 ath10k WiFi 驱动就是如此。但是你可以在网 +上很容易找到这些列表的存档。例如搜索“archive ath10k@lists.infradead.org”, +很快就能找到 `Info page for the ath10k mailing list(ath10k邮件列表信息页 +面) `_ 邮件列表的信息 +页面,在顶部链接到它的 `list archives(列表存档) +`_ 。 + +遗憾的是,这个列表和其他不少列表都缺少搜索存档的功能。在这种情况下,使用纯 +净的互联网搜索引擎,并添加类似“site:lists.infadead.org/pipermail/ath10k/”这 +样的搜索条件,这会把结果限制在该链接中的档案。 + +也请进一步搜索网络和 `Linux Kernel Mailing List (LKML) archives +`_ ,因为真正的罪魁祸首可能在其他子系统中。 +在 `bugzilla.kernel.org `_ 中搜索也是一个好 +主意,但是如果你在那里发现了什么,请知晓:大多数子系统期望得到报告的地方不 +同,因此你在那里发现的那些可能还没有到达负责相关子系统的人手中。尽管如此, +那里的数据可能会提供有价值的见解。 + +如果搜索结果实在太多,可以考虑让你的搜索引擎将搜索时间范围限制在过去的一个 +月或一年。而且无论你在哪里搜索,一定要用恰当的搜索关键词;也要变化几次关键 +词。同时,试着从别人的角度看问题:这将帮助你想出其他的关键词。另外,一定不 +要同时使用过多的关键词。记住搜索时要同时尝试包含和不包含内核驱动程序的名称 +或受影响的硬件组件的名称等信息。但其确切的品牌名称(比如说“华硕红魔 Radeon +RX 5700 XT Gaming OC”)往往帮助不大,因为它太具体了。相反,尝试搜索术语,如 +型号(Radeon 5700 或 Radeon 5000)和核心代号(“Navi”或“Navi10”),以及包含 +和不包含其制造商(“AMD”)。 + +如果你发现了关于你的问题的现有报告,请加入讨论,因为你可能会提供有价值的额 +外信息。这一点很重要,即使是在修复程序已经准备好或处于最后阶段,因为开发人 +员可能会寻找能够提供额外信息或测试建议修复程序的人。跳到“发布报告后的责任” +一节,了解有关如何正确参与的细节。 + + +为紧急情况做好准备 +------------------- + + *创建一个全新的备份,并将系统修复和还原工具放在手边* + +我得提醒您,您正在和计算机打交道,计算机有时会出现意想不到的事情,尤其是当 +您折腾其操作系统的内核等关键部件时。而这就是你在这个过程中要做的事情。因此, +一定要创建一个全新的备份;还要确保你手头有修复或重装操作系统的所有工具, +以及恢复备份所需的一切。 + + +确保你的内核不会被增强 +------------------------ + + *确保您的系统不会通过动态构建额外的内核模块来增强其内核,像DKMS这样的解 + 决方案可能在您不知情的情况下就在本地进行了这样的工作。* + +当报告一个问题时,你的内核必须是“纯净的”,一旦加载了一个不是从编译内核映像 +的源代码构建的内核模块,它就不再是纯净的内核了。这就是为什么你需要通过移除 +或禁用像 akmods 和 DKMS 这样的机制来确保你的 Linux 内核保持纯净:这些机制可 +能会自动构建额外的内核模块,例如当你首次启动到一个新安装的 Linux 内核时。在 +删除它们和它们安装的任何模块后重新启动。 + +注意,你可能不知道你的系统正在使用这些解决方案之一:当你安装 Nvidia 专有图 +形驱动程序、VirtualBox 或其他需要 Linux 内核以外的模块支持的软件时,它们通 +常会静默设置。这就是为什么你可能需要卸载这些软件的软件包,以摆脱任何第三方 +内核模块。 + + +确保环境健康 +-------------- + + *确保不是内核所处环境导致了你所面临的问题。* + +看起来很像内核问题的问题有时是由构建或运行时环境引起的。很难完全排除这种问 +题,但你应该尽量减少这种问题: + + * 构建内核时,请使用经过验证的工具,因为编译器或二进制文件中的错误可能会导 + 致内核出现错误行为。 + + * 确保您的计算机组件在其设计规范内运行;这对处理器、内存和主板尤为重要。因 + 此,当面临潜在的内核问题时,停止低电压或超频。 + + * 尽量确保不是硬件故障导致了你的问题。例如,内存损坏会导致大量的问题,这些 + 问题会表现为看起来像内核问题。 + + * 如果你正在处理一个文件系统问题,你可能需要用 ``fsck`` 检查一下文件系统, + 因为它可能会以某种方式被损坏,从而导致无法预期的内核行为。 + + * 在处理回归问题时,要确保没有在更新内核的同时发生了其他变化。例如,这个问 + 题可能是由同时更新的其他软件引起的。也有可能是在你第一次重启进入新内核时, + 某个硬件巧合地坏了。更新系统 BIOS 或改变 BIOS 设置中的某些内容也会导致 + 一些看起来很像内核回归的问题。 + + +记录如何重现问题 +------------------ + + *粗略地写下如何重现这个问题。如果您同时处理多个问题,请为每个问题单独写 + 注释,并确保它们在新启动的系统上独立出现。这是必要的,因为每个问题都需 + 要分别报告给内核开发人员,除非它们严重纠缠在一起。* + +如果你同时处理多个问题,必须分别报告每个问题,因为它们可能由不同的开发人员 +处理。在一份报告中描述多种问题,也会让其他人难以将其分开。因此只有在问题严 +重纠缠的情况下,才能将问题合并在一份报告中。 + +此外,在报告过程中,你必须测试该问题是否发生在其他内核版本上。因此,如果您 +知道如何在一个新启动的系统上快速重现问题,将使您的工作更加轻松。 + +注意:报告只发生过一次的问题往往是没有结果的,因为它们可能是由于宇宙辐射导 +致的位翻转。所以你应该尝试通过重现问题来排除这种情况,然后再继续。如果你有 +足够的经验来区分由于硬件故障引起的一次性错误和难以重现的罕见内核问题,可以 +忽略这个建议。 + + +安装一个新的内核进行测试 +-------------------------- + + *安装最新的Linux主线内核:这是所有问题首先得到修复的地方,因为它是内核 + 开发人员主要关注的版本线。在某些情况下,使用最新的Linux稳定版内核进行测 + 试和报告也是一个可以接受的替代方案,例如在合并窗口期间;但在这段时间里, + 你可能想要暂停努力直到它结束。* + +向 Linux 内核开发者报告一个他们几周或几个月前就已经解决的问题是很烦人的,还 +浪费了他们和你的时间。这就是为什么在报告之前要先检查一下这个问题是否发生在 +最新的代码库中,这对大家都有好处。 + +在 Linux 内核的范畴内,术语“latest最新”意味着:一个最近从开发主线中创建的内 +核版本,因为这个“主线”树是开发者首先应用修复的地方;只有在那之后,它们才被 +允许被移植回更老的仍然受支持的版本线,即“稳定版”和“长期支持”内核。这就是为 +什么你应该检查最近的主线内核,即使你处理的是一个你只想在旧版本线中看到修复 +的问题。另一个原因是:有些修复只应用于主线或最近的版本新,因为将它们回溯到 +旧版本太难或风险太大。如果是这样,再次报告问题不太可能改变什么。 + +因此,长期支持内核(有时也被称为“LTS 内核”)不适合进行测试,它们与当前的开 +发相距太远。即使是最新的 Linux“稳定版”内核也要落后很多,因此最好避免使用。 +至少在大多数时候是这样,因为有时稳定的内核是最好的选择;但在这种情况下,你 +可能想再等几天。 + +选择主线、稳定版还是继续等待 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +前往 `kernel.org `_ 来决定使用哪个版本。忽略那个写着 +“Latest release最新版本”的巨大黄色按钮,往下看有一个表格。在表格的顶部,你会 +看到一行以“mainline”开头的字样,大多数情况下它会指向一个版本号类似“5.8-rc2” +的预发布版本。如果是这样的话,你将需要使用这个主线内核进行测试。不要让“rc” +吓到你,这些“开发版内核”实际上非常可靠——而且你已经按照上面的指示做了备份, +不是吗? + +大概每九到十周,“mainline”可能会给你指出一个版本号类似“5.7”的正式版本。如果 +碰见这种情况,请考虑暂停报告过程,直到下一个版本的第一个预发布(5.8-rc1)出 +现在 `kernel.org `_ 上。这是因为 Linux 的开发周期正在 +两周的“合并窗口”内。大部分的改动和所有干扰性的改动都会在这段时间内被合并到 +下一个版本中。在此期间使用主线是比较危险的。内核开发者通常也很忙,可能没有 +多余的时间来处理问题报告。这也是很有可能在合并窗口中应用了许多修改来修复你 +所面临的问题;这就是为什么你很快就得用一个新的内核版本重新测试,就像下面“发 +布报告后的责任”一节中所述的那样。 + +这就是为什么要等到合并窗口结束后才去做。但是如果你处理的是一些不应该等待的 +东西,则无需这样做。在这种情况下,可以考虑通过 git 获取最新的主线内核(见下 +文),或者使用 kernel.org 上提供的最新稳定版本。如果 mainline 因为某些原因 +不无法正常工作,那么使用它也是可以接受的。总的来说:用它来重现问题也比完全 +不报告问题要好。 + +如何获得新的 Linux 内核 +~~~~~~~~~~~~~~~~~~~~~~~~~ + +你可以使用预编译或自编译的内核进行测试;如果你选择后者,可以使用 git 获取源 +代码,或者下载其 tar 存档包。 + +使用预编译的内核进行测试往往是最快速、最简单、最安全的方法——尤其是在你不熟 +悉 Linux 内核的情况下。但它需要是一个纯净内核,这可能很难直接得到。如果你使 +用的是流行的 Linux 发行版,那么你是幸运的:在网络上,你会发现不少发行版都有 +包含最新的主线或稳定版内核的软件包。使用这些包是完全没问题的,只要从仓库的 +文档中确认它们真的是纯净的。并且确保这些软件包是 `kernel.org +`_ 上提供的最新版本;如果软件包的时间超过了一周,那么 +可能就不合适了,因为新的主线和稳定版内核通常至少一周发布一次。需要注意的是, +在帮助测试修复的时候,你可能无论如何都得自己构建内核,这一点在本文后面会 +有介绍。 + +熟悉 git 的开发者和有经验的 Linux 用户通常最好直接从 `kernel.org 上的官方开 +发仓库 +`_ +中获取最新的 Linux 内核源代码。这些很可能比最新的主线预发布版本更新一些。不 +用担心:它们和正式的预发布版本一样可靠,除非内核的开发周期目前正处于合并窗 +口中。不过即便如此,它们也是相当可靠的。 + +不熟悉 git 的人通常最好从 `kernel.org `_ 下载源码的 +tar 存档包。 + +如何实际构建一个内核并不在这里描述,因为许多网站已经解释了必要的步骤。如果 +你是新手,可以考虑按照那些建议使用 ``make localmodconfig`` 来做,它将尝试获 +取你当前内核的配置,然后根据你的系统进行一些调整。这样做并不能使编译出来的 +内核更好,但可以更快地编译。 + + +检查“污染”标志 +---------------- + + *确保您刚刚安装的内核在运行时不会“污染”自己。* + +正如上面已经详细介绍过的:当发生一些可能会导致一些看起来完全不相关的后续错 +误的事情时,内核会设置一个“污染”标志。这就是为什么你需要检查你刚刚安装的内 +核是否有设置此标志。如果有的话,几乎在任何情况下你都需要在报告问题之前先消 +除它。详细的操作方法请看上面的章节。 + + +用新内核重现问题 +------------------ + + *在您刚刚安装的内核中复现这个问题。如果它没有出现,请查看只发生在稳定版 + 和长期支持内核的问题的说明。* + +检查这个问题是否发生在你刚刚安装的新 Linux 内核版本上。如果新内核已经修复了, +可以考虑使用此版本线,放弃报告问题。但是请记住,只要它没有在 `kernel.org +`_ 的稳定版和长期版(以及由这些版本衍生出来的厂商内核) +中得到修复,其他用户可能仍然会受到它的困扰。如果你喜欢使用其中的一个,或 +者只是想帮助它们的用户,请前往下面的“报告只发生在较旧内核版本线的问题”一节。 + + +优化复现问题的描述 +-------------------- + + *优化你的笔记:试着找到并写出最直接的复现问题的方法。确保最终结果包含所 + 有重要的细节,同时让第一次听说的人容易阅读和理解。如果您在此过程中学到 + 了一些东西,请考虑再次搜索关于该问题的现有报告。* + +过于复杂的报告会让别人很难理解。因此请尽量找到一个可以直接描述、易于以书面 +形式理解的再现方法。包含所有重要的细节,但同时也要尽量保持简短。 + +在这在前面的步骤中,你很可能已经了解了一些关于你所面临的问题的点。利用这些 +知识,再次搜索可以转而加入的现有报告。 + + +解码失败信息 +------------- + +.. note:: + + FIXME: 本节文字暂时是占位符,与目前 + “Documentation/admin-guide/reporting-bugs.rst”中的旧文字非常相似。它和它 + 所引用的文档已经过时,因此需要重新审视。因此,请将此说明视为一个求助:如 + 果你熟悉这个主题,请写几行适合这里的文字。或者只需向本文件的主要作者(见 + 导言)大致概述一下当前的情况,因为他们也许能写出一些东西来。 + + 最后这部分应该回答“什么时候真正需要这个”、“理想的情况下,早一点设置哪些 + .config 选项会让这一步变得简单或不必要?”这样的问题(可能是类似 + CONFIG_UNWINDER_ORC,要不是CONFIG_UNWINDER_FRAME_POINTER;还有其它什么是 + 需要的吗?)。 + +.. + + *如果失败包含堆栈转储(stack dump),例如Oops所做的,则请考虑对其进行解 + 码以找到出错的代码行。* + +当内核检测到错误时,它将打印一个堆栈转储以便于确定问题发生的确切代码行。但 +是这些信息有时需要解码后才能阅读,这在 +“Documentation/admin-guide/bug-hunting.rst”中有介绍。 + + +对回归的特别关照 +----------------- + + *如果您的问题是回归问题,请尽可能缩小引入问题时的范围。* + +Linux 首席开发者 Linus Torvalds 认为 Linux 内核永远不应恶化,这就是为什么他 +认为回归是不可接受的,并希望看到它们被迅速修复。这就是为什么引入了回归的改 +动导致的问题若无法通过其他方式快速解决,通常会被迅速撤销。因此,报告回归有 +点像“王炸”,会迅速得到修复。但要做到这一点,需要知道导致回归的变化。通常情 +况下,要由报告者来追查罪魁祸首,因为维护者往往没有时间或手头设置不便来自行 +重现它。 + +有一个叫做“二分”的过程可以来寻找变化,这在 +“Documentation/admin-guide/bug-bisect.rst”文档中进行了详细的描述,这个过程通 +常需要你构建十到二十个内核镜像,每次都尝试在构建下一个镜像之前重现问题。是 +的,这需要花费一些时间,但不用担心,它比大多数人想象的要快得多。多亏了 +“binary search二进制搜索”,这将引导你在源代码管理系统中找到导致回归的提交。 +一旦你找到它,就在网上搜索其主题、提交ID和缩短的提交ID(提交ID的前12个字符)。 +如果有的话,这将引导您找到关于它的现有报告。 + +需要注意的是,二分法需要一点窍门,不是每个人都懂得诀窍,也需要相当多的努力, +不是每个人都愿意投入。尽管如此,还是强烈建议自己进行一次二分。如果你真的 +不能或者不想走这条路,至少要找出是哪个主线内核引入的回归。比如说从 5.5.15 +切换到 5.8.4 的时候出现了一些问题,那么至少可以尝试一下相近的所有的主线版本 +(5.6、5.7 和 5.8)来检查它是什么时候出现的。除非你想在一个稳定版或长期支持 +内核中找到一个回归,否则要避免测试那些编号有三段的版本(5.6.12、5.7.8),因 +为那会使结果难以解释,可能会让你的测试变得无用。一旦你找到了引入回归的主要 +版本,就可以放心地继续报告了。但请记住:在不知道罪魁祸首的情况下,开发人员 +是否能够提供帮助取决于手头的问题。有时他们可能会从报告中确认是什么出现了问 +题,并能修复它;有时他们可能无法提供帮助,除非你进行二分。 + +当处理回归问题时,请确保你所面临的问题真的是由内核引起的,而不是由其他东西 +引起的,如上文所述。 + +在整个过程中,请记住:只有当旧内核和新内核的配置相似时,问题才算回归。最好 +的方法是:把配置文件(``.config``)从旧的工作内核直接复制到你尝试的每个新内 +核版本。之后运行 ``make oldnoconfig`` 来调整它以适应新版本的需要,而不启用 +任何新的功能,因为那些功能也可能导致回归。 + + +撰写并发送报告 +--------------- + + *通过详细描述问题来开始编写报告。记得包括以下条目:您为复现而安装的最新 + 内核版本、使用的Linux发行版以及关于如何复现该问题的说明。如果可能,将内 + 核构建配置(.config)和 ``dmesg`` 的输出放在网上的某个地方,并链接到它。 + 包含或上传所有其他可能相关的信息,如Oops的输出/截图或来自 ``lspci`` + 的输出。一旦你写完了这个主要部分,请在上方插入一个正常长度的段落快速概 + 述问题和影响。再在此之上添加一个简单描述问题的句子,以得到人们的阅读。 + 现在给出一个更短的描述性标题或主题。然后就可以像MAINTAINERS文件告诉你的 + 那样发送或提交报告了,除非你在处理一个“高优先级问题”:它们需要按照下面 + “高优先级问题的特殊处理”所述特别关照。* + +现在你已经准备好了一切,是时候写你的报告了。上文前言中链接的三篇文档对如何 +写报告做了部分解释。这就是为什么本文将只提到一些基本的内容以及 Linux 内核特 +有的东西。 + +有一点是符合这两类的:你的报告中最关键的部分是标题/主题、第一句话和第一段。 +开发者经常会收到许多邮件。因此,他们往往只是花几秒钟的时间浏览一下邮件,然 +后再决定继续下一封或仔细查看。因此,你报告的开头越好,有人研究并帮助你的机 +会就越大。这就是为什么你应该暂时忽略他们,先写出详细的报告。;-) + +每份报告都应提及的事项 +~~~~~~~~~~~~~~~~~~~~~~~~ + +详细描述你的问题是如何发生在你安装的新纯净内核上的。试着包含你之前写的和优 +化过的分步说明,概述你和其他人如何重现这个问题;在极少数无法重现的情况下, +尽量描述你做了什么来触发它。 + +还应包括其他人为了解该问题及其环境而可能需要的所有相关信息。实际需要的东西 +在很大程度上取决于具体问题,但有些事项你总是应该包括在内: + + * ``cat /proc/version`` 的输出,其中包含 Linux 内核版本号和构建时的编译器。 + + * 机器正在运行的 Linux 发行版( ``hostnamectl | grep “Operating System“`` ) + + * CPU 和操作系统的架构( ``uname -mi`` ) + + * 如果您正在处理回归,并进行了二分,请提及导致回归的变更的主题和提交ID。 + +许多情况下,让读你报告的人多了解两件事也是明智之举: + + * 用于构建 Linux 内核的配置(“.config”文件) + + * 内核的信息,你从 ``dmesg`` 得到的信息写到一个文件里。确保它以像“Linux + version 5.8-1 (foobar@example.com) (gcc (GCC) 10.2.1, GNU ld version + 2.34) #1 SMP Mon Aug 3 14:54:37 UTC 2020”这样的行开始,如果没有,那么第 + 一次启动阶段的重要信息已经被丢弃了。在这种情况下,可以考虑使用 + ``journalctl -b 0 -k`` ;或者你也可以重启,重现这个问题,然后调用 + ``dmesg`` 。 + +这两个文件很大,所以直接把它们放到你的报告中是个坏主意。如果你是在缺陷跟踪 +器中提交问题,那么将它们附加到工单中。如果你通过邮件报告问题,不要用附件附 +上它们,因为那会使邮件变得太大,可以按下列之一做: + + * 将文件上传到某个公开的地方(你的网站,公共文件粘贴服务,在 + `bugzilla.kernel.org `_ 上创建的工单……), + 并在你的报告中放上链接。理想情况下请使用允许这些文件保存很多年的地方,因 + 为它们可能在很多年后对别人有用;例如 5 年或 10 年后,一个开发者正在修改 + 一些代码,而这些代码正是为了修复你的问题。 + + * 把文件放在一边,然后说明你会在他人回复时再单独发送。只要记得报告发出去后, + 真正做到这一点就可以了。;-) + +提供这些东西可能是明智的 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +根据问题的不同,你可能需要提供更多的背景数据。这里有一些关于提供什么比较好 +的建议: + + * 如果你处理的是内核的“warning”、“OOPS”或“panic”,请包含它。如果你不能复制 + 粘贴它,试着用netconsole网络终端远程跟踪或者至少拍一张屏幕的照片。 + + * 如果问题可能与你的电脑硬件有关,请说明你使用的是什么系统。例如,如果你的 + 显卡有问题,请提及它的制造商,显卡的型号,以及使用的芯片。如果是笔记本电 + 脑,请提及它的型号名称,但尽量确保意义明确。例如“戴尔 XPS 13”就不很明确, + 因为它可能是 2012 年的那款,那款除了看起来和现在销售的没有什么不同之外, + 两者没有任何共同之处。因此,在这种情况下,要加上准确的型号,例如 2019 + 年内推出的 XPS 13 型号为“9380”或“7390”。像“联想 Thinkpad T590”这样的名字 + 也有些含糊不清:这款笔记本有带独立显卡和不带的子型号,所以要尽量找到准确 + 的型号名称或注明主要部件。 + + * 说明正在使用的相关软件。如果你在加载模块时遇到了问题,你要说明正在使用的 + kmod、systemd 和 udev 的版本。如果其中一个 DRM 驱动出现问题,你要说明 + libdrm 和 Mesa 的版本;还要说明你的 Wayland 合成器或 X-Server 及其驱动。 + 如果你有文件系统问题,请注明相应的文件系统实用程序的版本(e2fsprogs, + btrfs-progs, xfsprogs……)。 + + * 从内核中收集可能有用的额外信息。例如, ``lspci -nn`` 的输出可以帮助别人 + 识别你使用的硬件。如果你的硬件有问题,你甚至可以给出 ``sudo lspci -vvv`` + 的结果,因为它提供了组件是如何配置的信息。对于一些问题,可能最好包含 + ``/proc/cpuinfo`` , ``/proc/ioports`` , ``/proc/iomem`` , + ``/proc/modules`` 或 ``/proc/scsi/scsi`` 等文件的内容。一些子系统还提 + 供了收集相关信息的工具。 ``alsa-info.sh`` `就是这样一个工具,它是音频/声 + 音子系统开发者提供的 `_ 。 + +这些例子应该会给你一些知识点,让你知道附上什么数据可能是明智的,但你自己也 +要想一想,哪些数据对别人会有帮助。不要太担心忘记一些东西,因为开发人员会要 +求提供他们需要的额外细节。但从一开始就把所有重要的东西都提供出来,会增加别 +人仔细查看的机会。 + + +重要部分:报告的开头 +~~~~~~~~~~~~~~~~~~~~~~ + +现在你已经准备好了报告的详细部分,让我们进入最重要的部分:开头几句。现在到 +报告的最前面,在你刚才写的部分之前加上类似“The detailed description:”(详细 +描述)这样的内容,并在最前面插入两个新行。现在写一个正常长度的段落,大致概 +述这个问题。去掉所有枯燥的细节,把重点放在读者需要知道的关键部分,以让人了 +解这是怎么回事;如果你认为这个缺陷影响了很多用户,就提一下这点来吸引大家关 +注。 + +做好这一点后,在顶部再插入两行,写一句话的摘要,快速解释报告的内容。之后你 +要更加抽象,为报告写一个更短的主题/标题。 + +现在你已经写好了这部分,请花点时间来优化它,因为它是你的报告中最重要的部分: +很多人会先读这部分,然后才会决定是否值得花时间阅读其他部分。 + +现在就像 :ref:`MAINTAINERS ` 维护者文件告诉你的那样发送或提交 +报告,除非它是前面概述的那些“高优先级问题”之一:在这种情况下,请先阅读下一 +小节,然后再发送报告。 + +高优先级问题的特殊处理 +~~~~~~~~~~~~~~~~~~~~~~~~ + +高优先级问题的报告需要特殊处理。 + +**非常严重的缺陷** :确保在主题或工单标题以及第一段中明显标出 severeness +(非常严重的)。 + +**回归** :如果问题是一个回归,请在邮件的主题或缺陷跟踪器的标题中添加 +[REGRESSION]。如果您没有进行二分,请至少注明您测试的最新主线版本(比如 5.7) +和出现问题的最新版本(比如 5.8)。如果您成功地进行了二分,请注明导致回归 +的提交ID和主题。也请添加该变更的作者到你的报告中;如果您需要将您的缺陷提交 +到缺陷跟踪器中,请将报告以私人邮件的形式转发给他,并注明报告提交地点。 + +**安全问题** :对于这种问题,你将必须评估:如果细节被公开披露,是否会对其他 +用户产生短期风险。如果不会,只需按照所述继续报告问题。如果有此风险,你需要 +稍微调整一下报告流程。 + + * 如果 MAINTAINERS 文件指示您通过邮件报告问题,请不要抄送任何公共邮件列表。 + + * 如果你应该在缺陷跟踪器中提交问题,请确保将工单标记为“私有”或“安全问题”。 + 如果缺陷跟踪器没有提供保持报告私密性的方法,那就别想了,把你的报告以私人 + 邮件的形式发送给维护者吧。 + +在这两种情况下,都一定要将报告发到 MAINTAINERS 文件中“安全联络”部分列出的 +地址。理想的情况是在发送报告的时候直接抄送他们。如果您在缺陷跟踪器中提交了 +报告,请将报告的文本转发到这些地址;但请在报告的顶部加上注释,表明您提交了 +报告,并附上工单链接。 + +更多信息请参见“Documentation/admin-guide/security-bugs.rst”。 + + +发布报告后的责任 +------------------ + + *等待别人的反应,继续推进事情,直到你能够接受这样或那样的结果。因此,请 + 公开和及时地回应任何询问。测试提出的修复。积极地测试:至少重新测试每个 + 新主线版本的首个候选版本(RC),并报告你的结果。如果出现拖延,就友好地 + 提醒一下。如果你没有得到任何帮助或者未能满意,请试着自己帮助自己。* + +如果你的报告非常优秀,而且你真的很幸运,那么某个开发者可能会立即发现导致问 +题的原因;然后他们可能会写一个补丁来修复、测试它,并直接发送给主线集成,同 +时标记它以便以后回溯到需要它的稳定版和长期支持内核。那么你需要做的就是回复 +一句“Thank you very much”(非常感谢),然后在发布后换上修复好的版本。 + +但这种理想状况很少发生。这就是为什么你把报告拿出来之后工作才开始。你要做的 +事情要视情况而定,但通常会是下面列出的事情。但在深入研究细节之前,这里有几 +件重要的事情,你需要记住这部分的过程。 + + +关于进一步互动的一般建议 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**总是公开回复** :当你在缺陷跟踪器中提交问题时,一定要在那里回复,不要私下 +联系任何开发者。对于邮件报告,在回复您收到的任何邮件时,总是使用“全部回复” +功能。这包括带有任何你可能想要添加到你的报告中的额外数据的邮件:进入邮件应 +用程序“已发送”文件夹,并在邮件上使用“全部回复”来回复报告。这种方法可以确保 +公共邮件列表和其他所有参与者都能及时了解情况;它还能保持邮件线程的完整性, +这对于邮件列表将所有相关邮件归为一类是非常重要的。 + +只有两种情况不适合在缺陷跟踪器或“全部回复”中发表评论: + + * 有人让你私下发东西。 + + * 你被告知要发送一些东西,但注意到其中包含需要保密的敏感信息。在这种情况下, + 可以私下发送给要求发送的开发者。但要在工单或邮件中注明你是这么做的,这 + 样其他人就知道你尊重了这个要求。 + +**在请求解释或帮助之前先研究一下** :在这部分过程中,有人可能会告诉你用尚未 +掌握的技能做一些事情。例如你可能会被要求使用一些你从未听说过的测试工具;或 +者你可能会被要求在 Linux 内核源代码上应用一个补丁来测试它是否有帮助。在某些 +情况下,发个回复询问如何做就可以了。但在走这条路之前,尽量通过在互联网上搜 +索自行找到答案;或者考虑在其他地方询问建议。比如询问朋友,或者到你平时常去 +的聊天室或论坛发帖咨询。 + +**要有耐心** :如果你真的很幸运,你可能会在几个小时内收到对你的报告的答复。 +但大多数情况下会花费更多的时间,因为维护者分散在全球各地,因此可能在不同的 +时区——在那里他们已经享受着远离键盘的夜晚。 + +一般来说,内核开发者需要一到五个工作日来回复报告。有时会花费更长的时间,因 +为他们可能正忙于合并窗口、其他工作、参加开发者会议,或者只是在享受一个漫长 +的暑假。 + +“高优先级的问题”(见上面的解释)例外:维护者应该尽快解决这些问题;这就是为 +什么你应该最多等待一个星期(如果是紧急的事情,则只需两天),然后再发送友好 +的提醒。 + +有时维护者可能没有及时回复;有时候可能会出现分歧,例如一个问题是否符合回归 +的条件。在这种情况下,在邮件列表上提出你的顾虑,并请求其他人公开或私下回复 +如何继续推进。如果失败了,可能应该让更高级别的维护者介入。如果是 WiFi 驱动, +那就是无线维护者;如果没有更高级别的维护者,或者其他一切努力都失败了,那 +这可能是一种罕见的、可以让 Linus Torvalds 参与进来的情况。 + +**主动测试** :每当一个新的主线内核版本的第一个预发布版本(rc1)发布的时候, +去检查一下这个问题是否得到了解决,或者是否有什么重要的变化。在工单中或在 +回复报告的邮件中提及结果(确保所有参与讨论的人都被抄送)。这将表明你的承诺 +和你愿意帮忙。如果问题持续存在,它也会提醒开发者确保他们不会忘记它。其他一 +些不定期的重新测试(例如用rc3、rc5 和最终版本)也是一个好主意,但只有在相关 +的东西发生变化或者你正在写什么东西的时候才报告你的结果。 + +这些些常规的事情就不说了,我们来谈谈报告后如何帮助解决问题的细节。 + +查询和测试请求 +~~~~~~~~~~~~~~~ + +如果你的报告得到了回复则需履行以下责任: + +**检查与你打交道的人** :大多数情况下,会是维护者或特定代码区域的开发人员对 +你的报告做出回应。但由于问题通常是公开报告的,所以回复的可能是任何人——包括 +那些想要帮忙的人,但最后可能会用他们的问题或请求引导你完全偏离轨道。这很少 +发生,但这是快速上网搜搜看你正在与谁互动是明智之举的许多原因之一。通过这样 +做,你也可以知道你的报告是否被正确的人听到,因为如果讨论没有导致满意的问题 +解决方案而淡出,之后可能需要提醒维护者(见下文)。 + +**查询数据** :通常你会被要求测试一些东西或提供更多细节。尽快提供所要求的信 +息,因为你已经得到了可能会帮助你的人的注意,你等待的时间越长就有越可能失去 +关注;如果你不在数个工作日内提供信息,甚至可能出现这种结果。 + +**测试请求** :当你被要求测试一个诊断补丁或可能的修复时,也要尽量及时测试。 +但要做得恰当,一定不要急于求成:混淆事情很容易发生,这会给所有人带来许多困 +惑。例如一个常见的错误是以为应用了一个带修复的建议补丁,但事实上并没有。即 +使是有经验的测试人员也会偶尔发生这样的事情,但当有修复的内核和没有修复的内 +核表现得一样时,他们大多时候会注意到。 + +当没有任何实质性进展时该怎么办 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +有些报告不会得到负有相关责任的 Linux 内核开发者的任何反应;或者围绕这个问题 +的讨论有所发展,但渐渐淡出,没有任何实质内容产出。 + +在这种情况下,要等两个星期(最好是三个星期)后再发出友好的提醒:也许当你的 +报告到达时,维护者刚刚离开键盘一段时间,或者有更重要的事情要处理。在写提醒 +信的时候,要善意地问一下,是否还需要你这边提供什么来让事情推进下去。如果报 +告是通过邮件发出来的,那就在邮件的第一行回复你的初始邮件(见上文),其中包 +括下方的原始报告的完整引用:这是少数几种情况下,这样的“TOFU”(Text Over, +Fullquote Under文字在上,完整引用在下)是正确的做法,因为这样所有的收件人都 +会以适当的顺序立即让细节到手头上来。 + +在提醒之后,再等三周的回复。如果你仍然没有得到适当的反馈,你首先应该重新考 +虑你的方法。你是否可能尝试接触了错误的人?是不是报告也许令人反感或者太混乱, +以至于人们决定完全远离它?排除这些因素的最好方法是:把报告给一两个熟悉 +FLOSS 问题报告的人看,询问他们的意见。同时征求他们关于如何继续推进的建议。 +这可能意味着:准备一份更好的报告,让这些人在你发出去之前对它进行审查。这样 +的方法完全可以;只需说明这是关于这个问题的第二份改进的报告,并附上第一份报 +告的链接。 + +如果报告是恰当的,你可以发送第二封提醒信;在其中询问为什么报告没有得到任何 +回复。第二封提醒邮件的好时机是在新 Linux 内核版本的首个预发布版本('rc1') +发布后不久,因为无论如何你都应该在那个时候重新测试并提供状态更新(见上文)。 + +如果第二次提醒的结果又在一周内没有任何反应,可以尝试联系上级维护者询问意见: +即使再忙的维护者在这时候也至少应该发过某种确认。 + +记住要做好失望的准备:理想状况下维护者最好对每一个问题报告做出回应,但他们 +只有义务解决之前列出的“高优先级问题”。所以,如果你得到的回复是“谢谢你的报告, +我目前有更重要的问题要处理,在可预见的未来没有时间去研究这个问题”,那请不 +要太沮丧。 + +也有可能在缺陷跟踪器或列表中进行了一些讨论之后,什么都没有发生,提醒也无助 +于激励大家进行修复。这种情况可能是毁灭性的,但在 Linux 内核开发中确实会发生。 +这些和其他得不到帮助的原因在本文结尾处的“为什么有些问题在被报告后没有得到 +任何回应或者仍然没有修复”中进行了解释。 + +如果你没有得到任何帮助或问题最终没有得到解决,不要沮丧:Linux 内核是 FLOSS, +因此你仍然可以自己帮助自己。例如,你可以试着找到其他受影响的人,和他们一 +起合作来解决这个问题。这样的团队可以一起准备一份新的报告,提到团队有多少人, +为什么你们认为这是应该得到解决的事情。也许你们还可以一起缩小确切原因或引 +入回归的变化,这往往会使修复更容易。而且如果运气好的话,团队中可能会有懂点 +编程的人,也许能写出一个修复方案。 + + +报告仅在旧内核版本线中发生的问题的细节 +---------------------------------------- + +本节提供了关于:如果你不能在主线内核上重现你的问题,但又想看到它在旧的版本 +线(也就是稳定版和长期支持内核)上得到修复时,需要采取的步骤之细节。 + +有些修复太复杂 +~~~~~~~~~~~~~~~ + + *请做好准备,接下来的几个步骤可能无法在旧版本中解决问题:修复可能太大或 + 太冒险,无法移植到那里。* + +即使是微小的、看似明显的代码变化,有时也会带来新的、完全意想不到的问题。稳 +定版和长期支持内核的维护者非常清楚这一点,因此他们只对这些内核进行符合 +“Documentation/translations/zh_CN/process/stable-kernel-rules.rst”中所列出的 +规则的修改。 + +复杂或有风险的修改不符合条件,因此只能应用于主线。其他的修复很容易被回溯到 +最新的稳定版和长期支持内核,但是风险太大,无法集成到旧版内核中。所以要注意 +你所希望的修复可能是那些不会被回溯到你所关心的版本线的修复之一。在这种情况 +下,你将别无选择,要么忍受这个问题,要么切换到一个较新的 Linux 版本,除非你 +想自己把修复补丁应用到你的内核中。 + +确保特定版本线仍然受支持 +~~~~~~~~~~~~~~~~~~~~~~~~~ + + *检查内核开发人员是否仍然维护你关心的Linux内核版本线:去 kernel.org 的 + 首页,确保此特定版本线的最新版没有“[EOL]”标记。* + +大多数内核版本线只支持三个月左右,因为延长维护时间会带来相当多的工作。因此, +每年只会选择一个版本来支持至少两年(通常是六年)。这就是为什么你需要检查 +内核开发者是否还支持你关心的版本线。 + +注意,如果 `kernel.org `_ 在首页上列出了两个“稳定”版本, +你应该考虑切换到较新的版本,而忘掉较旧的版本:对它的支持可能很快就会结束。 +然后,它将被标记为“生命周期结束”(EOL)。达到这个程度的版本线仍然会在 +`kernel.org `_ 首页上被显示一两周,但不适合用于测试和 +报告。 + +搜索稳定版邮件列表 +~~~~~~~~~~~~~~~~~~~ + + *检查Linux稳定版邮件列表中的现有报告。* + +也许你所面临的问题已经被发现,并且已经或即将被修复。因此,请在 `Linux 稳定 +版邮件列表的档案 `_ 中搜索类似问题的报告。 +如果你找到任何匹配的问题,可以考虑加入讨论,除非修复工作已经完成并计划很快 +得到应用。 + +用最新版本复现问题 +~~~~~~~~~~~~~~~~~~~ + + *从特定的版本线安装最新版本作为纯净内核。确保这个内核没有被污染,并且仍 + 然存在问题,因为问题可能已经在那里被修复了。* + +在投入更多时间到这个过程中之前,你要检查这个问题是否在你关注的版本线的最新 +版本中已经得到了修复。这个内核需要是纯净的,在问题发生之前不应该被污染,正 +如上面已经在测试主线的过程中详细介绍过的一样。 + +检查代码历史和搜索现有的讨论 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + *在Linux内核版本控制系统中搜索修复主线问题的更改,因为它的提交消息可能 + 会告诉你修复是否已经计划好了支持。如果你没有找到,搜索适当的邮件列表, + 寻找讨论此类问题或同行评议可能修复的帖子;然后检查讨论是否认为修复不适 + 合支持。如果支持根本不被考虑,加入最新的讨论,询问是否有可能。* + +在许多情况下,你所处理的问题会发生在主线上,但已在主线上得到了解决。修正它 +的提交也需要被回溯才能解决这个问题。这就是为什么你要搜索它或任何相关讨论。 + + * 首先尝试在存放 Linux 内核源代码的 Git 仓库中找到修复。你可以通过 + `kernel.org 上的网页 + `_ + 或 `GitHub 上的镜像 `_ 来实现;如果你 + 有一个本地克隆,你也可以在命令行用 ``git log --grep=`` 来搜索。 + + 如果你找到了修复,请查看提交消息的尾部是否包含了类似这样的“稳定版标签”: + + Cc: # 5.4+ + + 像上面这行,开发者标记了安全修复可以回传到 5.4 及以后的版本。大多数情况 + 下,它会在两周内被应用到那里,但有时需要更长的时间。 + + * 如果提交没有告诉你任何东西,或者你找不到修复,请再找找关于这个问题的讨论。 + 用你最喜欢的搜索引擎搜索网络,以及 `Linux kernel developers mailing + list 内核开发者邮件列表 `_ 的档案。也可以 + 阅读上面的 `定位导致问题的内核区域` 一节,然后按照说明找到导致问题的子系 + 统:它的缺陷跟踪器或邮件列表存档中可能有你要找的答案。 + + * 如果你看到了一个计划的修复,请按上所述在版本控制系统中搜索它,因为提交可 + 能会告诉你是否可以进行回溯。 + + * 检查讨论中是否有任何迹象表明,该修复程序可能风险太大,无法回溯到你关心 + 的版本线。如果是这样的话,你必须忍受这个问题,或者切换到应用了修复的内 + 核版本线。 + + * 如果修复的问题未包含稳定版标签,并且没有讨论过回溯问题,请加入讨论:如 + 果合适的话,请提及你所面对的问题的版本,以及你希望看到它被修复。 + +检查是否是稳定版内核或长期支持内核特有的回归。 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + *通过安装您所关心的版本线的首个发行版,检查您是否正在处理主线中从未出现 + 过的回归。如果这个问题没有出现,你基本上需要用此版本来报告这个问题,就 + 像你用主线报告一个问题一样(见上面)。理想情况下,在该主题和两个相关提 + 交ID的帮助下,通过对网上现有报告的搜索,将能二分问题。如果还是一无所获, + 那就写份报告;将报告抄送或转发给稳定版维护者、稳定版邮件列表和编写更 + 改的人。如果您发现了导致问题的更改,请包含缩短的提交ID。* + +有时你在上一步中不会发现任何东西:你所面临的问题可能从未在主线中发生过,因 +为它是由一些不完整或未正确应用的更改引起的。要检查这一点,安装你关注的版本 +线的首个版本,例如如果你关注 5.4.x 就安装 5.4。 + +如果问题没有在那显示出来,那就是特定版本线的回归。在这种情况下,你需要像在 +主线中发生的问题一样报告它,就像上面大纲中主线部分的最后几步。 + +在这种情况下,强烈建议你做二分处理。找到罪魁祸首后,再在网上搜索现有的报告: +不仅要搜索准确的主题和变更的提交ID(完整的与12个字符的缩短版),还要搜索 +提交信息中提到的“上游提交”的提交ID(完整的,缩短的)。 + +撰写报告;只要记住几个点就可以了:把报告抄送或转发给稳定版维护者、稳定版邮 +件列表,:ref:`MAINTAINERS ` 文件在“STABLE BRANCH”一节中提到了 +这一点。如果你执行了一个成功的二分,请抄送提交的作者,并包含它的主题和缩短 +的提交ID。 + +请求建议 +~~~~~~~~~ + + *前面的步骤之一应该会给出一个解决方案。如果仍未能成功,请向可能引起问题 + 的子系统的维护人员询问建议;抄送特定子系统的邮件列表以及稳定版邮件列表。* + +如果前面的三个步骤都没有让你更接近解决方案,那么只剩下一个选择:请求建议。 +在你发给可能是问题根源的子系统的维护者的邮件中这样做;抄送子系统的邮件列表 +以及 :ref:`MAINTAINERS ` 文件在“STABLE BRANCH”一节中提到的稳定 +邮件列表。 + + +为什么有些问题在报告后没有任何回应或仍未解决? +=============================================== + +当向 Linux 开发者报告问题时,要注意只有“高优先级的问题”(回归、安全问题、严 +重问题)才一定会得到解决。如果维护者或其他人都失败了,Linus Torvalds 他自己 +会确保这一点。他们和其他内核开发者也会解决很多其他问题。但是要知道,有时他 +们也会不能或不愿帮忙;有时甚至没有人发报告给他们。 + +最好的解释就是那些内核开发者常常是在业余时间为 Linux 内核做出贡献。内核中的 +不少驱动程序都是由这样的程序员编写的,往往只是因为他们想让自己的硬件可以在 +自己喜欢的操作系统上使用。 + +这些程序员大多数时候会很乐意修复别人报告的问题。但是没有人可以强迫他们这样 +做,因为他们是自愿贡献的。 + +还有一些情况下,这些开发者真的很想解决一个问题,但却不能解决:有时他们缺乏 +硬件编程文档来解决问题。这种情况往往由于公开的文档太简陋,或者驱动程序是通 +过逆向工程编写的。 + +业余开发者迟早也会不再关心某驱动。也许他们的测试硬件坏了,被更高级的玩意取 +代了,或者是太老了以至于只能在计算机博物馆里找到。有时开发者根本就不关心他 +们的代码和 Linux 了,因为在他们的生活中一些不同的东西变得更重要了。在某些情 +况下,没有人愿意接手维护者的工作——也没有人可以被强迫,因为对 Linux 内核的贡 +献是自愿的。然而被遗弃的驱动程序仍然存在于内核中:它们对人们仍然有用,删除 +它们可能导致回归。 + +对于那些为 Linux 内核工作而获得报酬的开发者来说,情况并没有什么不同。这些人 +现在贡献了大部分的变更。但是他们的雇主迟早也会停止关注他们的代码或者让程序 +员专注于其他事情。例如,硬件厂商主要通过销售新硬件来赚钱;因此,他们中的不 +少人并没有投入太多时间和精力来维护他们多年前就停止销售的东西的 Linux 内核驱 +动。企业级 Linux 发行商往往持续维护的时间比较长,但在新版本中往往会把对老旧 +和稀有硬件的支持放在一边,以限制范围。一旦公司抛弃了一些代码,往往由业余贡 +献者接手,但正如上面提到的:他们迟早也会放下代码。 + +优先级是一些问题没有被修复的另一个原因,因为维护者相当多的时候是被迫设置这 +些优先级的,因为在 Linux 上工作的时间是有限的。对于业余时间或者雇主给予他们 +的开发人员用于上游内核维护工作的时间也是如此。有时维护人员也会被报告淹没, +即使一个驱动程序几乎完美地工作。为了不被完全缠住,程序员可能别无选择,只能 +对问题报告进行优先级排序而拒绝其中的一些报告。 + +不过这些都不用太过担心,很多驱动都有积极的维护者,他们对尽可能多的解决问题 +相当感兴趣。 + + +结束语 +======= + +与其他免费/自由&开源软件(Free/Libre & Open Source Software,FLOSS)相比, +向 Linux 内核开发者报告问题是很难的:这个文档的长度和复杂性以及字里行间的内 +涵都说明了这一点。但目前就是这样了。这篇文字的主要作者希望通过记录现状来为 +以后改善这种状况打下一些基础。 -- cgit v1.2.3 From 84dc0c20e89849c24907d682b842d90a40add779 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 18 Mar 2021 15:19:39 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/bug-bisect.rst Add translation zh_CN/admin-guide/bug-bisect.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/b9106f76fdc8e20ce4fcd43aec499f00df411610.1616050069.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/bug-bisect.rst | 81 ++++++++++++++++++++++ .../translations/zh_CN/admin-guide/index.rst | 2 +- 2 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/bug-bisect.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/bug-bisect.rst b/Documentation/translations/zh_CN/admin-guide/bug-bisect.rst new file mode 100644 index 000000000000..662eb5b46e84 --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/bug-bisect.rst @@ -0,0 +1,81 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../admin-guide/bug-bisect` + +:译者: + + 吴想成 Wu XiangCheng + +二分(bisect)缺陷 ++++++++++++++++++++ + +(英文版)最后更新:2016年10月28日 + +引言 +===== + +始终尝试由来自kernel.org的源代码构建的最新内核。如果您没有信心这样做,请将 +错误报告给您的发行版供应商,而不是内核开发人员。 + +找到缺陷(bug)并不总是那么容易,不过仍然得去找。如果你找不到它,不要放弃。 +尽可能多的向相关维护人员报告您发现的信息。请参阅MAINTAINERS文件以了解您所 +关注的子系统的维护人员。 + +在提交错误报告之前,请阅读“Documentation/admin-guide/reporting-issues.rst”。 + +设备未出现(Devices not appearing) +==================================== + +这通常是由udev/systemd引起的。在将其归咎于内核之前先检查一下。 + +查找导致缺陷的补丁 +=================== + +使用 ``git`` 提供的工具可以很容易地找到缺陷,只要缺陷是可复现的。 + +操作步骤: + +- 从git源代码构建内核 +- 以此开始二分 [#f1]_:: + + $ git bisect start + +- 标记损坏的变更集:: + + $ git bisect bad [commit] + +- 标记正常工作的变更集:: + + $ git bisect good [commit] + +- 重新构建内核并测试 +- 使用以下任一与git bisect进行交互:: + + $ git bisect good + + 或:: + + $ git bisect bad + + 这取决于您测试的变更集上是否有缺陷 +- 在一些交互之后,git bisect将给出可能导致缺陷的变更集。 + +- 例如,如果您知道当前版本有问题,而4.8版本是正常的,则可以执行以下操作:: + + $ git bisect start + $ git bisect bad # Current version is bad + $ git bisect good v4.8 + + +.. [#f1] 您可以(可选地)在开始git bisect的时候提供good或bad参数 + ``git bisect start [BAD] [GOOD]`` + +如需进一步参考,请阅读: + +- ``git-bisect`` 的手册页 +- `Fighting regressions with git bisect(用git bisect解决回归) + `_ +- `Fully automated bisecting with "git bisect run"(使用git bisect run + 来全自动二分) `_ +- `Using Git bisect to figure out when brokenness was introduced + (使用Git二分来找出何时引入了错误) `_ diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index fe2abc3fec86..7dc3540629f0 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -36,13 +36,13 @@ Todolist: :maxdepth: 1 reporting-issues + bug-bisect Todolist: reporting-bugs security-bugs bug-hunting - bug-bisect tainted-kernels ramoops dynamic-debug-howto -- cgit v1.2.3 From b1b381e2c0d6d45ee4407af72c031c7184b72deb Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 18 Mar 2021 15:19:58 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/bug-hunting.rst Add translation zh_CN/admin-guide/bug-hunting.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/dad9f26205e9cae7254ed21c796688851ca5ebfd.1616050069.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/bug-hunting.rst | 340 +++++++++++++++++++++ .../translations/zh_CN/admin-guide/index.rst | 2 +- 2 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/bug-hunting.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/bug-hunting.rst b/Documentation/translations/zh_CN/admin-guide/bug-hunting.rst new file mode 100644 index 000000000000..decb9b26d2f1 --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/bug-hunting.rst @@ -0,0 +1,340 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../admin-guide/bug-hunting` + +:译者: + + 吴想成 Wu XiangCheng + +追踪缺陷 +========= + +内核错误报告通常附带如下堆栈转储:: + + ------------[ cut here ]------------ + WARNING: CPU: 1 PID: 28102 at kernel/module.c:1108 module_put+0x57/0x70 + Modules linked in: dvb_usb_gp8psk(-) dvb_usb dvb_core nvidia_drm(PO) nvidia_modeset(PO) snd_hda_codec_hdmi snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd soundcore nvidia(PO) [last unloaded: rc_core] + CPU: 1 PID: 28102 Comm: rmmod Tainted: P WC O 4.8.4-build.1 #1 + Hardware name: MSI MS-7309/MS-7309, BIOS V1.12 02/23/2009 + 00000000 c12ba080 00000000 00000000 c103ed6a c1616014 00000001 00006dc6 + c1615862 00000454 c109e8a7 c109e8a7 00000009 ffffffff 00000000 f13f6a10 + f5f5a600 c103ee33 00000009 00000000 00000000 c109e8a7 f80ca4d0 c109f617 + Call Trace: + [] ? dump_stack+0x44/0x64 + [] ? __warn+0xfa/0x120 + [] ? module_put+0x57/0x70 + [] ? module_put+0x57/0x70 + [] ? warn_slowpath_null+0x23/0x30 + [] ? module_put+0x57/0x70 + [] ? gp8psk_fe_set_frontend+0x460/0x460 [dvb_usb_gp8psk] + [] ? symbol_put_addr+0x27/0x50 + [] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] + [] ? dvb_usb_exit+0x2f/0xd0 [dvb_usb] + [] ? usb_disable_endpoint+0x7c/0xb0 + [] ? dvb_usb_device_exit+0x2a/0x50 [dvb_usb] + [] ? usb_unbind_interface+0x62/0x250 + [] ? __pm_runtime_idle+0x44/0x70 + [] ? __device_release_driver+0x78/0x120 + [] ? driver_detach+0x87/0x90 + [] ? bus_remove_driver+0x38/0x90 + [] ? usb_deregister+0x58/0xb0 + [] ? SyS_delete_module+0x130/0x1f0 + [] ? task_work_run+0x64/0x80 + [] ? exit_to_usermode_loop+0x85/0x90 + [] ? do_fast_syscall_32+0x80/0x130 + [] ? sysenter_past_esp+0x40/0x6a + ---[ end trace 6ebc60ef3981792f ]--- + +这样的堆栈跟踪提供了足够的信息来识别内核源代码中发生错误的那一行。根据问题的 +严重性,它还可能包含 **“Oops”** 一词,比如:: + + BUG: unable to handle kernel NULL pointer dereference at (null) + IP: [] iret_exc+0x7d0/0xa59 + *pdpt = 000000002258a001 *pde = 0000000000000000 + Oops: 0002 [#1] PREEMPT SMP + ... + +尽管有 **Oops** 或其他类型的堆栈跟踪,但通常需要找到出问题的行来识别和处理缺 +陷。在本章中,我们将参考“Oops”来了解需要分析的各种堆栈跟踪。 + +如果内核是用 ``CONFIG_DEBUG_INFO`` 编译的,那么可以使用文件: +`scripts/decode_stacktrace.sh` 。 + +链接的模块 +----------- + +受到污染或正在加载/卸载的模块用“(…)”标记,污染标志在 +`Documentation/admin-guide/tainted-kernels.rst` 文件中进行了描述,“正在被加 +载”用“+”标注,“正在被卸载”用“-”标注。 + + +Oops消息在哪? +--------------- + +通常,Oops文本由klogd从内核缓冲区读取,然后交给 ``syslogd`` ,后者将其写入 +syslog文件,通常是 ``/var/log/messages`` (取决于 ``/etc/syslog.conf`` )。 +在使用systemd的系统上,它也可以由 ``journald`` 守护进程存储,并通过运行 +``journalctl`` 命令进行访问。 + +有时 ``klogd`` 会挂掉,这种情况下您可以运行 ``dmesg > file`` 从内核缓冲区 +读取数据并保存它。或者您可以 ``cat /proc/kmsg > file`` ,但是您必须适时 +中断以停止传输,因为 ``kmsg`` 是一个“永无止境的文件”。 + +如果机器严重崩溃,无法输入命令或磁盘不可用,那还有三个选项: + +(1) 手动复制屏幕上的文本,并在机器重新启动后输入。很难受,但这是突然崩溃下 + 唯一的选择。或者你可以用数码相机拍下屏幕——虽然不那么好,但总比什么都没 + 有好。如果消息滚动超出控制台顶部,使用更高分辨率(例如 ``vga=791`` ) + 引导启动将允许您阅读更多文本。(警告:这需要 ``vesafb`` ,因此对“早期” + 的Oppses没有帮助) + +(2) 从串口终端启动(参见 + :ref:`Documentation/admin-guide/serial-console.rst ` ), + 在另一台机器上运行调制解调器然后用你喜欢的通信程序捕获输出。 + Minicom运行良好。 + +(3) 使用Kdump(参阅 Documentation/admin-guide/kdump/kdump.rst ),使用 + Documentation/admin-guide/kdump/gdbmacros.txt 中的dmesg gdbmacro从旧内存 + 中提取内核环形缓冲区。 + +找到缺陷位置 +------------- + +如果你能指出缺陷在内核源代码中的位置,则报告缺陷的效果会非常好。这有两种方法。 +通常来说使用 ``gdb`` 会比较容易,不过内核需要用调试信息来预编译。 + +gdb +^^^^ + +GNU 调试器(GNU debugger, ``gdb`` )是从 ``vmlinux`` 文件中找出OOPS的确切 +文件和行号的最佳方法。 + +在使用 ``CONFIG_DEBUG_INFO`` 编译的内核上使用gdb效果最好。可通过运行以下命令 +进行设置:: + + $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO + +在用 ``CONFIG_DEBUG_INFO`` 编译的内核上,你可以直接从OOPS复制EIP值:: + + EIP: 0060:[] Not tainted VLI + +并使用GDB来将其翻译成可读形式:: + + $ gdb vmlinux + (gdb) l *0xc021e50e + +如果没有启用 ``CONFIG_DEBUG_INFO`` ,则使用OOPS的函数偏移:: + + EIP is at vt_ioctl+0xda8/0x1482 + +并在启用 ``CONFIG_DEBUG_INFO`` 的情况下重新编译内核:: + + $ ./scripts/config -d COMPILE_TEST -e DEBUG_KERNEL -e DEBUG_INFO + $ make vmlinux + $ gdb vmlinux + (gdb) l *vt_ioctl+0xda8 + 0x1888 is in vt_ioctl (drivers/tty/vt/vt_ioctl.c:293). + 288 { + 289 struct vc_data *vc = NULL; + 290 int ret = 0; + 291 + 292 console_lock(); + 293 if (VT_BUSY(vc_num)) + 294 ret = -EBUSY; + 295 else if (vc_num) + 296 vc = vc_deallocate(vc_num); + 297 console_unlock(); + +或者若您想要更详细的显示:: + + (gdb) p vt_ioctl + $1 = {int (struct tty_struct *, unsigned int, unsigned long)} 0xae0 + (gdb) l *0xae0+0xda8 + +您也可以使用对象文件作为替代:: + + $ make drivers/tty/ + $ gdb drivers/tty/vt/vt_ioctl.o + (gdb) l *vt_ioctl+0xda8 + +如果你有调用跟踪,类似:: + + Call Trace: + [] :jbd:log_wait_commit+0xa3/0xf5 + [] autoremove_wake_function+0x0/0x2e + [] :jbd:journal_stop+0x1be/0x1ee + ... + +这表明问题可能在 :jbd: 模块中。您可以在gdb中加载该模块并列出相关代码:: + + $ gdb fs/jbd/jbd.ko + (gdb) l *log_wait_commit+0xa3 + +.. note:: + + 您还可以对堆栈跟踪处的任何函数调用执行相同的操作,例如:: + + [] ? dvb_usb_adapter_frontend_exit+0x3a/0x70 [dvb_usb] + + 上述调用发生的位置可以通过以下方式看到:: + + $ gdb drivers/media/usb/dvb-usb/dvb-usb.o + (gdb) l *dvb_usb_adapter_frontend_exit+0x3a + +objdump +^^^^^^^^ + +要调试内核,请使用objdump并从崩溃输出中查找十六进制偏移,以找到有效的代码/汇 +编行。如果没有调试符号,您将看到所示例程的汇编程序代码,但是如果内核有调试 +符号,C代码也将可见(调试符号可以在内核配置菜单的hacking项中启用)。例如:: + + $ objdump -r -S -l --disassemble net/dccp/ipv4.o + +.. note:: + + 您需要处于内核树的顶层以便此获得您的C文件。 + +如果您无法访问源代码,仍然可以使用以下方法调试一些崩溃转储(如Dave Miller的 +示例崩溃转储输出所示):: + + EIP is at +0x14/0x4c0 + ... + Code: 44 24 04 e8 6f 05 00 00 e9 e8 fe ff ff 8d 76 00 8d bc 27 00 00 + 00 00 55 57 56 53 81 ec bc 00 00 00 8b ac 24 d0 00 00 00 8b 5d 08 + <8b> 83 3c 01 00 00 89 44 24 14 8b 45 28 85 c0 89 44 24 18 0f 85 + + Put the bytes into a "foo.s" file like this: + + .text + .globl foo + foo: + .byte .... /* bytes from Code: part of OOPS dump */ + + Compile it with "gcc -c -o foo.o foo.s" then look at the output of + "objdump --disassemble foo.o". + + Output: + + ip_queue_xmit: + push %ebp + push %edi + push %esi + push %ebx + sub $0xbc, %esp + mov 0xd0(%esp), %ebp ! %ebp = arg0 (skb) + mov 0x8(%ebp), %ebx ! %ebx = skb->sk + mov 0x13c(%ebx), %eax ! %eax = inet_sk(sk)->opt + +`scripts/decodecode` 文件可以用来自动完成大部分工作,这取决于正在调试的CPU +体系结构。 + +报告缺陷 +--------- + +一旦你通过定位缺陷找到了其发生的地方,你可以尝试自己修复它或者向上游报告它。 + +为了向上游报告,您应该找出用于开发受影响代码的邮件列表。这可以使用 ``get_maintainer.pl`` 。 + + +例如,您在gspca的sonixj.c文件中发现一个缺陷,则可以通过以下方法找到它的维护者:: + + $ ./scripts/get_maintainer.pl -f drivers/media/usb/gspca/sonixj.c + Hans Verkuil (odd fixer:GSPCA USB WEBCAM DRIVER,commit_signer:1/1=100%) + Mauro Carvalho Chehab (maintainer:MEDIA INPUT INFRASTRUCTURE (V4L/DVB),commit_signer:1/1=100%) + Tejun Heo (commit_signer:1/1=100%) + Bhaktipriya Shridhar (commit_signer:1/1=100%,authored:1/1=100%,added_lines:4/4=100%,removed_lines:9/9=100%) + linux-media@vger.kernel.org (open list:GSPCA USB WEBCAM DRIVER) + linux-kernel@vger.kernel.org (open list) + +请注意它将指出: + +- 最后接触源代码的开发人员(如果这是在git树中完成的)。在上面的例子中是Tejun + 和Bhaktipriya(在这个特定的案例中,没有人真正参与这个文件的开发); +- 驱动维护人员(Hans Verkuil); +- 子系统维护人员(Mauro Carvalho Chehab); +- 驱动程序和/或子系统邮件列表(linux-media@vger.kernel.org); +- Linux内核邮件列表(linux-kernel@vger.kernel.org)。 + +通常,修复缺陷的最快方法是将它报告给用于开发相关代码的邮件列表(linux-media +ML),抄送驱动程序维护者(Hans)。 + +如果你完全不知道该把报告寄给谁,且 ``get_maintainer.pl`` 也没有提供任何有用 +的信息,请发送到linux-kernel@vger.kernel.org。 + +感谢您的帮助,这使Linux尽可能稳定:-) + +修复缺陷 +--------- + +如果你懂得编程,你不仅可以通过报告错误来帮助我们,还可以提供一个解决方案。 +毕竟,开源就是分享你的工作,你不想因为你的天才而被认可吗? + +如果你决定这样做,请在制定解决方案后将其提交到上游。 + +请务必阅读 +:ref:`Documentation/process/submitting-patches.rst ` , +以帮助您的代码被接受。 + + +--------------------------------------------------------------------------- + +用 ``klogd`` 进行Oops跟踪的注意事项 +------------------------------------ + +为了帮助Linus和其他内核开发人员, ``klogd`` 对保护故障的处理提供了大量支持。 +为了完整支持地址解析,至少应该使用 ``sysklogd`` 包的1.3-pl3版本。 + +当发生保护故障时, ``klogd`` 守护进程会自动将内核日志消息中的重要地址转换为 +它们的等效符号。然后通过 ``klogd`` 使用的任何报告机制来转发这个已翻译的内核 +消息。保护错误消息可以直接从消息文件中剪切出来并转发给内核开发人员。 + +``klogd`` 执行两种类型的地址解析,静态翻译和动态翻译。静态翻译使用System.map +文件。为了进行静态转换, ``klogd`` 守护进程必须能够在守护进程初始化时找到系 +统映射文件。有关 ``klogd`` 如何搜索映射文件的信息,请参见klogd手册页。 + +当使用内核可加载模块时,动态地址转换非常重要。由于内核模块的内存是从内核的 +动态内存池中分配的,因此无论是模块的开头还是模块中的函数和符号都没有固定的 +位置。 + +内核支持系统调用,允许程序确定加载哪些模块及其在内存中的位置。klogd守护进程 +使用这些系统调用构建了一个符号表,可用于调试可加载内核模块中发生的保护错误。 + +klogd至少会提供产生保护故障的模块的名称。如果可加载模块的开发人员选择从模块 +导出符号信息,则可能会有其他可用的符号信息。 + +由于内核模块环境可以是动态的,因此当模块环境发生变化时,必须有一种通知 +``klogd`` 守护进程的机制。有一些可用的命令行选项允许klogd向当前正在执行的守 +护进程发出信号示意应该刷新符号信息。有关更多信息,请参阅 ``klogd`` 手册页。 + +sysklogd发行版附带了一个补丁,它修改了 ``modules-2.0.0`` 包,以便在加载或 +卸载模块时自动向klogd发送信号。应用此补丁基本上可无缝支持调试内核可加载模块 +发生的保护故障。 + +以下是 ``klogd`` 处理的可加载模块中的保护故障示例:: + + Aug 29 09:51:01 blizard kernel: Unable to handle kernel paging request at virtual address f15e97cc + Aug 29 09:51:01 blizard kernel: current->tss.cr3 = 0062d000, %cr3 = 0062d000 + Aug 29 09:51:01 blizard kernel: *pde = 00000000 + Aug 29 09:51:01 blizard kernel: Oops: 0002 + Aug 29 09:51:01 blizard kernel: CPU: 0 + Aug 29 09:51:01 blizard kernel: EIP: 0010:[oops:_oops+16/3868] + Aug 29 09:51:01 blizard kernel: EFLAGS: 00010212 + Aug 29 09:51:01 blizard kernel: eax: 315e97cc ebx: 003a6f80 ecx: 001be77b edx: 00237c0c + Aug 29 09:51:01 blizard kernel: esi: 00000000 edi: bffffdb3 ebp: 00589f90 esp: 00589f8c + Aug 29 09:51:01 blizard kernel: ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018 + Aug 29 09:51:01 blizard kernel: Process oops_test (pid: 3374, process nr: 21, stackpage=00589000) + Aug 29 09:51:01 blizard kernel: Stack: 315e97cc 00589f98 0100b0b4 bffffed4 0012e38e 00240c64 003a6f80 00000001 + Aug 29 09:51:01 blizard kernel: 00000000 00237810 bfffff00 0010a7fa 00000003 00000001 00000000 bfffff00 + Aug 29 09:51:01 blizard kernel: bffffdb3 bffffed4 ffffffda 0000002b 0007002b 0000002b 0000002b 00000036 + Aug 29 09:51:01 blizard kernel: Call Trace: [oops:_oops_ioctl+48/80] [_sys_ioctl+254/272] [_system_call+82/128] + Aug 29 09:51:01 blizard kernel: Code: c7 00 05 00 00 00 eb 08 90 90 90 90 90 90 90 90 89 ec 5d c3 + +--------------------------------------------------------------------------- + +:: + + Dr. G.W. Wettstein Oncology Research Div. Computing Facility + Roger Maris Cancer Center INTERNET: greg@wind.rmcc.com + 820 4th St. N. + Fargo, ND 58122 + Phone: 701-234-7556 diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index 7dc3540629f0..d487e8adb804 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -36,13 +36,13 @@ Todolist: :maxdepth: 1 reporting-issues + bug-hunting bug-bisect Todolist: reporting-bugs security-bugs - bug-hunting tainted-kernels ramoops dynamic-debug-howto -- cgit v1.2.3 From 2d153571003b22f35caa90305801d04af4703e72 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 18 Mar 2021 15:20:11 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/security-bugs.rst Add translation zh_CN/admin-guide/security-bugs.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/f4210d304fa3f0b2a6e9eb798f63bf2e267231a0.1616050069.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/index.rst | 2 +- .../zh_CN/admin-guide/security-bugs.rst | 74 ++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/security-bugs.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index d487e8adb804..9669b32e90ef 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -36,13 +36,13 @@ Todolist: :maxdepth: 1 reporting-issues + security-bugs bug-hunting bug-bisect Todolist: reporting-bugs - security-bugs tainted-kernels ramoops dynamic-debug-howto diff --git a/Documentation/translations/zh_CN/admin-guide/security-bugs.rst b/Documentation/translations/zh_CN/admin-guide/security-bugs.rst new file mode 100644 index 000000000000..b8120391755d --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/security-bugs.rst @@ -0,0 +1,74 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../admin-guide/security-bugs` + +:译者: + + 吴想成 Wu XiangCheng + +安全缺陷 +========= + +Linux内核开发人员非常重视安全性。因此我们想知道何时发现了安全漏洞,以便尽快 +修复和披露。请向Linux内核安全团队报告安全漏洞。 + +联络 +----- + +可以通过电子邮件联系Linux内核安全团队。这是一个安全人员 +的私有列表,他们将帮助验证错误报告并开发和发布修复程序。如果您已经有了一个 +修复,请将其包含在您的报告中,这样可以大大加快进程。安全团队可能会从区域维护 +人员那里获得额外的帮助,以理解和修复安全漏洞。 + +与任何缺陷一样,提供的信息越多,诊断和修复就越容易。如果您不清楚哪些信息有用, +请查看“Documentation/translations/zh_CN/admin-guide/reporting-issues.rst”中 +概述的步骤。任何利用漏洞的攻击代码都非常有用,未经报告者同意不会对外发布,除 +非已经公开。 + +请尽可能发送无附件的纯文本电子邮件。如果所有的细节都藏在附件里,那么就很难对 +一个复杂的问题进行上下文引用的讨论。把它想象成一个 +:doc:`常规的补丁提交 <../process/submitting-patches>` (即使你还没有补丁): +描述问题和影响,列出复现步骤,然后给出一个建议的解决方案,所有这些都是纯文本的。 + +披露和限制信息 +--------------- + +安全列表不是公开渠道。为此,请参见下面的协作。 + +一旦开发出了健壮的补丁,发布过程就开始了。对公开的缺陷的修复会立即发布。 + +尽管我们倾向于在未公开缺陷的修复可用时即发布补丁,但应报告者或受影响方的请求, +这可能会被推迟到发布过程开始后的7日内,如果根据缺陷的严重性需要更多的时间, +则可额外延长到14天。推迟发布修复的唯一有效原因是为了适应QA的逻辑和需要发布 +协调的大规模部署。 + +虽然可能与受信任的个人共享受限信息以开发修复,但未经报告者许可,此类信息不会 +与修复程序一起发布或发布在任何其他披露渠道上。这包括但不限于原始错误报告和 +后续讨论(如有)、漏洞、CVE信息或报告者的身份。 + +换句话说,我们唯一感兴趣的是修复缺陷。提交给安全列表的所有其他资料以及对报告 +的任何后续讨论,即使在解除限制之后,也将永久保密。 + +协调 +------ + +对敏感缺陷(例如那些可能导致权限提升的缺陷)的修复可能需要与私有邮件列表 +进行协调,以便分发供应商做好准备,在公开披露 +上游补丁时发布一个已修复的内核。发行版将需要一些时间来测试建议的补丁,通常 +会要求至少几天的限制,而供应商更新发布更倾向于周二至周四。若合适,安全团队 +可以协助这种协调,或者报告者可以从一开始就包括linux发行版。在这种情况下,请 +记住在电子邮件主题行前面加上“[vs]”,如linux发行版wiki中所述: +。 + +CVE分配 +-------- + +安全团队通常不分配CVE,我们也不需要它们来进行报告或修复,因为这会使过程不必 +要的复杂化,并可能耽误缺陷处理。如果报告者希望在公开披露之前分配一个CVE编号, +他们需要联系上述的私有linux-distros列表。当在提供补丁之前已有这样的CVE编号时, +如报告者愿意,最好在提交消息中提及它。 + +保密协议 +--------- + +Linux内核安全团队不是一个正式的机构实体,因此无法签订任何保密协议。 -- cgit v1.2.3 From e54882ff38c5a68fe95781286a799eb755c6d2ca Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 18 Mar 2021 15:20:29 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/tainted-kernels.rst Add translation zh_CN/admin-guide/tainted-kernels.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/189f2403ad168dafb4d5e50847c235064a2acaad.1616050069.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/index.rst | 2 +- .../zh_CN/admin-guide/tainted-kernels.rst | 157 +++++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index 9669b32e90ef..a671d16710f3 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -39,11 +39,11 @@ Todolist: security-bugs bug-hunting bug-bisect + tainted-kernels Todolist: reporting-bugs - tainted-kernels ramoops dynamic-debug-howto init diff --git a/Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst b/Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst new file mode 100644 index 000000000000..bc51d7cff9b0 --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/tainted-kernels.rst @@ -0,0 +1,157 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../admin-guide/tainted-kernels` + +:译者: + + 吴想成 Wu XiangCheng + +受污染的内核 +------------- + +当发生一些在稍后调查问题时可能相关的事件时,内核会将自己标记为“受污染 +(tainted)”的。不用太过担心,大多数情况下运行受污染的内核没有问题;这些信息 +主要在有人想调查某个问题时才有意义的,因为问题的真正原因可能是导致内核受污染 +的事件。这就是为什么来自受污染内核的缺陷报告常常被开发人员忽略,因此请尝试用 +未受污染的内核重现问题。 + +请注意,即使在您消除导致污染的原因(亦即卸载专有内核模块)之后,内核仍将保持 +污染状态,以表示内核仍然不可信。这也是为什么内核在注意到内部问题(“kernel +bug”)、可恢复错误(“kernel oops”)或不可恢复错误(“kernel panic”)时会打印 +受污染状态,并将有关此的调试信息写入日志 ``dmesg`` 输出。也可以通过 +``/proc/`` 中的文件在运行时检查受污染的状态。 + + +BUG、Oops或Panics消息中的污染标志 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +在顶部以“CPU:”开头的一行中可以找到受污染的状态;内核是否受到污染和原因会显示 +在进程ID(“PID:”)和触发事件命令的缩写名称(“Comm:”)之后:: + + BUG: unable to handle kernel NULL pointer dereference at 0000000000000000 + Oops: 0002 [#1] SMP PTI + CPU: 0 PID: 4424 Comm: insmod Tainted: P W O 4.20.0-0.rc6.fc30 #1 + Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011 + RIP: 0010:my_oops_init+0x13/0x1000 [kpanic] + [...] + +如果内核在事件发生时没有被污染,您将在那里看到“Not-tainted:”;如果被污染,那 +么它将是“Tainted:”以及字母或空格。在上面的例子中,它看起来是这样的:: + + Tainted: P W O + +下表解释了这些字符的含义。在本例中,由于加载了专有模块( ``P`` ),出现了 +警告( ``W`` ),并且加载了外部构建的模块( ``O`` ),所以内核早些时候受到 +了污染。要解码其他字符,请使用下表。 + + +解码运行时的污染状态 +~~~~~~~~~~~~~~~~~~~~~ + +在运行时,您可以通过读取 ``cat /proc/sys/kernel/tainted`` 来查询受污染状态。 +如果返回 ``0`` ,则内核没有受到污染;任何其他数字都表示受到污染的原因。解码 +这个数字的最简单方法是使用脚本 ``tools/debugging/kernel-chktaint`` ,您的 +发行版可能会将其作为名为 ``linux-tools`` 或 ``kernel-tools`` 的包的一部分提 +供;如果没有,您可以从 +`git.kernel.org `_ +网站下载此脚本并用 ``sh kernel-chktaint`` 执行,它会在上面引用的日志中有类似 +语句的机器上打印这样的内容:: + + Kernel is Tainted for following reasons: + * Proprietary module was loaded (#0) + * Kernel issued warning (#9) + * Externally-built ('out-of-tree') module was loaded (#12) + See Documentation/admin-guide/tainted-kernels.rst in the Linux kernel or + https://www.kernel.org/doc/html/latest/admin-guide/tainted-kernels.html for + a more details explanation of the various taint flags. + Raw taint value as int/string: 4609/'P W O ' + +你也可以试着自己解码这个数字。如果内核被污染的原因只有一个,那么这很简单, +在本例中您可以通过下表找到数字。如果你需要解码有多个原因的数字,因为它是一 +个位域(bitfield),其中每个位表示一个特定类型的污染的存在或不存在,最好让 +前面提到的脚本来处理。但是如果您需要快速看一下,可以使用这个shell命令来检查 +设置了哪些位:: + + $ for i in $(seq 18); do echo $(($i-1)) $(($(cat /proc/sys/kernel/tainted)>>($i-1)&1));done + +污染状态代码表 +~~~~~~~~~~~~~~~ + +=== ===== ====== ======================================================== + 位 日志 数字 内核被污染的原因 +=== ===== ====== ======================================================== + 0 G/P 1 已加载专用模块 + 1 _/F 2 模块被强制加载 + 2 _/S 4 内核运行在不合规范的系统上 + 3 _/R 8 模块被强制卸载 + 4 _/M 16 处理器报告了机器检测异常(MCE) + 5 _/B 32 引用了错误的页或某些意外的页标志 + 6 _/U 64 用户空间应用程序请求的污染 + 7 _/D 128 内核最近死机了,即曾出现OOPS或BUG + 8 _/A 256 ACPI表被用户覆盖 + 9 _/W 512 内核发出警告 + 10 _/C 1024 已加载staging驱动程序 + 11 _/I 2048 已应用平台固件缺陷的解决方案 + 12 _/O 4096 已加载外部构建(“树外”)模块 + 13 _/E 8192 已加载未签名的模块 + 14 _/L 16384 发生软锁定 + 15 _/K 32768 内核已实时打补丁 + 16 _/X 65536 备用污染,为发行版定义并使用 + 17 _/T 131072 内核是用结构随机化插件构建的 +=== ===== ====== ======================================================== + +注:字符 ``_`` 表示空白,以便于阅读表。 + +污染的更详细解释 +~~~~~~~~~~~~~~~~~ + + 0) ``G`` 加载的所有模块都有GPL或兼容许可证, ``P`` 加载了任何专有模块。 + 没有MODULE_LICENSE(模块许可证)或MODULE_LICENSE未被insmod认可为GPL + 兼容的模块被认为是专有的。 + + + 1) ``F`` 任何模块被 ``insmod -f`` 强制加载, ``' '`` 所有模块正常加载。 + + 2) ``S`` 内核运行在不合规范的处理器或系统上:硬件已运行在不受支持的配置中, + 因此无法保证正确执行。内核将被污染,例如: + + - 在x86上:PAE是通过intel CPU(如Pentium M)上的forcepae强制执行的,这些 + CPU不报告PAE,但可能有功能实现,SMP内核在非官方支持的SMP Athlon CPU上 + 运行,MSR被暴露到用户空间中。 + - 在arm上:在某些CPU(如Keystone 2)上运行的内核,没有启用某些内核特性。 + - 在arm64上:CPU之间存在不匹配的硬件特性,引导加载程序以不同的模式引导CPU。 + - 某些驱动程序正在被用在不受支持的体系结构上(例如x86_64以外的其他系统 + 上的scsi/snic,非x86/x86_64/itanium上的scsi/ips,已经损坏了arm64上 + irqchip/irq-gic的固件设置…)。 + + 3) ``R`` 模块被 ``rmmod -f`` 强制卸载, ``' '`` 所有模块都正常卸载。 + + 4) ``M`` 任何处理器报告了机器检测异常, ``' '`` 未发生机器检测异常。 + + 5) ``B`` 页面释放函数发现错误的页面引用或某些意外的页面标志。这表示硬件问题 + 或内核错误;日志中应该有其他信息指示发生此污染的原因。 + + 6) ``U`` 用户或用户应用程序特意请求设置受污染标志,否则应为 ``' '`` 。 + + 7) ``D`` 内核最近死机了,即出现了OOPS或BUG。 + + 8) ``A`` ACPI表被重写。 + + 9) ``W`` 内核之前已发出过警告(尽管有些警告可能会设置更具体的污染标志)。 + + 10) ``C`` 已加载staging驱动程序。 + + 11) ``I`` 内核正在处理平台固件(BIOS或类似软件)中的严重错误。 + + 12) ``O`` 已加载外部构建(“树外”)模块。 + + 13) ``E`` 在支持模块签名的内核中加载了未签名的模块。 + + 14) ``L`` 系统上先前发生过软锁定。 + + 15) ``K`` 内核已经实时打了补丁。 + + 16) ``X`` 备用污染,由Linux发行版定义和使用。 + + 17) ``T`` 内核构建时使用了randstruct插件,它可以有意生成非常不寻常的内核结构 + 布局(甚至是性能病态的布局),这在调试时非常有用。于构建时设置。 -- cgit v1.2.3 From 33282cc7cf3debac63eb7bc33f04922ec4da9297 Mon Sep 17 00:00:00 2001 From: Wu XiangCheng Date: Thu, 18 Mar 2021 15:20:48 +0800 Subject: docs/zh_CN: Add zh_CN/admin-guide/init.rst Add translation zh_CN/admin-guide/init.rst, and link it to zh_CN/admin-guide/index.rst while clean its todo entry. Signed-off-by: Wu XiangCheng Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/cd2fd8d0ea2ad50afc6bd2abe15eba73b6c7940c.1616050069.git.bobwxc@email.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/admin-guide/index.rst | 2 +- .../translations/zh_CN/admin-guide/init.rst | 54 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 Documentation/translations/zh_CN/admin-guide/init.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/admin-guide/index.rst b/Documentation/translations/zh_CN/admin-guide/index.rst index a671d16710f3..be835ec8e632 100644 --- a/Documentation/translations/zh_CN/admin-guide/index.rst +++ b/Documentation/translations/zh_CN/admin-guide/index.rst @@ -40,13 +40,13 @@ Todolist: bug-hunting bug-bisect tainted-kernels + init Todolist: reporting-bugs ramoops dynamic-debug-howto - init kdump/index perf/index diff --git a/Documentation/translations/zh_CN/admin-guide/init.rst b/Documentation/translations/zh_CN/admin-guide/init.rst new file mode 100644 index 000000000000..fbaf6d97f86c --- /dev/null +++ b/Documentation/translations/zh_CN/admin-guide/init.rst @@ -0,0 +1,54 @@ +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../admin-guide/init` + +:译者: + + 吴想成 Wu XiangCheng + +解释“No working init found.”启动挂起消息 +========================================= + +:作者: + + Andreas Mohr + + Cristian Souza + +本文档提供了加载初始化二进制(init binary)失败的一些高层级原因(大致按执行 +顺序列出)。 + +1) **无法挂载根文件系统Unable to mount root FS** :请设置“debug”内核参数(在 + 引导加载程序bootloader配置文件或CONFIG_CMDLINE)以获取更详细的内核消息。 + +2) **初始化二进制不存在于根文件系统上init binary doesn't exist on rootfs** : + 确保您的根文件系统类型正确(并且 ``root=`` 内核参数指向正确的分区);拥有 + 所需的驱动程序,例如SCSI或USB等存储硬件;文件系统(ext3、jffs2等)是内建的 + (或者作为模块由initrd预加载)。 + +3) **控制台设备损坏Broken console device** : ``console= setup`` 中可能存在 + 冲突 --> 初始控制台不可用(initial console unavailable)。例如,由于串行 + IRQ问题(如缺少基于中断的配置)导致的某些串行控制台不可靠。尝试使用不同的 + ``console= device`` 或像 ``netconsole=`` 。 + +4) **二进制存在但依赖项不可用Binary exists but dependencies not available** : + 例如初始化二进制的必需库依赖项,像 ``/lib/ld-linux.so.2`` 丢失或损坏。使用 + ``readelf -d |grep NEEDED`` 找出需要哪些库。 + +5) **无法加载二进制Binary cannot be loaded** :请确保二进制的体系结构与您的 + 硬件匹配。例如i386不匹配x86_64,或者尝试在ARM硬件上加载x86。如果您尝试在 + 此处加载非二进制文件(shell脚本?),您应该确保脚本在其工作头(shebang + header)行 ``#!/...`` 中指定能正常工作的解释器(包括其库依赖项)。在处理 + 脚本之前,最好先测试一个简单的非脚本二进制文件,比如 ``/bin/sh`` ,并确认 + 它能成功执行。要了解更多信息,请将代码添加到 ``init/main.c`` 以显示 + kernel_execve()的返回值。 + +当您发现新的失败原因时,请扩展本解释(毕竟加载初始化二进制是一个 **关键** 且 +艰难的过渡步骤,需要尽可能无痛地进行),然后向LKML提交一个补丁。 + +待办事项: + +- 通过一个可以存储 ``kernel_execve()`` 结果值的结构体数组实现各种 + ``run_init_process()`` 调用,并在失败时通过迭代 **所有** 结果来记录一切 + (非常重要的可用性修复)。 +- 试着使实现本身在一般情况下更有帮助,例如在受影响的地方提供额外的错误消息。 -- cgit v1.2.3 From d4b61e17e2e49c7146e7b96e17aef0b42c3ba90a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 2 Mar 2021 23:18:22 +0900 Subject: docs: Remove make headers_check from checklist in translations Commit 1a63f9cce7b7 ("docs: Remove make headers_check from checklist") fixed only the English version. Let's fix the translated variants too. Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20210302141822.504773-1-masahiroy@kernel.org Signed-off-by: Jonathan Corbet --- .../translations/it_IT/process/submit-checklist.rst | 14 ++++++-------- Documentation/translations/ja_JP/SubmitChecklist | 8 +++----- .../translations/zh_CN/process/submit-checklist.rst | 14 ++++++-------- 3 files changed, 15 insertions(+), 21 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/it_IT/process/submit-checklist.rst b/Documentation/translations/it_IT/process/submit-checklist.rst index 614fc17d9086..62ba471921b6 100644 --- a/Documentation/translations/it_IT/process/submit-checklist.rst +++ b/Documentation/translations/it_IT/process/submit-checklist.rst @@ -95,31 +95,29 @@ sottomissione delle patch, in particolare informazioni. Le patch che modificano le interfacce utente dovrebbero essere inviate in copia anche a linux-api@vger.kernel.org. -20) Verifica che il kernel passi con successo ``make headers_check`` - -21) La patch è stata verificata con l'iniezione di fallimenti in slab e +20) La patch è stata verificata con l'iniezione di fallimenti in slab e nell'allocazione di pagine. Vedere ``Documentation/fault-injection/``. Se il nuovo codice è corposo, potrebbe essere opportuno aggiungere l'iniezione di fallimenti specifici per il sottosistema. -22) Il nuovo codice è stato compilato con ``gcc -W`` (usate +21) Il nuovo codice è stato compilato con ``gcc -W`` (usate ``make KCFLAGS=-W``). Questo genererà molti avvisi, ma è ottimo per scovare bachi come "warning: comparison between signed and unsigned". -23) La patch è stata verificata dopo essere stata inclusa nella serie di patch +22) La patch è stata verificata dopo essere stata inclusa nella serie di patch -mm; questo al fine di assicurarsi che continui a funzionare assieme a tutte le altre patch in coda e i vari cambiamenti nei sottosistemi VM, VFS e altri. -24) Tutte le barriere di sincronizzazione {per esempio, ``barrier()``, +23) Tutte le barriere di sincronizzazione {per esempio, ``barrier()``, ``rmb()``, ``wmb()``} devono essere accompagnate da un commento nei sorgenti che ne spieghi la logica: cosa fanno e perché. -25) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate +24) Se la patch aggiunge nuove chiamate ioctl, allora aggiornate ``Documentation/userspace-api/ioctl/ioctl-number.rst``. -26) Se il codice che avete modificato dipende o usa una qualsiasi interfaccia o +25) Se il codice che avete modificato dipende o usa una qualsiasi interfaccia o funzionalità del kernel che è associata a uno dei seguenti simboli ``Kconfig``, allora verificate che il kernel compili con diverse configurazioni dove i simboli sono disabilitati e/o ``=m`` (se c'è la diff --git a/Documentation/translations/ja_JP/SubmitChecklist b/Documentation/translations/ja_JP/SubmitChecklist index b42220d3d46c..4429447b0965 100644 --- a/Documentation/translations/ja_JP/SubmitChecklist +++ b/Documentation/translations/ja_JP/SubmitChecklist @@ -88,20 +88,18 @@ Linux カーネルパッチ投稿者向けチェックリスト 18: 新しいuserspaceインタフェースを作成した場合には、Documentation/ABI/ に Documentation/ABI/README を参考にして必ずドキュメントを追加してください。 -19: 'make headers_check'を実行して全く問題がないことを確認してください。 - -20: 少なくともslabアロケーションとpageアロケーションに失敗した場合の +19: 少なくともslabアロケーションとpageアロケーションに失敗した場合の 挙動について、fault-injectionを利用して確認してください。 Documentation/fault-injection/ を参照してください。 追加したコードがかなりの量であったならば、サブシステム特有の fault-injectionを追加したほうが良いかもしれません。 -21: 新たに追加したコードは、`gcc -W'でコンパイルしてください。 +20: 新たに追加したコードは、`gcc -W'でコンパイルしてください。 このオプションは大量の不要なメッセージを出力しますが、 "warning: comparison between signed and unsigned" のようなメッセージは、 バグを見つけるのに役に立ちます。 -22: 投稿したパッチが -mm パッチセットにマージされた後、全ての既存のパッチや +21: 投稿したパッチが -mm パッチセットにマージされた後、全ての既存のパッチや VM, VFS およびその他のサブシステムに関する様々な変更と、現時点でも共存 できることを確認するテストを行ってください。 diff --git a/Documentation/translations/zh_CN/process/submit-checklist.rst b/Documentation/translations/zh_CN/process/submit-checklist.rst index 50386e0e42e7..a64858d321fc 100644 --- a/Documentation/translations/zh_CN/process/submit-checklist.rst +++ b/Documentation/translations/zh_CN/process/submit-checklist.rst @@ -82,24 +82,22 @@ Linux内核补丁提交清单 请参阅 ``Documentation/ABI/README`` 。更改用户空间接口的补丁应该抄送 linux-api@vger.kernel.org。 -20) 检查是否全部通过 ``make headers_check`` 。 - -21) 已通过至少注入slab和page分配失败进行检查。请参阅 ``Documentation/fault-injection/`` +20) 已通过至少注入slab和page分配失败进行检查。请参阅 ``Documentation/fault-injection/`` 如果新代码是实质性的,那么添加子系统特定的故障注入可能是合适的。 -22) 新添加的代码已经用 ``gcc -W`` 编译(使用 ``make EXTRA-CFLAGS=-W`` )。这 +21) 新添加的代码已经用 ``gcc -W`` 编译(使用 ``make EXTRA-CFLAGS=-W`` )。这 将产生大量噪声,但对于查找诸如“警告:有符号和无符号之间的比较”之类的错误 很有用。 -23) 在它被合并到-mm补丁集中之后进行测试,以确保它仍然与所有其他排队的补丁以 +22) 在它被合并到-mm补丁集中之后进行测试,以确保它仍然与所有其他排队的补丁以 及VM、VFS和其他子系统中的各种更改一起工作。 -24) 所有内存屏障例如 ``barrier()``, ``rmb()``, ``wmb()`` 都需要源代码中的注 +23) 所有内存屏障例如 ``barrier()``, ``rmb()``, ``wmb()`` 都需要源代码中的注 释来解释它们正在执行的操作及其原因的逻辑。 -25) 如果补丁添加了任何ioctl,那么也要更新 ``Documentation/userspace-api/ioctl/ioctl-number.rst`` +24) 如果补丁添加了任何ioctl,那么也要更新 ``Documentation/userspace-api/ioctl/ioctl-number.rst`` -26) 如果修改后的源代码依赖或使用与以下 ``Kconfig`` 符号相关的任何内核API或 +25) 如果修改后的源代码依赖或使用与以下 ``Kconfig`` 符号相关的任何内核API或 功能,则在禁用相关 ``Kconfig`` 符号和/或 ``=m`` (如果该选项可用)的情况 下测试以下多个构建[并非所有这些都同时存在,只是它们的各种/随机组合]: -- cgit v1.2.3 From 2bb5baf9d22764fff6baca4c3ad93055848bbf03 Mon Sep 17 00:00:00 2001 From: Alex Shi Date: Fri, 26 Mar 2021 16:49:31 +0800 Subject: Docs/zh_CN: update Alex Shi new email address I am leaving Alibaba, udpate the old email address to new one. Signed-off-by: Alex Shi Cc: Harry Wei Cc: Alex Shi Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Cc: linux-kernel@vger.kernel.org Link: https://lore.kernel.org/r/1616748571-52058-2-git-send-email-alex.shi@linux.alibaba.com Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/disclaimer-zh_CN.rst | 2 +- MAINTAINERS | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/disclaimer-zh_CN.rst b/Documentation/translations/zh_CN/disclaimer-zh_CN.rst index dcf803ede85a..3c6db094a63c 100644 --- a/Documentation/translations/zh_CN/disclaimer-zh_CN.rst +++ b/Documentation/translations/zh_CN/disclaimer-zh_CN.rst @@ -6,4 +6,4 @@ .. note:: 如果您发现本文档与原始文件有任何不同或者有翻译问题,请联系该文件的译者, - 或者请求时奎亮的帮助:。 + 或者请求时奎亮的帮助:。 diff --git a/MAINTAINERS b/MAINTAINERS index b5d38fedff6c..03b2096a5f8f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4195,7 +4195,7 @@ F: Documentation/dev-tools/checkpatch.rst CHINESE DOCUMENTATION M: Harry Wei -M: Alex Shi +M: Alex Shi L: xiyoulinuxkernelgroup@googlegroups.com (subscribers-only) S: Maintained F: Documentation/translations/zh_CN/ -- cgit v1.2.3 From dde201b901bf40ffa792fd94c3873af5c5deb015 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 6 Apr 2021 15:02:32 +0800 Subject: docs/zh_CN: add cpu-freq core.rst translation This patch translates Documention/cpu-freq/core.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210406070239.19910-2-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- Documentation/translations/zh_CN/cpu-freq/core.rst | 105 +++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Documentation/translations/zh_CN/cpu-freq/core.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/cpu-freq/core.rst b/Documentation/translations/zh_CN/cpu-freq/core.rst new file mode 100644 index 000000000000..19fb9c029cfe --- /dev/null +++ b/Documentation/translations/zh_CN/cpu-freq/core.rst @@ -0,0 +1,105 @@ +.. SPDX-License-Identifier: GPL-2.0 +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../cpu-freq/core` +:Translator: Yanteng Si + +.. _cn_core.rst: + + +==================================== +CPUFreq核心和CPUFreq通知器的通用说明 +==================================== + +作者: + - Dominik Brodowski + - David Kimdon + - Rafael J. Wysocki + - Viresh Kumar + +.. 目录: + + 1. CPUFreq核心和接口 + 2. CPUFreq通知器 + 3. 含有Operating Performance Point (OPP)的CPUFreq表的生成 + +1. CPUFreq核心和接口 +====================== + +cpufreq核心代码位于drivers/cpufreq/cpufreq.c中。这些cpufreq代码为CPUFreq架构的驱 +动程序(那些操作硬件切换频率的代码)以及 "通知器 "提供了一个标准化的接口。 +这些是设备驱动程序或需要了解策略变化的其它内核部分(如 ACPI 热量管理)或所有频率更改(除 +计时代码外),甚至需要强制确定速度限制的通知器(如 ARM 架构上的 LCD 驱动程序)。 +此外, 内核 "常数" loops_per_jiffy会根据频率变化而更新。 + +cpufreq策略的引用计数由 cpufreq_cpu_get 和 cpufreq_cpu_put 来完成,以确保 cpufreq 驱 +动程序被正确地注册到核心中,并且驱动程序在 cpufreq_put_cpu 被调用之前不会被卸载。这也保证 +了每个CPU核的cpufreq 策略在使用期间不会被释放。 + +2. CPUFreq 通知器 +==================== + +CPUFreq通知器符合标准的内核通知器接口。 +关于通知器的细节请参阅 linux/include/linux/notifier.h。 + +这里有两个不同的CPUfreq通知器 - 策略通知器和转换通知器。 + + +2.1 CPUFreq策略通知器 +---------------------------- + +当创建或移除策略时,这些都会被通知。 + +阶段是在通知器的第二个参数中指定的。当第一次创建策略时,阶段是CPUFREQ_CREATE_POLICY,当 +策略被移除时,阶段是CPUFREQ_REMOVE_POLICY。 + +第三个参数 ``void *pointer`` 指向一个结构体cpufreq_policy,其包括min,max(新策略的下限和 +上限(单位为kHz))这几个值。 + + +2.2 CPUFreq转换通知器 +-------------------------------- + +当CPUfreq驱动切换CPU核心频率时,策略中的每个在线CPU都会收到两次通知,这些变化没有任何外部干 +预。 + +第二个参数指定阶段 - CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE. + +第三个参数是一个包含如下值的结构体cpufreq_freqs: + +===== ==================== +cpu 受影响cpu的编号 +old 旧频率 +new 新频率 +flags cpufreq驱动的标志 +===== ==================== + +3. 含有Operating Performance Point (OPP)的CPUFreq表的生成 +================================================================== +关于OPP的细节请参阅 Documentation/power/opp.rst + +dev_pm_opp_init_cpufreq_table - + 这个功能提供了一个随时可用的转换程序,用来将OPP层关于可用频率的内部信息翻译成一种容易提供给 + cpufreq的格式。 + + .. Warning:: + + 不要在中断上下文中使用此函数。 + + 例如:: + + soc_pm_init() + { + /* Do things */ + r = dev_pm_opp_init_cpufreq_table(dev, &freq_table); + if (!r) + policy->freq_table = freq_table; + /* Do other things */ + } + + .. note:: + + 该函数只有在CONFIG_PM_OPP之外还启用了CONFIG_CPU_FREQ时才可用。 + +dev_pm_opp_free_cpufreq_table + 释放dev_pm_opp_init_cpufreq_table分配的表。 -- cgit v1.2.3 From 8b6d5ae8a9968c0a3807587d33b5952cdf71de1b Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 6 Apr 2021 15:02:33 +0800 Subject: docs/zh_CN: add cpu-freq cpu-drivers.rst translation This patch translates Documention/cpu-freq/cpu-drivers.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210406070239.19910-3-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/cpu-freq/cpu-drivers.rst | 259 +++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst b/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst new file mode 100644 index 000000000000..0ca2cb646666 --- /dev/null +++ b/Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst @@ -0,0 +1,259 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../cpu-freq/cpu-drivers` +:Translator: Yanteng Si + +.. _cn_cpu-drivers.rst: + + +======================================= +如何实现一个新的CPUFreq处理器驱动程序? +======================================= + +作者: + + + - Dominik Brodowski + - Rafael J. Wysocki + - Viresh Kumar + +.. Contents + + 1. 怎么做? + 1.1 初始化 + 1.2 Per-CPU 初始化 + 1.3 验证 + 1.4 target/target_index 或 setpolicy? + 1.5 target/target_index + 1.6 setpolicy + 1.7 get_intermediate 与 target_intermediate + 2. 频率表助手 + + + +1. 怎么做? +=========== + +如此,你刚刚得到了一个全新的CPU/芯片组及其数据手册,并希望为这个CPU/芯片组添加cpufreq +支持?很好,这里有一些至关重要的提示: + + +1.1 初始化 +---------- + +首先,在__initcall_level_7 (module_init())或更靠后的函数中检查这个内核是否 +运行在正确的CPU和正确的芯片组上。如果是,则使用cpufreq_register_driver()向 +CPUfreq核心层注册一个cpufreq_driver结构体。 + +结构体cpufreq_driver应该包含什么成员? + + .name - 驱动的名字。 + + .init - 一个指向per-policy初始化函数的指针。 + + .verify - 一个指向"verification"函数的指针。 + + .setpolicy 或 .fast_switch 或 .target 或 .target_index - 差异见 + 下文。 + +并且可选择 + + .flags - cpufreq核的提示。 + + .driver_data - cpufreq驱动程序的特定数据。 + + .resolve_freq - 返回最适合目标频率的频率。不过并不能改变频率。 + + .get_intermediate 和 target_intermediate - 用于在改变CPU频率时切换到稳定 + 的频率。 + + .get - 返回CPU的当前频率。 + + .bios_limit - 返回HW/BIOS对CPU的最大频率限制值。 + + .exit - 一个指向per-policy清理函数的指针,该函数在cpu热插拔过程的CPU_POST_DEAD + 阶段被调用。 + + .stop_cpu - 一个指向per-policy停止函数的指针,该函数在cpu热插拔过程的CPU_DOWN_PREPARE + 阶段被调用。 + + .suspend - 一个指向per-policy暂停函数的指针,该函数在关中断且在该策略的调节器停止 + 后被调用。 + + .resume - 一个指向per-policy恢复函数的指针,该函数在关中断且在调节器再一次开始前被 + 调用。 + + .ready - 一个指向per-policy准备函数的指针,该函数在策略完全初始化之后被调用。 + + .attr - 一个指向NULL结尾的"struct freq_attr"列表的指针,该函数允许导出值到 + sysfs。 + + .boost_enabled - 如果设置,则启用提升(boost)频率。 + + .set_boost - 一个指向per-policy函数的指针,该函数用来开启/关闭提升(boost)频率功能。 + + +1.2 Per-CPU 初始化 +------------------ + +每当一个新的CPU被注册到设备模型中,或者在cpufreq驱动注册自己之后,如果此CPU的cpufreq策 +略不存在,则会调用per-policy的初始化函数cpufreq_driver.init。请注意,.init()和.exit()程序 +只对策略调用一次,而不是对策略管理的每个CPU调用一次。它需要一个 ``struct cpufreq_policy +*policy`` 作为参数。现在该怎么做呢? + +如果有必要,请在你的CPU上激活CPUfreq功能支持。 + +然后,驱动程序必须填写以下数值: + ++-----------------------------------+--------------------------------------+ +|policy->cpuinfo.min_freq 和 | | +|policy->cpuinfo.max_freq | 该CPU支持的最低和最高频率(kHz) | +| | | +| | | ++-----------------------------------+--------------------------------------+ +|policy->cpuinfo.transition_latency | | +| | CPU在两个频率之间切换所需的时间,以 | +| | 纳秒为单位(如适用,否则指定 | +| | CPUFREQ_ETERNAL) | ++-----------------------------------+--------------------------------------+ +|policy->cur | 该CPU当前的工作频率(如适用) | +| | | ++-----------------------------------+--------------------------------------+ +|policy->min, | | +|policy->max, | | +|policy->policy and, if necessary, | | +|policy->governor | 必须包含该cpu的 “默认策略”。稍后 | +| | 会用这些值调用 | +| | cpufreq_driver.verify and either | +| | cpufreq_driver.setpolicy or | +| | cpufreq_driver.target/target_index | +| | | ++-----------------------------------+--------------------------------------+ +|policy->cpus | 用与这个CPU一起做DVFS的(在线+离线) | +| | CPU(即与它共享时钟/电压轨)的掩码更新 | +| | 这个 | +| | | ++-----------------------------------+--------------------------------------+ + +对于设置其中的一些值(cpuinfo.min[max]_freq, policy->min[max]),频率表助手可能会有帮 +助。关于它们的更多信息,请参见第2节。 + + +1.3 验证 +-------- + +当用户决定设置一个新的策略(由 “policy,governor,min,max组成”)时,必须对这个策略进行验证, +以便纠正不兼容的值。为了验证这些值,cpufreq_verify_within_limits(``struct cpufreq_policy +*policy``, ``unsigned int min_freq``, ``unsigned int max_freq``)函数可能会有帮助。 +关于频率表助手的详细内容请参见第2节。 + +您需要确保至少有一个有效频率(或工作范围)在 policy->min 和 policy->max 范围内。如果有必 +要,先增加policy->max,只有在没有办法的情况下,才减少policy->min。 + + +1.4 target 或 target_index 或 setpolicy 或 fast_switch? +------------------------------------------------------- + +大多数cpufreq驱动甚至大多数cpu频率升降算法只允许将CPU频率设置为预定义的固定值。对于这些,你 +可以使用->target(),->target_index()或->fast_switch()回调。 + +有些cpufreq功能的处理器可以自己在某些限制之间切换频率。这些应使用->setpolicy()回调。 + + +1.5. target/target_index +------------------------ + +target_index调用有两个参数:``struct cpufreq_policy * policy``和``unsigned int`` +索引(于列出的频率表)。 + +当调用这里时,CPUfreq驱动必须设置新的频率。实际频率必须由freq_table[index].frequency决定。 + +它应该总是在错误的情况下恢复到之前的频率(即policy->restore_freq),即使我们之前切换到中间频率。 + +已弃用 +---------- +目标调用有三个参数。``struct cpufreq_policy * policy``, unsigned int target_frequency, +unsigned int relation. + +CPUfreq驱动在调用这里时必须设置新的频率。实际的频率必须使用以下规则来确定。 + +- 紧跟 "目标频率"。 +- policy->min <= new_freq <= policy->max (这必须是有效的!!!) +- 如果 relation==CPUFREQ_REL_L,尝试选择一个高于或等于 target_freq 的 new_freq。("L代表 + 最低,但不能低于") +- 如果 relation==CPUFREQ_REL_H,尝试选择一个低于或等于 target_freq 的 new_freq。("H代表 + 最高,但不能高于") + +这里,频率表助手可能会帮助你--详见第2节。 + +1.6. fast_switch +---------------- + +这个函数用于从调度器的上下文进行频率切换。并非所有的驱动都要实现它,因为不允许在这个回调中睡眠。这 +个回调必须经过高度优化,以尽可能快地进行切换。 + +这个函数有两个参数: ``struct cpufreq_policy *policy`` 和 ``unsigned int target_frequency``。 + + +1.7 setpolicy +------------- + +setpolicy调用只需要一个``struct cpufreq_policy * policy``作为参数。需要将处理器内或芯片组内动态频 +率切换的下限设置为policy->min,上限设置为policy->max,如果支持的话,当policy->policy为 +CPUFREQ_POLICY_PERFORMANCE时选择面向性能的设置,当CPUFREQ_POLICY_POWERSAVE时选择面向省电的设置。 +也可以查看drivers/cpufreq/longrun.c中的参考实现。 + +1.8 get_intermediate 和 target_intermediate +-------------------------------------------- + +仅适用于 target_index() 和 CPUFREQ_ASYNC_NOTIFICATION 未设置的驱动。 + +get_intermediate应该返回一个平台想要切换到的稳定的中间频率,target_intermediate()应该将CPU设置为 +该频率,然后再跳转到'index'对应的频率。核心会负责发送通知,驱动不必在target_intermediate()或 +target_index()中处理。 + +在驱动程序不想因为某个目标频率切换到中间频率的情况下,它们可以从get_intermediate()中返回'0'。在这种情况 +下,核心将直接调用->target_index()。 + +注意:->target_index()应该在失败的情况下恢复到policy->restore_freq,因为core会为此发送通知。 + + +2. 频率表助手 +============= + +由于大多数cpufreq处理器只允许被设置为几个特定的频率,因此,一个带有一些函数的 “频率表”可能会辅助处理器驱动 +程序的一些工作。这样的 "频率表" 由一个cpufreq_frequency_table条目构成的数组组成,"driver_data" 中包 +含了驱动程序的具体数值,"frequency" 中包含了相应的频率,并设置了标志。在表的最后,需要添加一个 +cpufreq_frequency_table条目,频率设置为CPUFREQ_TABLE_END。而如果想跳过表中的一个条目,则将频率设置为 +CPUFREQ_ENTRY_INVALID。这些条目不需要按照任何特定的顺序排序,但如果它们是cpufreq 核心会对它们进行快速的DVFS, +因为搜索最佳匹配会更快。 + +如果策略在其policy->freq_table字段中包含一个有效的指针,cpufreq表就会被核心自动验证。 + +cpufreq_frequency_table_verify()保证至少有一个有效的频率在policy->min和policy->max范围内,并且所有其他 +标准都被满足。这对->verify调用很有帮助。 + +cpufreq_frequency_table_target()是对应于->target阶段的频率表助手。只要把数值传递给这个函数,这个函数就会返 +回包含CPU要设置的频率的频率表条目。 + +以下宏可以作为cpufreq_frequency_table的迭代器。 + +cpufreq_for_each_entry(pos, table) - 遍历频率表的所有条目。 + +cpufreq_for_each_valid_entry(pos, table) - 该函数遍历所有条目,不包括CPUFREQ_ENTRY_INVALID频率。 +使用参数 "pos"-一个``cpufreq_frequency_table * `` 作为循环变量,使用参数 "table"-作为你想迭代 +的``cpufreq_frequency_table * `` 。 + +例如:: + + struct cpufreq_frequency_table *pos, *driver_freq_table; + + cpufreq_for_each_entry(pos, driver_freq_table) { + /* Do something with pos */ + pos->frequency = ... + } + +如果你需要在driver_freq_table中处理pos的位置,不要减去指针,因为它的代价相当高。相反,使用宏 +cpufreq_for_each_entry_idx() 和 cpufreq_for_each_valid_entry_idx() 。 -- cgit v1.2.3 From ffd1f19d083432d708412c5252571bc69e16d499 Mon Sep 17 00:00:00 2001 From: Yanteng Si Date: Tue, 6 Apr 2021 15:02:34 +0800 Subject: docs/zh_CN: add cpu-freq cpufreq-stats.rst translation This patch translates Documention/cpu-freq/cpufreq-stats.rst into Chinese. Signed-off-by: Yanteng Si Reviewed-by: Alex Shi Link: https://lore.kernel.org/r/20210406070239.19910-4-siyanteng@loongson.cn Signed-off-by: Jonathan Corbet --- .../translations/zh_CN/cpu-freq/cpufreq-stats.rst | 130 +++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 Documentation/translations/zh_CN/cpu-freq/cpufreq-stats.rst (limited to 'Documentation/translations') diff --git a/Documentation/translations/zh_CN/cpu-freq/cpufreq-stats.rst b/Documentation/translations/zh_CN/cpu-freq/cpufreq-stats.rst new file mode 100644 index 000000000000..c90d1d8353ed --- /dev/null +++ b/Documentation/translations/zh_CN/cpu-freq/cpufreq-stats.rst @@ -0,0 +1,130 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. include:: ../disclaimer-zh_CN.rst + +:Original: :doc:`../../../cpu-freq/cpufreq-stats` +:Translator: Yanteng Si + +.. _cn_cpufreq-stats.rst: + + +========================================== +sysfs CPUFreq Stats的一般说明 +========================================== + +用户信息 + + +作者: Venkatesh Pallipadi + +.. Contents + + 1. 简介 + 2. 提供的统计数据(举例说明) + 3. 配置cpufreq-stats + + +1. 简介 +=============== + +cpufreq-stats是一个为每个CPU提供CPU频率统计的驱动。 +这些统计数据在/sysfs中以一堆只读接口的形式提供。这个接口(在配置好后)将出现在 +/sysfs(/devices/system/cpu/cpuX/cpufreq/stats/)中cpufreq下的一个单 +独的目录中,提供给每个CPU。 +各种统计数据将在此目录下形成只读文件。 + +此驱动是独立于任何可能运行在你所用CPU上的特定cpufreq_driver而设计的。因此,它将与所有 +cpufreq_driver一起工作。 + + +2. 提供的统计数据(举例说明) +===================================== + +cpufreq stats提供了以下统计数据(在下面详细解释)。 + +- time_in_state +- total_trans +- trans_table + +所有的统计数据将从统计驱动被载入的时间(或统计被重置的时间)开始,到某一统计数据被读取的时间为止。 +显然,统计驱动不会有任何关于统计驱动载入之前的频率转换信息。 + +:: + + :/sys/devices/system/cpu/cpu0/cpufreq/stats # ls -l + total 0 + drwxr-xr-x 2 root root 0 May 14 16:06 . + drwxr-xr-x 3 root root 0 May 14 15:58 .. + --w------- 1 root root 4096 May 14 16:06 reset + -r--r--r-- 1 root root 4096 May 14 16:06 time_in_state + -r--r--r-- 1 root root 4096 May 14 16:06 total_trans + -r--r--r-- 1 root root 4096 May 14 16:06 trans_table + +- **reset** + +只写属性,可用于重置统计计数器。这对于评估不同调节器下的系统行为非常有用,且无需重启。 + + +- **time_in_state** + +此项给出了这个CPU所支持的每个频率所花费的时间。cat输出的每一行都会有" +