当前位置: 首页 > 工具软件 > riscv-isa-sim > 使用案例 >

RISCV仿真环境搭建

董高洁
2023-12-01

主要参考了这几篇文章:

总纲:RISCV仿真环境搭建:riscv-tools_Like_ai的博客-CSDN博客

riscv-gnu-toolchain:搭建RISC-V编译环境与运行环境 - 知乎 (zhihu.com)

riscv-gnu-toolchain代码下载:riscv-gnu-toolchain工具链-从下载到运行_limanjihe的博客-CSDN博客_riscv-gnu-toolchain

riscv-gnu-toolchain是交叉工具链,利用这个工具链对C/C++文件进行编译,生成一个输出文件(file.o或者file.elf),riscv-tools是仿真工具(模拟目标机器),对前面输出的可执行文件进行仿真。

环境准备:centos7

  • RISCV环境变量设置为RISC-V工具链安装路径,可以写在/etc/profile或者~/.bashrc中

export RISCV="/tools/riscv/toolchain"   #工具链的安装链接路径
​
export PATH=$PATH:$RISCV/bin   # $RISCV/bin链接工具的位置
  • 安装软件包:对于centos在装过riscv-gnu-toolchain交叉编译器情况下,主要查看device-tree-compiler(即dtc工具)是否拥有。

yum install dtc
  • 在编译时,会要求更高版本的gcc版本:(g++: error: unrecognized command line option '-std=c++17')

在编译环境上安装高版本gcc,或者拷贝一个源码安装的gcc目录,设置PATH
export PATH=/tools/misc/gcc/7.4.0/bin:$PATH
export LD_LIBRARY_PATH=/tools/misc/gcc/7.4.0/lib:$LD_LIBRARY_PATH

一、riscv-gnu-toolchain安装

1.1 下载代码

github源码:https://github.com/riscv-collab/riscv-gnu-toolchain

下载代码算是环境安装中的一个比较耗时的一步了,想要在GitHub上拿到源码编译非常困难,即使使用了科学上网网络也不是很好。比较庆幸的是Gitee上有镜像源,每天同步一次。但是注意子仓的下载才是最难的,要把子仓一个个换成Gitee仓库。(子仓需要在Gitee上搜索仓库是否同步正确,对应分支是否存在:Gitee 极速下载 - Gitee.com)子仓中还有几个开源软件,用到的是清华的开源软件源:清华大学开源软件镜像站 | Tsinghua Open Source Mirror

步骤如下:

  1. 下载主仓:

git clone https://gitee.com/mirrors/riscv-gnu-toolchain.git
cd riscv-gnu-toolchain

      2. 修改子仓url:

原.gitmodules

cat .gitmodules
[submodule "binutils"]
    path = binutils
    url = https://sourceware.org/git/binutils-gdb.git
    branch = binutils-2_39-branch
[submodule "gcc"]
    path = gcc
    url = https://gcc.gnu.org/git/gcc.git
    branch = releases/gcc-12.1.0
[submodule "glibc"]
    path = glibc
    url = https://sourceware.org/git/glibc.git
[submodule "riscv-dejagnu"]
    path = riscv-dejagnu
    url = https://github.com/riscv-collab/riscv-dejagnu.git
    branch = riscv-dejagnu-1.6
[submodule "newlib"]
    path = newlib
    url = https://sourceware.org/git/newlib-cygwin.git
    branch = master
[submodule "riscv-gdb"]
    path = riscv-gdb
    url = https://github.com/riscv-collab/riscv-binutils-gdb.git
    branch = fsf-gdb-10.1-with-sim
[submodule "qemu"]
    path = qemu
    url = https://gitlab.com/qemu-project/qemu.git
[submodule "musl"]
    path = musl
    url = git://git.musl-libc.org/musl
    branch = master
[submodule "spike"]
    path = spike
    url = https://github.com/riscv-software-src/riscv-isa-sim.git
    branch = master
[submodule "pk"]
    path = pk
    url = https://github.com/riscv-software-src/riscv-pk.git
    branch = master

修改后,其中用到了清华的开源软件源,以及Gitee源:

[submodule "binutils"]
        path = binutils
        url = https://mirrors.tuna.tsinghua.edu.cn/git/binutils-gdb.git
        branch = binutils-2_39-branch
[submodule "gcc"]
        path = gcc
        url = https://mirrors.tuna.tsinghua.edu.cn/git/gcc.git
        branch = releases/gcc-12.1.0
[submodule "glibc"]
        path = glibc
        url = https://mirrors.tuna.tsinghua.edu.cn/git/glibc.git
[submodule "riscv-dejagnu"]
        path = riscv-dejagnu
        url = https://gitee.com/mirrors/riscv-dejagnu
        branch = riscv-dejagnu-1.6
[submodule "newlib"]
        path = newlib
        url = https://gitee.com/mirrors/riscv-newlib
        branch = master
[submodule "riscv-gdb"]
        path = riscv-gdb
        url = https://gitee.com/mirrors/riscv-binutils-gdb.git
        branch = fsf-gdb-10.1-with-sim
[submodule "qemu"]
        path = qemu
        url = https://mirrors.tuna.tsinghua.edu.cn/git/qemu.git
[submodule "musl"]
        path = musl
        url = https://gitee.com/mirrors/musl.git
        branch = master
[submodule "spike"]
        path = spike
        url = https://gitee.com/mirrors/riscv-isa-sim.git
        branch = master
[submodule "pk"]
        path = pk
        url = https://github.com/riscv-software-src/riscv-pk.git
        branch = master

    3. 更新子仓:

git submodule update --init --recursive

1.2 依赖软件下载

sudo yum install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel gawk  bison flex texinfo patchutils gcc gcc-c++ zlib-devel expat-devel

1.3 编译GCC

编译riscv64-unknown-elf-gcc: (本文只编译了这个gcc)

./configure --prefix=$RISCV
sudo make                  # 可以用make -j$(nproc)  来加速编译

编译64-bitriscv64-unknown-linux-gnu-gcc:

./configure --prefix=/opt/riscv
sudo make linux

编译32-bit:

./configure --prefix=/opt/riscv --with-arch=rv32gc --with-abi=ilp32d
sudo make linux

编译32-bit和64-bit:

./configure --prefix=/opt/riscv --enable-multilib
sudo make linux

这两个gcc的区别在于,elf-gcc是静态链接,linux-gnu-gcc是动态链接。

编译完可以去$RISCV/bin目录下检查下生成的二进制文件:

