Trust is earned, not given

A different perspective

2022-12-13 · Projects

Rust, part 4: Rust lands in the Linux kernel

Part 4from the Rust series · 15 parts in all

In December 2022, Linux 6.1 shipped the first Rust code in the kernel tree. It is easy to file that under "historical curiosity" and it would be a mistake: the constraints the kernel put on Rust are the constraints of the hardest embedding problem there is, and the way the project answered them says a lot about what the language is now for.

Why it took years to say yes

The kernel is not written in C because of inertia. It is C because C gives you:

What was actually merged

The first commit was not a driver. It was the infrastructure — enough to write a minimal module, with the abstractions built in-tree:

// A kernel module, in the shape the in-tree `kernel` crate allows.
// no_std, no libc, and panics that abort rather than unwind.
#![no_std]

use kernel::prelude::*;

module! {
    type: Hello,
    name: "hello_rust",
    author: "Bob Huang",
    description: "a minimal module",
    license: "GPL",
}

struct Hello;

impl kernel::Module for Hello {
    fn init(_module: &'static ThisModule) -> Result<Self> {
        pr_info!("hello from Rust\n");
        Ok(Hello)
    }
}

Note what is absent: no std, no alloc by default, no Box::new, and pr_info! is a kernel macro rather than println!. The interesting part is the Result in init — a module that fails to initialise returns the error rather than calling panic!, which is a language-level answer to a kernel-level problem.

What it changed outside the kernel

Even if you never write a driver, the effort paid back into the language and the ecosystem, and that is the part worth knowing:

It also set the pattern every other large codebase has followed since: adopt incrementally, at the leaves, through a C ABI. Next: the type-system feature that decides which of your function calls are indirections — traits, generics and monomorphization.