# minos — a minimal multi-arch kernel One tiny OS core, three ISAs: **x86 (i386)**, **RISC-V (rv64)**, **ARM (Cortex-A9 / Zynq-7000)**. Built by a single `clang` in parallel so you can compare how the same C behaves across architectures. Milestone **M1** (this state): each target boots, brings up its UART, sets its interrupt/trap vector, and prints a banner from shared C (`kmain`). ## Design The only boundary is a small per-arch **contract** (`include/arch.h`): ``` arch_early_init() bring up the UART arch_uart_putc(c) emit one byte arch_set_trap_vector() install IDT / mtvec / VBAR arch_name() banner string arch_halt() hlt / wfi ``` Everything in `common/` is portable C and calls only that contract. Each `arch//` supplies the irreducible assembly (`boot.S`, trap/vector table) plus a C file implementing the contract and a linker script. ``` common/ main.c (kmain), console.c (putc/puts/puthex) include/ arch.h (the contract), console.h arch/x86/ boot.S (multiboot) arch.c (COM1 0x3F8, IDT) link.ld (1 MiB) arch/riscv/ boot.S (_start) trap.S (mtvec) arch.c (UART 0x10000000) arch/arm/ boot.S (_start) vectors.S (VBAR) arch.c (Cadence UART 0xE0000000) ``` ## Build & run ```sh make -j # build all three in parallel make run-x86 # boot under QEMU (Ctrl-A X to quit) make run-riscv make run-arm make sizes # compare stripped binary size make clean ``` ## The interesting comparison (M1) | Aspect | x86 (i386) | RISC-V (rv64) | ARM (Cortex-A9) | |-------------------|-------------------------|-----------------------|--------------------------| | Entry protocol | Multiboot1 header | `_start` @ 0x80000000 | `_start` @ DDR | | Console | port I/O `outb` 0x3F8 | MMIO 16550 0x10000000 | MMIO Cadence 0xE0000000 | | Trap vector | IDT via `lidt` | `mtvec` CSR | `VBAR` (CP15) | | Multi-core gate | (single by default) | `mhartid` check | `MPIDR` check | | Halt | `hlt` | `wfi` | `wfi` | | Idle byte size | ~890 | ~816 | ~800 | ## Real hardware (next) - **RISC-V**: the only change is the UART base — `0x10000000` (QEMU virt) → `0x02500000` (Allwinner D1 / Lichee RV). Loadable via `xfel`. - **ARM/Zynq**: same Cadence UART base as the real PS; boot via U-Boot/JTAG. - **x86**: boot the multiboot ELF from GRUB. ## Roadmap - **M2**: real trap handlers + a timer tick per arch. - **M3**: expose a tiny syscall-style interface (the "own interface").