GNU toolchain(GNU工具链)是一个包含了由GNU项目所产生的各种编程工具的集合。这些工具形成了一条工具链(串行使用的一组工具),用于开发应用程序和操作系统。riscv-gnu-toolchain与普通gnu-toolchain基本相同,支持riscv32/64位指令集架构。
本文将在Ubuntu-22.04-LTS上编译riscv-gnu-toolchain

一、安装依赖包

sudo apt-get install autoconf
sudo apt-get install automake
sudo apt-get install autotools-dev
sudo apt-get install curl
sudo apt-get install python3
sudo apt-get install libmpc-dev
sudo apt-get install libmpfr-dev
sudo apt-get install libgmp-dev
sudo apt-get install gawk
sudo apt-get install build-essential
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install texinfo
sudo apt-get install gperf
sudo apt-get install libtool
sudo apt-get install patchutils
sudo apt-get install bc
sudo apt-get install zlib1g-dev
sudo apt-get install libexpat-dev
sudo apt-get install libnewlib-dev
sudo apt-get install device-tree-compiler

二、下载源码

下载riscv-gnu-toolchain

git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
git submodule update --init   #递归下载子模块

整个工具链主要包括以下模块:

  • -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和一个能处理系统调用的代理内核
    由于众所周知的原因,该过程可能持续一到两个小时。当出现如下信息时,表示下载成功,整个项目文件所占空间约1.8GB。
子模组路径 'glibc':检出 '9826b03b747b841f5fc6de2054bf1ef3f5c4bdf3'
子模组路径 'musl':检出 '85e0e3519655220688e757b9d5bfd314923548bd'
子模组路径 'newlib':检出 '415fdd4279b85eeec9d54775ce13c5c412451e08'
子模组路径 'pk':检出 '2efabd3e6604b8a9e8f70baf52f57696680c7855'
子模组路径 'qemu':检出 '823a3f11fb8f04c3c3cc0f95f968fef1bfc6534f'
子模组路径 'riscv-binutils':检出 '20756b0fbe065a84710aa38f2457563b57546440'
子模组路径 'riscv-dejagnu':检出 '4ea498a8e1fafeb568530d84db1880066478c86b'
子模组路径 'riscv-gcc':检出 '5964b5cd72721186ea2195a7be8d40cfe6554023'
子模组路径 'riscv-gdb':检出 '5da071ef0965b8054310d8dde9975037b0467311'
子模组路径 'spike':检出 'a0298a33e7b2091ba8d9f3a20838d96dc1164cac'

此时不要关闭终端。在图形界面进入riscv-gnu-toolchain文件夹,检查子模块的文件夹是否为空。

可能出现的问题及解决方法

1、下载失败
可以选择科学上网,也可选择重试大法。或者选择别的时间点进行下载,亲测北京时间凌晨3点至4点的下载速度很快。
2、提示下载完成,本地文件夹中却显示此文件夹为空
此时不要关闭终端,在riscv-gnu-toolchain文件夹下删除为空的子文件夹,在终端中重新执行git submodule update --init 命令即可。

三、创建安装目录及设置环境变量

sudo mkdir /opt/RISCV/riscv64
sudo chmod -R 777 /opt/RISCV/riscv64
sudo vim ~/.bashrc
export RISCV="/opt/RISCV/riscv64"       #工具链的安装链接路径
export PATH=$PATH:$RISCV/bin
source ~/.bashrc                      #使此设置永久有效,不然每次打开终端都需要重新设置

四、编译安装riscv-gnu-toolchain

riscv-gnu-toolchain可以编译为以下版本:

  • riscv32-unknown-elf-gcc
  • riscv64-unknown-elf-gcc
  • riscv32-unknown-linux-gnu-gcc
  • riscv64-unknown-linux-gnu-gcc
  • riscv64-multilib-elf-gcc
  • riscv64-linux-multilib-gcc
  • riscv-none-embed-gcc

riscv64-unknown-linux-gnu为前缀表示该版本的工具链是64位架构的Linux版本工具链。注意:此linux不是指当前版本工具链一定要运行在linux操作系统的电脑上,而是是指该GCC工具链会使用Linux的Glibc作为C运行库。
同理,riscv32-unknown-linux-gnu前缀的版本则是32位架构。
riscv64-unknown-elf为前缀表示该版本为非linux(Non-linux)版本的工具链。注意:此Non-Linux不是指当前版本工具链一定不能运行在Linux操作系统的电脑上,而是指该GCC工具链会使用newlib作为C运行库。
同理,riscv32-unknown-elf前缀的版本则是32位架构。
riscv64-multilib-elf为前缀表示该版本为同时支持32位和64位的裸机编译工具链。
riscv64-linux-multilib为前缀表示该版本为同时支持32位和64位的linux版本编译工具链。
riscv-none-embed为前缀版本表示是最新为裸机(bare-metal)嵌入式系统而生成的交叉编译工具链,所谓裸机(bare-metal)是嵌入式领域的一个常见形态,表示不运行操作系统的系统。该版本使用新版本的newlib作为C运行库,并且支持newlib-nano,能够为嵌入式系统生成更加优化的代码体积(Code Size)。

总结: riscv的gcc编译器,分为2大类:

  • 裸机: unknown-elf,none-embed
  • linux: linux
    除了non-embed编译器,对于每一类,如果禁用multilib,那么又分为32位版本和64位版本。如果使能multilib,那么就只有一个版本,但是这个版本工具,可以同时支持32位和64位。

1、编译riscv32-unknown-elf-gcc

cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=/opt/RISCV/riscv64 --with-arch=rv32imc --with-abi=xxx
sudo make -jN

2、编译 riscv64-unknown-elf-gcc

cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=/opt/RISCV/riscv64 --with-arch=rv64imc --with-abi=xxx
sudo make -jN

3、编译riscv32-unknown-linux-gnu-gcc

cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=/opt/RISCV/riscv32 --with-arch=rv64imc --with-abi=xxx --enable-linux
sudo make linux -jN

4、编译riscv64-unknown-linux-gnu-gcc

cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=/opt/RISCV/riscv64 --with-arch=rv64imafd --with-abi=lp64d --enable-linux --disable-multilib
sudo make linux -jN

5、编译riscv64-multilib-elf-gcc

编译multilib版本的gcc,可以同时支持32位和64位

cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=/opt/riscv64-multilib-elf --enable-multilib --target=riscv64-multilib-elf
sudo make -jN

对于riscv64-multilib-elf-gcc编译器,可以通过以下选项,来决定生成的程序是32位版本还是64位版本:

-march=rv32 : 32位版本
-march=rv64 : 64位版本

6、编译 riscv64-linux-multilib-gcc

cd riscv-gnu-toolchain
mkdir build
cd build
../configure --prefix=/opt/riscv-linux-multilib --enable-multilib --target=riscv64-linux-multilib
sudo make -jN

对于riscv64-linux-multilib-gcc编译器,可以通过以下选项,来决定生成的程序是32位版本还是64位版本:

-march=rv32 : 32位版本
-march=rv64 : 64位版本

7、riscv-none-embed-gcc

专门为嵌入式使用的gcc交叉编译工具链。官方网站:https://gnu-mcu-eclipse.github.io/toolchain/riscv/
可以直接下载linux的二进制执行程序,以及windows的安装包。这个一般要搭配GNU MCU eclipse工具一起使用。
因为这个工具,直接提供可执行程序,因此就不介绍了。

8、编译选项的含义

  • –prefix:编译结果安装目录
  • –with-arch:要安装的指令集架构

RISCV指令集采用模块化设计,用户可按需选择指令集。其中基本整数指令集为唯一强制要求实现的指令集。

基本指令集 指令数 描述
RV32I 47 32位整数指令集,包含算术、分支、访存指令,32位寻址空间,32个32位寄存器
RV32E 47 RV32I的子集,用于小型的嵌入式场景,16个32位寄存器
RV64I 59 64位整数指令集,兼容RV32I,64位寻址空间,32个64位寄存器
RV128I 71 128位整数指令集,兼容RV32I和RV64I,128位寻址空间,32个128位寄存器
拓展指令集 指令数 描述
M 8 乘法(Multiplication)指令集和除法指令集,包括4条乘法、2条除法、2条余数操作指令
A 11 存储原子(Automic)指令集,包含原子操作指令,如读-修改-写、比较-交换等
F 26 单精度浮点(Float,32bit)指令集
D 26 双精度浮点(Double,64bit)指令集,兼容F
C 26 压缩(Compresses)指令集,指令长度变为16位,目的是减少代码大小

【注:特定组合“IMAFD”被称为“通用(General)”组合,用字母G表示】
其他的扩展指令集还包括:

  • “B”标准扩展:位操作
  • “E”标准扩展:嵌入式
  • “H”特权态架构扩展:支持管理程序(Hypervisor)
  • “J”标准扩展:动态翻译语言
  • “L”标准扩展:十进制浮点
  • “N”标准扩展:用户态中断
  • “P”标准扩展:封装的单指令多数据(Packed-SIMD)指令
  • “Q”标准扩展:四精度浮点
  • –with-abi
    ABI(Application Binary Interface):应用程序二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口。ABI涵盖了各种细节,如:

数据类型的大小、布局和对齐;
调用约定(控制着函数的参数如何传送以及如何接受返回值),例如,是所有的参数都通过栈传递,还是部分参数通过寄存器传递;哪个寄存器用于哪个函数参数;通过栈传递的第一个函数参数是最先push到栈上还是最后;
系统调用的编码和一个应用如何向操作系统进行系统调用; 一个完整的操作系统ABI中,目标文件的二进制格式、程序库等等

i即int,l即long,p即pointer(指针),32/64指前面给出的类型是32位还是64位;
f即float,指float型浮点数参数通过浮点数寄存器传递
d即double,指float型和double型浮点数参数通过浮点数寄存器传递

数据模型 int字长 long字长 指针字长
ilp32 / ilp32f / ilp32d 32bit 32bit 32bit
lp64 / lp64f / lp64d 32bit 64bit 64bit
是否需要浮点扩展指令 float参数 double参数
ilp32 / lp64 不需要 通过整数寄存器(a0~a1)传递 通过整数寄存器(a0~a3)传递
ilp32f / lp64f 需要F扩展 通过浮点寄存器(fa0~fa1)传递 通过整数寄存器(a0~a3)传递
ilp32d / lp64d 需要F扩展和D扩展 通过浮点寄存器(fa0~fa1)传递 通过浮点寄存器(fa0~fa1)传递

浮点参数传递规则只与 --mabi选项有关,与--march选项没有直接关系。但是部分--mabi选项需要浮点寄存器,浮点寄存器是通过浮点扩展指令引入的,这就需要在--march选项中指定浮点扩展。

  • –enable-linux:编译结果在linux环境下运行
  • –disable-multilib:只编译64位程序,不兼容32位
    更多编译选项请使用命令../configure --help查看

9、测试

riscv64-unknown-linux-gnu-gcc -v

出现如下信息则表示安装成功

Using built-in specs.
COLLECT_GCC=riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/opt/RISCV/riscv64/libexec/gcc/riscv64-unknown-linux-gnu/11.1.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /home/lihua/riscv-gnu-toolchain/build/../riscv-gcc/configure --target=riscv64-unknown-linux-gnu --prefix=/opt/RISCV/riscv64 --with-sysroot=/opt/RISCV/riscv64/sysroot --with-pkgversion=g --with-system-zlib --enable-shared --enable-tls --enable-languages=c,c++,fortran --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libsanitizer --disable-nls --disable-bootstrap --src=../../riscv-gcc --disable-multilib --with-abi=lp64d --with-arch=rv64imafd --with-tune=rocket --with-isa-spec=2.2 'CFLAGS_FOR_TARGET=-O2   -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2   -mcmodel=medlow'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.1.0 (g)

五、编译安装riscv-tools

编译spike

进入spike目录下

cd spike
mkdir build
cd build
../configure --prefix=$RISCV
make
[sudo] make install                       #sudo为可选项

编译pk

进入pk目录下

cd pk
mkdir build
cd build
../configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu
make
make install

其中–host选项要为与之前构建的交叉编译器相匹配,如果之前构建的交叉编译器为riscv64-unknown-elf-gcc,则该项应设置为riscv64-unknown-elf。默认情况下将生成64位的可执行程序,如果想要生成32位可执行程序,请在configure后面添加--with-arch=rv32i

六、综合测试

编写一个测试程序

#include<stdio.h>
void main(){printf("hello world!\n");
}

使用riscv64-unknown-linux-gnu-gcc编译:

riscv64-unknown-linux-gnu-gcc -o hello hello.c -static

使用spike执行可执行文件:

spike pk hello

当屏幕上出现hello world时,则说明全套工具安装成功。

可能出现的问题及解决方法

当安装有多个版本的pk时,执行命令spike pk会报如下错误:

terminate called after throwing an instance of 'std::runtime_error'what():  could not open pk (did you misspell it? If VCS, did you forget +permissive/+permissive-off?)

此时则需要我们指定pk的绝对路径:

spike /opt/RISCV/riscv64/bin/pk hello

