SimpleOS is a from-scratch, educational bare-metal operating system for the Raspberry Pi family, built using Assembly, C, and (eventually) Rust. The goal is to explore low-level systems programming while creating a minimal, efficient kernel that runs directly on the hardware — no Linux, no firmware blobs, just the metal and myself.
The repository is structured to support both 32-bit and 64-bit architectures in a single codebase where possible:
SimpleOS/
├── 32bit/ # Raspberry Pi 1, Zero, 2, 3 (ARMv7/AArch32)
├── 64bit/ # Raspberry Pi 4, 5 (AArch64)
├── common/ # Shared code (planned)
└── README.md
The user-facing API and high-level design will be virtually identical across both branches, with architecture-specific differences isolated to boot code, UART drivers, and low-level initialisation.
We are actively developing the 64-bit version for Raspberry Pi 4 & 5. The kernel currently:
- Boots in AArch64 EL1
- Initialises the PL011 UART for early console output
- Provides a simple echoing terminal
- Parks secondary cores safely
- Builds with a clean, freestanding toolchain
We are actively developing the 32-bit version for Raspberry Pi 1, 2b & 3. The kernel currently:
- Boots in AArch32 EL1
- Initialises the PL011 UART for early console output
- Provides a simple echoing terminal
- Parks secondary cores safely
- Builds with a clean, freestanding toolchain
- Multi-core safe boot (core 0 runs, others parked)
- Reliable early UART console (PL011 for QEMU reliability, conditional GPIO mux for real hardware)
- Basic
puts/putc/getcwith echo loop - stdio and stdlib building for more diverse terminal output.
- Robust exception vector table (synchronous, IRQ, FIQ, SError)
- Hex terminal colors
- System timer interrupts
- Physical memory manager (frame allocator)
- Virtual memory with page tables
- Simple round-robin scheduler
- Heap allocation (custom allocator)
- Wake secondary cores
- Per-core stacks and data
- Spinlocks and basic synchronisation
-
no_stdRust crate for higher-level kernel code - Mixed C/Rust build system
- Safe abstractions over hardware (drivers in Rust)
- Framebuffer/graphics output
- GPIO & basic input
- SD card / filesystem
- USB & keyboard input
- Simple shell
- User-mode processes
- Networking
To build and test SimpleOS, you will need:
- Toolchain:
- For 64-bit:
aarch64-none-elf-gcc(ARM GNU Toolchain, Apple Silicon build recommended on macOS) - For 32-bit:
arm-none-eabi-gcc
- For 64-bit:
- QEMU:
qemu-system-aarch64for 64bit orqemu-system-armfor 32bit (QEMU version 8.0 or newer recommended) - Make: I provide an included makefile which simplifies the kenel compilation process if you wish to compile from source.
- macOS/Linux recommended (Windows via WSL works)
brew install qemuThen download and install the ARM GNU Toolchain from developer.arm.com
Inside the 64bit directory
make clean
make
make run # Uses -nographic -serial stdio for direct terminal outputYou should see:
Hello, World!
followed by an interactive echo loop. To quit QEMU: Ctrl+A then X (or Ctrl+C in some configurations).
Build with GPIO pin muxing enabled:
make realCopy kernel8.img to an SD card (replace the stock one on a fresh Raspberry Pi OS image, or use a minimal boot setup).
On Pi 4/5, disable Bluetooth if using PL011 on GPIO 14/15:
Add to config.txt:
dtoverlay=disable-bt
Boot the Pi — output appears on the serial console (3.3V TTL USB adapter on GPIO 14/15).
Feel free to open issues, suggest features, or submit pull requests. This is an educational project, so clean, well-commented code and explanations are highly valued.
MIT License — see LICENSE for details.