RISC-V Toolchain
There are two RISC-V toolchains that are popularly used:
- The GNU RISC-V toolchain
- The LLVM RISC-V toolchain
Both toolchains provide a state-of-the-art optimising compiler, assembler, linker, and various other tools to build applications that run on RISC-V machines.
Where to download the toolchains and simulator
The official RISC-V GitHub repository provides the source code for the riscv-gnu
toolchain, and the prebuilt toolchain can be downloaded from here.
The RISC-V compiler is generally used as a cross-compiler, as many RISC-V processors are used for low-power embedded applications. Currently, the RISC-V cross-compilers can only be run on ELF targets like Linux machines.
The RISC-V LLVM toolchain is not readily available from third-party providers, but one can build it from source by downloading the open source llvm-project. We describe an easy way to use the llvm toolchain with gnu sysroot.
The RISC-V simulator can be downloaded from the official RISC-V GitHub repository: riscv/riscv-isa-sim: Spike, a RISC-V ISA Simulator. Although RISC-V boards are readily available from several vendors, using simulators is an easy way to get started with RISC-V development.
Building Application with the Toolchain
In order to build a RISC-V application, using a cross-compiler toolchain is the same as any other cross-compiler-based development system. Two things are required:
We have described the compiler toolchain and sysroot in the first chapter. Before learning how to build applications with the RISC-V toolchain, we’d like to introduce an interesting naming convention that has been used for cross-compilers.
Compiler Naming Convention
When you download the GCC toolchain, you’ll find a riscv64-unknown-elf-gcc
binary in the bin
directory. This is the same GCC compiler with inbuilt information of sysroot and platform. It is a convention to name cross-compilers that way.
The naming is typically using the arch-vendor-os-abi
format. So, riscv64-unknown-elf-gcc
means that this is a cross-compiler for RISC-V 64 bit, and tit will generate an elf
binary, which can run on Linux machines for example. An excellent reference on naming convention can be found here. In cases where a compiler’s name doesn’t have the target triplet, the -dumpmachine
flag can be used to get that:
$ gcc -dumpmachine
x86_64-linux-gnu
With the riscv64-unknown-elf-gcc
compiler handy, a file can then be compiled in the following ways:
$ riscv64-unknown-elf-gcc -O2 -o a.out hello.c
$ riscv64-unknown-elf-gcc -O2 hello.c -mabi=lp64d -march=rv64ifd
The -march
flag is used to specify the target sub-architecture for which the assembly will be generated. The -mabi
flag is used to specify data models. For more details on data models, refer to section of 64-bit computing in Wikipedia.
With the llvm toolchain, the binary can be built similarly. Assuming sysroot is in the riscv64-unknown-elf
directory:
$ clang test.c -c --sysroot riscv64-unknown-elf -target
riscv64-unknown-elf -march=rv64ifd
RISC-V applications can be launched on a device, a simulator, or an emulator.
Running the Applications on Spike Simulator
One of the most convenient ways to run small applications is to use the RISC-V simulator. The build and installation steps are fairly straightforward. For this, you need the following dependencies:
- A Linux machine - building a Linux image on non-Linux machines is non-trivial, so it is recommended you have a Linux machine to begin with.
- RISC-V toolchain: [https://github.com/riscv-software-src](https://courses.edx.org/xblock/One of the most convenient ways to run small applications is to use the RISC-V simulator. The build and installation steps are fairly straightforward. For this you need the following dependencies: A Linux machine. Building a Linux image on non-Linux machines is non-trivial so it is recommended you have a Linux machine to begin with. RISC-V toolchain (https://github.com/riscv-software-src) RISC-V simulator spike (https://github.com/riscv-software-src/riscv-isa-sim) RISC-V proxy kernel pk (https://github.com/riscv-software-src/riscv-pk) The instructions to run a simple hello world app on the spike simulator is mentioned in their github README. To install the proxy kernel follow the instructions on their github README. For convenience, you can install both spike and pk in the same directory as the riscv64 toolchain directory by providing the path to toolchain directory as install prefix for both.)
- RISC-V simulator spike: https://github.com/riscv-software-src/riscv-isa-sim
- RISC-V proxy kernel pk: https://github.com/riscv-software-src/riscv-pk
The instructions to run a simple hello-world
app on the Spike simulator are mentioned in their GitHub . To install the proxy kernel, follow the instructions on their GitHub README. For convenience, you can install both spike
and pk
in the same directory as the riscv64
toolchain directory by providing the path to the toolchain directory as install prefix
for both.
Running Applications on an Emulator
Running a RISC-V application on an emulator gives you more flexibility, but the installation steps are more involved. In order to run a RISC-V application on an emulator, you need to have the following dependencies:
- A Linux machine - building a Linux image on non-Linux machines is non-trivial, so it is recommended you have a Linux machine to begin with.
- RISC-V toolchain: [https://github.com/riscv-software-src](https://courses.edx.org/xblock/Running an RISC-V application on an emulator gives you more flexibility but the installation steps are more involved. In order to run a RISC-V application on an emulator you need to have the following dependencies. A Linux machine. Building a Linux image on non-Linux machines is non-trivial so it is recommended you have a Linux machine to begin with. RISC-V toolchain (https://github.com/riscv-software-src) QEMU (git clone —depth 1 —branch v5.0.0 https://github.com/qemu/qemu) Linux (git clone —depth 1 —branch v5.4 https://github.com/torvalds/linux) Busybox (git clone —depth 1 git://git.busybox.net/busybox) The branches listed above are suggested versions and that may change frequently. You can choose other branches as well. The documentation above may become stale if any of the dependencies have breaking changes. Check https://risc-v-getting-started-guide.readthedocs.io/en/latest/linux-qemu.html to see the latest supported versions. If this documentation does not work, be sure to ask in the linux-riscv mailing list. Build QEMU with the RISC-V target: cd qemu ./configure —target-list=riscv64-softmmu —prefix=/path/to/keep/qemu make -j (nproc) Make sure to have the prefix of the cross compiler match from your toolchain. In the above example the gcc compiler is riscv64-unknown-linux-gnu-gcc so the CROSS_COMPILE flag is riscv64-unknown-linux-gnu- Build the busybox cd busybox CROSS_COMPILE=riscv64-unknown-linux-gnu- make defconfig CROSS_COMPILE=riscv64-unknown-linux-gnu- make -j $(nproc) To run linux image on QEMU run sudo /path/to/keep/qemu/bin/qemu-system-riscv64 -nographic -machine virt / -kernel /path/to/linux/image -append “root=/dev/vda ro console=ttyS0” / -drive file=busybox,format=raw,id=hd0 / -device virtio-blk-device,drive=hd0 You can also run bare metal app on QEMU like this /path/to/keep/qemu/bin/qemu-system-riscv64 -nographic -machine virt -kernel /path/to/binary -bios none For additional QEMU configurations for RISC-V, checkout the official documentation. In addition to simulators and emulators, RISC-V applications can be run on virtual machines as well as commercially available development boards. Additional documentation to debug bare metal issues can be found here. You can install the RISC-V virtual machine as documented here.)
- QEMU:
git clone --depth 1 --branch v5.0.0 https://github.com/qemu/qemu
- Linux:
git clone --depth 1 --branch v5.4 https://github.com/torvalds/linux
- Busybox:
git clone --depth 1 git://git.busybox.net/busybox
The branches listed above are suggested versions and that may change frequently. You can choose other branches as well. The documentation above may become stale if any of the dependencies have breaking changes. Check the Running 64- and 32-bit RISC-V Linux on QEMU documentation page to see the latest supported versions. If this documentation does not work, be sure to ask in the linux-riscv mailing list.
Build QEMU with the RISC-V target:
cd qemu
./configure --target-list=riscv64-softmmu --prefix=/path/to/keep/qemu
make -j $(nproc)
make install
Build Linux for the RISC-V target:
cd linux
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- defconfig
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- -j $(nproc)
Make sure to have the prefix of the cross-compiler match from your toolchain. In the above example, the GCC compiler is riscv64-unknown-linux-gnu-gcc
so the CROSS_COMPILE
flag is riscv64-unknown-linux-gnu-
Build the busybox:
cd busybox
CROSS_COMPILE=riscv64-unknown-linux-gnu- make defconfig
CROSS_COMPILE=riscv64-unknown-linux-gnu- make -j $(nproc)
To run the Linux image on QEMU, do:
sudo /path/to/keep/qemu/bin/qemu-system-riscv64 -nographic -machin
virt
-kernel /path/to/linux/image -append "root=/dev/vda ro
console=ttyS0" \
-drive file=busybox,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0
You can also run the bare metal app on QEMU like this:
/path/to/keep/qemu/bin/qemu-system-riscv64 -nographic -machine virt
-kernel /path/to/binary -bios none
For additional QEMU configurations for RISC-V, check out the official documentation. In addition to simulators and emulators, RISC-V applications can be run on virtual machines, as well as commercially available development boards.
Additional documentation to debug bare metal issues can be found here. You can install the RISC-V virtual machine as documented here.
References
- Tech: Toolchain & Runtime Subcommittee mailing list
- GCC Cross-Compiler
- Running 64- and 32-bit RISC-V Linux on QEMU
- Qemu: Documentation/Platforms/RISCV
- Debian - RISC-V Wiki
RISC-V Boards:
The RISC-V Exchange page is a collection of available physical hardware in the RISC-V ecosystem. This list is curated by the community.
RISC-V Cores:
The RISC-V Exchange: Cores & SoCs page is a collection of available intellectual property (IP) cores and SoCs in the RISC-V ecosystem.