本文主要介绍riscv交叉编译工具链的安装方法。特别注意,请将“存在的问题”部分看完再尝试安装。
基本方法 首先安装编译环境。
sudo apt install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev git libncurses5-dev
riscv toolchain的地址为https://github.com/riscv-collab/riscv-gnu-toolchain ,使用git将项目clone下来。
git clone https://github.com/riscv-collab/riscv-gnu-toolchain
在当前目录下会出现riscv-gnu-toolchain
,进入该文件夹,然后执行configure
进行配置。
cd riscv-gnu-toolchain ./configure --prefix=/opt/riscv --with-arch=rv64imafdc
configure
的参数说明如下。
--prefix=/opt/riscv
表示工具将会被安装在/opt/riscv
文件夹下。
--with-arch=rv64imafdc
表示安装的是RISC-V 64的ISA,扩展包为i, m, a, f, d, c
默认的configure
生成的gdb配置是不会带tui的,需要手动在Makefile
中加上--enable-tui=yes
,如下所示。
GDB_TARGET_FLAGS := --with-expat =yes --enable-tui =yes $(GDB_TARGET_FLAGS_EXTRA)
然后执行make
编译。
sudo make linux -j$(nproc)
编译完成后,会在/opt/riscv/bin
文件夹下出现如下工具。
如果希望使用riscv64-unknown-linux-gnu-gcc
来编译C
代码,需要加上路径/opt/riscv/bin
,例如
/opt/riscv/bin/riscv64-unknown-linux-gnu-gcc main.c -o main.out
将/opt/riscv/
加入环境变量PATH
就可以在调用gcc
时不用加上路径,一种方法是在~/.bashrc
的最后添加如下语句,然后保存退出即可。
export PATH=/opt/ riscv/bin:/ opt/qemu/ bin:$PATH
重启终端即可生效,使用如下命令可以测试是否成功加入环境变量。
riscv64-unknown-linux-gnu-gcc --version
上述命令并没有编译qemu
,进入riscv-gnu-toolchain
中的qemu
文件夹,使用如下命令来编译。
sudo apt install ninja-build libglib2.0-dev libpixman-1-dev libcairo2-dev libpango1.0-dev libjpeg8-dev libgif-dev ./configure --target-list=riscv64-linux-user,riscv64-softmmu --prefix=/opt/qemu --enable-debug sudo make CROSS_COMPILE=riscv64-unknown-linux-gnu- qemu-riscv64_smode_defconfig sudo make CROSS_COMPILE=riscv64-unknown-linux-gnu- -j$(nproc)
将/opt/qemu/bin
加入环境变量后,使用如下命令可以检查qemu
是否安装成功。
qemu-system-riscv64 --version
存在的问题 It is universally acknowledged that 在国内使用github来clone代码是非常慢的。而且,riscv-gnu-toolchain
在编译的时候会拉取.gitmodules
中需要的若干个模块,这就导致了配环境的时间+++++++++++++++++++++++++++。
解决网络问题的方法如下。
从gitee镜像源和清华源拉取代码。
在clone的时候指定分支和depth。
首先从gitee上拉取riscv-gnu-toolchain
。
git clone -b master --depth=1 https://gitee.com/mirrors/riscv-gnu-toolchain.git
在riscv-gnu-toolchain
文件夹下,拉取如下几个仓库。
git clone -b riscv-binutils-2.36.1 --depth=1 https://gitee.com/mirrors/riscv-binutils-gdb.git riscv-binutils git clone -b riscv-gcc-10.2.0 --depth=1 https://gitee.com/mirrors/riscv-gcc.git riscv-gcc git clone -b riscv-glibc-2.31 --depth=1 https://gitee.com/mirrors/riscv-glibc.git riscv-glibc git clone -b riscv-dejagnu-1.6 --depth=1 https://gitee.com/mirrors/riscv-dejagnu.git riscv-dejagnu git clone -b riscv-newlib-4.1.0-be --depth=1 https://gitee.com/mirrors/riscv-newlib.git riscv-newlib git clone -b fsf-gdb-10.1-with-sim --depth=1 https://gitee.com/mirrors/riscv-binutils-gdb.git riscv-gdb git clone -b master --depth=1 https://mirrors.tuna.tsinghua.edu.cn/git/qemu.git qemu
编译riscv-gnu-toolchain
和qemu
的方法和上面一致。
使用工具 首先写一个Hello World代码,保存在test.cpp
中。
#include <iostream> int main () { std::cout << "Hello RISC-V 64" << std::endl; }
编译test.cpp
。
riscv64-unknown-linux-gnu-g++ test.cpp -o test.out
使用readelf
工具即可查看生成的可执行文件的ISA。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 nelson@asus:~/code$ riscv64-unknown-linux-gnu-readelf -h test.out ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: RISC-V Version: 0x1 Entry point address: 0x10750 Start of program headers: 64 (bytes into file) Start of section headers: 10176 (bytes into file) Flags: 0x5, RVC, double-float ABI Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 9 Size of section headers: 64 (bytes) Number of section headers: 34 Section header string table index: 33
可以看到machine
一项是RISC-V
。
此时无法使用./test.out
来执行,需要使用qemu
来模拟执行。
qemu-riscv64 -L /opt/riscv/sysroot/ test.out
可以看到输出了如下信息。
nelson@asus :~/code $ qemu-riscv64 -L /opt/riscv/sysroot/ test.out Hello RISC-V 64