Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog

Containerized Development

In a previous post I used docker to containerize building for a RISC-V target.

In this post I’ll simulate that target file in a containerized RISC-V ISA Simulator.

Spike ISA Sim

The official reference ISA simulator for RISC-V is spike. There are other more functional and performant open source and commercial simulators , however the aim of this post is to describe a solution for quick and easy debugging and simulation of the low level examples on this blog.

Spike implements a functional model of the RISC-V hart(s) and the debug interface. GDB must connect to OpenOCD, which will in turn connect to Spike’s model of the RISC-V serial debug interface. Spike’s Readme file describes how to do this, but it’s pretty tedious to load an example program.

The container example downloads and builds the appropriate source code and manages running the independent tools.

Docker Images

The docker files are in https://github.com/five-embeddev/build-and-verify. Assume it’s checked out to build-and-verify.

Firstly, the docker images in these folders should be built:

cd build-and-verify/
make -C docker/riscv-openocd
make -C docker/riscv-spike
make -C docker/riscv-xpack-gcc
make -C examples/debug-sim

Running a RISC-V Target Elf File on Desktop OS Host

Let’s assume we’ve already compiled an elf file build/main.elf.

The Docker image is tagged as five_embeddev/examples/riscv_spike_debug_env_sim_gdb, built in the folder examples/debug-sim. In the command line below, docker arguments are placed before the image name and spike simulator arguments are after the image name.

The docker arguments needs to configure the local build directory to be mounted as a volume inside the container, In this case to /project/build. It also needs to configure an interactive TTY mode for debugging.

The spike arguments needs to configure the ISA, memory map and target image.

docker \
  run \
     -i --rm --tty \
     -v `pwd`:/project \
     five_embeddev/examples/riscv_spike_debug_env_sim_gdb \
     --priv=m \
     --isa=rv32imac \
     -m0x8000000:0x2000,0x80000000:0x4000,0x20010000:0x6a120 \
     /project/build/main.elf  

It’s pretty easy to step through the code.

tui enable
b main
c 
next
next

Debugging

The compose.yml file captures this configuration the mapping of local files to /project in the container, and the simulator arguments.

services:
  spike_openocd_gdb:
    image: five_embeddev/examples/riscv_spike_debug_env_sim_gdb
    command: [  "--priv=m" ,"--isa=rv32imac", "-m0x8000000:0x2000,0x80000000:0x4000,0x20010000:0x6a120", "/project/build/main.elf"]
    tty: true
    volumes:
        - .:/project
docker-compose run  spike_openocd_gdb

Conclusion

I’d like to customize spike for development flow and architecture experimentation, so having an automated from-source to single run command is convenient.

A few general advantages are: