RvRun is an emulator for RISC-V 64bit Linux programs. It is meant to run under Linux and Linux only. Tested under Gentoo, Archlinux, and Ubuntu 25.10
RvRun is an emulator for RISC-V 64bit Linux programs. It is meant to run under Linux and Linux only. Tested under Gentoo, Archlinux, and Ubuntu 25.10
on commit c6f8e8f:
Therefore, I will probably only do some small refactoring/optimizations before getting work started on the F and D extensions. I’m curious on how I can implement the floating point environment instructions, and if simply affecting the emulator’s environment is enough (after all, that’s considerably faster than saving/fetching bit masks and doing floating point operations by hand). Regardless, I probably won’t be coding in the next 4 days for personal reasons, so I’ll have lots of time to think about a good design.
It is also worth mentioning that these instructions were not included in my first ship (which while currently pending, was done at the 15th devlog). The binary on the v1.0 release only supports the base ISA (Rv64I). I’ll be making a second ship later this month, perhaps in one or two weeks, that supports all of these instructions, and maybe a few more system calls.
Log in to leave a comment
on commit 493c809:
I had some problems with shipping, but it should hopefully be fixed by now too! The people on slack are really helpful.
Log in to leave a comment
on commit 0616547:
The project has now had it’s first release (on github), and I’m going to ship it here, on flavortown, too!
Log in to leave a comment
on commit 5bbcc22:
I am now taking a look at packaging, I added install and uninstall targets to my Makefile, and will rewrite the README to better reflect where the project now is. I’m going to put a statically compiled binary on the github releases page, to make sure no problems can happen, it is about 15 times bigger than the dynamically compiled one, but still under 1Mb (there are no dependencies other than libc, after all), so no problems.
I also realized that I need a banner, so I’m thinking of making a pixelart for a logo.
Log in to leave a comment
on commit c1bf362:
I’m also thinking of what programs I should write as examples, they’ll probably be recreations of classical UNIX utilities, like cat(1), ls(1), echo(1), etc.
Log in to leave a comment
I had some problems with hacktime’s time tracking, but am finally back!
on commit fbcaefb:
Log in to leave a comment
on commit 4f3ebba:
Added a README, should have done this some time ago, but only now the project is starting to get usable. I’ll finish implementing the base ISA, perhaps add some system calls, and then release the version one.
Log in to leave a comment
on commit 1883f67:
RvRun can now interpret arguments, this might have been a bit late, but there are actual things to be set as arguments now. The currently added ones are:
Log in to leave a comment
on commit74aaa7b :
I Added all the W-type instructions, some other ones I had forgotten, and added support for file descriptor related system calls, like openat(), close(), read(), and write(). There is no open() system call on RISC-V, it is only a libc wrapper around open() (no __NR_open macro in include/uapi/asm-generic/unitsd.h under the linux kernel source code).
I am working on passing options to the emulator, writing a README, and making some examples, I’ll probably do that over the weekend. After that, there shouldn’t be that much work other than simple repetitive stuff (aka adding more instructions and more system calls)
I forgot to do the devlog earlier, so about one hour of the time being logged was actually spent adding flag support, haha.
Log in to leave a comment
on commit 1eb5f81:
I implemented ECALL, and can now emulate both exit(2) and exit_group(2) (they are both the same, as I don’t have thread support yet), with now a proper way to decide when a process exits and when it doesn’t, I implemented an actual Von Neumann cycle too.
I am going to iterate back between finishing the implementation of all Rv64I instructions, and supporting more system calls (most likely, file descriptor related ones). My objective is to support all the instructions from Rv64IMFD, and a handful of system calls, in about 2 weeks and a half.
Log in to leave a comment
on commit b264055:
I am finally back! I did some refactoring on src/proc.c yesterday, and implemented the I-type from Rv32I instructions today, I am ignoring the W variations that Rv64I adds for simplicity, I’d like to cover the most important instructions first.
I will probably start basic work on ecall next, so that I can do a real von neumann execution cycle by having an exit system call, after that, I’ll go on with the U-type, B-type, and J-type instructions, before going back to the things I ignored, and continuing with all the system calls.
I will probably change the license to GPLv2, too, and perhaps make some artwork.
Log in to leave a comment
on commit 6423204:
I can now execute all R instructions from Rv64I, except for the “*W” ones. I am downloading and building https://github.com/riscv/riscv-opcodes.git at compile time, setting this in the Makefile was a bit of a pain but I eventually got it. I will now work on some logging/debugging functions, so that I can test the instructions I add properly, and then work on the Register-Immediate instructions.
I’m not sure if I’m going to “speedrun” a hello-world, or try to support most instructions from the base ISA first, but they should both lead to the same outcome.
All of this is being done while I read the specification, and while it can get quite tedious, I feel way better in RISC-V now, I might even write my next project in raw assembly.
Log in to leave a comment
on commit 9611fd6:
I can now load and store values into memory, it respects the permissions set when loading the ELF binary, and fail gracefully both when trying to access out of bound memory or when doing invalid operations (aka writing to a read-only address). Unaligned memory access is also supported, as RISC-V allows that, even if the host machine does not support it. I decided to use C11 to allow for the _Generic macro, and enabled the _GNU_SOURCE macro to use some extensions (they weren’t needed, but I’ll be using other ones further down the road anyways).
I will now implement instruction fetching, and later the decoding
Log in to leave a comment
on commit 0e626b8:
I ended up spending the whole day thinking about how to support both 32bit and 64bit applications, I went over C11’s _Generic, void pointers, wider types + type casts, etc, but ended up realizing the best choice was to only support one. Some time was thrown away, but at the very least, I think I made a really good and important design decision, one I could not go back later.
Log in to leave a comment
on commit d7c2c71:
Finished implementing the loading of ELF segments, it felt a bit tricky at first but it turns out the format is beautifully designed.
I am using a linked list to represent the segments, it saves the RISC-V addresses it maps, a pointer to the memory that represents it, and the flags (Read/Write/Exec). I might change this design by using mmap, but I’m not sure how I would mark the address space as executable or not (since it should be executable by the emulator, not by the host OS itself). But it seems to work now, therefore I’ll leave this to a future refactor when I have a better idea of how the project as a whole should be designed.
Log in to leave a comment
Started working on my project, created the directory structure, added a license, and a Makefile. Will add README further down the road.
Had some problems making GNU Make automatically deduce prerequisites, but it eventually worked.
Log in to leave a comment