How to build Spike emulator and Proxy Kernel (PK) on macOS.
Information
Spike
Spike is a RISC-V ISA Simulator that is the golden reference for the ISA.
It supports several ISA extensions.
It is a simulator of the RISCV instruction set, which can write, compile and run RISCV programs on non-RISCV platforms to facilitate the study and research of relevant personnel.
It provides full system emulation or proxied emulation (using HTIF/FESVR).
It is the universal starting point to explore RISC-V targeted software.
More information about Spike:
https://github.com/riscv/riscv-isa-sim.git
Proxy Kernel (PK)
RISC-V Proxy Kernel, commonly known as pk is an application execution environment that can host statically linked RISC-V ELF binaries.
Besides initialization and basic system setup, pk primarily traps I/O system calls in a tethered I/O limited environment and proxies them to the host.
If the RISC-V core runs tethered to an actual host over FESVR, pk send it back to the host.
In the case of spike, the requests are relayed back to the OS hosting spike.
More information about Proxy Kernel (PK):
https://github.com/riscv/riscv-pk.git
Operating system used
macOS Monterey
Software prerequisites
Homebrew
Procedure
- This tutorial is a continuation of tutorial:
How to build the Nuclei RISC-V GNU Compiler Toolchain (riscv-gnu-toolchain) on macOS.
Please follow that tutorial first, otherwise the steps below do not make any sense.
- Install the Device tree compiler (A dependency for spike):
Type: brew install dtc
Type: brew info dtc
dtc: stable 1.6.1 (bottled)
Device tree compiler
- *** Build and install spike ***
Create directories ~/riscv_spike and ~/riscv_spike/install
Type: cd ~
Type: mkdir riscv_spike
Type: cd riscv_spike
Type: mkdir install
- Clone riscv-isa-sim.git:
Type: git clone https://github.com/riscv/riscv-isa-sim.git
Type: cd riscv-isa-sim
To show the last commit on this branch, type: git log
commit e93b9cbbbcd3ad0a02ae298e9f1a2d98d3ac0153 (HEAD -> master, origin/master, origin/HEAD)
Merge: d1a3a42 fc572da
Author: Andrew Waterman <[email protected]>
Date: Mon Jan 10 14:34:16 2022 -0800
- Create directory ~/riscv_spike/riscv-isa-sim/build.
Type: mkdir build
- Create the Makefile.
Type: export PATH=`pwd`/install/bin:$PATH
Type: cd build
Type: ../configure --prefix=`pwd`/../../install --with-isa=RV32IMAC
After a few seconds a ~/riscv_spike/riscv-isa-sim/build/Makefile is generated.
Note 1:
I have set --with-isa=RV32IMAC
This sets the default RISC-V ISA to RV32IMAC.
The Sipeed Logan Nano CPU is the GigaDevice GD32VF103CBT6, based on Nuclei System Technology Bumblebee core.
The Nuclei Bumblebee core supports the RISC-V ISA version 2.2 RV32IMAC instruction set.
This means the GD32VF103CBT6 has no floating-point support.
See: How to build the Nuclei RISC-V GNU Compiler Toolchain (riscv-gnu-toolchain) on macOS.
Note 2:
The ~/riscv_spike/riscv-isa-sim/configure tool is a shell script.
More information about the many configure options, type: ./configure --help
See also: configure_riscv_isa_sim_help.txt
- Build spike, it will take approximately 3 minutes depending on your machine. There are no errors.
Type: cd ~/riscv_spike/riscv-isa-sim/build
Type: make -j`nproc`
- Install spike at ~/riscv_spike/install/bin.
Type: cd ~/riscv_spike/riscv-isa-sim/build
Type: make install
- Update PATH in .bash_profile
Type: cd ~
Type: nano .bash_profile
Type: export PATH=$PATH:/Users/robertlie/riscv_spike/install/bin
- Show spike help.
Type: spike --help
See: spike_help.txt
- *** Build and install Proxy Kernel (PK) ***
Create directory ~/riscv_spike/install_pk
Type: cd ~/riscv_spike
Type: mkdir install_pk
- Clone riscv-pk.git:
Type: git clone https://github.com/riscv/riscv-pk.git
Type: cd riscv-pk
To show the last commit on this branch, type: git log
commit 387e54a5804653c4c4a22d958f05b4f91277a552 (HEAD -> master, origin/master, origin/HEAD)
Author: Andrew Waterman <[email protected]>
Date: Sun Jan 9 18:58:03 2022 -0800
- Create directory ~/riscv_spike/riscv-pk/build.
Type: mkdir build
- Set the RISCV environment variable.
This variable must point to the RISC-V toolchain install directory.
Type: export RISCV=/Users/robertlie/riscv_toolchain/install
More information about the toolchain install directory, see:
How to build the Nuclei RISC-V GNU Compiler Toolchain (riscv-gnu-toolchain) on macOS.
The RISCV variable is used in ~/riscv_spike/riscv-pk/configure.ac
- Goto RISC-V toolchain install directory and create symbolic links.
Type: cd ~/riscv_toolchain/install
Create shell script create_symlinks.sh
See: create_symlinks.sh.txt
Type: chmod 755 create_symlinks.sh
Type: ./create_symlinks
- Create the Makefile.
Type: cd ~/riscv_spike/riscv-pk/build
Type: ../configure --prefix=`pwd`/../../install_pk --host=riscv32-nuclei-elf \
--with-arch=rv32imac --with-abi=ilp32
Output:
checking build system type... x86_64-apple-darwin21.1.0
checking host system type... riscv32-nuclei-elf
checking for riscv32-nuclei-elf-gcc... riscv32-nuclei-elf-gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether riscv32-nuclei-elf-gcc accepts -g... yes
checking for riscv32-nuclei-elf-gcc option to accept ISO C89... none needed
checking for riscv32-nuclei-elf-g++... riscv32-nuclei-elf-g++
checking whether we are using the GNU C++ compiler... yes
checking whether riscv32-nuclei-elf-g++ accepts -g... yes
checking for riscv32-nuclei-elf-ar... riscv32-nuclei-elf-ar
checking for riscv32-nuclei-elf-ranlib... riscv32-nuclei-elf-ranlib
checking for riscv32-nuclei-elf-readelf... riscv32-nuclei-elf-readelf
checking for riscv32-nuclei-elf-objcopy... riscv32-nuclei-elf-objcopy
checking for a BSD-compatible install... /opt/local/bin/ginstall -c
checking how to run the C preprocessor... riscv32-nuclei-elf-gcc -E
checking for grep that handles long lines and -e... /opt/local/bin/ggrep
checking for egrep... /opt/local/bin/ggrep -E
checking for ANSI C header files... yes
configure: configuring default subproject : pk
configure: configuring default subproject : bbl
configure: configuring default subproject : softfloat
configure: configuring default subproject : dummy_payload
configure: configuring default subproject : machine
configure: configuring default subproject : util
configure: creating ./config.status
config.status: creating pk.mk
config.status: creating bbl.mk
config.status: creating softfloat.mk
config.status: creating dummy_payload.mk
config.status: creating machine.mk
config.status: creating util.mk
config.status: creating Makefile
config.status: creating config.h
After a few seconds a ~/riscv_spike/riscv-pk/build/Makefile is generated.
Note 1:
I have set --with-arch=rv32imac --with-abi=ilp32
Why I have done this, see:
How to build the Nuclei RISC-V GNU Compiler Toolchain (riscv-gnu-toolchain) on macOS.
Note 2:
You can set --host=riscv32-unknown-elf or --host=riscv64-unknown-elf
Instead of "unknown" I used "nuclei", because I have changed this when creating my Nuclei RISC-V GNU Compiler Toolchain.
The configure script will search for words "riscv32" or "riscv64", that is why I created symbolic links.
The configure script will check if certain toolchain tools can be found, for example:
$RISCV/bin/riscv32-nuclei-elf-gcc
Note 3:
The ~/riscv_spike/riscv-pk/configure tool is a shell script.
More information about the many configure options, type: ./configure --help
See also: configure_riscv_pk_help.txt
- Build pk. There should be no errors.
Type: cd ~/riscv_spike/riscv-pk/build
Type: make -j`nproc`
- Install pk at ~/riscv_spike/install_pk/riscv32-nuclei-elf/bin.
Type: cd ~/riscv_spike/riscv-pk/build
Type: make install
- Test spike and pk.
- Open a terminal.
Type: cd ~/riscv_toolchain
- Write a test program.
Create a file ~/riscv_toolchain/hello.c with the following content:
#include <stdio.h>
int main(void) {
printf("Hello World\n");
return 0;
}
- Compile the test program (for arch=rv32imac and abi=ilp32) into the compatible RISC-V instruction code that can be executed on the processor.
Type: riscv-nuclei-elf-gcc hello.c -O2 -march=rv32imac -mabi=ilp32 \
-o hello
If you did not specify -march=rv32imac and -mabi=ilp32 the default -march=rv64imafdc and -mabi=lp64d is used.
See: riscv-nuclei-elf-gcc -v
Type: file hello
Output:
hello: ELF 32-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, not stripped
Type: ./hello
Output:
-bash: ./hello: cannot execute binary file
The hello program has been compiled for the riscv32 platform, and thus, will not run on macOS unless it is compatible.
You can use spike, which is a RISC-V ISA simulator which run programs in a user space as if it is on a RISC-V hardware.
Type: spike ~/riscv_spike/install_pk/riscv32-nuclei-elf/bin/pk hello
Output:
bbl loader
Hello World
Note:
You must use the full path to pk.
Instead of the full path, modify .bash_profile and add the following line:
Type: export PK_PATH=/Users/robertlie/riscv_spike/install_pk/riscv32-nuclei-elf/bin
Type: spike $PK_PATH/pk hello
This will not work:
Type: export PATH=/Users/robertlie/riscv_spike/install_pk/riscv32-nuclei-elf/bin:$PATH
Type: spike pk hello
Output:
libc++abi: terminating with uncaught exception of type std::runtime_error: could not open pk (did you misspell it? If VCS, did you forget +permissive/+permissive-off?)
|