Rust support was merged into the Linux kernel mainline in version 6.1. It gives kernel developers a second implementation language alongside C: one with a type system that eliminates entire classes of memory-safety bugs—use-after-free, null dereference, data races—at compile time. The Rust integration does not replace C; instead it provides an opt-in path for new drivers and subsystems, with a thin safe abstraction layer over the existing C kernel APIs.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/DeelerDev/linux/llms.txt
Use this file to discover all available pages before exploring further.
Why Rust
Memory safety, no undefined behavior, zero-cost abstractions.
Toolchain setup
Install rustc, rust-src, bindgen, and LLVM.
The kernel crate
rust/kernel/ modules, the module! macro, and the Module trait.Hello world module
A complete, annotated minimal Rust kernel module.
Available abstractions
Task, File, Mutex, SpinLock, workqueue, and more.
Building
CONFIG_RUST=y, make LLVM=1, and the rustdoc target.What Rust brings to the kernel
Kernel code written in C has historically relied on programmer discipline to avoid memory errors. Rust’s ownership and borrowing rules enforce the same invariants mechanically:- No use-after-free: the borrow checker prevents accessing memory after the owning value is dropped.
- No null-pointer dereferences: pointers in Rust are non-null by default; nullable pointers are wrapped in
Option<*mut T>. - No data races: the
SendandSyncmarker traits prevent sharing mutable state across threads without synchronization. - No uninitialized memory reads: variables must be initialized before use; the compiler rejects programs that read from uninitialized memory.
- Deterministic cleanup: destructors (
Drop) run automatically and cannot be skipped, so resource leaks are a compiler error rather than a runtime bug.
Rust code in the kernel is written in
#![no_std] mode. Only the core crate (a subset of the standard library with no heap dependency) is available by default. The kernel’s own kernel crate provides the allocator and kernel-specific wrappers.Abstractions vs. bindings
The Rust-for-Linux architecture has two layers:- Bindings (
rust/bindings/): auto-generated bybindgenfrom C headers. Calling bindgen-generated functions isunsafebecause C provides no safety guarantees the compiler can verify. - Abstractions (
rust/kernel/): hand-written, safe Rust wrappers around the bindings. A driver or file system written in Rust should call only abstraction APIs, never raw bindings directly.
Setting up the toolchain
Rust kernel development requires a recent stablerustc, the Rust standard library source, bindgen, and an LLVM toolchain.
Distribution packages (recommended)
Arch Linux
Arch Linux
Debian / Ubuntu (recent releases)
Debian / Ubuntu (recent releases)
Fedora Linux
Fedora Linux
Using rustup
Using rustup
Verify the toolchain
CONFIG_RUST. If requirements are not met, it explains exactly what is missing.
The kernel crate
Thekernel crate (source in rust/kernel/) is the primary API surface for Rust kernel code. It re-exports a curated set of abstractions through its prelude.
Key modules in rust/kernel/
| Module | Contents |
|---|---|
sync | Mutex, SpinLock, Arc, Completion, RcuData |
task | Task — wraps struct task_struct |
mm | Memory management helpers |
fs | Virtual filesystem abstractions |
net | Networking socket abstractions |
workqueue | Work, Queue — wraps kernel workqueues |
error | Error, Result — maps C errno values to Rust |
str | CStr, CString — kernel C-string types |
print | pr_info!, pr_err!, pr_debug!, dev_info! |
alloc | KBox, KVec — kernel-allocator-backed collections |
irq | IRQ descriptor and handler abstractions |
pci / platform | Bus driver abstractions |
The prelude
module!, pr_info!, GFP_KERNEL, KBox, KVec, Arc, Result, Error, and others.
Writing a Rust kernel module
Every Rust kernel module uses themodule! macro to declare its metadata and the kernel::Module trait to define its lifecycle. The module struct is instantiated on insmod and dropped on rmmod.
Minimal module
The following is the actualrust_minimal sample from samples/rust/rust_minimal.rs:
Anatomy of a Rust module
module! macro generates the C-visible init_module() and cleanup_module() symbols. It calls MyDriver::init() on load and drop() on unload.
Error propagation uses Rust’s
? operator. Result<T> in the kernel maps to Result<T, kernel::error::Error> where Error wraps a C errno integer. ENOMEM, EIO, EINVAL, and the rest are available as kernel::error::code::ENOMEM, etc., or via the prelude.Available abstractions
Logging
Rust provides the samepr_* family as C, as macros that forward to the C printk implementation:
Synchronization: Mutex and SpinLock
Task
Work queues
Memory: KBox and KVec
KBox and KVec are kernel-allocator-backed equivalents of Box and Vec. They require a GFP flag to allow the caller to control whether the allocation may sleep.
Building Rust modules
Enabling Rust support
make LLVM=1 rustavailable confirms this.
Building the kernel and Rust samples
Building an out-of-tree Rust module
Out-of-tree Rust modules use the sameMakefile structure as C modules:
Generating Rust API documentation
https://rust.docs.kernel.org.
Checking style
SAFETY comments and unsafe code
Rust’sunsafe keyword is not banned in kernel Rust code, but its use must be minimal, well-justified, and auditable. Every unsafe block must be preceded by a // SAFETY: comment explaining why the code is correct:
// SAFETY: comment is not optional. Reviewers will reject unsafe blocks without them, and the kernel CI checks for their presence. This discipline is what makes the safety guarantees of Rust abstractions trustworthy.