RISC-V on Rust 从零开始(6) - 使用Spike模拟器

其实RISC-V官方也有开发了一个instruction accurate等级的模拟器Spike,只是主要以C++撰写。从提交纪录看起来,这个模拟器已经开发超过十年,支援的指令集也相当丰富,可以作为後续验证的golden。这次尝试从原始码编译整个模拟器,并且实际执行一个简单的RISC-V程序,看看Spike可以提供给我们那些资讯。

安装RISC-V GNU Toolchain

官方已经提供了执行档,下载後将其加入PATH即可。

# Setup RISC-V toolchain
wget https://github.com/riscv/riscv-gnu-toolchain/releases/download/2021.06.26/riscv32-elf-ubuntu-20.04-nightly-2021.06.26-nightly.tar.gz
tar -xvf riscv32-elf-ubuntu-20.04-nightly-2021.06.26-nightly.tar.gz
mv riscv riscv-toolchain
export PATH=$(realpath riscv-toolchain/bin):$PATH

编译Proxy Kernel

官方说明如下:

It is designed to support tethered RISC-V implementations with limited I/O capability and thus handles I/O-related system calls by proxying them to a host computer.

简单来说proxy kernel能将Spike的I/O系统呼叫重新导向host。由於Spike本身没有模拟外部的I/O装置,因此需要proxy kernel才能让这些I/O操作能正常运作。

# Compile the proxy kernel
git clone https://github.com/riscv/riscv-pk.git
cd riscv-pk
mkdir build
cd build
../configure --prefix=$(realpath ../../riscv-toolchain) --host=riscv32-unknown-elf
make
cd ../..

编译Spike模拟器

终於可以编译模拟器本身了,过程与编译proxy kernel类似,只是需要额外安装device-tree-compiler。

# Compile Spike simulator
sudo apt install device-tree-compiler
git clone https://github.com/riscv/riscv-isa-sim.git
cd riscv-isa-sim
mkdir build
cd build
../configure
make
cd ../..

编译RISC-V程序

程序码

int main() {
    return 0;
}

编译指令

./riscv-toolchain/bin/riscv32-unknown-elf-gcc -o main.elf main.c

执行Spike

加上-l选项可以看到执行结果,并且指定isa为RV32,才能执行刚刚编译出来的ELF档。

./riscv-isa-sim/build/spike -l --isa=RV32 ./riscv-pk/build/pk main.elf

可以看到以下输出:

core   0: 0x00001000 (0x00000297) auipc   t0, 0x0
core   0: 0x00001004 (0x02028593) addi    a1, t0, 32
core   0: 0x00001008 (0xf1402573) csrr    a0, mhartid
core   0: 0x0000100c (0x0182a283) lw      t0, 24(t0)
core   0: 0x00001010 (0x00028067) jr      t0
core   0: 0x80000000 (0x1f80006f) j       pc + 0x1f8
core   0: 0x800001f8 (0x00000093) li      ra, 0
core   0: 0x800001fc (0x00000113) li      sp, 0
core   0: 0x80000200 (0x00000193) li      gp, 0
core   0: 0x80000204 (0x00000213) li      tp, 0
core   0: 0x80000208 (0x00000293) li      t0, 0
...

每行的格式固定,依序为core ID、目前PC address、指令hex、以及相对应的反组译结果。当我们实作完指令decoder之後,就可以使用这个PC trace,来验证我们实作的正确性。


<<:  在 Linux 上轻松安装 Fcitx 与呒虾米

>>:  存取令牌(Access Token)

Day 8 - Kotlin的回圈(上)

Day 8 - Kotlin的回圈(上) Kotlin的回圈我会分两天来讲,今天我们会讲for的部分...

20210208-台湾菁英圆桌分享会 (Elite Round Table in Taiwan)

这是我个人的考上Cissp的分享会,其中分享如何有效的念书,提供想考Cissp的朋友一些参考。 ...

Day28:每天一个小练习 - JS30-13-Slide in on Scroll

参考资料: Alex老师教学 PJCHENder笔记 卷动出现图片。 题目预设的过滤效果,避免多次触...

[Day 4] 排版布局Grid

布局排板大板型左右留边 Container 接下来就是这个Container里头需要载运那些内容了 ...

Day2-LeetCode 118. Pascal's Triangle

Problem: 118. Pascal's Triangle(Easy) Pascal's Tri...