Hsphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/process/4.CodingmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/zh_TW/process/4.CodingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/it_IT/process/4.CodingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ja_JP/process/4.CodingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ko_KR/process/4.CodingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/pt_BR/process/4.CodingmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/sp_SP/process/4.CodingmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh](hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhQ/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/process/4.Coding.rsthKubh field_body)}(h?:ref:`Documentation/process/4.Coding.rst ` h]h)}(h>:ref:`Documentation/process/4.Coding.rst `h]h)}(hhh]hinline)}(hhh]h"Documentation/process/4.Coding.rst}(hhhhhNhNubah}(h]h ](xrefstdstd-refeh"]h$]h&]uh1hhhubah}(h]h ]h"]h$]h&]refdoc#translations/zh_CN/process/4.Coding refdomainjreftyperef refexplicitrefwarn reftargetdevelopment_codinguh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h Translatorh]h Translator}(hj0hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj-hhhKubh)}(h0时奎亮 Alex Shi h]h)}(h/时奎亮 Alex Shi h](h时奎亮 Alex Shi <}(hjBhhhNhNubh reference)}(halex.shi@linux.alibaba.comh]halex.shi@linux.alibaba.com}(hjLhhhNhNubah}(h]h ]h"]h$]h&]refuri!mailto:alex.shi@linux.alibaba.comuh1jJhjBubh>}(hjBhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj>ubah}(h]h ]h"]h$]h&]uh1hhj-ubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hhh](h)}(h校译h]h校译}(hjuhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjrhhhKubh)}(h*吴想成 Wu XiangCheng h]h)}(h)吴想成 Wu XiangCheng h](h吴想成 Wu XiangCheng <}(hjhhhNhNubjK)}(hbobwxc@email.cnh]hbobwxc@email.cn}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:bobwxc@email.cnuh1jJhjubh>}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK hjubah}(h]h ]h"]h$]h&]uh1hhjrubeh}(h]h ]h"]h$]h&]uh1hhhhK hhhhubeh}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhtarget)}(h.. _cn_development_coding:h]h}(h]h ]h"]h$]h&]refidcn-development-codinguh1jhKhhhhhhubhsection)}(hhh](htitle)}(h使代码正确h]h使代码正确}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKubh)}(hX+虽然一个坚实的、面向社区的设计过程有很多值得说道的,但是任何内核开发项目工作 的证明都反映在代码中。它是将由其他开发人员检查并合并(或不合并)到主线树中 的代码。所以这段代码的质量决定了项目的最终成功。h]hX+虽然一个坚实的、面向社区的设计过程有很多值得说道的,但是任何内核开发项目工作 的证明都反映在代码中。它是将由其他开发人员检查并合并(或不合并)到主线树中 的代码。所以这段代码的质量决定了项目的最终成功。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h本节将检查编码过程。我们将从内核开发人员常犯的几种错误开始。然后重点将转移 到正确的做法和相关有用的工具上。h]h本节将检查编码过程。我们将从内核开发人员常犯的几种错误开始。然后重点将转移 到正确的做法和相关有用的工具上。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(hhh](j)}(h陷阱h]h陷阱}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h 代码风格h]h 代码风格}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhj hhhhhKubh)}(hXq内核长期以来都有其标准的代码风格,如 :ref:`Documentation/translations/zh_CN/process/coding-style.rst ` 中所述。在多数时候,该文档中描述的准则至多被认为是建议性的。因此,内核中存在 大量不符合代码风格准则的代码。这种代码的存在会给内核开发人员带来两方面的危害。h](h7内核长期以来都有其标准的代码风格,如 }(hjhhhNhNubh)}(hQ:ref:`Documentation/translations/zh_CN/process/coding-style.rst `h]h)}(hj&h]h9Documentation/translations/zh_CN/process/coding-style.rst}(hj(hhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhj$ubah}(h]h ]h"]h$]h&]refdocj refdomainj2reftyperef refexplicitrefwarnjcn_codingstyleuh1hhhhKhjubh 中所述。在多数时候,该文档中描述的准则至多被认为是建议性的。因此,内核中存在 大量不符合代码风格准则的代码。这种代码的存在会给内核开发人员带来两方面的危害。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hX首先,相信内核代码标准并不重要,也不强制执行。但事实上,如果没有按照标准 编写代码,那么新代码将很难加入到内核中;许多开发人员甚至会在审查代码之前要求 对代码进行重新格式化。一个像内核这么大的代码库需要一些统一格式的代码,以使 开发人员能够快速理解其中的任何部分。所以再也经不起奇怪格式的代码的折腾了。h]hX首先,相信内核代码标准并不重要,也不强制执行。但事实上,如果没有按照标准 编写代码,那么新代码将很难加入到内核中;许多开发人员甚至会在审查代码之前要求 对代码进行重新格式化。一个像内核这么大的代码库需要一些统一格式的代码,以使 开发人员能够快速理解其中的任何部分。所以再也经不起奇怪格式的代码的折腾了。}(hjNhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK$hj hhubh)}(h内核的代码风格偶尔会与雇主的强制风格发生冲突。在这种情况下,必须在代码合并 之前遵从内核代码风格。将代码放入内核意味着以多种方式放弃一定程度的控制权—— 包括控制代码样式。h]h内核的代码风格偶尔会与雇主的强制风格发生冲突。在这种情况下,必须在代码合并 之前遵从内核代码风格。将代码放入内核意味着以多种方式放弃一定程度的控制权—— 包括控制代码样式。}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK)hj hhubh)}(hX/另一个危害是认为已经在内核中的代码迫切需要修复代码样式。开发者可能会开始编写 重新格式化补丁,作为熟悉开发过程的一种方式,或者作为将其名字写入内核变更日志 的一种方式,或者两者兼而有之。但是纯代码风格的修复被开发社区视为噪音,它们往 往受到冷遇。因此,最好避免编写这种类型的补丁。在由于其他原因处理一段代码的 同时顺带修复其样式是很自然的,但是不应该仅为了更改代码样式而更改之。h]hX/另一个危害是认为已经在内核中的代码迫切需要修复代码样式。开发者可能会开始编写 重新格式化补丁,作为熟悉开发过程的一种方式,或者作为将其名字写入内核变更日志 的一种方式,或者两者兼而有之。但是纯代码风格的修复被开发社区视为噪音,它们往 往受到冷遇。因此,最好避免编写这种类型的补丁。在由于其他原因处理一段代码的 同时顺带修复其样式是很自然的,但是不应该仅为了更改代码样式而更改之。}(hjjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK-hj hhubh)}(h代码风格文档也不应该被视为绝对不可违反的规则。如果有一个足够的理由反对这种 样式(例如为了80列限制拆分行会导致可读性大大降低),那么就这样做吧。h]h代码风格文档也不应该被视为绝对不可违反的规则。如果有一个足够的理由反对这种 样式(例如为了80列限制拆分行会导致可读性大大降低),那么就这样做吧。}(hjxhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK3hj hhubh)}(hX注意您还可以使用 ``clang-format`` 工具来帮助您处理这些规则,快速自动重新格式 化部分代码,和审阅完整的文件以发现代码样式错误、拼写错误和可能的改进。它还 可以方便地排序 ``#includes`` 、对齐变量/宏、重排文本和其他类似任务。有关详细 信息,请参阅文档 :ref:`Documentation/dev-tools/clang-format.rst `h](h注意您还可以使用 }(hjhhhNhNubhliteral)}(h``clang-format``h]h clang-format}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubh 工具来帮助您处理这些规则,快速自动重新格式 化部分代码,和审阅完整的文件以发现代码样式错误、拼写错误和可能的改进。它还 可以方便地排序 }(hjhhhNhNubj)}(h ``#includes``h]h #includes}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjubha 、对齐变量/宏、重排文本和其他类似任务。有关详细 信息,请参阅文档 }(hjhhhNhNubh)}(h=:ref:`Documentation/dev-tools/clang-format.rst `h]h)}(hjh]h(Documentation/dev-tools/clang-format.rst}(hjhhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftyperef refexplicitrefwarnj clangformatuh1hhhhK6hjubeh}(h]h ]h"]h$]h&]uh1hhhhK6hj hhubeh}(h]id3ah ]h"] 代码风格ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h 抽象层h]h 抽象层}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhKhjhhubh)}(hX&简单点,先考虑一个调用时始终只有一个参数且总为零的函数。我们可以保留这个参数, 以在需要使用它时提供的额外灵活性。不过,在那时实现了这个额外参数的代码很有 可能以某种从未被注意到的微妙方式被破坏——因为它从未被使用过。或者当需要额外 的灵活性时,它并未以符合程序员当初期望的方式来实现。内核开发人员通常会提交 补丁来删除未使用的参数;一般来说,一开始就不应该添加这些参数。h]hX&简单点,先考虑一个调用时始终只有一个参数且总为零的函数。我们可以保留这个参数, 以在需要使用它时提供的额外灵活性。不过,在那时实现了这个额外参数的代码很有 可能以某种从未被注意到的微妙方式被破坏——因为它从未被使用过。或者当需要额外 的灵活性时,它并未以符合程序员当初期望的方式来实现。内核开发人员通常会提交 补丁来删除未使用的参数;一般来说,一开始就不应该添加这些参数。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjhhubh)}(h隐藏硬件访问的抽象层——通常为了允许大量的驱动程序兼容多个操作系统——尤其不受 欢迎。这样的层使代码变得模糊,可能会造成性能损失;它们不属于Linux内核。h]h隐藏硬件访问的抽象层——通常为了允许大量的驱动程序兼容多个操作系统——尤其不受 欢迎。这样的层使代码变得模糊,可能会造成性能损失;它们不属于Linux内核。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKIhjhhubh)}(hX"另一方面,如果您发现自己从另一个内核子系统复制了大量的代码,那么是时候 了解一下:是否需要将这些代码中的部分提取到单独的库中,或者在更高的层次上 实现这些功能。在整个内核中复制相同的代码没有价值。h]hX"另一方面,如果您发现自己从另一个内核子系统复制了大量的代码,那么是时候 了解一下:是否需要将这些代码中的部分提取到单独的库中,或者在更高的层次上 实现这些功能。在整个内核中复制相同的代码没有价值。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKLhjhhubeh}(h]id4ah ]h"] 抽象层ah$]h&]uh1jhjhhhhhKhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj:ubah}(h]h ]h"]h$]h&]uh1jhjubeh}(h]h ]h"]h$]h&]bullet-uh1jhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(h还有很多其他调试选项,其中一些将在下面讨论。其中一些有显著的性能影响,不应 一直使用。在学习可用选项上花费一些时间,可能会在短期内得到许多回报。h]h还有很多其他调试选项,其中一些将在下面讨论。其中一些有显著的性能影响,不应 一直使用。在学习可用选项上花费一些时间,可能会在短期内得到许多回报。}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX}其中一个较重的调试工具是锁检查器或“lockdep”。该工具将跟踪系统中每个锁 (spinlock或mutex)的获取和释放、获取锁的相对顺序、当前中断环境等等。然后, 它可以确保总是以相同的顺序获取锁,相同的中断假设适用于所有情况等等。换句话 说,lockdep可以找到许多导致系统死锁的场景。在部署的系统中,这种问题可能会 很痛苦(对于开发人员和用户而言);LockDep允许提前以自动方式发现问题。具有 任何类型的非普通锁的代码在提交合并前应在启用lockdep的情况下运行测试。h]hX}其中一个较重的调试工具是锁检查器或“lockdep”。该工具将跟踪系统中每个锁 (spinlock或mutex)的获取和释放、获取锁的相对顺序、当前中断环境等等。然后, 它可以确保总是以相同的顺序获取锁,相同的中断假设适用于所有情况等等。换句话 说,lockdep可以找到许多导致系统死锁的场景。在部署的系统中,这种问题可能会 很痛苦(对于开发人员和用户而言);LockDep允许提前以自动方式发现问题。具有 任何类型的非普通锁的代码在提交合并前应在启用lockdep的情况下运行测试。}(hjnhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXb作为一个勤奋的内核程序员,毫无疑问,您将检查任何可能失败的操作(如内存分配) 的返回状态。然而,事实上,最终的故障复现路径可能完全没有经过测试。未测试的 代码往往会出问题;如果所有这些错误处理路径都被执行了几次,那么您可能对代码 更有信心。h]hXb作为一个勤奋的内核程序员,毫无疑问,您将检查任何可能失败的操作(如内存分配) 的返回状态。然而,事实上,最终的故障复现路径可能完全没有经过测试。未测试的 代码往往会出问题;如果所有这些错误处理路径都被执行了几次,那么您可能对代码 更有信心。}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX内核提供了一个可以做到这一点的错误注入框架,特别是在涉及内存分配的情况下。 启用故障注入后,内存分配的可配置失败的百分比;这些失败可以限定在特定的代码 范围内。在启用了故障注入的情况下运行,程序员可以看到当情况恶化时代码如何响 应。有关如何使用此工具的详细信息,请参阅 Documentation/fault-injection/fault-injection.rst。h]hX内核提供了一个可以做到这一点的错误注入框架,特别是在涉及内存分配的情况下。 启用故障注入后,内存分配的可配置失败的百分比;这些失败可以限定在特定的代码 范围内。在启用了故障注入的情况下运行,程序员可以看到当情况恶化时代码如何响 应。有关如何使用此工具的详细信息,请参阅 Documentation/fault-injection/fault-injection.rst。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX“sparse”静态分析工具可以发现其他类型的错误。sparse可以警告程序员用户空间 和内核空间地址之间的混淆、大端序与小端序的混淆、在需要一组位标志的地方传递 整数值等等。sparse必须单独安装(如果您的分发服务器没有将其打包, 可以在 https://sparse.wiki.kernel.org/index.php/Main_page 找到), 然后可以通过在make命令中添加“C=1”在代码上运行它。h](hX@“sparse”静态分析工具可以发现其他类型的错误。sparse可以警告程序员用户空间 和内核空间地址之间的混淆、大端序与小端序的混淆、在需要一组位标志的地方传递 整数值等等。sparse必须单独安装(如果您的分发服务器没有将其打包, 可以在 }(hjhhhNhNubjK)}(h2https://sparse.wiki.kernel.org/index.php/Main_pageh]h2https://sparse.wiki.kernel.org/index.php/Main_page}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jJhjubhU 找到), 然后可以通过在make命令中添加“C=1”在代码上运行它。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX“Coccinelle”工具 :ref:`https://coccinelle.gitlabpages.inria.fr/website/ ` 能够发现各种潜在的编码问题;它还可以为这些问题提出修复方案。在 scripts/coccinelle目录下已经打包了相当多的内核“语义补丁”;运行 “make coccicheck”将运行这些语义补丁并报告发现的任何问题。有关详细信息,请参阅 :ref:`Documentation/dev-tools/coccinelle.rst `h](h“Coccinelle”工具 }(hjhhhNhNubh)}(hM:ref:`https://coccinelle.gitlabpages.inria.fr/website/ `h]h)}(hjh]h0https://coccinelle.gitlabpages.inria.fr/website/}(hjhhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftyperef refexplicitrefwarnjdevtools_coccinelleuh1hhhhKhjubhX' 能够发现各种潜在的编码问题;它还可以为这些问题提出修复方案。在 scripts/coccinelle目录下已经打包了相当多的内核“语义补丁”;运行 “make coccicheck”将运行这些语义补丁并报告发现的任何问题。有关详细信息,请参阅 }(hjhhhNhNubh)}(hC:ref:`Documentation/dev-tools/coccinelle.rst `h]h)}(hjh]h&Documentation/dev-tools/coccinelle.rst}(hjhhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftyperef refexplicitrefwarnjdevtools_coccinelleuh1hhhhKhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h其他类型的可移植性错误最好通过为其他体系结构编译代码来发现。如果没有S/390系统 或Blackfin开发板,您仍然可以执行编译步骤。可以在以下位置找到一大堆用于x86系统的 交叉编译器:h]h其他类型的可移植性错误最好通过为其他体系结构编译代码来发现。如果没有S/390系统 或Blackfin开发板,您仍然可以执行编译步骤。可以在以下位置找到一大堆用于x86系统的 交叉编译器:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj)}(h,https://www.kernel.org/pub/tools/crosstool/ h]h)}(h+https://www.kernel.org/pub/tools/crosstool/h]jK)}(hjh]h+https://www.kernel.org/pub/tools/crosstool/}(hj!hhhNhNubah}(h]h ]h"]h$]h&]refurijuh1jJhjubah}(h]h ]h"]h$]h&]uh1hhhhKhjubah}(h]h ]h"]h$]h&]uh1jhhhKhjhhubh)}(hQ花一些时间安装和使用这些编译器将有助于避免以后的尴尬。h]hQ花一些时间安装和使用这些编译器将有助于避免以后的尴尬。}(hj;hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]id8ah ]h"]代码检查工具ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h文档h]h文档}(hjThhhNhNubah}(h]h ]h"]h$]h&]uh1jhjQhhhhhKubh)}(hX文档通常比内核开发规则更为例外。即便如此,足够的文档将有助于简化将新代码合并 到内核中的过程,使其他开发人员的生活更轻松,并对您的用户有所帮助。在许多情况 下,添加文档已基本上是强制性的。h]hX文档通常比内核开发规则更为例外。即便如此,足够的文档将有助于简化将新代码合并 到内核中的过程,使其他开发人员的生活更轻松,并对您的用户有所帮助。在许多情况 下,添加文档已基本上是强制性的。}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjQhhubh)}(hXZ任何补丁的第一个文档是其关联的变更日志。日志条目应该描述正在解决的问题、解决 方案的形式、处理补丁的人员、对性能的任何相关影响,以及理解补丁可能需要的任何 其他内容。确保变更日志说明了*为什么*补丁值得应用;大量开发者未能提供这些信息。h]hXZ任何补丁的第一个文档是其关联的变更日志。日志条目应该描述正在解决的问题、解决 方案的形式、处理补丁的人员、对性能的任何相关影响,以及理解补丁可能需要的任何 其他内容。确保变更日志说明了*为什么*补丁值得应用;大量开发者未能提供这些信息。}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjQhhubh)}(hX#任何添加新用户空间接口的代码——包括新的sysfs或/proc文件——都应该包含该接口 的文档,该文档使用户空间开发人员能够知道他们在使用什么。请参阅 Documentation/ABI/README,了解如何此文档格式以及需要提供哪些信息。h]hX#任何添加新用户空间接口的代码——包括新的sysfs或/proc文件——都应该包含该接口 的文档,该文档使用户空间开发人员能够知道他们在使用什么。请参阅 Documentation/ABI/README,了解如何此文档格式以及需要提供哪些信息。}(hj~hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjQhhubh)}(h文档 :ref:`Documentation/admin-guide/kernel-parameters.rst ` 描述了内核的所有引导时间参数。任何添加新参数的补丁都应该向该文档添加适当的 条目。h](h文档 }(hjhhhNhNubh)}(hI:ref:`Documentation/admin-guide/kernel-parameters.rst `h]h)}(hjh]h/Documentation/admin-guide/kernel-parameters.rst}(hjhhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftyperef refexplicitrefwarnjkernelparametersuh1hhhhKhjubhz 描述了内核的所有引导时间参数。任何添加新参数的补丁都应该向该文档添加适当的 条目。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjQhhubh)}(h任何新的配置选项都必须附有帮助文本,帮助文本需清楚地解释这些选项以及用户可能 希望何时使用它们。h]h任何新的配置选项都必须附有帮助文本,帮助文本需清楚地解释这些选项以及用户可能 希望何时使用它们。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjQhhubh)}(hX]许多子系统的内部API信息通过专门格式化的注释进行记录;这些注释可以通过 “kernel-doc”脚本以多种方式提取和格式化。如果您在具有kerneldoc注释的子系统中 工作,则应该维护它们,并根据需要为外部可用的功能添加它们。即使在没有如此记录 的领域中,为将来添加kerneldoc注释也没有坏处;实际上,这对于刚开始开发内核的人 来说是一个有用的活动。这些注释的格式以及如何创建kerneldoc模板的一些信息可以在 :ref:`Documentation/doc-guide/ ` 上找到。h](hX%许多子系统的内部API信息通过专门格式化的注释进行记录;这些注释可以通过 “kernel-doc”脚本以多种方式提取和格式化。如果您在具有kerneldoc注释的子系统中 工作,则应该维护它们,并根据需要为外部可用的功能添加它们。即使在没有如此记录 的领域中,为将来添加kerneldoc注释也没有坏处;实际上,这对于刚开始开发内核的人 来说是一个有用的活动。这些注释的格式以及如何创建kerneldoc模板的一些信息可以在 }(hjhhhNhNubh)}(h+:ref:`Documentation/doc-guide/ `h]h)}(hjh]hDocumentation/doc-guide/}(hjhhhNhNubah}(h]h ](jstdstd-refeh"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]refdocj refdomainjreftyperef refexplicitrefwarnj doc_guideuh1hhhhMhjubh 上找到。}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMhjQhhubh)}(hXF任何阅读大量现有内核代码的人都会注意到,注释的缺失往往是最值得注意的。同时, 对新代码的要求比过去更高;合并未注释的代码将更加困难。这就是说,人们并不期望 详细注释的代码。代码本身应该是自解释的,注释阐释了更微妙的方面。h]hXF任何阅读大量现有内核代码的人都会注意到,注释的缺失往往是最值得注意的。同时, 对新代码的要求比过去更高;合并未注释的代码将更加困难。这就是说,人们并不期望 详细注释的代码。代码本身应该是自解释的,注释阐释了更微妙的方面。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhjQhhubh)}(hX某些事情应该总是被注释。使用内存屏障时,应附上一行文字,解释为什么需要设置内存 屏障。数据结构的锁规则通常需要在某个地方解释。一般来说,主要数据结构需要全面 的文档。应该指出代码中分立的位之间不明显的依赖性。任何可能诱使代码管理人进行 错误的“清理”的事情都需要一个注释来说明为什么要这样做。等等。h]hX某些事情应该总是被注释。使用内存屏障时,应附上一行文字,解释为什么需要设置内存 屏障。数据结构的锁规则通常需要在某个地方解释。一般来说,主要数据结构需要全面 的文档。应该指出代码中分立的位之间不明显的依赖性。任何可能诱使代码管理人进行 错误的“清理”的事情都需要一个注释来说明为什么要这样做。等等。}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM hjQhhubeh}(h]id9ah ]h"]文档ah$]h&]uh1jhjhhhhhKubj)}(hhh](j)}(h内部API更改h]h内部API更改}(hj%hhhNhNubah}(h]h ]h"]h$]h&]uh1jhj"hhhhhMubh)}(hX内核提供给用户空间的二进制接口不能被破坏,除非逼不得已。而内核的内部编程接口 是高度流动的,当需要时可以更改。如果你发现自己不得不处理一个内核API,或者仅 仅因为它不满足你的需求导致无法使用特定的功能,这可能是API需要改变的一个标志。 作为内核开发人员,您有权进行此类更改。h]hX内核提供给用户空间的二进制接口不能被破坏,除非逼不得已。而内核的内部编程接口 是高度流动的,当需要时可以更改。如果你发现自己不得不处理一个内核API,或者仅 仅因为它不满足你的需求导致无法使用特定的功能,这可能是API需要改变的一个标志。 作为内核开发人员,您有权进行此类更改。}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj"hhubh)}(hX的确可以进行API更改,但更改必须是合理的。因此任何进行内部API更改的补丁都应该 附带关于更改内容和必要原因的描述。这种变化也应该拆分成一个单独的补丁,而不是 埋在一个更大的补丁中。h]hX的确可以进行API更改,但更改必须是合理的。因此任何进行内部API更改的补丁都应该 附带关于更改内容和必要原因的描述。这种变化也应该拆分成一个单独的补丁,而不是 埋在一个更大的补丁中。}(hjAhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj"hhubh)}(hX另一个要点是,更改内部API的开发人员通常要负责修复内核树中被更改破坏的任何代码。 对于一个广泛使用的函数,这个责任可以导致成百上千的变化,其中许多变化可能与其他 开发人员正在做的工作相冲突。不用说,这可能是一项大工程,所以最好确保理由是 可靠的。请注意,coccinelle工具可以帮助进行广泛的API更改。h]hX另一个要点是,更改内部API的开发人员通常要负责修复内核树中被更改破坏的任何代码。 对于一个广泛使用的函数,这个责任可以导致成百上千的变化,其中许多变化可能与其他 开发人员正在做的工作相冲突。不用说,这可能是一项大工程,所以最好确保理由是 可靠的。请注意,coccinelle工具可以帮助进行广泛的API更改。}(hjOhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMhj"hhubh)}(hXk在进行不兼容的API更改时,应尽可能确保编译器捕获未更新的代码。这将帮助您确保找 到该接口的树内用处。它还将警告开发人员树外代码存在他们需要响应的更改。支持树外 代码不是内核开发人员需要担心的事情,但是我们也不必使树外开发人员的生活有不必要 的困难。h]hXk在进行不兼容的API更改时,应尽可能确保编译器捕获未更新的代码。这将帮助您确保找 到该接口的树内用处。它还将警告开发人员树外代码存在他们需要响应的更改。支持树外 代码不是内核开发人员需要担心的事情,但是我们也不必使树外开发人员的生活有不必要 的困难。}(hj]hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhM"hj"hhubeh}(h]apiah ]h"]内部api更改ah$]h&]uh1jhjhhhhhMubeh}(h](jid1eh ]h"](使代码正确cn_development_codingeh$]h&]uh1jhhhhhhhKexpect_referenced_by_name}jyjsexpect_referenced_by_id}jjsubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}j]jasnameids}(jyjjxjujjjjj0j-jsjpjjjjjjjNjKjjjpjmu nametypes}(jyjxjjj0jsjjjjNjjpuh}(jjjujjjjj j-jjpj3jjvjjjjjKjjjQjmj"u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}jK sRparse_messages]transform_messages]hsystem_message)}(hhh]h)}(hhh]h;Hyperlink target "cn-development-coding" is not referenced.}hj sbah}(h]h ]h"]h$]h&]uh1hhj ubah}(h]h ]h"]h$]h&]levelKtypeINFOsourcehlineKuh1juba transformerN include_log]5Documentation/translations/zh_CN/process/4.Coding.rst(NNNNta decorationNhhub.