December 06, 2022
After waiting in the Linux-next integration tree for about 18 months, the basic Rust infrastructure will finally land in the mainline Linux kernel with the imminent release of v6.1. While this will not include any real device drivers and only a few toy sample modules, further subsystem-specific bindings with real drivers should be added in the future.
During the 2022 Linux Maintainers Summit in Dublin, Linus Torvalds asked CI systems to start testing the new Rust infrastructure. So, with that in mind, we are excited to announce that as of today, Rust testing has now been added to KernelCI!
Here is a very brief review at the current state of Rust on the kernel side (which is already well documented on LWN.net, i.e. in this article or this v6.2 focused article) along with a look at the current status and future plans on the KernelCI project side, with some examples.
Only a specific version (currently v1.62) of the LLVM-based Rustc compiler (short: rustc) is supported - later versions might work but are not guaranteed. Work is still on-going on the GCC Rust front-end, so for the time being, building the Linux kernel with Rust requires LLVM. It is also worth mentioning that only the x86_64 architecture is supported for now.
The kernel provides a useful command
make LLVM=1 rustavailable to check whether the host distro has the required dependencies, which prints a cute
Rust is available! if a suitable toolchain in installed, otherwise the failure cause. One can also verify the toolchain dependency presence via the kernel config
CONFIG_HAVE_RUST=y to see whether the architecture supports Rust.
KernelCI has a modular design where multiple toolchains can be used with various combinations of kernel trees and .config files/fragments. It can be integrated with LAVA for boot and runtime testing on various boards, and so on.
Each toolchain used by KernelCI is self-contained into a docker image for reproducibility, built with kci_docker. Since kci_docker already contains some base definitions, it was an easy task to define an extra rustc toolchain on top of the existing clang toolchain versions. Should GCC-Rust become usable for example, it will be just as trivial to add a separate Dockerfile and start testing all the kernel trees, configs, and boards with the new toolchain.
To build and use the KernelCI rustc-1.62 container image, first, specify a config file to avoid passing all options via command line arguments:
$ git clone https://github.com/kernelci/kernelci-core.git $ cd kernelci-core $ cat > kernelci.conf <<EOF [kci_build] kdir: linux output: linux/build-x86 build_env: rustc-1.62 arch: x86_64 install: true EOF
Then invoke kci_docker to build the rustc-1.62 container:
$ cd kernelci-core/config/docker $ ./kci_docker build rustc-1.62 --fragment kernelci
An interesting challenge for the rustc docker builds was the fact that the standard Rust method of installing toolchains is via
curl https://sh.rustup.rs | sh which might be ok-ish for individual local development, but is a particularly bad idea in an automated CI system. Rustup itself does not (yet) do any signature verifications for its downloads.
Distros like Debian do not ship the version required by the kernel (v1.62), nor even rustup in some cases, and it's unlikely the distro maintainers will keep the versions in sync with the mainline kernel which likely will become a moving target. Thankfully the Rust project provides standalone installers together with GPG signatures which are very useful for CI.
Once a toolchain docker image is built, create a container and enter it.
$ cd ../.. $ docker run -it -v $PWD:/kernelci-core --workdir /kernelci-core kernelci/rustc-1.62:kernelci /bin/bash
Instruct KernelCI to generate config fragments for the rust enabled KCI build. The config fragments enable various kernel features when generating the final .config to build the kernel:
(inside docker) $ ./kci_build generate_fragments --build-config=rust
Finally, create a full .config by combining the config fragments and build the kernel & modules:
(inside docker) $ ./kci_build make_config --defconfig=defconfig+rust+rust-samples (inside docker) $ ./kci_build make_kernel (inside docker) $ ./kci_build make_modules
We also added the ability to build the Rust-for-Linux tree by specifying
--build-config=rust-for-linux instead of
--build-config=rust which builds mainline.
Hopefully, this complexity is bearable in a CI system to have flexible and reproducible builds. These mechanisms are then used by the KernelCI infrastructure to build and test the various trees (mainline, next, maintainer/subsystem specific trees, etc.), use LAVA for runtime tests, bisect, and report regressions, and so on.
It is still uncertain what will be the future of Rust in the Linux kernel in general and what community adoption Rust will have within the project. The codebase is still in its early stages of experimentation, and some topics are controversial.
However, we do plan to help test Rust code via KernelCI and this is why we're adding build testing early.
Going forward, we plan to add kunit tests, more toolchain and Kconfig combinations, GCC-Rust when it eventually becomes ready, extend testing to cover more subsystems and architectures (as they are added), and just maybe, if the stars align, even do boot and runtime testing, bisections, and the like for drivers implemented in Rust.
After two years of hosting the event virtually, Brussels will once again welcome attendees on February 4 & 5 on the old stomping grounds…
With only a few months passing since our last new joiner update, it should come as no surprise that the Collabora crowd has expanded yet…
Contributing to the Vulkan Working Group since 2015, Jason has continues to make a significant impact. His expertise and dilligence has…