riscemu is a minimal RISC-V emulator written in Rust. It currently supports only the RV32I instruction set.
fn main() {
let cpu = Cpu::default();
let mem = Memory::default();
let mut machine = Machine { cpu, mem };
// Load an ELF program at a given base address.
// 0x10000 can be used for Position Independent Executables.
// Otherwise, you can use 0x0 as the base.
machine.load_elf("path_to_elf", 0x10000).unwrap();
machine.step_on(); // Run the program
machine.inspect_cpu(); // Inspect CPU registers
machine.inspect_mem(); // Inspect memory content
}
This is a very minimal implementation, done as a side project. Many behaviors of a real RISC-V CPU are not implemented, and it is intended only for experimenting with small programs.
Some functions like inspect_cpu()
or inspect_mem()
are not fully developed yet.
If you find errors or want to contribute improvements, please open an issue or submit a pull request.
- Run small programs only.
- For very simple programs, there is no return address handling, so execution can be undefined. We use
ecall
to trap the CPU and inspect results.
Example: computing the Fibonacci sequence:
int main() {
int n = 10;
int a = 0;
int b = 1;
int c = 0;
for (int i = 2; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
// Store the syscall ID (93 = exit) and result in RISC-V registers
register int syscall_id asm("a7") = 93; // exit syscall
register int code asm("a0") = b; // exit code = Fibonacci(n)
asm volatile("ecall" : : "r"(syscall_id), "r"(code) : "memory");
// The following instructions are not executed.
// When inspecting the CPU, you can find `b` stored in `a0 (x10)`
return b;
}
To run programs on riscemu, cross-compile using a RISC-V toolchain (unless you're already on a RISC-V machine). Example:
riscv64-linux-gnu-gcc -march=rv32i -mabi=ilp32 -nostdlib -nostartfiles \
-Wl,-e,main -static -Ttext=0x0 fibo_rec.c -o fibo_rec.elf
Notes:
-nostdlib
and-nostartfiles
disable standard library and startup code.-Wl,-e,main
sets the ELF entry point to themain
function.-Ttext=0x0
sets the program load base address. Adjust if using position-independent code.