An open-source entry in TopGit's GitHub warehouse: cnlohr/mini-rv32ima, 2.2k stars, C. A tiny C header-only risc-v emulator.
Snapshot summary built from the project's own GitHub metadata — there's no written TopGit review yet. The page will update automatically when a full review is published.
WHY NO REVIEW YET
TopGit writes full reviews for the most-starred, most-requested repositories. This page is a snapshot until then — see the READ ME tab for the original README in full.
Click below for the YouTube video introducing this project:
What
mini-rv32ima is a single-file-header, mini-rv32ima.h, in the STB Style library that:
Implements a RISC-V rv32ima/Zifencei†+Zicsr (and partial su), with CLINT and MMIO.
Is about 400 lines of actual code.
Has no dependencies, not even libc.
Is easily extensible. So you can easily add CSRs, instructions, MMIO, etc!
Is pretty performant. (~450 coremark on my laptop, about 1/2 the speed of QEMU)
Is human-readable and in basic C code.
Is "incomplete" in that it didn't implement the tons of the spec that Linux doesn't (and you shouldn't) use.
Is trivially embeddable in applications.
It has a demo wrapper that:
Implements a CLI, SYSCON, UART, DTB and Kernel image loading.
And it only around 250 lines of code, itself.
Compiles down to a ~18kB executable and only relies on libc.
†: Zifence+RV32A are stubbed. So, tweaks will need to be made if you want to emulate a multiprocessor system with this emulator.
Just see the mini-rv32ima folder.
It's "fully functional" now in that I can run Linux, apps, etc. Compile flat binaries and drop them in an image.
Why
I'm working on a really really simple C Risc-V emulator. So simple it doesn't even have an MMU (Memory Management Unit). I have a few goals, they include:
Furthering RV32-NOMMU work to improve Linux support for RV32-NOMMU. (Imagine if we could run Linux on the $1 ESP32-C3)
Learning more about RV32 and writing emulators.
Being further inspired by @pimaker's amazing work on Running Linux in a Pixel Shader and having the sneaking suspicion performance could be even better!
Hoping to port it to some weird places.
Understand the most simplistic system you can run Linux on and trying to push that boundary.
Continue to include my education of people about assembly language.
How
Windows instructions (Just playing with the image)
Clone this repo.
Install or have TinyCC. Powershell Installer or Regular Windows Installer
Run winrun.ps in the windows folder.
WSL (For full toolchain and image build:
You will need to remove all spaces from your path i.e. export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/system32:/snap/bin and continue the instructions. P.S. What in the world was Windows thinking, putting a space between "Program" and "Files"??!?
Linux instructions (both):
Clone this repo.
Install git build-essential and/or whatever other requirements are in place for buildroot.
make testdlimage
It automatically downloads the image (~1MB) and runs the emulator.
Should be up and running in about 2.5s depending on internet speed.
You can do in-depth work on Linux by:
make everything
If you want to play with the bare metal system, see below, or if you have the toolchain installed, just:
make testbare
If you just want to play emdoom, and use the prebuilt image:
On Windows, run windows\winrundoom.ps1
On Linux, cd mini-rv32ima, and type make testdoom
Questions?
Why not rv64?
Because then I can't run it as easily in a pixel shader if I ever hope to.
Can I add an MMU?
Yes. It actually probably wouldn't be too difficult.
Should I add an MMU?
No. It is important to further support for nommu systems to empower minimal Risc-V designs!
Everything else: Contact us on my Discord: https://discord.com/invite/CCeyWyZ
How do I use this in my own project?
You shoud not need to modify mini-rv32ima.h, but instead, use mini-rv32ima.c as a template for what you are trying to do in your own project.
You can override all functionality by defining the following macros. Here are examples of what mini-rv32ima.c does with them. You can see the definition of the functions, or augment their definitions, by altering mini-rv32ima.c.
Macro
Definition / Comment
MINIRV32WARN( x... )
printf( x ); Warnings emitted from mini-rv32ima.h
MINIRV32_DECORATE
static How to decorate the functions.
MINI_RV32_RAM_SIZE
ram_amt A variable, how big is system RAM?
MINIRV32_IMPLEMENTATION
If using mini-rv32ima.h, need to define this.
MINIRV32_POSTEXEC( pc, ir, retval )
{ if( retval > 0 ) { if( fail_on_all_faults ) { printf( "FAULT\n" ); return 3; } else retval = HandleException( ir, retval ); } } If you want to execute something every time slice.
MINIRV32_HANDLE_MEM_STORE_CONTROL( addy, val )
if( HandleControlStore( addy, val ) ) return val; Called on non-RAM memory access.
MINIRV32_HANDLE_MEM_LOAD_CONTROL( addy, rval )
rval = HandleControlLoad( addy ); Called on non-RAM memory access return a value.
MINIRV32_OTHERCSR_WRITE( csrno, value )
HandleOtherCSRWrite( image, csrno, value ); You can use CSRs for control requests.
MINIRV32_OTHERCSR_READ( csrno, value )
value = HandleOtherCSRRead( image, csrno ); You can use CSRs for control requests.
Hopeful goals?
Further drive down needed features to run Linux.
Remove need for RV32A extension on systems with only one CPU.
Support for relocatable ELF executables.
Add support for an unreal UART. One that's much simpler than the current 8250 driver.
Maybe run this in a pixelshader too!
Get opensbi working with this.
Be able to "embed" rv32 emulators in random projects.
Can I use early console to be a full system console?
Can I increase the maximum contiguous memory allocatable?
Special Thanks
For @regymm and their patches to buildroot and help!
callout: Regymm's quazisoc project.
Buildroot (For being so helpful).
@vowstar and their team working on k210-linux-nommu.
This guide
rvcodecjs I probably went through over 1,000 codes here.
@splinedrive from the KianV RISC-V noMMU SoC project.
More details
If you want to build the kernel yourself:
make everything
About 20 minutes. (Or 4+ hours if you're on Windows Subsytem for Linux 2)
And you should be dropped into a Linux busybox shell with some little tools that were compiled here.
Emdoom notes
Emdoom building is in the experiments/emdoom folder
You MUST build your kernel with MAX_ORDER set to >12 in buildroot/output/build/linux-5.19/include/linux/mmzone.h if you are building your own image.
You CAN use the pre-existing image that is described above.
On Windows, it will be very slow. Not sure why.
If you want to use bare metal to build your binaries so you don't need buildroot, you can use the rv64 gcc in 32-bit mode built into Ubuntu 20.04 and up.
sudo apt-get install gcc-multilib gcc-riscv64-unknown-elf make
Links
"Hackaday Supercon 2022: Charles Lohr - Assembly in 2022: Yes! We Still Use it and Here's Why" : https://www.youtube.com/watch?v=Gelf0AyVGy4
cd riscv-tests
export CROSS_COMPILE=riscv64-linux-gnu-
export PLATFORM_RISCV_XLEN=32
CC=riscv64-linux-gnu-gcc ./configure
make XLEN=32 RISCV_PREFIX=riscv64-unknown-elf- RISCV_GCC_OPTS="-g -O1 -march=rv32imaf -mabi=ilp32f -I/usr/include"
Building OpenSBI
(This does not currently work!)
cd opensbi
export CROSS_COMPILE=riscv64-unknown-elf-
export PLATFORM_RISCV_XLEN=32
make
Extra links
Clear outline of CSRs: https://five-embeddev.com/riscv-isa-manual/latest/priv-csrs.html
Fonts used in videos: https://audiolink.dev/
Using custom build
Where yminpatch is the patch from the mailing list.
rm -rf buildroot
git clone git://git.buildroot.net/buildroot
cd buildroot
git am < ../yminpatch.txt
make qemu_riscv32_nommu_virt_defconfig
make
# Or use our configs.
Note: For emdoom you will need to modify include/linux/mmzone.h and change MAX_ORDER to 13.
TopGit's last sync did not record any GitHub topics for cnlohr/mini-rv32ima. GitHub topics appear in the right sidebar of a repository page; that's the authoritative place to check.
How active is development on cnlohr/mini-rv32ima?
The most recent commit recorded on cnlohr/mini-rv32ima was 8 months ago, based on the GitHub push timestamp. The repository has 168 forks — one of the better signals of community interest.
How many stars does cnlohr/mini-rv32ima have?
cnlohr/mini-rv32ima has 2.2k GitHub stars — refresh the page for the live number, or check github.com/cnlohr/mini-rv32ima. TopGit mirrors GitHub's count but does not claim minute-by-minute accuracy.
What language is cnlohr/mini-rv32ima written in?
cnlohr/mini-rv32ima is written primarily in C. GitHub's language field is based on the largest share of bytes in the default branch.
Where do I read more about cnlohr/mini-rv32ima?
This TopGit page is a snapshot — the READ ME tab shows the project's own README content (links stripped, images preserved). The GitHub repository at github.com/cnlohr/mini-rv32ima is the definitive source.
Read full README in the tab above.
Still deciding about mini-rv32ima?
One click hands the question to an AI along with this page — see what it says about mini-rv32ima.