rust: upskilling toward kernel rust · @martinthebad
c64.jpg ─ □ ✕
thank you
bannerz.sys ─ □ ✕
libre culture open source it all make art encrypt everything junkerz
nav.exe ─ □ ✕
20260612 rust: upskilling toward kernel rust

The Rust milestone

Of everything on my list, Rust is the one I am being most deliberate about, because it is the only genuinely new thing here. I know Go well. The plan is a post-assessment track, a marathon not a sprint, paced at about 30 to 60 minutes a day. The week numbers below are a rhythm, not a deadline. The only rule that actually matters for retention is that short regular sessions beat rare long ones.

What carries over from Go

Coming from Go this is not learning to program again. It is learning one new idea plus a set of nicer but familiar tools. The map:

ConceptGoRust
Memorygarbage collectorownership and the borrow checker, no GC
Nullnilno null, Option<T>
Errorserror plus multiple returnResult<T, E> and the ? operator
Interfacesinterface (implicit)trait (explicit impl)
CleanupdeferRAII, the Drop trait runs automatically
Collectionsslice, map, appendVec<T>, HashMap<K,V>, .push()
Mutabilitymutable by defaultimmutable by default, opt in with mut
Buildgo.mod, go buildCargo.toml, cargo build

Go's if err != nil is the same instinct as Rust's Result. Rust just makes the compiler enforce that you handle it.

The one genuinely hard thing

Go's garbage collector hid memory management completely. Rust makes it explicit and checks it at compile time. That is the borrow checker, and it is the whole learning curve. Three rules in plain terms:

  • Ownership. Every value has exactly one owner. When the owner goes out of scope the value is dropped automatically. No GC, no manual free.
  • Move. Assigning or passing a non-Copy value moves ownership. The old name can no longer use it.
  • Borrow. Instead of moving you can lend a reference: &T (shared, read-only, many at once) or &mut T (exclusive, one at a time). The compiler enforces many readers or one writer, never both. That is what kills data races and use-after-free.

Lifetimes are just the compiler's bookkeeping for how long a borrow is valid. The plan is honest that you fight the borrow checker for a week or two and that this is normal. It is the model being installed, not a sign you do not get it.

The four phases

  • Fundamentals. The Rust Book chapters 1 to 10 (do not skim ch.4 ownership or ch.10 generics and traits), Rustlings up through error handling, and one small program from scratch: read a file, count word frequency, print the top ten. That one touches String, Vec, HashMap, Option, Result and iteration all at once.
  • Idiomatic. The Book 11 to 20, the rest of Rustlings, drilling match and iterator chains (map, filter, collect, fold), and understanding when each of Box, Rc, RefCell is needed. That last one is the GC-shaped hole: Rust makes you pick the strategy yourself.
  • Systems. The bridge to the kernel. unsafe and raw pointers, FFI with extern "C" and #[repr(C)], and no_std: Rust without the standard library, which is the environment the kernel runs in. You lose std and keep core. The Rustonomicon covers the unsafe and FFI parts.
  • Kernel Rust. Read Documentation/rust/, build a kernel with CONFIG_RUST=y on x86_64 first then cross-compile for s390x, build and load a module from samples/rust/, and study the kernel crate: a thin audited unsafe core with a safe Rust surface on top. bindgen auto-generates the Rust bindings from the C headers.

Keep a scratch crate for trying one idea at a time, and let the compiler teach you. Its error messages are unusually good if you actually read them instead of skipping past:

rustup default stable      # toolchain; add nightly later for kernel work
cargo new scratch          # somewhere to try one idea at a time

Where this ties back to IBM Z

The reason Rust sits inside the s390 thread and not off on its own: IBM engineer Jan Polensky posted the first patches to bring in-kernel Rust to s390. That would make s390 the sixth architecture with Rust support, after x86_64, ARM, ARM64, LoongArch and RISC-V. Since the 2025 Maintainer Summit made kernel Rust permanent, per-architecture enablement is real engineering work now, not a science project.

What the s390 patches have to deal with is a neat tour of why this arch is awkward:

  • Architecture wiring. Add s390 to the Rust-capable arch list and set the rustc target s390x-unknown-linux-gnu.
  • Assembly stubs. WARN / BUG reporting and the static-branch patching machinery use arch-specific assembly trampolines that had to be exposed to Rust.
  • Bindgen adjustments. s390 hardware structs (CCW, the SIE block, ORB) use __packed and __aligned together, which creates layout conflicts that bindgen cannot reconcile. The patches work around it for those types.

And the real blocker on full upstreaming: s390 needs nightly rustc today because of -Zpacked-stack, an unstable flag for the s390 calling convention. On s390 the ABI reserves a 160-byte register save area at the bottom of the frame, and callees save into the caller's area rather than their own. The standard Rust and LLVM stack layout does not produce that, and -Zpacked-stack is not stabilised yet. Until it is, s390 Rust kernel support is nightly-only.

Milestones I am holding myself to

  • M1: the borrow checker stops surprising me.
  • M2: I write idiomatic Rust, not transliterated Go.
  • M3: I can explain unsafe, FFI and no_std.
  • M4: I built and loaded a Rust kernel module.
  • M5: I can discuss the s390 Rust patch series accurately.

Reading: The Rust Book, Rustlings, Rust for Linux, and the rustc s390x platform support page.

Next week, away from the mainframe entirely and over to the other prospect: the Rockchip RK3576 and the Flipper One.

← arm64 guests on a mainframe all posts next: picking an rk3576 board →

Tune in next time. Same Bat time. Same Bat channel
gb.log
Guestbook
rollin.ini ─ □ ✕
solarpunk.bat ─ □ ✕
garden wizard