← Documents Documentation/rust/general-information.rst GitHub 원문 ↗

Linux 6.18.37 · Rust

커널 Rust 일반 정보

no_std와 개발 도구, C binding과 안전 추상화의 경계, Kconfig 조건부 컴파일을 설명합니다.

Source pathDocumentation/rust/general-information.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

general-information.rst:1-161

no_std와 개발 도구, C binding과 안전 추상화의 경계, Kconfig 조건부 컴파일을 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 General Information
4 ===================
5
6 This document contains useful information to know when working with
7 the Rust support in the kernel.
8
9
10 ``no_std``
11 ----------
12
13 The Rust support in the kernel can link only `core <https://doc.rust-lang.org/core/>`_,
14 but not `std <https://doc.rust-lang.org/std/>`_. Crates for use in the
15 kernel must opt into this behavior using the ``#![no_std]`` attribute.
16
17
18 .. _rust_code_documentation:
19
20 Code documentation
21 ------------------
22
23 Rust kernel code is documented using ``rustdoc``, its built-in documentation
24 generator.
25
26 The generated HTML docs include integrated search, linked items (e.g. types,
27 functions, constants), source code, etc. They may be read at:
28
29 https://rust.docs.kernel.org
30
31 For linux-next, please see:
32
33 https://rust.docs.kernel.org/next/
34
35 There are also tags for each main release, e.g.:
36
37 https://rust.docs.kernel.org/6.10/
38
39 The docs can also be easily generated and read locally. This is quite fast
40 (same order as compiling the code itself) and no special tools or environment
41 are needed. This has the added advantage that they will be tailored to
42 the particular kernel configuration used. To generate them, use the ``rustdoc``
43 target with the same invocation used for compilation, e.g.::
44
45 make LLVM=1 rustdoc
46
47 To read the docs locally in your web browser, run e.g.::
48
49 xdg-open Documentation/output/rust/rustdoc/kernel/index.html
50
51 To learn about how to write the documentation, please see coding-guidelines.rst.
52
53
54 Extra lints
55 -----------
56
57 While ``rustc`` is a very helpful compiler, some extra lints and analyses are
58 available via ``clippy``, a Rust linter. To enable it, pass ``CLIPPY=1`` to
59 the same invocation used for compilation, e.g.::
60
61 make LLVM=1 CLIPPY=1
62
63 Please note that Clippy may change code generation, thus it should not be
64 enabled while building a production kernel.
65
66
67 Abstractions vs. bindings
68 -------------------------
69
70 Abstractions are Rust code wrapping kernel functionality from the C side.
71
72 In order to use functions and types from the C side, bindings are created.
73 Bindings are the declarations for Rust of those functions and types from
74 the C side.
75
76 For instance, one may write a ``Mutex`` abstraction in Rust which wraps
77 a ``struct mutex`` from the C side and calls its functions through the bindings.
78
79 Abstractions are not available for all the kernel internal APIs and concepts,
80 but it is intended that coverage is expanded as time goes on. "Leaf" modules
81 (e.g. drivers) should not use the C bindings directly. Instead, subsystems
82 should provide as-safe-as-possible abstractions as needed.
83
84 .. code-block::
85
86 rust/bindings/
87 (rust/helpers/)
88
89 include/ -----+ <-+
90 | |
91 drivers/ rust/kernel/ +----------+ <-+ |
92 fs/ | bindgen | |
93 .../ +-------------------+ +----------+ --+ |
94 | Abstractions | | |
95 +---------+ | +------+ +------+ | +----------+ | |
96 | my_foo | -----> | | foo | | bar | | -------> | Bindings | <-+ |
97 | driver | Safe | | sub- | | sub- | | Unsafe | | |
98 +---------+ | |system| |system| | | bindings | <-----+
99 | | +------+ +------+ | | crate | |
100 | | kernel crate | +----------+ |
101 | +-------------------+ |
102 | |
103 +------------------# FORBIDDEN #--------------------------------+
104
105 The main idea is to encapsulate all direct interaction with the kernel's C APIs
106 into carefully reviewed and documented abstractions. Then users of these
107 abstractions cannot introduce undefined behavior (UB) as long as:
108
109 #. The abstractions are correct ("sound").
110 #. Any ``unsafe`` blocks respect the safety contract necessary to call the
111 operations inside the block. Similarly, any ``unsafe impl``\ s respect the
112 safety contract necessary to implement the trait.
113
114 Bindings
115 ~~~~~~~~
116
117 By including a C header from ``include/`` into
118 ``rust/bindings/bindings_helper.h``, the ``bindgen`` tool will auto-generate the
119 bindings for the included subsystem. After building, see the ``*_generated.rs``
120 output files in the ``rust/bindings/`` directory.
121
122 For parts of the C header that ``bindgen`` does not auto generate, e.g. C
123 ``inline`` functions or non-trivial macros, it is acceptable to add a small
124 wrapper function to ``rust/helpers/`` to make it available for the Rust side as
125 well.
126
127 Abstractions
128 ~~~~~~~~~~~~
129
130 Abstractions are the layer between the bindings and the in-kernel users. They
131 are located in ``rust/kernel/`` and their role is to encapsulate the unsafe
132 access to the bindings into an as-safe-as-possible API that they expose to their
133 users. Users of the abstractions include things like drivers or file systems
134 written in Rust.
135
136 Besides the safety aspect, the abstractions are supposed to be "ergonomic", in
137 the sense that they turn the C interfaces into "idiomatic" Rust code. Basic
138 examples are to turn the C resource acquisition and release into Rust
139 constructors and destructors or C integer error codes into Rust's ``Result``\ s.
140
141
142 Conditional compilation
143 -----------------------
144
145 Rust code has access to conditional compilation based on the kernel
146 configuration:
147
148 .. code-block:: rust
149
150 #[cfg(CONFIG_X)] // Enabled (`y` or `m`)
151 #[cfg(CONFIG_X="y")] // Enabled as a built-in (`y`)
152 #[cfg(CONFIG_X="m")] // Enabled as a module (`m`)
153 #[cfg(not(CONFIG_X))] // Disabled
154
155 For other predicates that Rust's ``cfg`` does not support, e.g. expressions with
156 numerical comparisons, one may define a new Kconfig symbol:
157
158 .. code-block:: kconfig
159
160 config RUSTC_VERSION_MIN_107900
161 def_bool y if RUSTC_VERSION >= 107900
162

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

no_std, rustdoc와 Clippy

1-66

커널 Rust 지원을 사용할 때 알아야 할 기본 정보다. 커널은 Rust `core` crate에는 링크할 수 있지만 userspace 기능을 담은 `std`에는 링크할 수 없다. 커널용 crate는 `#![no_std]` 속성으로 이 동작을 명시해야 한다.

Rust 커널 코드는 내장 문서 생성기 `rustdoc`으로 문서화한다. 생성된 HTML에는 통합 검색, 타입·함수·상수 링크와 소스 코드가 포함된다. 현재 문서는 `https://rust.docs.kernel.org`, linux-next는 `/next/`, 각 주 릴리스는 `/6.10/` 같은 tag 경로에서 읽을 수 있다.

로컬 문서는 현재 커널 설정에 맞춰 빠르게 만들 수 있다. 커널 컴파일과 같은 옵션으로 `make LLVM=1 rustdoc`를 실행하고 `Documentation/output/rust/rustdoc/kernel/index.html`을 연다. 작성 규칙은 `coding-guidelines.rst`를 따른다.

추가 lint와 분석에는 Clippy를 사용한다. 평소 컴파일 명령에 `CLIPPY=1`을 더해 `make LLVM=1 CLIPPY=1`로 실행한다. Clippy가 코드 생성을 바꿀 수 있으므로 production kernel을 빌드할 때는 켜지 않는다.

Rust 도구의 역할
도구/속성역할주의
#![no_std]core만 쓰는 커널 crate 선언std 링크 불가
rustdoc검색·링크·소스가 있는 HTML 문서현재 config에 맞춰 생성
CLIPPY=1추가 lint와 분석production build에는 사용하지 않음

빌드, 문서와 추가 검사를 서로 다른 목적으로 사용합니다.

.. SPDX-License-Identifier: GPL-2.0

General Information
===================

This document contains useful information to know when working with
the Rust support in the kernel.


``no_std``
----------

The Rust support in the kernel can link only `core <https://doc.rust-lang.org/core/>`_,
but not `std <https://doc.rust-lang.org/std/>`_. Crates for use in the
kernel must opt into this behavior using the ``#![no_std]`` attribute.


.. _rust_code_documentation:

Code documentation
------------------

Rust kernel code is documented using ``rustdoc``, its built-in documentation
generator.

The generated HTML docs include integrated search, linked items (e.g. types,
functions, constants), source code, etc. They may be read at:

        https://rust.docs.kernel.org

For linux-next, please see:

        https://rust.docs.kernel.org/next/

There are also tags for each main release, e.g.:

        https://rust.docs.kernel.org/6.10/

The docs can also be easily generated and read locally. This is quite fast
(same order as compiling the code itself) and no special tools or environment
are needed. This has the added advantage that they will be tailored to
the particular kernel configuration used. To generate them, use the ``rustdoc``
target with the same invocation used for compilation, e.g.::

        make LLVM=1 rustdoc

To read the docs locally in your web browser, run e.g.::

        xdg-open Documentation/output/rust/rustdoc/kernel/index.html

To learn about how to write the documentation, please see coding-guidelines.rst.


Extra lints
-----------

While ``rustc`` is a very helpful compiler, some extra lints and analyses are
available via ``clippy``, a Rust linter. To enable it, pass ``CLIPPY=1`` to
the same invocation used for compilation, e.g.::

        make LLVM=1 CLIPPY=1

Please note that Clippy may change code generation, thus it should not be
enabled while building a production kernel.

안전 추상화와 C binding의 경계

67-113

추상화는 C 쪽 커널 기능을 감싸는 Rust 코드이고, binding은 C 함수와 타입을 Rust에서 부를 수 있게 만든 선언이다. 예를 들어 Rust의 `Mutex` 추상화는 C의 `struct mutex`를 보관하고 binding을 통해 C 함수를 호출한다.

아직 모든 내부 API와 개념에 추상화가 있는 것은 아니지만 범위를 계속 넓히는 것이 목표다. Driver 같은 leaf module은 C binding을 직접 사용하지 않아야 한다. 대신 subsystem이 필요한 기능을 가능한 한 안전한 추상화로 제공한다.

핵심은 C API와의 직접 상호작용을 꼼꼼히 검토하고 문서화한 추상화 안에 가두는 것이다. 추상화 자체가 sound하고, 모든 `unsafe` 블록과 `unsafe impl`이 각각 호출과 trait 구현에 필요한 safety contract를 지키면 그 사용자는 undefined behavior를 새로 만들 수 없다.

Rust 커널 계층
drivers/ 및 fs/의 leaf 사용자Safe API 호출rust/kernel/의 subsystem 추상화검토된 Unsafe 경계rust/bindings/의 Bindings cratebindgen과 rust/helpers/include/의 C API

원문의 ASCII 그림을 계층과 허용 방향이 드러나는 구조로 다시 표현했습니다.

허용되는 접근 경로
출발도착판정
Driver/File systemrust/kernel 추상화허용, Safe
rust/kernel 추상화Bindings허용, 검토된 Unsafe
Bindings/bindgeninclude/ C API생성 경로
Driver/File systemBindings 또는 C API금지

Leaf module에서 C binding으로 가는 직접 경로는 금지됩니다.

Abstractions vs. bindings
-------------------------

Abstractions are Rust code wrapping kernel functionality from the C side.

In order to use functions and types from the C side, bindings are created.
Bindings are the declarations for Rust of those functions and types from
the C side.

For instance, one may write a ``Mutex`` abstraction in Rust which wraps
a ``struct mutex`` from the C side and calls its functions through the bindings.

Abstractions are not available for all the kernel internal APIs and concepts,
but it is intended that coverage is expanded as time goes on. "Leaf" modules
(e.g. drivers) should not use the C bindings directly. Instead, subsystems
should provide as-safe-as-possible abstractions as needed.

.. code-block::

                                                        rust/bindings/
                                                       (rust/helpers/)

                                                           include/ -----+ <-+
                                                                         |   |
          drivers/              rust/kernel/              +----------+ <-+   |
            fs/                                           | bindgen  |       |
           .../            +-------------------+          +----------+ --+   |
                           |    Abstractions   |                         |   |
        +---------+        | +------+ +------+ |          +----------+   |   |
        | my_foo  | -----> | | foo  | | bar  | | -------> | Bindings | <-+   |
        | driver  |  Safe  | | sub- | | sub- | |  Unsafe  |          |       |
        +---------+        | |system| |system| |          | bindings | <-----+
             |             | +------+ +------+ |          |  crate   |       |
             |             |   kernel crate    |          +----------+       |
             |             +-------------------+                             |
             |                                                               |
             +------------------# FORBIDDEN #--------------------------------+

The main idea is to encapsulate all direct interaction with the kernel's C APIs
into carefully reviewed and documented abstractions. Then users of these
abstractions cannot introduce undefined behavior (UB) as long as:

#. The abstractions are correct ("sound").
#. Any ``unsafe`` blocks respect the safety contract necessary to call the
   operations inside the block. Similarly, any ``unsafe impl``\ s respect the
   safety contract necessary to implement the trait.

Binding 생성과 helper wrapper

114-126

`include/`의 C header를 `rust/bindings/bindings_helper.h`에 포함하면 `bindgen`이 해당 subsystem의 Rust binding을 자동 생성한다. 빌드 뒤 결과는 `rust/bindings/` 디렉터리의 `*_generated.rs` 파일에서 확인할 수 있다.

C `inline` 함수나 단순하지 않은 macro처럼 `bindgen`이 자동 생성하지 못하는 부분은 `rust/helpers/`에 작은 wrapper 함수를 추가해 Rust 쪽에 제공할 수 있다.

C API binding 생성
include/ C header 선택bindings_helper.h에 포함bindgen 실행rust/bindings/*_generated.rs누락된 inline/macro 확인rust/helpers/ wrapper 추가

자동 생성 범위와 수동 wrapper 범위를 분리합니다.

Bindings
~~~~~~~~

By including a C header from ``include/`` into
``rust/bindings/bindings_helper.h``, the ``bindgen`` tool will auto-generate the
bindings for the included subsystem. After building, see the ``*_generated.rs``
output files in the ``rust/bindings/`` directory.

For parts of the C header that ``bindgen`` does not auto generate, e.g. C
``inline`` functions or non-trivial macros, it is acceptable to add a small
wrapper function to ``rust/helpers/`` to make it available for the Rust side as
well.

관용적이고 안전한 Rust API

127-141

추상화는 binding과 커널 내부 사용자 사이의 계층이며 `rust/kernel/`에 둔다. Unsafe binding 접근을 감싸 가능한 한 안전한 API로 노출하고, Rust로 작성한 driver와 file system 등이 이를 사용한다.

안전성뿐 아니라 사용성도 목표다. C 인터페이스를 관용적인 Rust 코드로 바꾸며, C의 자원 획득과 해제를 Rust constructor와 destructor, 즉 RAII 수명으로 표현하고 C 정수 오류 코드를 Rust `Result`로 바꾸는 것이 기본 예다.

추상화의 변환
C 인터페이스Rust 추상화
명시적 acquire/releaseconstructor/destructor와 RAII
정수 오류 코드Result
직접 포인터와 함수 호출검토된 안전 API
Subsystem 내부 계약타입과 safety 문서

C의 명시적 규약을 Rust 타입과 수명 규칙으로 옮깁니다.

Abstractions
~~~~~~~~~~~~

Abstractions are the layer between the bindings and the in-kernel users. They
are located in ``rust/kernel/`` and their role is to encapsulate the unsafe
access to the bindings into an as-safe-as-possible API that they expose to their
users. Users of the abstractions include things like drivers or file systems
written in Rust.

Besides the safety aspect, the abstractions are supposed to be "ergonomic", in
the sense that they turn the C interfaces into "idiomatic" Rust code. Basic
examples are to turn the C resource acquisition and release into Rust
constructors and destructors or C integer error codes into Rust's ``Result``\ s.

커널 설정에 따른 조건부 컴파일

142-161

Rust 코드는 커널 설정을 `cfg` 조건으로 사용할 수 있다. `#[cfg(CONFIG_X)]`는 built-in `y` 또는 module `m`이면 활성화되고, `#[cfg(CONFIG_X="y")]`와 `#[cfg(CONFIG_X="m")]`는 각각 두 상태를 구분한다. `#[cfg(not(CONFIG_X))]`는 설정이 꺼졌을 때 선택된다.

숫자 비교처럼 Rust `cfg`가 직접 지원하지 않는 조건은 Kconfig symbol을 새로 정의해 boolean으로 바꾼다. 예를 들어 `RUSTC_VERSION >= 107900` 조건을 `RUSTC_VERSION_MIN_107900`의 `def_bool`로 만들고 Rust에서는 그 symbol을 조건으로 사용한다.

CONFIG_X 조건
Rust cfg선택 상태
cfg(CONFIG_X)y 또는 m
cfg(CONFIG_X="y")built-in y
cfg(CONFIG_X="m")module m
cfg(not(CONFIG_X))비활성
새 Kconfig boolean숫자 비교 등 cfg 미지원 조건

Kconfig의 y, m, 비활성 상태를 Rust cfg로 정확히 구분합니다.

Conditional compilation
-----------------------

Rust code has access to conditional compilation based on the kernel
configuration:

.. 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

For other predicates that Rust's ``cfg`` does not support, e.g. expressions with
numerical comparisons, one may define a new Kconfig symbol:

.. code-block:: kconfig

        config RUSTC_VERSION_MIN_107900
                def_bool y if RUSTC_VERSION >= 107900