A simple RISC-V emulator
Find a file
2024-12-19 00:50:10 +00:00
example Add a timer device 2024-12-19 00:50:10 +00:00
src Add a timer device 2024-12-19 00:50:10 +00:00
test Fix the RVMODEL_HALT macro (not sure how it worked before) 2024-12-17 01:58:22 +00:00
.clang-format Add clangd and clang-format configs 2024-12-09 00:48:40 +00:00
.clangd Add clangd and clang-format configs 2024-12-09 00:48:40 +00:00
.gitignore Add RISCOF test suite (doesn't function yet) 2024-12-15 13:50:18 +00:00
CMakeLists.txt Implement loading of ELF files 2024-12-10 17:32:33 +00:00
flake.lock Run RISCOF test suite via nix on normal builds 2024-12-16 23:20:53 +00:00
flake.nix Run RISCOF test suite via nix on normal builds 2024-12-16 23:20:53 +00:00
README.md Implement reporting current file path to GDB 2024-12-10 17:49:19 +00:00
rve.nix Run RISCOF test suite via nix on normal builds 2024-12-16 23:20:53 +00:00

A simple RISC-V emulator

This is a toy emulator for RISC-V, made for educational purposes. The goal is to have a base rv32i instruction set (the bare minimum) plus a M-extension for division and multiplication. It is capable of running normal ELF binaries produced by compiling C programs with GCC. It also has support for attaching the GDB debugger to the GDB stub port, so you can debug your programs running in the virtual machine.

The code is small and compact on purpose, to make the implementation easy to understand.

Compiling and running

You'd need nix package manager in order to build the project. This is because installing cross-toolchain to compile an example project is difficult, and I don't know of other ways except nix that make it easy.

If you don't have it, install it like this:

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install

Now, to build the emulator:

nix develop

eval "$configurePhase"
ninja

As a result you should get an executable called rve

Cross-toolchain and an example program in C

There is an example program which you can compile. It requires some custom toolchain so currently not built with CMake. To compile it:

cd example
make

As a result, you'll get an example binary. To execute it:

./rve ../example/example

The expected output of the example program is 40320.

Debugging programs under GDB

The virtual machine contains an implementation of GDB stub protocol. To run the program in debug mode, execute:

./rve --debug ../example/example

The program would load, and stop at first instruction. It will then prompt you to connect the debugger. Then run riscv32-none-elf-gdb, and in the gdb prompt, type:

target remote :1234

From now on, you can set breakpoints, examine variables, registers and memory as you would expect under GDB.