Installing a RISC-V GCC embedded compiler
$ xpm install --global @ xpack-dev-tools / riscv-none-embed-gcc @ latest
See more here:https: // gnu-mcu-eclipse .github.io / install /
Installing a RISC-V GCC linux compiler
To get C exceptions and other things, you will need a (limited) Linux userspace environment. You will need to build this cross-compiler yourself:
git clone https://github.com/riscv/riscv-gnu-toolchain.git cd riscv-gnu-toolchain ./configure --prefix=$ HOME / riscv --with-arch=rv 32 gc --with-abi=ilp 32 make -j4
This will build a newlib cross-compiler with C exception support.
Note how the ABI is ilp 32 and not ilp 32 d, which requires full floating- point support. Support will be added later on, and is instead emulated by the compiler.
Note that if you want a full glibc cross-compiler instead, simply appendinglinux
to the make command will suffice, like so:make linux
. Glibc is harder to support, and produces larger binaries, but will be more performant.
Building and running test program
From one of the binary subfolders:
$ ./build.sh
Which will produce ahello_world
binary in the sub-projects build folder.
Building the emulator (starting from project root) and booting the newlibhello_world
:
mkdir -p buildcdbuild cmake ..&&make -j4 ./remu ../binaries/newlib/build/hello_world
Building and running your own ELF files that can run in freestanding RV 32 IM is quite challenging, so consult the hello world example! It’s a bit like booting on bare metal using multiboot, except you have easier access to system functions.
The newlib ELF files have much more C and C support, but still misses things like environment variables and such. This is a deliberate design as newlib is intended for embedded development.
Instruction set support
The emulator currently supports RV 32 IM, however the foundation is laid for RV 64 IM. Eventually RV 32 C extension will also be supported (compressed).
Usage
Load a binary and let the machine simulate from_ start
(ELF entry-point):
#includelibriscv / machine.hpp>templateintW>longsyscall_exit(riscv :: Machine& machine) {printf(">>>Program exit (% d) n", machine.cpureg(riscv :: RISCV :: REG_ARG0)); machine.stop();return0; }int(main) ********************** (intargc,constchar** argv) {const(auto) ********************** (binary=) ; riscv :: Machine<:riscv32>machine {binary};//install a system call handlermachine.install_syscall_handler93, syscall_exit<:riscv32>);while(! machine.stopped()) { machine.simulate(); } }
You can find details on the Linux system call ABI online as well as in thesyscall .h
header in the src folder. You can use this header to make syscalls from your RISC-V programs. It is the Linux RISC-V syscall ABI.
Be careful about modifying registers during system calls, as it may cause problems in the simulated program.
GIPHY App Key not set. Please check settings