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:
- build-and-verify/docker/riscv-openocd/
- build-and-verify/docker/riscv-spike/
- build-and-verify/docker/riscv-xpack-gcc/
- examples/debug-sim
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
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:
- Containerized tools can be used to integrate with modern development environments, like VSCode.
- The latest tools can be downloaded and utilized using automated scripts.
- This can be built on for automated testing and cloud based CI.