[root@gerrit-backup bin]# ls -lt
total 815924
-rwxr-xr-x. 1 root root   3804552 Aug 30 11:30 riscv64-unknown-elf-gcov-dump
-rwxr-xr-x. 1 root root   4073824 Aug 30 11:30 riscv64-unknown-elf-gcov-tool
-rwxr-xr-x. 1 root root   5760744 Aug 30 11:30 riscv64-unknown-elf-gcov
-rwxr-xr-x. 1 root root    152912 Aug 30 11:30 riscv64-unknown-elf-gcc-ranlib
-rwxr-xr-x. 1 root root    152896 Aug 30 11:30 riscv64-unknown-elf-gcc-nm
-rwxr-xr-x. 1 root root    153008 Aug 30 11:30 riscv64-unknown-elf-gcc-ar
-rwxr-xr-x. 1 root root  13760048 Aug 30 11:30 riscv64-unknown-elf-cpp
-rwxr-xr-x. 2 root root  13739832 Aug 30 11:30 riscv64-unknown-elf-gcc
-rwxr-xr-x. 2 root root  13739832 Aug 30 11:30 riscv64-unknown-elf-gcc-12.1.0
-rwxr-xr-x. 1 root root 198479896 Aug 30 11:30 riscv64-unknown-elf-lto-dump
-rwxr-xr-x. 2 root root  13762680 Aug 30 11:30 riscv64-unknown-elf-c++
-rwxr-xr-x. 2 root root  13762680 Aug 30 11:30 riscv64-unknown-elf-g++
-rwxr-xr-x. 1 root root      4045 Aug 30 11:16 riscv64-unknown-elf-gdb-add-index
-rwxr-xr-x. 1 root root 104069296 Aug 30 11:16 riscv64-unknown-elf-gdb
-rwxr-xr-x. 1 root root   7847096 Aug 30 11:16 riscv64-unknown-elf-run
-rwxr-xr-x. 1 root root   5162208 Aug 30 11:12 riscv64-unknown-elf-c++filt
-rwxr-xr-x. 2 root root   6060840 Aug 30 11:12 riscv64-unknown-elf-strip
-rwxr-xr-x. 2 root root   5276296 Aug 30 11:12 riscv64-unknown-elf-nm
-rwxr-xr-x. 1 root root    271312 Aug 30 11:12 riscv64-unknown-elf-elfedit
-rwxr-xr-x. 2 root root   4080960 Aug 30 11:12 riscv64-unknown-elf-readelf
-rwxr-xr-x. 1 root root   5219200 Aug 30 11:12 riscv64-unknown-elf-addr2line
-rwxr-xr-x. 2 root root   6060848 Aug 30 11:12 riscv64-unknown-elf-objcopy
-rwxr-xr-x. 2 root root   5442872 Aug 30 11:12 riscv64-unknown-elf-ranlib
-rwxr-xr-x. 4 root root   8526168 Aug 30 11:12 riscv64-unknown-elf-ld
-rwxr-xr-x. 4 root root   8526168 Aug 30 11:12 riscv64-unknown-elf-ld.bfd
-rwxr-xr-x. 1 root root   5226056 Aug 30 11:12 riscv64-unknown-elf-strings
-rwxr-xr-x. 2 root root   5442872 Aug 30 11:12 riscv64-unknown-elf-ar
-rwxr-xr-x. 2 root root   8672264 Aug 30 11:12 riscv64-unknown-elf-objdump
-rwxr-xr-x. 1 root root   5204520 Aug 30 11:12 riscv64-unknown-elf-size
-rwxr-xr-x. 1 root root   5862048 Aug 30 11:12 riscv64-unknown-elf-gprof
-rwxr-xr-x. 2 root root   7632544 Aug 30 11:12 riscv64-unknown-elf-as
​

这一步一定要检查是否已经生成riscv64-unknown-elf-cpp并且$RISCV/bin路径已经加入PATH,否则后续编译riscv-tools会报错:

gcc: error: unrecognized argument in option ‘-mcmodel=medany’ gcc: note: valid arguments to ‘-mcmodel=’ are: 32 kernel large medium small; did you mean ‘medium’? make: *** [file.o] Error 1

二、下载并编译riscv-fesvr

git clone https://github.com/riscv/riscv-fesvr.git
cd riscv-fesvr  #克隆完成进入克隆下来的目录
mkdir build && cd build   #创建并进入build文件夹
../configure --prefix=$RISCV --target=riscv64-unknown-elf  #检查环境并生成当前环境使用的Makefile,如果需要指定编译链的输出目录,就可以把R I S C V 改 为 相 应 目 录 或 者 配 置 RISCV改为相应目录或者配置RISCV改为相应目录或者配置RISCV环境变量为相应的目录。
如果没有配置就默认为/bin --target=为你的编译链的路径
[sudo] make install  #编译安装,[sudo]代表sudo可选,安装输出目录的读写全写的实际情况选择

具体细节见:GitHub - riscvarchive/riscv-fesvr: RISC-V Frontend Server

三、下载安装riscv-tools

git clone --recursive https://github.com/riscv/riscv-tools.git

会下载下面的几个模块

Spike, the ISA simulator

riscv-tests, a battery of ISA-level tests

riscv-opcodes, the enumeration of all RISC-V

opcodes executable by the simulator

riscv-pk, which contains bbl, a boot loader for Linux and similar OS kernels, and pk, a proxy kernel that services system calls for a target-machine application by forwarding them to the host machine

由于网络环境不好,而且需求清单中只需要安装:riscv isa simulator和riscv proxy kernel

笔者选择下载这两个库并分别安装:

参考:https://github.com/riscv-software-src/riscv-isa-sim 和 GitHub - riscv-software-src/riscv-pk: RISC-V Proxy Kernel

  • riscv-isa-sim:

$ git clone https://github.com/riscv-software-src/riscv-isa-sim.git
$ cd riscv-isa-sim
$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV
$ make
$ make install
  • riscv-pk

$ git clone https://github.com/riscv-software-src/riscv-pk.git
$ cd riscv-pk
$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV --host=riscv64-unknown-elf   #此处指定了编译器为riscv64-unknown-elf,需确保该文件能在PATH中被找到。
$ make
$ make install

自此,安装完成,$RISCV/目录结构一览:

[root@gerrit-backup bin]# cd /tools/riscv/toolchain/
[root@gerrit-backup toolchain]# ls
bin  include  lib  lib64  libexec  riscv64-unknown-elf  share
[root@gerrit-backup toolchain]# cd bin/
[root@gerrit-backup bin]# ls
elf2hex                        riscv64-unknown-elf-cpp         riscv64-unknown-elf-gcc-nm      riscv64-unknown-elf-gdb-add-index  riscv64-unknown-elf-objcopy  riscv64-unknown-elf-strings  xspike
riscv64-unknown-elf-addr2line  riscv64-unknown-elf-elfedit     riscv64-unknown-elf-gcc-ranlib  riscv64-unknown-elf-gprof          riscv64-unknown-elf-objdump  riscv64-unknown-elf-strip
riscv64-unknown-elf-ar         riscv64-unknown-elf-g++         riscv64-unknown-elf-gcov        riscv64-unknown-elf-ld             riscv64-unknown-elf-ranlib   spike
riscv64-unknown-elf-as         riscv64-unknown-elf-gcc         riscv64-unknown-elf-gcov-dump   riscv64-unknown-elf-ld.bfd         riscv64-unknown-elf-readelf  spike-dasm
riscv64-unknown-elf-c++        riscv64-unknown-elf-gcc-12.1.0  riscv64-unknown-elf-gcov-tool   riscv64-unknown-elf-lto-dump       riscv64-unknown-elf-run      spike-log-parser
riscv64-unknown-elf-c++filt    riscv64-unknown-elf-gcc-ar      riscv64-unknown-elf-gdb         riscv64-unknown-elf-nm             riscv64-unknown-elf-size     termios-xspike

四、验证环境

  1. 创建hello.c

#include <stdio.h>
 
int main(void)
{
        printf("Hello Word!\n");
        return 0;
}
  1. 编译执行(如果$RISCV/bin已经加入PATH,则不用指定绝对路径)

riscv64-unknown-elf-gcc hello.c -o hello.o
spike pk hello.o

    2. 执行结果

bbl loader
hello, word

此外,在验证时出现报错:

[root@gerrit-backup local]# /tools/riscv/toolchain/bin/spike pk hello.o
/tools/riscv/toolchain/bin/spike: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /tools/riscv/toolchain/bin/spike)
/tools/riscv/toolchain/bin/spike: /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /tools/riscv/toolchain/bin/spike)
/tools/riscv/toolchain/bin/spike: /lib64/libstdc++.so.6: version `CXXABI_1.3.9' not found (required by /tools/riscv/toolchain/bin/spike)
/tools/riscv/toolchain/bin/spike: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /tools/riscv/toolchain/bin/spike)
[root@gerrit-backup local]# strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
strings: '/usr/lib/x86_64-linux-gnu/libstdc++.so.6': No such file

这是因为环境上的libstdc++版本太低了,升级到libstdc++.so.6.0.26就可以了。

# 将libstdc++.so.6.0.26放到/usr/lib64目录下
scp -r root@10.2***:/usr/local/share/libstdc++.so.6.0.26 ./
ls -al libstdc++*
mv libstdc++.so.6 libstdc++.so.6.bak
ln -s libstdc++.so.6.0.26 libstdc++.so.6

 类似资料: