General Information

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

no_std

The Rust support in the kernel can link onlycore,but notstd. Crates for use in thekernel must opt into this behavior using the#![no_std] attribute.

Code documentation

Rust kernel code is documented usingrustdoc, its built-in documentationgenerator.

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

For linux-next, please see:

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

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 environmentare needed. This has the added advantage that they will be tailored tothe particular kernel configuration used. To generate them, use therustdoctarget 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 seeCoding Guidelines.

Extra lints

Whilerustc is a very helpful compiler, some extra lints and analyses areavailable viaclippy, a Rust linter. To enable it, passCLIPPY=1 tothe same invocation used for compilation, e.g.:

make LLVM=1 CLIPPY=1

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

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 fromthe C side.

For instance, one may write aMutex abstraction in Rust which wrapsastructmutex 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, subsystemsshould provide as-safe-as-possible abstractions as needed.

                                                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 APIsinto carefully reviewed and documented abstractions. Then users of theseabstractions cannot introduce undefined behavior (UB) as long as:

  1. The abstractions are correct (“sound”).

  2. Anyunsafe blocks respect the safety contract necessary to call theoperations inside the block. Similarly, anyunsafeimpls respect thesafety contract necessary to implement the trait.

Bindings

By including a C header frominclude/ intorust/bindings/bindings_helper.h, thebindgen tool will auto-generate thebindings for the included subsystem. After building, see the*_generated.rsoutput files in therust/bindings/ directory.

For parts of the C header thatbindgen does not auto generate, e.g. Cinline functions or non-trivial macros, it is acceptable to add a smallwrapper function torust/helpers/ to make it available for the Rust side aswell.

Abstractions

Abstractions are the layer between the bindings and the in-kernel users. Theyare located inrust/kernel/ and their role is to encapsulate the unsafeaccess to the bindings into an as-safe-as-possible API that they expose to theirusers. Users of the abstractions include things like drivers or file systemswritten in Rust.

Besides the safety aspect, the abstractions are supposed to be “ergonomic”, inthe sense that they turn the C interfaces into “idiomatic” Rust code. Basicexamples are to turn the C resource acquisition and release into Rustconstructors and destructors or C integer error codes into Rust’sResults.

Conditional compilation

Rust code has access to conditional compilation based on the kernelconfiguration:

#[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’scfg does not support, e.g. expressions withnumerical comparisons, one may define a new Kconfig symbol:

configRUSTC_VERSION_MIN_107900def_boolyifRUSTC_VERSION>=107900