(Designed for COMP22111 STUMP Board)
STUMP OS is a fully functional, from-scratch operating system written in pure assembly for the University of Manchester’s STUMP teaching board (second year) using the StumpOS ISA.
It demonstrates almost every classic OS concept that is possible under the extreme hardware constraints:
- 16-bit address space (0x0000 – 0x1FFF = 8 KB total writable RAM)
- No MMU / memory protection
- No hardware interrupts whatsoever (purely cooperative multitasking)
- No secondary storage, no serial loader, no network → all programs are statically linked at compile time
Despite these limitations, the OS still provides a surprisingly rich environment.
| Category | Feature | Notes |
|---|---|---|
| Boot & Kernel | Full reset → boot melody → clean peripheral state | Plays a short 5-note jingle on startup |
| Kernel PCB + per-process 64-word stack | Fixed stack size (0x40 words) | |
Cooperative scheduler via yield() |
Processes must voluntarily yield | |
| Context switching (full register save/restore) | Including proper kernel stack handling | |
| Memory Management | sys_malloc() / sys_free() with first-fit + splitting + coalescing on free |
Full adjacent-block merging |
| Tiny heap (≈ 4-5 KB usable after code & static data) | ||
| Device Arbitration | Mutex-per-peripheral with bounded stack (force-claim evicts oldest claimant) | Prevents two processes fighting over LCD, LED matrix, buzzer, etc. |
sys_force_claim, sys_check_claim, automatic relinquish on kill/exit |
||
| Syscalls | enter, yield, exit, kill, malloc, free, all peripheral wrappers |
All implemented via syscall table |
| LCD Driver (4×20) | lcd_putc_at, lcd_puts_at, lcd_puts_center, lcd_clear_line, lcd_clear |
Bounds-checked, centred text, selective redraw |
| LED Matrix (8×8) | Full clear + row-write primitive → used for smooth sine-wave animation | |
| Buzzer | Blocking note & melody player (duration + octave + note encoding) | Used for boot sound and Rickroll demo |
| RTC | Full rtc_read() with BCD → binary conversion, 12/24-hour mode support |
|
| Input | Switch buttons (SW-A to SW-G) with software debounce | Reliable navigation |
| UI / Launcher | Paginated program selector (Page X of Y) | Shows program title + current status (INACTIVE / PAUSED / RUNNING) |
| Controls: SW-A ← SW-C → SW-E Start SW-F Pause/Resume SW-G Kill | Very intuitive once you know the mapping | |
| Smart redraw – only updates changed lines | Reduces flicker | |
| Demo Programs | 1. Matrix Animation – smooth moving sine wave on LED matrix | Yields every few frames |
| 2. Buzzer Song – loops a non-blocking “Never Gonna Give You Up” (Rickroll) | Claims buzzer exclusively | |
| 3. Timer – User inputted coutdown (HH:MM:SS) updated from the RTC and displayed on the LCD | Updates once per second | |
| 4. Reset Button – waits for any spartan button press → goes to boot init | Useful for demos | |
| 5. Panic / Crash Demo – deliberate kernel panic screen + distress melody | Shows panic handler in action | |
| 6. Firework program - waits for user input and creates a "firework" on the led matrix | Dynamic allocation and animation | |
| Utilities | strlen, strcpy, i_to_str, multiply, modulo, shift_left, bitwise not |
All hand-rolled in assembly |
More information about the demo programs can be found in the implementation files as well as in the User Program Documentation
| Limitation | Reason / Consequence |
|---|---|
| Only 8 KB total RAM (0x0000–0x1FFF) | Code + static data + heap + all process stacks must fit → very tight memory budget |
| No MMU / memory protection | Any process can corrupt kernel or other processes if buggy |
| No hardware interrupts | Purely cooperative scheduling → a process that forgets to yield starves everything |
| No preemption | Long-running or infinite loops without yield will freeze the entire system |
| Fixed number of processes | Program table is static; no way to load new binaries at runtime |
| No dynamic linking or loading | No storage or communication channel → all programs compiled in |
| Blocking peripheral calls | Buzzer melodies block the entire CPU until finished |
| Fixed mutex stack depth | When full, force_claim silently evicts the oldest user (FIFO) |
| No file system, no persistent storage | Obviously impossible on this hardware |
| No power management | Always running at full speed |
| No floating-point or advanced math | Everything done with 16-bit integer arithmetic |
| Heap can fragment | Repeated malloc/free of varying sizes will eventually waste space |
STUMP OS has defined: r6 to always be the stack pointer
For system calls: r1 - r3 being inputs r4 is the system call id
More information on system calls can be found in the System Call Documentation
The stack pointer is defined as r6 and since it is allocated via the heap it can be dangerous to use since it may overflow and corrupt the next heap header (and cause undefined behaviour)
The stack is quite unconventional and grows from low addressess to high. The sp points to the (filled) head of the stack
To push:
- increment the sp by one
- store the value
To pop:
- decrement the sp by one
- ld rx [sp, #1]
Given the extreme constraints (8 KB RAM, no interrupts, no MMU), STUMP OS pushes the STUMP platform to its absolute limits and successfully demonstrates almost every fundamental OS concept that is physically possible on this hardware.
It boots, multitasks, allocates memory dynamically, arbitrates shared devices safely, and provides a usable UI with multiple concurrent demo applications — all in under 8 KB of painfully hand-written assembly.
Enjoy the Rickroll.
(You have been successfully operating-system'd.)