summaryrefslogtreecommitdiffstats
path: root/Documentation/translations/zh_CN/rust
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation/translations/zh_CN/rust')
-rw-r--r--Documentation/translations/zh_CN/rust/arch-support.rst23
-rw-r--r--Documentation/translations/zh_CN/rust/coding-guidelines.rst192
-rw-r--r--Documentation/translations/zh_CN/rust/general-information.rst75
-rw-r--r--Documentation/translations/zh_CN/rust/index.rst28
-rw-r--r--Documentation/translations/zh_CN/rust/quick-start.rst211
5 files changed, 529 insertions, 0 deletions
diff --git a/Documentation/translations/zh_CN/rust/arch-support.rst b/Documentation/translations/zh_CN/rust/arch-support.rst
new file mode 100644
index 0000000000..afbd02afec
--- /dev/null
+++ b/Documentation/translations/zh_CN/rust/arch-support.rst
@@ -0,0 +1,23 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/rust/arch-support.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+架构支持
+========
+
+目前,Rust编译器(``rustc``)使用LLVM进行代码生成,这限制了可以支持的目标架构。此外,对
+使用LLVM/Clang构建内核的支持也有所不同(请参见 Documentation/kbuild/llvm.rst )。这
+种支持对于使用 ``libclang`` 的 ``bindgen`` 来说是必需的。
+
+下面是目前可以工作的架构的一般总结。支持程度与 ``MAINTAINERS`` 文件中的``S`` 值相对应:
+
+============ ================ ==============================================
+架构 支持水平 限制因素
+============ ================ ==============================================
+``x86`` Maintained 只有 ``x86_64``
+============ ================ ==============================================
diff --git a/Documentation/translations/zh_CN/rust/coding-guidelines.rst b/Documentation/translations/zh_CN/rust/coding-guidelines.rst
new file mode 100644
index 0000000000..6c0bdbbc5a
--- /dev/null
+++ b/Documentation/translations/zh_CN/rust/coding-guidelines.rst
@@ -0,0 +1,192 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/rust/coding-guidelines.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+编码指南
+========
+
+本文档描述了如何在内核中编写Rust代码。
+
+
+风格和格式化
+------------
+
+代码应该使用 ``rustfmt`` 进行格式化。这样一来,一个不时为内核做贡献的人就不需要再去学
+习和记忆一个样式指南了。更重要的是,审阅者和维护者不需要再花时间指出风格问题,这样就可以
+减少补丁落地所需的邮件往返。
+
+.. note:: ``rustfmt`` 不检查注释和文档的约定。因此,这些仍然需要照顾到。
+
+使用 ``rustfmt`` 的默认设置。这意味着遵循Rust的习惯性风格。例如,缩进时使用4个空格而
+不是制表符。
+
+在输入、保存或提交时告知编辑器/IDE进行格式化是很方便的。然而,如果因为某些原因需要在某
+个时候重新格式化整个内核Rust的源代码,可以运行以下程序::
+
+ make LLVM=1 rustfmt
+
+也可以检查所有的东西是否都是格式化的(否则就打印一个差异),例如对于一个CI,用::
+
+ make LLVM=1 rustfmtcheck
+
+像内核其他部分的 ``clang-format`` 一样, ``rustfmt`` 在单个文件上工作,并且不需要
+内核配置。有时,它甚至可以与破碎的代码一起工作。
+
+
+注释
+----
+
+“普通”注释(即以 ``//`` 开头,而不是 ``///`` 或 ``//!`` 开头的代码文档)的写法与文
+档注释相同,使用Markdown语法,尽管它们不会被渲染。这提高了一致性,简化了规则,并允许在
+这两种注释之间更容易地移动内容。比如说:
+
+.. code-block:: rust
+
+ // `object` is ready to be handled now.
+ f(object);
+
+此外,就像文档一样,注释在句子的开头要大写,并以句号结束(即使是单句)。这包括 ``// SAFETY:``,
+``// TODO:`` 和其他“标记”的注释,例如:
+
+.. code-block:: rust
+
+ // FIXME: The error should be handled properly.
+
+注释不应该被用于文档的目的:注释是为了实现细节,而不是为了用户。即使源文件的读者既是API
+的实现者又是用户,这种区分也是有用的。事实上,有时同时使用注释和文档是很有用的。例如,用
+于 ``TODO`` 列表或对文档本身的注释。对于后一种情况,注释可以插在中间;也就是说,离要注
+释的文档行更近。对于其他情况,注释会写在文档之后,例如:
+
+.. code-block:: rust
+
+ /// Returns a new [`Foo`].
+ ///
+ /// # Examples
+ ///
+ // TODO: Find a better example.
+ /// ```
+ /// let foo = f(42);
+ /// ```
+ // FIXME: Use fallible approach.
+ pub fn f(x: i32) -> Foo {
+ // ...
+ }
+
+一种特殊的注释是 ``// SAFETY:`` 注释。这些注释必须出现在每个 ``unsafe`` 块之前,它们
+解释了为什么该块内的代码是正确/健全的,即为什么它在任何情况下都不会触发未定义行为,例如:
+
+.. code-block:: rust
+
+ // SAFETY: `p` is valid by the safety requirements.
+ unsafe { *p = 0; }
+
+``// SAFETY:`` 注释不能与代码文档中的 ``# Safety`` 部分相混淆。 ``# Safety`` 部
+分指定了(函数)调用者或(特性)实现者需要遵守的契约。
+``// SAFETY:`` 注释显示了为什么一个(函数)调用者或(特性)实现者实际上尊重了
+``# Safety`` 部分或语言参考中的前提条件。
+
+
+代码文档
+--------
+
+Rust内核代码不像C内核代码那样被记录下来(即通过kernel-doc)。取而代之的是用于记录Rust
+代码的常用系统:rustdoc工具,它使用Markdown(一种轻量级的标记语言)。
+
+要学习Markdown,外面有很多指南。例如:
+
+https://commonmark.org/help/
+
+一个记录良好的Rust函数可能是这样的:
+
+.. code-block:: rust
+
+ /// Returns the contained [`Some`] value, consuming the `self` value,
+ /// without checking that the value is not [`None`].
+ ///
+ /// # Safety
+ ///
+ /// Calling this method on [`None`] is *[undefined behavior]*.
+ ///
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let x = Some("air");
+ /// assert_eq!(unsafe { x.unwrap_unchecked() }, "air");
+ /// ```
+ pub unsafe fn unwrap_unchecked(self) -> T {
+ match self {
+ Some(val) => val,
+
+ // SAFETY: The safety contract must be upheld by the caller.
+ None => unsafe { hint::unreachable_unchecked() },
+ }
+ }
+
+这个例子展示了一些 ``rustdoc`` 的特性和内核中遵循的一些惯例:
+
+ - 第一段必须是一个简单的句子,简要地描述被记录的项目的作用。进一步的解释必须放在额
+ 外的段落中。
+
+ - 不安全的函数必须在 ``# Safety`` 部分记录其安全前提条件。
+
+ - 虽然这里没有显示,但如果一个函数可能会恐慌,那么必须在 ``# Panics`` 部分描述发
+ 生这种情况的条件。
+
+ 请注意,恐慌应该是非常少见的,只有在有充分理由的情况下才会使用。几乎在所有的情况下,
+ 都应该使用一个可失败的方法,通常是返回一个 ``Result``。
+
+ - 如果提供使用实例对读者有帮助的话,必须写在一个叫做``# Examples``的部分。
+
+ - Rust项目(函数、类型、常量……)必须有适当的链接(``rustdoc`` 会自动创建一个
+ 链接)。
+
+ - 任何 ``unsafe`` 的代码块都必须在前面加上一个 ``// SAFETY:`` 的注释,描述里面
+ 的代码为什么是正确的。
+
+ 虽然有时原因可能看起来微不足道,但写这些注释不仅是记录已经考虑到的问题的好方法,
+ 最重要的是,它提供了一种知道没有额外隐含约束的方法。
+
+要了解更多关于如何编写Rust和拓展功能的文档,请看看 ``rustdoc`` 这本书,网址是:
+
+ https://doc.rust-lang.org/rustdoc/how-to-write-documentation.html
+
+
+命名
+----
+
+Rust内核代码遵循通常的Rust命名空间:
+
+ https://rust-lang.github.io/api-guidelines/naming.html
+
+当现有的C语言概念(如宏、函数、对象......)被包装成Rust抽象时,应该使用尽可能接近C语
+言的名称,以避免混淆,并在C语言和Rust语言之间来回切换时提高可读性。例如,C语言中的
+``pr_info`` 这样的宏在Rust中的命名是一样的。
+
+说到这里,应该调整大小写以遵循Rust的命名惯例,模块和类型引入的命名间隔不应该在项目名称
+中重复。例如,在包装常量时,如:
+
+.. code-block:: c
+
+ #define GPIO_LINE_DIRECTION_IN 0
+ #define GPIO_LINE_DIRECTION_OUT 1
+
+在Rust中的等价物可能是这样的(忽略文档)。:
+
+.. code-block:: rust
+
+ pub mod gpio {
+ pub enum LineDirection {
+ In = bindings::GPIO_LINE_DIRECTION_IN as _,
+ Out = bindings::GPIO_LINE_DIRECTION_OUT as _,
+ }
+ }
+
+也就是说, ``GPIO_LINE_DIRECTION_IN`` 的等价物将被称为 ``gpio::LineDirection::In`` 。
+特别是,它不应该被命名为 ``gpio::gpio_line_direction::GPIO_LINE_DIRECTION_IN`` 。
diff --git a/Documentation/translations/zh_CN/rust/general-information.rst b/Documentation/translations/zh_CN/rust/general-information.rst
new file mode 100644
index 0000000000..6b91dfe183
--- /dev/null
+++ b/Documentation/translations/zh_CN/rust/general-information.rst
@@ -0,0 +1,75 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/rust/general-information.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+
+基本信息
+========
+
+本文档包含了在内核中使用Rust支持时需要了解的有用信息。
+
+
+代码文档
+--------
+
+Rust内核代码使用其内置的文档生成器 ``rustdoc`` 进行记录。
+
+生成的HTML文档包括集成搜索、链接项(如类型、函数、常量)、源代码等。它们可以在以下地址阅读
+(TODO:当在主线中时链接,与其他文档一起生成):
+
+ http://kernel.org/
+
+这些文档也可以很容易地在本地生成和阅读。这相当快(与编译代码本身的顺序相同),而且不需要特
+殊的工具或环境。这有一个额外的好处,那就是它们将根据所使用的特定内核配置进行定制。要生成它
+们,请使用 ``rustdoc`` 目标,并使用编译时使用的相同调用,例如::
+
+ make LLVM=1 rustdoc
+
+要在你的网络浏览器中本地阅读该文档,请运行如::
+
+ xdg-open rust/doc/kernel/index.html
+
+要了解如何编写文档,请看 coding-guidelines.rst 。
+
+
+额外的lints
+-----------
+
+虽然 ``rustc`` 是一个非常有用的编译器,但一些额外的lints和分析可以通过 ``clippy``
+(一个Rust linter)来实现。要启用它,请将CLIPPY=1传递到用于编译的同一调用中,例如::
+
+ make LLVM=1 CLIPPY=1
+
+请注意,Clippy可能会改变代码生成,因此在构建产品内核时不应该启用它。
+
+抽象和绑定
+----------
+
+抽象是用Rust代码包装来自C端的内核功能。
+
+为了使用来自C端的函数和类型,需要创建绑定。绑定是Rust对那些来自C端的函数和类型的声明。
+
+例如,人们可以在Rust中写一个 ``Mutex`` 抽象,它从C端包装一个 ``Mutex结构体`` ,并
+通过绑定调用其函数。
+
+抽象并不能用于所有的内核内部API和概念,但随着时间的推移,我们打算扩大覆盖范围。“Leaf”
+模块(例如,驱动程序)不应该直接使用C语言的绑定。相反,子系统应该根据需要提供尽可能安
+全的抽象。
+
+
+有条件的编译
+------------
+
+Rust代码可以访问基于内核配置的条件性编译:
+
+.. code-block:: rust
+
+ #[cfg(CONFIG_X)] // Enabled (`y` or `m`)
+ #[cfg(CONFIG_X="y")] // Enabled as a built-in (`y`)
+ #[cfg(CONFIG_X="m")] // Enabled as a module (`m`)
+ #[cfg(not(CONFIG_X))] // Disabled
diff --git a/Documentation/translations/zh_CN/rust/index.rst b/Documentation/translations/zh_CN/rust/index.rst
new file mode 100644
index 0000000000..b01f887e71
--- /dev/null
+++ b/Documentation/translations/zh_CN/rust/index.rst
@@ -0,0 +1,28 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/rust/index.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+Rust
+====
+
+与内核中的Rust有关的文档。若要开始在内核中使用Rust,请阅读quick-start.rst指南。
+
+.. toctree::
+ :maxdepth: 1
+
+ quick-start
+ general-information
+ coding-guidelines
+ arch-support
+
+.. only:: subproject and html
+
+ Indices
+ =======
+
+ * :ref:`genindex`
diff --git a/Documentation/translations/zh_CN/rust/quick-start.rst b/Documentation/translations/zh_CN/rust/quick-start.rst
new file mode 100644
index 0000000000..a4b8e8a50a
--- /dev/null
+++ b/Documentation/translations/zh_CN/rust/quick-start.rst
@@ -0,0 +1,211 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. include:: ../disclaimer-zh_CN.rst
+
+:Original: Documentation/rust/quick-start.rst
+
+:翻译:
+
+ 司延腾 Yanteng Si <siyanteng@loongson.cn>
+
+
+快速入门
+========
+
+本文介绍了如何开始使用Rust进行内核开发。
+
+
+构建依赖
+--------
+
+本节描述了如何获取构建所需的工具。
+
+其中一些依赖也许可以从Linux发行版中获得,包名可能是 ``rustc`` , ``rust-src`` ,
+``rust-bindgen`` 等。然而,在写这篇文章的时候,它们很可能还不够新,除非发行版跟踪最
+新的版本。
+
+为了方便检查是否满足要求,可以使用以下目标::
+
+ make LLVM=1 rustavailable
+
+这会触发与Kconfig用来确定是否应该启用 ``RUST_IS_AVAILABLE`` 相同的逻辑;不过,如
+果Kconfig认为不该启用,它会列出未满足的条件。
+
+
+rustc
+*****
+
+需要一个特定版本的Rust编译器。较新的版本可能会也可能不会工作,因为就目前而言,内核依赖
+于一些不稳定的Rust特性。
+
+如果使用的是 ``rustup`` ,请进入检出的源代码目录并运行::
+
+ rustup override set $(scripts/min-tool-version.sh rustc)
+
+或者从以下网址获取一个独立的安装程序或安装 ``rustup`` :
+
+ https://www.rust-lang.org
+
+
+Rust标准库源代码
+****************
+
+Rust标准库的源代码是必需的,因为构建系统会交叉编译 ``core`` 和 ``alloc`` 。
+
+如果正在使用 ``rustup`` ,请运行::
+
+ rustup component add rust-src
+
+这些组件是按工具链安装的,因此以后升级Rust编译器版本需要重新添加组件。
+
+否则,如果使用独立的安装程序,可以将Rust仓库克隆到工具链的安装文件夹中::
+
+ git clone --recurse-submodules \
+ --branch $(scripts/min-tool-version.sh rustc) \
+ https://github.com/rust-lang/rust \
+ $(rustc --print sysroot)/lib/rustlib/src/rust
+
+在这种情况下,以后升级Rust编译器版本需要手动更新这个克隆的仓库。
+
+
+libclang
+********
+
+``bindgen`` 使用 ``libclang`` (LLVM的一部分)来理解内核中的C代码,这意味着需要安
+装LLVM;同在开启 ``CC=clang`` 或 ``LLVM=1`` 时编译内核一样。
+
+Linux发行版中可能会有合适的包,所以最好先检查一下。
+
+适用于部分系统和架构的二进制文件也可到以下网址下载:
+
+ https://releases.llvm.org/download.html
+
+或者自行构建LLVM,这需要相当长的时间,但并不是一个复杂的过程:
+
+ https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm
+
+请参阅 Documentation/kbuild/llvm.rst 了解更多信息,以及获取预构建版本和发行包
+的进一步方法。
+
+
+bindgen
+*******
+
+内核的C端绑定是在构建时使用 ``bindgen`` 工具生成的。这需要特定的版本。
+
+通过以下方式安装它(注意,这将从源码下载并构建该工具)::
+
+ cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen
+
+
+开发依赖
+--------
+
+本节解释了如何获取开发所需的工具。也就是说,在构建内核时不需要这些工具。
+
+
+rustfmt
+*******
+
+``rustfmt`` 工具被用来自动格式化所有的Rust内核代码,包括生成的C绑定(详情请见
+coding-guidelines.rst )。
+
+如果使用的是 ``rustup`` ,它的 ``默认`` 配置文件已经安装了这个工具,因此不需要做什么。
+如果使用的是其他配置文件,可以手动安装该组件::
+
+ rustup component add rustfmt
+
+独立的安装程序也带有 ``rustfmt`` 。
+
+
+clippy
+******
+
+``clippy`` 是一个Rust linter。运行它可以为Rust代码提供额外的警告。它可以通过向 ``make``
+传递 ``CLIPPY=1`` 来运行(关于细节,详见 general-information.rst )。
+
+如果正在使用 ``rustup`` ,它的 ``默认`` 配置文件已经安装了这个工具,因此不需要做什么。
+如果使用的是另一个配置文件,该组件可以被手动安装::
+
+ rustup component add clippy
+
+独立的安装程序也带有 ``clippy`` 。
+
+
+cargo
+*****
+
+``cargo`` 是Rust的本地构建系统。目前需要它来运行测试,因为它被用来构建一个自定义的标准
+库,其中包含了内核中自定义 ``alloc`` 所提供的设施。测试可以使用 ``rusttest`` Make 目标
+来运行。
+
+如果使用的是 ``rustup`` ,所有的配置文件都已经安装了该工具,因此不需要再做什么。
+
+独立的安装程序也带有 ``cargo`` 。
+
+
+rustdoc
+*******
+
+``rustdoc`` 是Rust的文档工具。它为Rust代码生成漂亮的HTML文档(详情请见 general-information.rst )。
+
+``rustdoc`` 也被用来测试文档化的Rust代码中提供的例子(称为doctests或文档测试)。
+``rusttest`` 是本功能的Make目标。
+
+如果使用的是 ``rustup`` ,所有的配置文件都已经安装了这个工具,因此不需要做什么。
+
+独立的安装程序也带有 ``rustdoc`` 。
+
+
+rust-analyzer
+*************
+
+`rust-analyzer <https://rust-analyzer.github.io/>`_ 语言服务器可以和许多编辑器
+一起使用,以实现语法高亮、补全、转到定义和其他功能。
+
+``rust-analyzer`` 需要一个配置文件, ``rust-project.json``, 它可以由 ``rust-analyzer``
+Make 目标生成。
+
+
+配置
+----
+
+Rust支持(CONFIG_RUST)需要在 ``General setup`` 菜单中启用。在其他要求得到满足的情
+况下,该选项只有在找到合适的Rust工具链时才会显示(见上文)。相应的,这将使依赖Rust的其
+他选项可见。
+
+之后,进入::
+
+ Kernel hacking
+ -> Sample kernel code
+ -> Rust samples
+
+并启用一些内置或可加载的样例模块。
+
+
+构建
+----
+
+用完整的LLVM工具链构建内核是目前支持的最佳设置。即::
+
+ make LLVM=1
+
+对于不支持完整LLVM工具链的架构,使用::
+
+ make CC=clang
+
+使用GCC对某些配置也是可行的,但目前它是非常试验性的。
+
+
+折腾
+----
+
+要想深入了解,请看 ``samples/rust/`` 下的样例源代码、 ``rust/`` 下的Rust支持代码和
+``Kernel hacking`` 下的 ``Rust hacking`` 菜单。
+
+如果使用的是GDB/Binutils,而Rust符号没有被demangled,原因是工具链还不支持Rust的新v0
+mangling方案。有几个办法可以解决:
+
+ - 安装一个较新的版本(GDB >= 10.2, Binutils >= 2.36)。
+
+ - 一些版本的GDB(例如vanilla GDB 10.1)能够使用嵌入在调试信息(``CONFIG_DEBUG_INFO``)
+ 中的pre-demangled的名字。