riscv-gnu-toolchain编译链及spike,pk安装使用指南

1.环境:Ubuntu18.04

2.安装依赖包(各种编译时需要用到的):

$ 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

3.区分下载riscv-gnu-toolchain和riscv-tools

这里至于为什么要区分主要是因为在github上下载的riscv-gnu-toolchain不只是有编译链,里面还会包含工具链的很多东西,所以两者其实有很多重复,就我们目的只是使用spike可以进行仿真来说只用在github上下载riscv-gnu-toolchain就可以了。

4.下载riscv-gnu-toolchain

为了尽可能下载成功,可以依次使用下面四条命令,这里是直接下载到当前目录,可以建一个空目录用来存放和后续使用方便分类,当然以上和以下都要是英文路径

git clone https://gitee.com/mirrors/riscv-gnu-toolchain.git #只是下载框架里面子模块没东西 
cd riscv-gnu-toolchain
git rm --cached qemu #先移除qemu模拟器,因为直接从GitHub下载太慢了,之后要用可以直接从官网下载
git submodule update --init --recursive #递归下载子模块

检出成功就是下载完全了,可能有网不好就要多次下载了,下载完看下保证每个子模块里有东西。如下

子模组路径 'glibc':检出 '9826b03b747b841f5fc6de2054bf1ef3f5c4bdf3'

这里面稍微说明下里面包含的东西,就spike和pk来说riscv-gnu-toolchain和riscv-tools里面是都有的,所以就目的来说下载riscv-gnu-toolchain就可以了
-GCC(GNU C Compiler):通过“预处理-编译-汇编-链接”,将.c文件转换为目标机器上的可执行文件
-C运行库:包括glibic, musl,newlib,为C标准库提供函数实现支持,可以根据需求进行自定义修改
-Binutils::一组二进制程序处理工具,包括ar(静态库处理),as(汇编器),ld(链接器)等
-GDB: 用于进行项目调试,程序运行检查
-DejaGnu:程序测试框架,为所有测试提供一个前端支持
-qemu:纯软件实现的虚拟化模拟器,几乎可以模拟任何硬件设备。如果不需要该模拟器,可在执行git submodule update --init 命令前将其删除:git rm qemu
-spike:RISC-V的一种仿真器,它可以仿真一个或多个hart
pk:(proxy kernel)包含了一个boot loader和一个能处理系统调用的代理内核

5.编译riscv-gnu-toolchain编译链

当下载完其实已经完成了整个工作的三分之一,下步就是编译RV交叉编译链,使它可以用RV架构编译c程序生成可执行文件。
这里先配置环境变量(就是设置路径)来方便之后的编译

$ sudo mkdir /opt/riscv #这里我们可以先建目录来存放到时候编译完的编译链,也可以自定义路径,如:$ sudo mkdir /home/cxc/RISC-V/riscv
$ sudo chmod -R 777 /opt/riscv #修改目录的权限,要不后续可能会报错,自定义的也可以改,看编译后图形化界面目录有没有出现一个锁,修改权限后锁就会消失
$ vim ~/.bashrc 
export RISCV="/opt/riscv" #这两句放在.bashrc 最后就行,是工具的安装路径,之后编译完编译链就存在此路径中,"/opt/riscv"路径可以自定义如/home/cxc/RISC-V/riscv 
export PATH=$PATH:$RISCV/bin #该路径下为链接工具 
:wq #保存退出 
$ source ~/.bashrc#更新环境

可以用echo $RISCV命令检查是否路径正确
环境配置完成后进行编译链的配置,添加参数选项 --enable-multilib 把“riscv32- xxx”和“riscv64- xxx”的二个工具统一到“riscv64- xxx”同一命名文件,这样既可以使用32位架构编译也可以使用64位编译c程序,方便后续使用,这里编译前最好看下虚拟机的剩余空间,因为编译链15个G左右会很大容易编译时存储空间不够,如何扩容虚拟机参考链接VMware 虚拟机 Ubuntu 18.04 数据无损扩容

$ cd riscv-gnu-toolchain
$ mkdir build && cd build
$ ../configure --prefix=$RISCV --enable-multilib

至此编译的前置工作完成,编译有两种选择,生成两种编译链,make生成使用使用 Newlib 库的“riscv64-unknown-elf-”编译链,这里我是用的这个编译链,该GCC工具链会使用newlib作为C运行库,make linux生成使用 Glibc 库的“riscv64-unknown-linux-gnu-”编译链,该GCC工具链会使用Linux的Glibc作为C运行库,这里命令中的-jn表示n个线程同时编译加快编译速度,因为这个编译链正常编译可能要30分钟左右所以我加上了这个参数可以提高速度,一般n的值为CPU核的2倍,但是,也要和Ubuntu的内存有关系,每个线程在编译时最少需要1G内存,如果没有很多内存,还是直接去掉

$ sudo make  -jn

$ sudo make  -jn linux

这里要等看情况编译40分钟左右,一般讲不会编译报错,报错一般因为可能之前克隆不全,或者权限问题,要是权限问题就可以用上面的sudo chmod命令修改权限,然后make clean清除一下之前编译失败的再make编译一遍,不过因为用了sudo应该不会报权限错误。编译完成后,可以在定义的目录下看见生成的编译工具链,就可以编译c程序生成可执行文件了,可以随便写个c测试下是否编译完生成可执行文件。

Vim hello.c

源码:

#include <stdio.h>

int main() {
    printf("Hello world\n");
    return 0;
}
:wq

默认编译是64位

$ riscv64-unknown-elf-gcc  hello.c  -o hello
$ file hello
hello: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped

如果编译32位程序,需要指定 -march 和 -mabi,这里的arch是编译用的指令集架构,abi是应用程序二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口。之前编译使用的选项–enable-multilib包括如下架构组合,ARCH 和 ABI 的选项不可以任意组合,按如下每一行的组合才可用,这里具体架构支持的指令类型含义参考链接Ubuntu安装riscv-gnu-toolchain和riscv-tools

rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv64imac/lp64;@march=rv64imac@mabi=lp64

接着32位编译,如下

$ riscv64-unknown-elf-gcc -march=rv32imac -mabi=ilp32 hello.c  -o hello
$ file hello
hello: ELF 32-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, not stripped

输完1,2行命令出现如上提示3,4行,然后在当前目录里看到可执行文件hello就是编译成功了

6.编译spike

Spike在riscv-gnu-toolchain里面有源码,需要编译使用

$ apt install device-tree-compiler
$ cd riscv-gnu-toolchain/spike
$ mkdir build
$ cd build
$ ../configure --prefix=/opt/spike #这里目录自定义的就用自定义如../configure --prefix=$RISCV/spike
$ sudo make #sudo可加可不加,如果没加报错就加上试试,这里如果加上提示报错找不到路径是因为echo $RISCV打印出来的是用户的环境变量,但是安装前加入sudo后,使用的超级管理员用户,而超级管理员用户没有设置RISCV这个环境变量,解决: 
$ su
export RISCV=/opt/riscv #自定义记得改
exit #退出超级管理员身份
$ sudo make

这里编译很快基本不会报错,等编译完成后用spike --help,如果提示版本信息等参数就是编译完成了,若果没有可以再使用命令sudo make install (我在编译的时候好像没用sudo make install就可以提示版本信息了)
这里其实已经可以作为裸机使用(但没有进行过实验),第二种就是搭配pk(代理内核),可以直接运行C程序

7.编译pk

这一次编译会比较麻烦,因为下载的pk是要区分架构的,可能是32也可能是64,默认是64(32理论上也可以编译但实际上编译不出来,可能是我的pk代码版本的问题)编译命令如下

$ cd riscv-gnu-toolchain/pk
$ mkdir build
$ cd build
$ ../configure --prefix=/opt/pk --host=riscv64-unknown-elf
$ make
$ make install

这里可能会编译报错,因为pk版本不同所以报错不一定一样,可以把报错直接去搜,如我的报错:

错误:unrecognized opcode `fence.i', extension `zifencei' required

这是编译时架构指令对不上,查的可能是里面abi接口类型有问题所以不能编译,解决如下:

$ make clean #先清一下之前编译的
$ ../configure --prefix=$RISCV --host=riscv64-unknown-elf --with-arch=rv64gc_zifencei
$ make
$ make install

这样就可以编译成功了,最后测试直接用之前生成的可执行文件hello

$ spike pk hello 

打印如下就是成功装好了。

bbl loader Hello World!

参考链接:
RISCV SOC开发环境 1——工具链的下载和安装
Ubuntu安装riscv-gnu-toolchain和riscv-tools

Logo

鸿蒙生态一站式服务平台。

更多推荐