Jikei (慈恵, "charity") is a RISC-V microkernel built from scratch in Rust, targeting QEMU's virt machine. Boots under OpenSBI in S-mode, implements Sv39 paging, preemptive scheduling across multiple harts, and seL4-style synchronous IPC endpoints.
An accompanying tutorial walks through the kernel chapter by chapter, from bare-metal boot to capability-based design.
- Supervisor-mode kernel running under OpenSBI on
riscv64gc - Sv39 virtual memory with per-process page tables and a W^X kernel identity map
- Buddy frame allocator for physical 4 KiB pages
- Preemptive multitasking with timer-driven scheduling
- SMP support — boots secondary harts via SBI, each running its own scheduler loop
- User-mode processes with isolated address spaces and a trap trampoline
- Synchronous endpoint IPC — sender and receiver rendezvous with zero-copy register transfer
- Syscall interface —
ecall-based ABI for exit, sleep, yield, putchar, and endpoint operations
- Rust with the
riscv64gc-unknown-none-elftarget qemu-system-riscv64
cargo build --release
cargo run --release # launches QEMU with the kernelThe repository is a Cargo workspace, and the root Cargo.lock pins the kernel dependencies. The Cargo runner is preconfigured in .cargo/config.toml to start QEMU with 256 MB RAM, 4 harts, and OpenSBI as the default BIOS.
.cargo/
config.toml # RISC-V target, linker script, and QEMU runner
kernel/
boot.S # entry point — saves hartid, sets stack, zeroes .bss
link.ld # linker script, loads at 0x80200000
src/
main.rs # kernel_main, module declarations
boot/ # FDT parsing, subsystem init, secondary hart startup
demo.rs # embedded user programs (inline assembly)
endpoint.rs # seL4-style IPC endpoints (send/receive matching)
memory/ # buddy frame allocator + kernel heap
paging/ # Sv39 page tables, kernel map, trampoline mapping
sched/ # scheduler loop, process table, syscall dispatch, timer
trap/ # trap frame, user/kernel trap handling, trampoline asm
utils/ # console I/O, SBI calls, linker symbols, panic handler
docs/ # internal design notes
tutorial/ # Starlight (Astro) site — the companion tutorial
User code invokes syscalls via ecall with a7 = syscall number:
| Number | Name | Arguments | Return |
|---|---|---|---|
| 1 | SYS_EXIT |
— | does not return |
| 2 | SYS_SLEEP |
a0 = milliseconds |
returns after sleep |
| 3 | SYS_YIELD |
— | returns when rescheduled |
| 10 | SYS_EP_CREATE |
— | a0 = endpoint ID |
| 11 | SYS_EP_SEND |
a0 = endpoint, a1/a2 = message |
a0 = 0 |
| 12 | SYS_EP_RECV |
a0 = endpoint |
a0/a1 = message |
| 100 | SYS_PUTCHAR |
a0 = byte |
— |
The tutorial/ directory contains a chapter-by-chapter guide that builds the kernel incrementally:
- Boot — bare-metal M-mode with
-bios none, UART, linker layout - OpenSBI — move to S-mode, SBI calls
- Memory — physical frame allocator
- Paging — Sv39 page tables, kernel identity map
- Traps —
stvec, trap frame, user/kernel transitions - Processes — user address spaces, ELF-less embedded programs
- Scheduling — preemptive round-robin, SMP
- IPC — synchronous endpoint rendezvous
- TODO: Capabilities — unforgeable access tokens (in progress)
To run the tutorial site locally:
cd tutorial
npm install
npm run dev