Programming concepts with RISC-V@QEMU

Posted by

This explains ABI(Application Binary Interface) concepts of  Operating system ,Language and processor architecture. Also QEMU simulation for RISC-V .

In NextGen Program@RISC-V , I discussed about Fixed Point, Floating Point data types and RISC-V ISA from user level perspective. We noticed that any processor core architecture as implementation of  particular ISA  . e.g. Power . You may take analogy of derived class in C++ .

Today , I will discuss other privileged modes.

I provided Power architecture reference to understand the new RISC-V. Lets look into the bigger picture to understand ABI .

What is the difference between API and ABI ?

API (Application Program Interface) is a format used for communication between two software modules.

ABI is the convention defined at binary level . An ABI(Application Binary Interface)  defines calling conventions, machine interface, and operating-system interface. This allows  a linker to combine separately compiled modules  , even object files generated by  different compilers for a specific platform.  The ABI is organized as a portable base document and platform-specific supplements

  • Base concept of ABI is from  SYSTEM-V ABI which has been adopted by major UNIX based operating systems. ELF is part of system-v ABI . If your application is incompatible with particular OS ELF ABI , It will not execute. This is one of the reason we can’t execute even an library independent application binary in different OSs of same target.
  • PSABI (Processor Specific Binary Interface) is the supplement to base ABI and provides detail about size of abstract type, endianness etc and must be referred for finer detail.  For example RISC-V ELF PSABI 
  •  EABI (Embedded ABI) is actually a family of ABIs and one of the “subABIs” is GNU EABI, for Linux. one can find many eabi specific options in GCC.
  • language-specific (C ABI, C++ ABI, Fortran ABI, Pascal ABI, Java bytecode spec) ABIs helps in interfacing library and application compiled in different versions.

Terminology @RISC-V

  • ABI – Application Binary Interface
  • SBI – Supervisor Binary Interface
  • HBI– Hypervisor Binary Interface (In Future)
  • Hardware
    • Core contains independent instruction fetch unit and might support RISC-V compatible hardware threads(harts)
    • Co-processor contains additional architecture state and instruction set extension with limited autonomy
    • Accelerator may be either non-programmable fixed instruction unit or an autonomous core to achieve a particular task
  • Privilege Levels
    • 0 User/Application  – U
    • Supervisor  -S
    • 2  Reserved
    • Machine -M (Highest and Mandatory Privileged level)
    • Implementation may add Debug(D-Mode) as well for off-chip debugging or manufacturer test
  • Use case
    • Mode M  – simple embedded system
    • Mode M+U  – secure embedded system
    • Mode M+U+S -POSIX based embedded OS

Control and Status Registers

  • User Level
  • Supervisor Level
  • Machine Level

Privileged Instruction Set Architecture

  • Machine Level ISA
  • Supervisor Level ISA


In linux , We use term like

  • Dropbear
    • Dropbear , a small SSH server and client, is designed by Matt Johnston for embedded linux systems.
  • busybear  Linux 
    • busybear-linux is a tiny RISC-V Linux root file system image that targets the virt board in riscv-qemu. Here is the Copyright and License information.
    • busybox + Dropbear = busybear
  • Tethered system
    • Depends on host to boot
    • May not have complete I/O
  • Berkeley Boot Loader, bbl
    • It is a supervisor execution environment for tethered RISC-V systems. It is designed to host the RISC-V Linux port.
  • RISC-V Proxy Kernel implements Linux ABI subset and supports a single process. It can host statically-linked RISC-V ELF binaries. It is designed to support tethered RISC-V implementations and thus handles I/O-related system calls by proxying them to a host computer.
  • Host m/c runs front end server which acts as boot loader by loading kernel ELF to target memory. It also execute system I/O calls on behalf of proxy kernel
  • Both Host(x86) and target (RISC-V) communicates using HTIF(Host Target Interface) protocol.

Step-By-Step Approach for RISC-V QEMU

Step 1: Extract RISCV toolchain

mkdir riscv-linux
cd riscv-linux/
git clone --recursive

Step 2:  Install RISCV toolchain. If any permission issue in make, use sudo

sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
cd riscv-gnu-toolchain
./configure --prefix=/opt/riscv --enable-multilib
make newlib -j8
make linux -j8
export PATH=$PATH:/opt/riscv/bin
export RISCV=/opt/riscv

Note: You may have to install some utilities for the build if asked :

sudo apt-get install libglib2.0-dev zlib1g-dev
apt-cache search pixman
sudo apt-get install libpixman-1-dev

Step 3:Build QEMU for RISCv

cd ..
git clone
cd riscv-qemu
./configure --target-list=riscv64-softmmu,riscv32-softmmu
make -j8
sudo make install

Step 4: Build busybear linux root file system

cd ..
git clone
cd busybear-linux
make -j8

Step 5: Build RISCV linux Kernel

git clone
cd riscv-linux
git checkout riscv-linux-4.14
cp ../busybear-linux/conf/linux.config .config
make ARCH=riscv olddefconfig
make ARCH=riscv vmlinux -j8

Step 6: Build Berkley bootloader with riscv-pk(Proxy Kernel)  and payload riscv-kernel

git clone
cd riscv-pk
mkdir build
cd build
../configure --enable-logo --host=riscv64-unknown-elf --with-payload=../../riscv-linux/vmlinux
make -j8

Step 7: If any issue in building above 3, use pre-built binaries as follows :

mkdir release
cd release
bzip2 -d *.bz2
Run linux on RISCV with QEMU (Inside riscv-pk/build/release
sudo qemu-system-riscv64 -nographic -machine virt   -kernel bbl -append "root=/dev/vda ro console=ttyS0"   -drive file=busybear.bin,format=raw,id=hd0   -device virtio-blk-device,drive=hd0   -netdev type=tap,script=./ifup,downscript=./ifdown,id=net0   -device virtio-net-device,netdev=net0
user:root password:busybear

How to  test  minimum RISC-V  Kernel with above setup ?

cd /home/sanjay/riscv-linux/riscv-pk/build/release
sudo qemu-system-riscv64 -nographic -machine virt -kernel bbl -append "root=/dev/vda ro console=ttyS0" -drive file=busybear.bin,format=raw,id=hd0 -device virtio-blk-device,drive=hd0
user:root password:busybear

Additional References :

Click to access riscv-software-toolchain-workshop-jan2015.pdf

This article is discussed at video Programming Concepts with RISC-V @QEMU

Thanks for reading till end. Please provide your feedback regarding this article. Also subscribe  Embedkari for other interesting topics. .

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.