2021-07-03 15:23:16 +00:00
|
|
|
.. SPDX-License-Identifier: GPL-2.0
|
|
|
|
|
|
|
|
Quick Start
|
|
|
|
===========
|
|
|
|
|
|
|
|
This document describes how to get started with kernel development in Rust.
|
|
|
|
|
|
|
|
|
|
|
|
Requirements: Building
|
|
|
|
----------------------
|
|
|
|
|
|
|
|
This section explains how to fetch the tools needed for building.
|
|
|
|
|
|
|
|
Some of these requirements might be available from Linux distributions
|
|
|
|
under names like ``rustc``, ``rust-src``, ``rust-bindgen``, etc. However,
|
|
|
|
at the time of writing, they are likely not to be recent enough unless
|
|
|
|
the distribution tracks the latest releases.
|
|
|
|
|
|
|
|
To easily check whether the requirements are met, the following target
|
|
|
|
can be used::
|
|
|
|
|
|
|
|
make LLVM=1 rustavailable
|
|
|
|
|
|
|
|
This triggers the same logic used by Kconfig to determine whether
|
|
|
|
``RUST_IS_AVAILABLE`` should be enabled; but it also explains why not
|
|
|
|
if that is the case.
|
|
|
|
|
|
|
|
|
|
|
|
rustc
|
|
|
|
*****
|
|
|
|
|
|
|
|
A particular version of the Rust compiler is required. Newer versions may or
|
|
|
|
may not work because, for the moment, the kernel depends on some unstable
|
|
|
|
Rust features.
|
|
|
|
|
|
|
|
If ``rustup`` is being used, enter the checked out source code directory
|
|
|
|
and run::
|
|
|
|
|
|
|
|
rustup override set $(scripts/min-tool-version.sh rustc)
|
|
|
|
|
2023-08-03 06:04:37 +00:00
|
|
|
This will configure your working directory to use the correct version of
|
|
|
|
``rustc`` without affecting your default toolchain. If you are not using
|
|
|
|
``rustup``, fetch a standalone installer from:
|
2021-07-03 15:23:16 +00:00
|
|
|
|
2023-03-06 22:09:59 +00:00
|
|
|
https://forge.rust-lang.org/infra/other-installation-methods.html#standalone
|
2021-07-03 15:23:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
Rust standard library source
|
|
|
|
****************************
|
|
|
|
|
|
|
|
The Rust standard library source is required because the build system will
|
|
|
|
cross-compile ``core`` and ``alloc``.
|
|
|
|
|
|
|
|
If ``rustup`` is being used, run::
|
|
|
|
|
|
|
|
rustup component add rust-src
|
|
|
|
|
|
|
|
The components are installed per toolchain, thus upgrading the Rust compiler
|
|
|
|
version later on requires re-adding the component.
|
|
|
|
|
2023-08-03 06:04:36 +00:00
|
|
|
Otherwise, if a standalone installer is used, the Rust source tree may be
|
|
|
|
downloaded into the toolchain's installation folder::
|
2021-07-03 15:23:16 +00:00
|
|
|
|
2023-08-03 06:04:36 +00:00
|
|
|
curl -L "https://static.rust-lang.org/dist/rust-src-$(scripts/min-tool-version.sh rustc).tar.gz" |
|
|
|
|
tar -xzf - -C "$(rustc --print sysroot)/lib" \
|
|
|
|
"rust-src-$(scripts/min-tool-version.sh rustc)/rust-src/lib/" \
|
|
|
|
--strip-components=3
|
2021-07-03 15:23:16 +00:00
|
|
|
|
|
|
|
In this case, upgrading the Rust compiler version later on requires manually
|
2023-08-03 06:04:36 +00:00
|
|
|
updating the source tree (this can be done by removing ``$(rustc --print
|
|
|
|
sysroot)/lib/rustlib/src/rust`` then rerunning the above command).
|
2021-07-03 15:23:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
libclang
|
|
|
|
********
|
|
|
|
|
|
|
|
``libclang`` (part of LLVM) is used by ``bindgen`` to understand the C code
|
|
|
|
in the kernel, which means LLVM needs to be installed; like when the kernel
|
|
|
|
is compiled with ``CC=clang`` or ``LLVM=1``.
|
|
|
|
|
|
|
|
Linux distributions are likely to have a suitable one available, so it is
|
|
|
|
best to check that first.
|
|
|
|
|
|
|
|
There are also some binaries for several systems and architectures uploaded at:
|
|
|
|
|
|
|
|
https://releases.llvm.org/download.html
|
|
|
|
|
|
|
|
Otherwise, building LLVM takes quite a while, but it is not a complex process:
|
|
|
|
|
|
|
|
https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm
|
|
|
|
|
|
|
|
Please see Documentation/kbuild/llvm.rst for more information and further ways
|
|
|
|
to fetch pre-built releases and distribution packages.
|
|
|
|
|
|
|
|
|
|
|
|
bindgen
|
|
|
|
*******
|
|
|
|
|
|
|
|
The bindings to the C side of the kernel are generated at build time using
|
|
|
|
the ``bindgen`` tool. A particular version is required.
|
|
|
|
|
|
|
|
Install it via (note that this will download and build the tool from source)::
|
|
|
|
|
rust: bindgen: upgrade to 0.65.1
In LLVM 16, anonymous items may return names like `(unnamed union at ..)`
rather than empty names [1], which breaks Rust-enabled builds because
bindgen assumed an empty name instead of detecting them via
`clang_Cursor_isAnonymous` [2]:
$ make rustdoc LLVM=1 CLIPPY=1 -j$(nproc)
RUSTC L rust/core.o
BINDGEN rust/bindings/bindings_generated.rs
BINDGEN rust/bindings/bindings_helpers_generated.rs
BINDGEN rust/uapi/uapi_generated.rs
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
thread 'main' panicked at '"ftrace_branch_data_union_(anonymous_at__/_/include/linux/compiler_types_h_146_2)" is not a valid Ident', .../proc-macro2-1.0.24/src/fallback.rs:693:9
...
This was fixed in bindgen 0.62.0. Therefore, upgrade bindgen to
a more recent version, 0.65.1, to support LLVM 16.
Since bindgen 0.58.0 changed the `--{white,black}list-*` flags to
`--{allow,block}list-*` [3], update them on our side too.
In addition, bindgen 0.61.0 moved its CLI utility into a binary crate
called `bindgen-cli` [4]. Thus update the installation command in the
Quick Start guide.
Moreover, bindgen 0.61.0 changed the default functionality to bind
`size_t` to `usize` [5] and added the `--no-size_t-is-usize` flag
to not bind `size_t` as `usize`. Then bindgen 0.65.0 removed
the `--size_t-is-usize` flag [6]. Thus stop passing the flag to bindgen.
Finally, bindgen 0.61.0 added support for the `noreturn` attribute (in
its different forms) [7]. Thus remove the infinite loop in our Rust
panic handler after calling `BUG()`, since bindgen now correctly
generates a `BUG()` binding that returns `!` instead of `()`.
Link: https://github.com/llvm/llvm-project/commit/19e984ef8f49bc3ccced15621989fa9703b2cd5b [1]
Link: https://github.com/rust-lang/rust-bindgen/pull/2319 [2]
Link: https://github.com/rust-lang/rust-bindgen/pull/1990 [3]
Link: https://github.com/rust-lang/rust-bindgen/pull/2284 [4]
Link: https://github.com/rust-lang/rust-bindgen/commit/cc78b6fdb6e829e5fb8fa1639f2182cb49333569 [5]
Link: https://github.com/rust-lang/rust-bindgen/pull/2408 [6]
Link: https://github.com/rust-lang/rust-bindgen/issues/2094 [7]
Signed-off-by: Aakash Sen Sharma <aakashsensharma@gmail.com>
Closes: https://github.com/Rust-for-Linux/linux/issues/1013
Tested-by: Ariel Miculas <amiculas@cisco.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
Link: https://lore.kernel.org/r/20230612194311.24826-1-aakashsensharma@gmail.com
[ Reworded commit message. Mentioned the `bindgen-cli` binary crate
change, linked to it and updated the Quick Start guide. Re-added a
deleted "as" word in a code comment and reflowed comment to respect
the maximum length. ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
2023-06-12 19:43:11 +00:00
|
|
|
cargo install --locked --version $(scripts/min-tool-version.sh bindgen) bindgen-cli
|
2021-07-03 15:23:16 +00:00
|
|
|
|
2023-06-16 00:16:23 +00:00
|
|
|
``bindgen`` needs to find a suitable ``libclang`` in order to work. If it is
|
|
|
|
not found (or a different ``libclang`` than the one found should be used),
|
|
|
|
the process can be tweaked using the environment variables understood by
|
|
|
|
``clang-sys`` (the Rust bindings crate that ``bindgen`` uses to access
|
|
|
|
``libclang``):
|
|
|
|
|
|
|
|
* ``LLVM_CONFIG_PATH`` can be pointed to an ``llvm-config`` executable.
|
|
|
|
|
|
|
|
* Or ``LIBCLANG_PATH`` can be pointed to a ``libclang`` shared library
|
|
|
|
or to the directory containing it.
|
|
|
|
|
|
|
|
* Or ``CLANG_PATH`` can be pointed to a ``clang`` executable.
|
|
|
|
|
|
|
|
For details, please see ``clang-sys``'s documentation at:
|
|
|
|
|
|
|
|
https://github.com/KyleMayes/clang-sys#environment-variables
|
|
|
|
|
2021-07-03 15:23:16 +00:00
|
|
|
|
|
|
|
Requirements: Developing
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
This section explains how to fetch the tools needed for developing. That is,
|
|
|
|
they are not needed when just building the kernel.
|
|
|
|
|
|
|
|
|
|
|
|
rustfmt
|
|
|
|
*******
|
|
|
|
|
|
|
|
The ``rustfmt`` tool is used to automatically format all the Rust kernel code,
|
|
|
|
including the generated C bindings (for details, please see
|
|
|
|
coding-guidelines.rst).
|
|
|
|
|
|
|
|
If ``rustup`` is being used, its ``default`` profile already installs the tool,
|
|
|
|
thus nothing needs to be done. If another profile is being used, the component
|
|
|
|
can be installed manually::
|
|
|
|
|
|
|
|
rustup component add rustfmt
|
|
|
|
|
|
|
|
The standalone installers also come with ``rustfmt``.
|
|
|
|
|
|
|
|
|
|
|
|
clippy
|
|
|
|
******
|
|
|
|
|
|
|
|
``clippy`` is a Rust linter. Running it provides extra warnings for Rust code.
|
|
|
|
It can be run by passing ``CLIPPY=1`` to ``make`` (for details, please see
|
|
|
|
general-information.rst).
|
|
|
|
|
|
|
|
If ``rustup`` is being used, its ``default`` profile already installs the tool,
|
|
|
|
thus nothing needs to be done. If another profile is being used, the component
|
|
|
|
can be installed manually::
|
|
|
|
|
|
|
|
rustup component add clippy
|
|
|
|
|
|
|
|
The standalone installers also come with ``clippy``.
|
|
|
|
|
|
|
|
|
|
|
|
cargo
|
|
|
|
*****
|
|
|
|
|
|
|
|
``cargo`` is the Rust native build system. It is currently required to run
|
|
|
|
the tests since it is used to build a custom standard library that contains
|
|
|
|
the facilities provided by the custom ``alloc`` in the kernel. The tests can
|
|
|
|
be run using the ``rusttest`` Make target.
|
|
|
|
|
|
|
|
If ``rustup`` is being used, all the profiles already install the tool,
|
|
|
|
thus nothing needs to be done.
|
|
|
|
|
|
|
|
The standalone installers also come with ``cargo``.
|
|
|
|
|
|
|
|
|
|
|
|
rustdoc
|
|
|
|
*******
|
|
|
|
|
|
|
|
``rustdoc`` is the documentation tool for Rust. It generates pretty HTML
|
|
|
|
documentation for Rust code (for details, please see
|
|
|
|
general-information.rst).
|
|
|
|
|
|
|
|
``rustdoc`` is also used to test the examples provided in documented Rust code
|
|
|
|
(called doctests or documentation tests). The ``rusttest`` Make target uses
|
|
|
|
this feature.
|
|
|
|
|
|
|
|
If ``rustup`` is being used, all the profiles already install the tool,
|
|
|
|
thus nothing needs to be done.
|
|
|
|
|
|
|
|
The standalone installers also come with ``rustdoc``.
|
|
|
|
|
|
|
|
|
|
|
|
rust-analyzer
|
|
|
|
*************
|
|
|
|
|
|
|
|
The `rust-analyzer <https://rust-analyzer.github.io/>`_ language server can
|
|
|
|
be used with many editors to enable syntax highlighting, completion, go to
|
|
|
|
definition, and other features.
|
|
|
|
|
|
|
|
``rust-analyzer`` needs a configuration file, ``rust-project.json``, which
|
2023-08-14 15:07:22 +00:00
|
|
|
can be generated by the ``rust-analyzer`` Make target::
|
|
|
|
|
|
|
|
make LLVM=1 rust-analyzer
|
2021-07-03 15:23:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
Configuration
|
|
|
|
-------------
|
|
|
|
|
|
|
|
``Rust support`` (``CONFIG_RUST``) needs to be enabled in the ``General setup``
|
|
|
|
menu. The option is only shown if a suitable Rust toolchain is found (see
|
|
|
|
above), as long as the other requirements are met. In turn, this will make
|
|
|
|
visible the rest of options that depend on Rust.
|
|
|
|
|
|
|
|
Afterwards, go to::
|
|
|
|
|
|
|
|
Kernel hacking
|
|
|
|
-> Sample kernel code
|
|
|
|
-> Rust samples
|
|
|
|
|
|
|
|
And enable some sample modules either as built-in or as loadable.
|
|
|
|
|
|
|
|
|
|
|
|
Building
|
|
|
|
--------
|
|
|
|
|
|
|
|
Building a kernel with a complete LLVM toolchain is the best supported setup
|
|
|
|
at the moment. That is::
|
|
|
|
|
|
|
|
make LLVM=1
|
|
|
|
|
|
|
|
For architectures that do not support a full LLVM toolchain, use::
|
|
|
|
|
|
|
|
make CC=clang
|
|
|
|
|
|
|
|
Using GCC also works for some configurations, but it is very experimental at
|
|
|
|
the moment.
|
|
|
|
|
|
|
|
|
|
|
|
Hacking
|
|
|
|
-------
|
|
|
|
|
|
|
|
To dive deeper, take a look at the source code of the samples
|
|
|
|
at ``samples/rust/``, the Rust support code under ``rust/`` and
|
|
|
|
the ``Rust hacking`` menu under ``Kernel hacking``.
|
|
|
|
|
|
|
|
If GDB/Binutils is used and Rust symbols are not getting demangled, the reason
|
|
|
|
is the toolchain does not support Rust's new v0 mangling scheme yet.
|
|
|
|
There are a few ways out:
|
|
|
|
|
|
|
|
- Install a newer release (GDB >= 10.2, Binutils >= 2.36).
|
|
|
|
|
|
|
|
- Some versions of GDB (e.g. vanilla GDB 10.1) are able to use
|
|
|
|
the pre-demangled names embedded in the debug info (``CONFIG_DEBUG_INFO``).
|