Phase 44
Rust Cross Compilation
Rust programs compiled on the host run natively inside the OS. A documented toolchain setup enables writing Rust code on the host, cross-compiling to an x86-64 ELF binary linked against musl, and deploying it to the OS's disk image. Stretch goal: a minimal Rust program compiles inside the OS itself.
Learning goal
Understand Rust's cross-compilation model: targets, sysroots, and linkers.
Category
productivity
Components touched
Builds on
Unlocked by this phase
Why this phase matters
Rust programs compiled on the host run natively inside the OS. A documented toolchain setup enables writing Rust code on the host, cross-compiling to an x86-64 ELF binary linked against musl, and deploying it to the OS’s disk image. Stretch goal: a minimal Rust program compiles inside the OS itself.
How it works in m3OS
Phase 44 enables Rust programs compiled on the host to run natively inside m3OS. Programs are cross-compiled with --target x86_64-unknown-linux-musl, producing statically-linked ELF binaries that make Linux syscalls. Because m3OS already implements a Linux syscall compatibility layer (Phase 12), these musl-linked binaries run without any kernel changes. The phase also introduces a custom x86_64-m3os target spec for #![no_std] programs and xtask automation for building and packaging Rust userspace binaries.
How it builds on earlier phases
This phase builds on Regression Stress Ci and turns that foundation into Rust Cross Compilation.
Implementation outline
- Set up
x86_64-unknown-linux-musltarget on the host. - Write and cross-compile
hello-rust— verify it runs in the OS. - Identify and implement any missing syscalls that
stdneeds. - Write the demonstration programs.
- Extend xtask to cross-compile and package Rust userspace programs.
- Create the custom m3os target specification for
no_stdprograms. - Write a
syscallcrate for native m3os programs. - Document the full cross-compilation workflow.
- (Stretch) Investigate porting mrustc or rustc.
Task progress snapshot
0 of 76 tracked tasks are complete.
Documentation targets
- Documentation deliverables have not been listed yet.
Deferred follow-on work
- Native
stdbackend for m3os (custom os module) - Running
cargoinside the OS - Crate registry access from inside the OS
- Remote debugging (gdb stub)
- Dynamic linking of Rust programs
Source materials
Important code
Code spotlight cards
Code spotlight
Create `userspace/hello-rust/` crate
userspace crates (which are no_std and use syscall-lib), this crate uses Rust's. Why it matters: This is the first Rust std program targeting m3OS. Unlike existing. Focus on `hello-rust` and `std` in `userspace/hello-rust/Cargo.toml` while you trace the snippet.
Code spotlight
Run hello-rust inside m3OS
inside m3OS using the Linux syscall compatibility layer. If it prints its message and. Why it matters: This is the key proof-of-concept: a musl-linked Rust binary running. Focus on `hello-rust` in `userspace/hello-rust/src/main.rs` while you trace the snippet.
Code spotlight
Audit musl startup syscalls
syscalls to set up the C runtime (e.g., set_tid_address, sigaltstack,. Why it matters: Before main() runs, musl's CRT startup code makes several. Focus on `sys_*` and `main` in `kernel/src/arch/x86_64/syscall.rs` while you trace the snippet.
// ---------------------------------------------------------------------------
// set_tid_address(tidptr) — syscall 218 (musl TLS initialization)
// ---------------------------------------------------------------------------
/// `set_tid_address(tidptr)` — store the `clear_child_tid` pointer for the
/// calling thread and return the caller's TID.
///
/// musl calls this during `__init_tls` to record the address that the kernel
/// should clear (and futex-wake) when the thread exits.
fn sys_linux_set_tid_address(tidptr: u64) -> u64 {
let pid = crate::process::current_pid(); Key files
- kernel/initrd/ — resulting binaries, and copies them to kernel/initrd/ for inclusion in the disk
- xtask/src/main.rs — Cross-compilation and packaging pipeline
- x86_64-m3os.json — Custom Rust target spec for no_std programs
- userspace/hello-rust/src/main.rs — Minimal Rust std validation
- userspace/sysinfo-rust/src/main.rs — File I/O via std::fs
- userspace/httpd-rust/src/main.rs — TCP server via std::net
- userspace/calc-rust/src/main.rs — Interactive I/O via std::io
- userspace/todo-rust/src/main.rs — Persistent storage via std::fs
How real OSes differ
- Full `std` library ports with OS-specific backends
- Cargo registry access for pulling dependencies
- CI/CD pipelines for continuous cross-compilation
- Debug symbol support and remote debugging
Success criteria
- `hello-rust` runs inside the OS and prints its message.
- A Rust program using `std::fs` can read and write files.
- A Rust program using `std::net` can open TCP connections.
- The xtask build system can cross-compile and package Rust programs.
- The cross-compilation workflow is documented and reproducible.
- At least 3 non-trivial Rust demonstration programs work.
Related phases
Keep exploring the roadmap
Phase 43
CompleteRegression Stress Ci
A layered test infrastructure that catches SMP race conditions through focused QEMU regression tests, looped stress tests with automatic artifact capture, seed-based iteration for reproducibility (guest-side timing variation deferred), host-side property and concurrency testing for extracted scheduler/fork/IPC models, and CI tier mapping that runs regressions on every PR and stress tests nightly.
Phase 45
CompletePorts System
A simple BSD-style ports system enables building and installing third-party software inside the OS from source recipes. A port is a directory containing a Makefile, patches, and a Portfile that automates extracting, compiling, and installing a piece of software. At least 5 ports build and install successfully, with dependency resolution.