THE JUNKYARD
ASSEMBLING DEBRIS . . .
0%
< Back> RustPi_

Building a Linux Distribution from Scratch

A deep dive into creating a minimal, custom Linux distribution for Raspberry Pi 3A+ with a Rust-based init system

512
MB Image Size
~3s
Boot Time
100%
Custom Built
View Source on GitHubRead Full Documentation
=============================================
RustPi Init v0.5.0
=============================================
[init] Mounting filesystems... OK
[init] Setting hostname: rustpi
[init] Starting SSH server... OK (port 22)
rustpi# _

Content

  1. 01Project Overview — What We Built
  2. 02Why Build Your Own Linux?
  3. 03System Architecture
  4. 04Core Components
  5. 05Complete Build Guide
  6. 06Debugging Adventures
  7. 07Key Learnings
  8. 08Resources & Next Steps
  9. 09Full Documentation (Notion)

Project Overview

RustPi is a minimal, custom-built Linux distribution designed to run on a Raspberry Pi 3 Model A+. What makes it unique is that the init system — the very first program that runs after the kernel boots — is written entirely in Rust.

This project demonstrates that building your own Linux distribution, while challenging, is absolutely achievable. It's an incredible learning experience that demystifies how operating systems work at the most fundamental level.

🦀

Rust Init System

Custom PID 1 process handling mounts, networking, and service management

🐧

Minimal Linux

Only essential components — no bloat, no unnecessary services

🥧

Pi 3A+ Target

Built specifically for Raspberry Pi's ARM64 architecture

📦

512MB Image

Complete bootable system in half a gigabyte

What's Included

Custom Rust init system (PID 1) with mount handling, hostname setup, and service spawning
BusyBox utilities providing 300+ common Linux commands
Networking via USB-Ethernet adapter with DHCP support
SSH server (Dropbear) for remote access
Proper user authentication with password and SSH key support
Pre-built Raspberry Pi kernel with full hardware support

Why Build Your Own Linux?

You might wonder: with hundreds of Linux distributions available, why build your own?

For Engineers

  • Deep System Understanding: There's no better way to understand how Linux works than building it yourself.
  • Embedded Systems Skills: IoT and embedded systems require minimal, purpose-built operating systems.
  • Rust Systems Programming: Writing an init system in Rust demonstrates the language's capability for low-level systems programming.
“The best way to understand something is to build it yourself.”

System Architecture

A Linux system is built in layers, each depending on the one below it:

User ApplicationsShell, SSH, Utilities
Init SystemRust (PID 1)
User-space LibrariesBusyBox, musl libc
Linux Kernel6.12.x ARM64
BootloaderRaspberry Pi GPU
HardwarePi 3A+ (BCM2837)

Core Components

The Rust Init System

The init system is the heart of RustPi. As PID 1, it's the first userspace process and the parent of all others.

rust
fn main() {
    // Verify we're running as PID 1
    if std::process::id() != 1 {
        eprintln!("[init] Error: Must run as PID 1");
        std::process::exit(1);
    }

    // Initialize the system
    mount_filesystems();    // /proc, /sys, /dev, /tmp
    setup_hostname();       // Set system hostname
    load_network_modules(); // Load USB-Ethernet driver
    setup_networking();     // DHCP configuration
    start_ssh_server();     // Dropbear SSH daemon
    spawn_shell();          // Interactive login shell

    // Reap zombie processes forever
    loop {
        waitpid(-1, WNOHANG);
        sleep(Duration::from_millis(100));
    }
}

BusyBox — The Swiss Army Knife

BusyBox provides 300+ common Unix utilities in a single ~1MB binary.

bash
# Creating command symlinks
for cmd in ls cat cp mv rm mkdir chmod; do
    ln -sf busybox /bin/$cmd
done

Complete Build Guide

Ready to build your own RustPi? Here are the key phases:

Phase 1

Development Environment Setup

bash
# Install cross-compilation toolchain
sudo apt update
sudo apt install -y gcc-aarch64-linux-gnu build-essential git

# Install Rust with ARM64 target
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add aarch64-unknown-linux-musl
Phase 2-3

Build Init & BusyBox

bash
# Build Rust init
cargo build --release --target aarch64-unknown-linux-musl

# Build BusyBox
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
sed -i 's/# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
Phase 4-5

Create SD Card Image

bash
# Create 512MB image
dd if=/dev/zero of=sdcard.img bs=1M count=512

# Create cmdline.txt
echo "console=serial0,115200 console=tty1 \
  root=/dev/mmcblk0p2 rootfstype=ext4 \
  rootwait rw init=/sbin/init" \
  | sudo tee mnt/boot/cmdline.txt

# Flash to SD card
sudo dd if=sdcard.img of=/dev/rdisk4 bs=4m status=progress

Debugging Adventures

Building a Linux distro involves solving many puzzles. Here are the issues we encountered:

Symptom: Kernel panic - not syncing: VFS: Unable to mount root fs

Cause: The kernel was compiled as an EFI executable instead of a raw ARM64 image.

Solution: Disable EFI stub in kernel config.

Key Learnings

Technical Skills Gained

Cross-compilationARM64 ArchitectureKernel ConfigurationDevice TreesInit SystemsStatic LinkingBoot ProcessNetwork ConfigurationSSH Server SetupRust Systems Programming

1. Static vs Dynamic Linking

In minimal systems without glibc, static linking is essential. The musl libc provides a lightweight alternative.

2. File Ownership is Critical

When building a rootfs, files are owned by your user (UID 1000). These must be changed to root (UID 0).

“Every error message is a clue. The key is knowing where to look.”

Resources & Next Steps

References Used

💡 Pro Tip

Keep detailed notes of everything you try and every error you encounter. This documentation becomes invaluable when you need to reproduce your work.

Full Documentation

Want the complete technical deep-dive? The full RustPi documentation covers every file, every function, and every decision made throughout the build process — from kernel configuration to debugging SSH authentication issues.

RustPi — Complete Technical Documentation

tungsten-bramble-977.notion.site

Boot ProcessKernel ConfigRust Init Deep DiveDropbear + muslDebugging GuideAll Build Scripts

Covers the complete Linux boot process, Vagrantfile setup, kernel compilation with USB Ethernet drivers, the Rust init system line-by-line, why Dropbear must be built with musl (not glibc), rootfs creation, SD card image assembly, and every issue encountered with its resolution.

Open in Notion