Ubuntu安装riscv-gnu-toolchain和riscv-tools相关推荐

  1. RISC-V GNU Toolchain及交叉编译

    交叉编译 想要理解riscv gnu Toolchain的作用,首先要了解交叉编译的概念.我们平时常见的架构有Intel的X86架构.龙芯处理器的MIPS架构.苹果A系列处理器的ARM架构等. 交叉编 ...

  2. linux使用交叉工具链产生的程序怎么下载到mini2440里,Ubuntu安装ARM架构GCC工具链(ubuntu install ARM toolchain)最简单办法...

    一.安装ARM-Linux-GCC工具链 只需要一句命令: sudo apt-get install gcc-arm-linux-gnueabi 前提是你的Ubuntu系统版本是官网支持的最新的版本, ...

  3. RISC-V GNU编译环境搭建与运行实践

    RISC-V GNU编译环境搭建与运行实践 riscv-gnu-toolchain交叉编译工具链 riscv-gnu-toolchain下载 riscv-gnu-toolchain编译 RISC-V运 ...

  4. ubuntu 安装linux 下vmVMware tools 步骤及问题解决

    ubuntu 安装linux 下vmVMware tools 步骤及问题解决 参考文章: (1)ubuntu 安装linux 下vmVMware tools 步骤及问题解决 (2)https://ww ...

  5. ubuntu安装VMware Tools

    ubuntu安装VMware Tools 安装VMware Tools安装包 安装VMware Tools 安装包为灰色 安装VMware Tools 安装成功 安装VMware Tools安装包 点 ...

  6. Ubuntu安装Caffe .build_release/tools/caffe: error while loading shared libraries: libcudart.so.8.0

    Ubuntu 安装caffe GPU版本的时候遇到 .build_release/tools/caffe: error while loading shared libraries: libcudar ...

  7. Ubuntu安装VMware Tools后不起作用

    Ubuntu安装VMware Tools后不起作用 问题: 按照教程安装VMware tools后,发现从Windows托文件到虚拟机还是不成功. 在网上找方法,重新卸载安装也不好使,卡了好久的问题. ...

  8. STM32MP157系列教程连载-Linux应用开发篇1:STM32MP1微处理器之Ubuntu安装与体验

    STM32MP157系列教程连载-Linux应用开发篇1:STM32MP1微处理器之Ubuntu安装与体验 截至目前上传的博文已经有6篇了(硬件4篇,安装环境2篇),最近手头在搞STM32MP157C ...

  9. [转]ubuntu 安装code blocks全记录

    ubuntu 安装code blocks全记录 转载来自 csdn 日志 (一)安装步骤: 1.先把编译环境,C库.C++库和Boost库装好,如下: sudo apt-get install bui ...

  10. ubuntu 安装code blocks全记录

    ubuntu 安装code blocks全记录   (一)安装步骤: 1.先把编译环境,C库.C++库和Boost库装好,如下: sudo apt-get install build-essentia ...

最新文章

  1. java string对象创建_String对象创建个数
  2. Citrx XenDesktop 7 实施三 配置XenServer
  3. *:学习心得——C语言----S1T62班 王作舟
  4. 20210307:力扣第231周周赛(上)
  5. Windows上Chrome被“毒霸网页“劫持启动页解决方式
  6. 判断二进制半整数_牛客网
  7. 怎样使用Javascript操作XMLDOM才能兼容IE、FireFox浏览器呢?
  8. Java class反编译工具
  9. OGNL表达式用法详解
  10. opencv4.0无法打开摄像头_笔记本电脑摄像头打不开怎么办
  11. Daily English Dictation Number Three
  12. cocoStudio工具的使用-----场景编辑器
  13. mysql 列连接_计数mysql中的连接列
  14. linux sed -i 命令
  15. kubernetes-准入控制器-13
  16. 测试韩国真假唇釉软件,3ce蓝管唇釉怎么辨别真假 3ce唇釉推荐色号
  17. 论文那些事—ZOO: Zeroth Order Optimization Based Black-box Attacks
  18. Eclipse clearcase plugin
  19. 汇编 浮点指令FLD,FSTP,FADD与FPU寄存器
  20. 从0开始使用百度地图

热门文章

  1. 练习-Java类和对象之包的定义(17)
  2. 电脑恶意软件删除方法
  3. ftp上传软件,推荐5款好用的ftp上传软件
  4. 实操!!!论坛项目开发流程(java)
  5. 如何加水印在图片上面?
  6. 我的深圳真实驾考经历
  7. 微信小程序Post方法提交数据
  8. 语义分割CCNet-Criss Cross Network论文中注意力机制Criss Cross Attention模块的tensorflow代码实现
  9. day 26 学习Linux-01天
  10. 算法 图3 六度空间