Add BIOS and tiny kernel roadmap phases
This commit is contained in:
+12
-10
@@ -27,13 +27,15 @@ is to explain what to learn, what to verify, and what mistakes to avoid.
|
||||
- [Phase 6 - Load/Store](phase-06-load-store/phase-06.md)
|
||||
- [Phase 7 - Memory-Mapped UART](phase-07-uart-mmio/phase-07.md)
|
||||
- [Phase 8 - GCC Toolchain Integration](phase-08-gcc-toolchain/phase-08.md)
|
||||
- [Phase 9 - CSRs + M-Mode Traps](phase-09-csrs-traps/phase-09.md)
|
||||
- [Phase 10 - Timer](phase-10-timer/phase-10.md)
|
||||
- [Phase 11 - Interrupt Controller](phase-11-interrupt-controller/phase-11.md)
|
||||
- [Phase 12 - Atomics](phase-12-atomics/phase-12.md)
|
||||
- [Phase 13 - Pipeline](phase-13-pipeline/phase-13.md)
|
||||
- [Phase 14 - SPI Flash + DRAM](phase-14-flash-dram/phase-14.md)
|
||||
- [Phase 15 - M/S/U + Sv32](phase-15-privilege-sv32/phase-15.md)
|
||||
- [Phase 16 - Linux Boot Contract](phase-16-linux-boot-contract/phase-16.md)
|
||||
- [Phase 17 - Linux](phase-17-linux/phase-17.md)
|
||||
|
||||
- [Phase 9 - GCC-Built BIOS / Serial Monitor](phase-09-bios-monitor/phase-09.md)
|
||||
- [Phase 10 - Minimal ELF Loader](phase-10-elf-loader/phase-10.md)
|
||||
- [Phase 11 - Tiny Kernel + Command Shell](phase-11-tiny-kernel/phase-11.md)
|
||||
- [Phase 12 - CSRs + M-Mode Traps](phase-12-csrs-traps/phase-12.md)
|
||||
- [Phase 13 - Timer](phase-13-timer/phase-13.md)
|
||||
- [Phase 14 - Interrupt Controller](phase-14-interrupt-controller/phase-14.md)
|
||||
- [Phase 15 - Atomics](phase-15-atomics/phase-15.md)
|
||||
- [Phase 16 - Pipeline](phase-16-pipeline/phase-16.md)
|
||||
- [Phase 17 - SPI Flash + DRAM](phase-17-flash-dram/phase-17.md)
|
||||
- [Phase 18 - M/S/U + Sv32](phase-18-privilege-sv32/phase-18.md)
|
||||
- [Phase 19 - Linux Boot Contract](phase-19-linux-boot-contract/phase-19.md)
|
||||
- [Phase 20 - Linux](phase-20-linux/phase-20.md)
|
||||
|
||||
@@ -27,7 +27,7 @@ more than minimizing cycles.
|
||||
|
||||
- Write a cycle-by-cycle timeline for a simple `addi` instruction.
|
||||
- Write a cycle-by-cycle timeline for a multiply/divide instruction.
|
||||
- Confirm the pre-Phase 9 illegal-instruction behavior: halt the core and expose
|
||||
- Confirm the pre-Phase 12 illegal-instruction behavior: halt the core and expose
|
||||
the offending PC and instruction word to the testbench.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
@@ -27,7 +27,7 @@ every emitted instruction is implemented or fails loudly.
|
||||
|
||||
- Compare C source to generated assembly.
|
||||
- Identify every load/store used for UART access.
|
||||
- Confirm no CSR or `fence.i` instructions appear before Phase 9.
|
||||
- Confirm no CSR or `fence.i` instructions appear before Phase 12.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
# Phase 9 - GCC-Built BIOS / Serial Monitor
|
||||
|
||||
## Context
|
||||
|
||||
This phase turns the GCC bring-up work into a persistent interactive firmware. The
|
||||
CPU boots into a small monitor instead of a one-off test program.
|
||||
|
||||
## Goals
|
||||
|
||||
- Build a freestanding C/assembly BIOS with its own linker script and startup code.
|
||||
- Provide a UART command prompt.
|
||||
- Add simple commands for memory inspection, loading, and jumping to test payloads.
|
||||
|
||||
## New Concepts
|
||||
|
||||
- Monitor: small firmware that lets you inspect and control a machine interactively.
|
||||
- Command parser: text interface that maps typed commands to firmware functions.
|
||||
- Firmware ABI: the calling convention and data contract between loaded code and BIOS.
|
||||
- Executable RAM window: memory that software can write and the fetch path can execute.
|
||||
|
||||
## How To Think About It
|
||||
|
||||
The BIOS is both a milestone and a tool. Keep it boring and reliable: UART in, UART out,
|
||||
explicit commands, clear error messages, and no hidden dependencies on host tooling.
|
||||
|
||||
## Learning Tasks
|
||||
|
||||
- Decide where UART-loaded code can live and how the I-bus fetches it.
|
||||
- Define a tiny BIOS call table for console I/O and returning to the monitor.
|
||||
- Write down the exact register state expected by `run <addr>`.
|
||||
- Add commands one at a time and test each on hardware.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Loading code into data memory that the instruction fetch path cannot see.
|
||||
- Letting a failed command corrupt the monitor's own stack or globals.
|
||||
- Building a clever shell before the load/run/debug basics work.
|
||||
|
||||
## Tooling And Testing
|
||||
|
||||
- Test the monitor in simulation with scripted UART input where practical.
|
||||
- Use a terminal program that can send raw files without changing line endings.
|
||||
- Keep a known-good tiny payload that prints one line and returns to the monitor.
|
||||
|
||||
## References
|
||||
|
||||
- RISC-V ELF psABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc
|
||||
- GNU linker scripts: https://sourceware.org/binutils/docs/ld/Scripts.html
|
||||
- OSDev bare bones background: https://wiki.osdev.org/Bare_Bones
|
||||
@@ -0,0 +1,51 @@
|
||||
# Phase 10 - Minimal ELF Loader
|
||||
|
||||
## Context
|
||||
|
||||
This phase lets the BIOS receive GCC-built programs as ELF files and run them without
|
||||
rebuilding the FPGA bitstream.
|
||||
|
||||
## Goals
|
||||
|
||||
- Parse enough ELF32 to recognize RISC-V executable files.
|
||||
- Load `PT_LOAD` segments into memory and zero BSS.
|
||||
- Jump to `e_entry` with a fixed tiny-program ABI.
|
||||
|
||||
## New Concepts
|
||||
|
||||
- ELF header: file-level metadata describing architecture, entry point, and tables.
|
||||
- Program header: runtime load description used by loaders.
|
||||
- `PT_LOAD`: segment that must be copied into memory before execution.
|
||||
- BSS: zero-initialized memory represented by `memsz > filesz`.
|
||||
|
||||
## How To Think About It
|
||||
|
||||
Do not build a general-purpose dynamic loader. Build a strict loader for the exact
|
||||
firmware shape you produce: static, little-endian, non-relocatable RV32 ELF files with
|
||||
fixed physical addresses.
|
||||
|
||||
## Learning Tasks
|
||||
|
||||
- Read the ELF header fields needed to reject unsupported files.
|
||||
- Map `p_paddr` or `p_vaddr` to your executable memory window.
|
||||
- Define the stack pointer and argument registers at program entry.
|
||||
- Decide how a loaded program returns a status code to the BIOS.
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Trusting malformed ELF offsets or sizes.
|
||||
- Forgetting to zero the BSS tail of a loadable segment.
|
||||
- Accidentally accepting relocatable or dynamically linked binaries.
|
||||
- Loading a segment over the BIOS itself.
|
||||
|
||||
## Tooling And Testing
|
||||
|
||||
- Use `readelf -h -l` and `objdump -d` on every early payload.
|
||||
- Start with one fixed link address and one loadable segment.
|
||||
- Add loud rejection messages for unsupported ELF class, endianness, machine, or type.
|
||||
|
||||
## References
|
||||
|
||||
- ELF specification overview: https://refspecs.linuxfoundation.org/elf/elf.pdf
|
||||
- RISC-V ELF psABI: https://github.com/riscv-non-isa/riscv-elf-psabi-doc
|
||||
- GNU binutils `readelf` documentation: https://sourceware.org/binutils/docs/binutils/readelf.html
|
||||
@@ -0,0 +1,50 @@
|
||||
# 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/
|
||||
@@ -1,4 +1,4 @@
|
||||
# Phase 9 - CSRs + M-Mode Trap Handling
|
||||
# Phase 12 - CSRs + M-Mode Trap Handling
|
||||
|
||||
## Context
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Phase 10 - Timer
|
||||
# Phase 13 - Timer
|
||||
|
||||
## Context
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Phase 11 - Interrupt Controller
|
||||
# Phase 14 - Interrupt Controller
|
||||
|
||||
## Context
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Phase 12 - A Extension
|
||||
# Phase 15 - A Extension
|
||||
|
||||
## Context
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Phase 13 - Pipeline
|
||||
# Phase 16 - Pipeline
|
||||
|
||||
## Context
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Phase 14 - SPI Flash Boot + DRAM
|
||||
# Phase 17 - SPI Flash Boot + DRAM
|
||||
|
||||
## Context
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Phase 15 - S-Mode, U-Mode, Sv32 Virtual Memory
|
||||
# Phase 18 - S-Mode, U-Mode, Sv32 Virtual Memory
|
||||
|
||||
## Context
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Phase 16 - Linux Boot Contract
|
||||
# Phase 19 - Linux Boot Contract
|
||||
|
||||
## Context
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Phase 17 - Linux
|
||||
# Phase 20 - Linux
|
||||
|
||||
## Context
|
||||
|
||||
Reference in New Issue
Block a user