# Phase 11 - Tiny Kernel + Command Shell ## Context This phase builds an OS-shaped firmware payload before the project moves into traps, interrupts, privilege, DRAM, and Linux. ## Goals - Load a separate GCC-built kernel ELF from the BIOS. - Provide a kernel-owned command shell. - Run tiny trusted ELF programs through a simple service table. ## New Concepts - Kernel: central program that owns machine services. Before traps, this is still trusted bare-machine firmware, not an isolated privileged OS. - Service table: function-pointer ABI for console I/O, exit, and simple utilities. - Bump allocator: simple allocator that hands out memory linearly. - Program table: small kernel data structure tracking loaded payloads. ## How To Think About It The goal is a complete loop, not a Unix clone: compile a tiny program on the host, send it over UART, load it as ELF, run it on the CPU, and return to the shell. ## Learning Tasks - Decide whether kernel console I/O calls the BIOS or drives UART directly. - Define the tiny-program ABI: entry registers, stack, service table, and return path. - Implement the smallest useful allocator. - Add shell commands that expose real machine state, not decorative output. ## Pitfalls - Pretending trusted payloads are isolated before traps and privilege modes exist. - Growing the kernel into a second large project too early. - Hiding loader or ABI bugs behind ad hoc special cases. ## Tooling And Testing - Keep kernel and user-payload linker scripts separate. - Build a tiny test suite of loaded programs: hello, echo, memory copy, return status. - Run the same payloads after Phase 12 trap handling lands to catch ABI regressions. ## References - OSDev kernel structure notes: https://wiki.osdev.org/Kernel - RISC-V calling convention: https://github.com/riscv-non-isa/riscv-elf-psabi-doc - Embedded Artistry first-fit allocator background: https://embeddedartistry.com/blog/2017/02/15/implementing-malloc-first-fit-free-list/