RISC-V 编译环境搭建:riscv-gnu-toolchain 和 riscv-tools

RISC-V 编译环境搭建:riscv-gnu-toolchain 和 riscv-tools

编译环境搭建以及说明

操作系统:什么系统都可以
虚拟机:VMmare Workstation Pro 17.50.x (版本不限)
编译环境:Ubuntu 18.04.5 
CPU:i7-8750h(虚拟机分配4核8线程,基频2.2GHz,睿频3.9GHz) 
RAM:32GB(虚拟机分配10GB,3G以上均可)
梯子:这里由于有些地方无法访问github,这里最好在 Linux 系统中搭建梯子,这样以确保成功下载
  • 建议有条件可以直接装Linux系统,虚拟机有很大的性能损失。如果使用虚拟机,建议分配足够多的RAM内存

  • 推荐搭建科学合理的上网方式,在git clone tool-gnu-chain这个库的时候,有几个submodule如果网络状态不好,下载速度会以kb状态,并以fatal error收尾(在尝试过6个上网工具之后的感受)

  • 编译riscv-gnu-toolchain和riscv-tools的顺序不能变,否则会在之后报错

riscv-tools 环境安装

  • Git库所需要的各种前述依赖(此处更新命令
sudo apt-get 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
  • 建议在自己制定路径下新建文件夹进行下载和配置,例如:
mkdir /home/{你的用户名}/RISCV
  • 下载riscv-tools(此处按照 GitHub 增补库,一次性库补全):
git clone --recursive https://github.com/riscv/riscv-tools.git

​ 如果上述命令中间存在失败的过程,我们就需要删除已经下载好的文件,重新下载安装,尝试优先建议国内先git clone库,进入库文件夹之后执行recursive命令(二者等效);可以同时开多个 terminal 下载各个库

​ 首先我们下载 riscv-tools 包:

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

​ 然后查看我们 riscv-tools 包中需要补充的子模块:

cat riscv-tools/.gitmodules

image

​ 图中子库均包含在顶层 .gitmodules 文件中,可以用下面命令进行安装:

cd riscv-tools 
git clone --recursive https://github.com/riscv/riscv-openocd.git 
git clone --recursive https://github.com/riscv/riscv-isa-sim.git 
git clone --recursive https://github.com/riscv/riscv-opcodes.git 
git clone --recursive https://github.com/riscv/riscv-pk.git 
git clone --recursive https://github.com/riscv/riscv-tests.git

riscv-gnu-toolchain 环境安装

  • 下载riscv-gnu-toolchain(主要内容)
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain

​ 同样可以先 git clone 库,再执行 recursive 的命令:

git clone https://github.com/riscv/riscv-gnu-toolchain 

​ 查看所需要的库:

cat riscv-gnu-toolchain/.gitmodules

image

​ 图中子库均包含在顶层 .gitmodules 文件中,可以用下面命令进行安装(已更新到最新版链接):

cd riscv-gnu-toolchain 
# git clone --recursive https://github.com/riscv-collab/riscv-binutils-gdb.git			#binutils与gdb在同一仓库地址,只是分支不同
git clone --recursive -b binutils-2_42-branch https://sourceware.org/git/binutils-gdb.git binutils
git clone --recursive -b gdb-14-branch https://sourceware.org/git/binutils-gdb.git gdb
# git clone --recursive https://github.com/riscv-collab/riscv-gcc.git 
git clone --recursive -b releases/gcc-13 https://gcc.gnu.org/git/gcc.git gcc
git clone --recursive https://sourceware.org/git/glibc.git glibc						#原链接git://sourceware.org/git/glibc.git; 修改为https协议便于下载,下同 
# git clone --recursive https://github.com/riscv-collab/riscv-dejagnu.git 
git clone --recursive -b master https://git.savannah.gnu.org/git/dejagnu.git dejagnu
git clone --recursive -b master https://sourceware.org/git/newlib-cygwin.git newlib		#原链接git://sourceware.org/git/newlib-cygwin.git
# git clone --recursive https://git.qemu.org/git/qemu.git 
git clone --recursive https://gitlab.com/qemu-project/qemu.git qemu
# git clone --recursive git://git.musl-libc.org/musl									#修改https也不一定有用,建议直接转到链接下载最新的压缩包
git clone --recursive -b master https://git.musl-libc.org/git/musl musl
git clone --recursive -b master https://github.com/riscv-software-src/riscv-isa-sim.git spike
git clone --recursive -b master https://github.com/riscv-software-src/riscv-pk.git pk
git clone --recursive -b release/17.x https://github.com/llvm/llvm-project.git llvm

riscv-binutils-gdb 实际上是两个文件夹内容,所以下载完成之后,需要进行分割,这里我们采用分支的方式已经完成了分割

​ 当前状态不需要手动分隔;该步骤已经更新入后续 makefile

提醒一下,如果是第一种直接 –recursive 的方式,binutils,gdb 和 riscv-gcc 大概率会在第一次失败,等待 reschedule 之后会成功

​ 这里的 binutils、qemu、musl、llvm 比较容易下载失败,如果下载失败后,需要删除文件夹,重新下载即可

​ 建议在拥有良好网络状态的环境下使用第一种方式,并且最后 git clone 校验表明所有 submodule 均已成功下载,否则,删除没有成功的文件夹,用第二种方式逐条下载

请务必保证每个 submodule 均已成功下载并且所在文件夹内拥有充足内容。整个 riscv-gnu-toolchain 大概有 6.65GB (官方声称)左右

  1. 编译步骤

​ export路径:

# 在 .bashrc 中定义路径和 export 之后 bin 文件,方便以后直接使用 tab 补全 riscv64 工具链
sudo vim ~/.bashrc

进入bashrc后在尾部添加

export RISCV="/home/{你的用户名}/RISCV/riscv" #参考链接中此处有误 
export PATH=$PATH:$RISCV/bin #该路径下为链接工具

保存退出后,执行source实时生效

source ~/.bashrc

可以在shell中敲入,确认路径是否正确

echo $RISCV

image

编译riscv-gnu-toolchain

​ 这一步是最头疼的地方,一方面是整个编译时间非常的长,在我前述配置环境下大概要1个小时多;另一方面,如果当前文件夹中任何一个 submodule 没有 clone --recuresive 完整的话,中途就会报错,再次编译只能重头开始

如果你中途报错了,不要犹豫,定位子模块文件夹之后重新git clone,make clean之后重新开始。

cd riscv-gnu-toolchain ./configure --prefix=$RISCV --enable-multilib make 
#注意是make而不是make linux(参考一个版主的讲解)

我在这里使用了 enable-multilib 的选项,主要是因为需要32和64位两种环境。一般情况下,建议你在 riscv-gnu-toolchain 网站中确认自己需要的编译库

​ riscv-gnu-toolchain

注:make 编译得到是我们最常用的 unknown-elf-gcc 等工具链,而 make linux 则是 unknown-linux-gnu-gcc

多嘴一句,目前 RISC-V 主流还在 32bit 的环境下,64bit 实用上确实是少之又少,但是虽然少,还是不能忽略

整个make大概需要一个小时,完成后,riscv-gnu-toolchain文件占用13GB左右空间。

事实上,到这一步结束,riscv-unknown-elf 工具链已经创建成功,接下来步骤是创建相关仿真工具,如果没有需求可以不用继续。

​ 编译riscv-tools

cd riscv-tools ./build.sh

一般教程上是这样的流程,但是因为我在之前 make gnu-toolchain 中开启了 –enable-multilib 的选项,所以在这里使用 build.sh 进行构建时会在编译 benchmark/dhrystone 这个 file 的时候出现 ld 链接重复的问题,如果你在 riscv-gnu-toolchain 中了其他选项,有可能不会出错。当然为了绕开这个东西,我选择执行另一个:

./build-spike-pk.sh

其实最主要使用的也就是 spike 和 pk 这个仿真工具

至此,在没有 error 的情况下,整个编译过程就结束了

Hello World

​ 用任意你喜欢的方式创建hello.c文件

#include <stdio.h>  int main(void) {         printf("Hello RISC-V!\n");         return 0; }`

​ 编译

riscv64-unknown-elf-gcc -march=rv32imac -mabi=ilp32 -o hello hello.c

需要注意的时,rv 工具链编译出来的文件,linux 系统是无法使用 ./hello 来执行的。需要用 spike 进行仿真,但是 spike 需要配置 text 段,这个之后我找到正确的方法再更新

我这里使用的 gem5 进行验证,没有出现问题

可能出现和存在的问题

​ 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-gnu-toolchain

​ 路径中不要有中文字符,这个就要修改路径下所有带有中文字符的文件夹名称了

梯子推荐

这里推荐使用”魔界“,靠谱稳定,某管视频可以实现 4k/8k 无延迟、无卡顿,github 连接快速,节点多,支持 chatgpt,流量付费,不限时间,价格最优惠

点击连接跳转注册使用:魔界

参考资料

参考版块:

riscv各种版本gcc工具链编译与安装 #链接库说明

GCC RISCV环境搭建 #另一篇指导

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/749877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM学习-JMM

目录 1.什么是JMM 2.JMM怎样保障数据的可见性、有序性、原子性 2.1保证原子性 2.2.保证可见性 2.3保证有序性 3.CAS 3.1乐观锁和悲观锁 3.2 CAS介绍 4.重量级锁的自旋优化 1.什么是JMM JMM即Java内存模型 &#xff0c;定义了一套在多线程读写共享数据&#xff08;如数组、成…

openssl3.2 - note - Writing OpenSSL Provider Skeleton

文章目录 openssl3.2 - note - Writing OpenSSL Provider Skeleton概述笔记测试工程的建立复现的provider工程总结Provider包含的头文件openssl/core.h中的数据结构实现 OSSL_provider_init()看一下openssl自带的提供者provider的openssl命令行测试provider的本质是hook了opens…

插入排序:一种简单而有效的排序算法

插入排序&#xff1a;一种简单而有效的排序算法 一、什么是插入排序&#xff1f;二、插入排序的步骤三、插入排序的C语言实现四、插入排序的性能分析五、插入排序的优化六、总结 在我们日常生活和工作中&#xff0c;排序是一种非常常见的操作。比如&#xff0c;我们可能需要对一…

【 c 语言 】指针入门

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;C语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&…

ChatGPT编程—实现小工具软件(文件查找和筛选)

ChatGPT编程—实现小工具软件(文件查找和筛选) 今天借助[小蜜蜂AI][https://zglg.work]网站的ChatGPT编程实现一个功能&#xff1a;根据特定需求结合通配符和其他条件来进行文件查找和筛选。在这个例子中&#xff0c;我们将创建一个函数find_files&#xff0c;它接受用户输入的…

RK3568平台开发系列讲解(基础篇)内核是如何发送事件到用户空间

🚀返回专栏总目录 文章目录 一、相关接口函数二、udevadm 命令三、实验沉淀、分享、成长,让自己和他人都能有所收获!😄 一、相关接口函数 kobject_uevent 是 Linux 内核中的一个函数, 用于生成和发送 uevent 事件。 它是 udev 和其他设备管理工具与内核通信的一种方式。…

设计模式学习笔记 - 规范与重构 - 8.实践:程序出错返回啥?NULL、异常、错误吗、空对象?重构ID生成器,处理各函数的异常

概述 我们可以把函数的运行结果分为两类。一类是预期结果&#xff0c;也就是正常情况下输出的结果。一类是非预期的结果&#xff0c;也就是函数在异常&#xff08;或出错&#xff09;情况下输出的结果。 在正常情况下&#xff0c;函数返回数据的类型非常明确&#xff0c;但是…

【Spring Boot】创建你的第一个 Spring Boot 应用

创建你的第一个 Spring Boot 应用 1.环境配置2.步骤详解3.项目结构分析3.1 入口类 DemoApplication3.2 控制器 PathVariableController3.3 控制器 BasicController3.4 模型 User 4.运行 Spring Boot 目前已经成为了 Java 开发领域的框架范式。本篇博客&#xff0c;我将带领大家…

layui table列表重载后保持进度条位置不变

使用layui的table表格组件时&#xff0c;当我们操作了某行的修改后&#xff0c;刷新了页面&#xff0c;进度条则跳回到最上面。 除了layui高版本应该内置有方法解决了此问题&#xff0c;但是低版本需要另外想办法解决。 具体解决方式如下&#xff1a; 1.在编辑操作成功前&am…

【List、Set、数据结构、Collections】-Collections

day03 【List、Set、数据结构、Collections】 5.3 简述Comparable和Comparator两个接口的区别。 Comparable&#xff1a;强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序&#xff0c;类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo…

【Linux的 yum_vim工具篇】

Linux学习笔记---004 Linux的yum_vim工具篇1、Linux软件包管理器yum1.1、yum是什么&#xff1f;1.2、软件包是什么&#xff1f;软件包是谁给提供的呢&#xff1f;1.3、Linux系统(其中的centos 7)生态 2、yum的相关操作2.1、yum基本指令格式2.2、软件源 3、yum的本地配置3.1、配…

Lua-Lua与C++的交互2

Lua与C的交互是指在C程序中使用Lua本语言&#xff0c;或者在Lua脚本中调用C代码的过程。这种交互可以实现C与Lua之间的数据传递和函数调用。 在C中与Lua交互的主要步骤如下&#xff1a; 引入Lua库&#xff1a;首先需要在C程序中引入Lua的头文件和库文件&#xff0c;以便能够使…

pytorch中张量变换函数

在PyTorch中view(), transpose() 和 permute() 函数都是用于改变张量&#xff08;Tensor&#xff09;维度结构的&#xff0c;但它们的作用和使用场景有所不同。 torch.view() 功能&#xff1a;该函数用于将一个张量重塑为新的形状&#xff0c;但它必须保持原有元素数量不变。它…

【MASM汇编语言快速入门】8086MASM汇编深入理解指令对标志位的影响

8086MASM汇编深入理解指令对标志位的影响 文章目录 8086MASM汇编深入理解指令对标志位的影响0. 指令对标志位影响1. 指令对标志位影响速查表2. flags标志寄存器: 标志位含义解读flags1. 状态标志cf, pf, af, zf, sf, of2. 控制标志df, if, tf 详解&#xff1a;1. 传送指令2. 算…

如何在IDEA 中设置背景图片

在IDEA 中设置背景图片&#xff0c;可以按照以下步骤操作&#xff1a; 1、打开 IntelliJ IDEA 软件&#xff0c;进入代码编辑主界面。 点击编辑窗口上方的“File”菜单项。 2、在下拉子菜单中&#xff0c;选择“Settings”选项&#xff08;如果你使用的是 macOS&#xff0c;可…

AUTOSAR汽车电子嵌入式编程精讲300篇-车载 CAN 总线延时特性分析及优化(续)

目录 3.1.2 通信错误恢复时间 3.2 延时指标研究 3.2.1 总线 Burst 情况 3.2.2 抖动

vue3子父组件之间的调用

子组件&#xff1a; capacityIndex.vue 父组件&#xff1a; index.vue A.子组件获取父组件属性 1.在父组件中引用子组件 import capacityIndex from "./capacityIndex"; <capacityIndex :tankInfo"tankInfo" :deviceNameInfo"deviceNameInfo…

Spark-Scala语言实战(1)

在之前的文章中&#xff0c;我们学习了如何在Linux安装Spark以及Scala&#xff0c;想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 Spark及Scala的安装https:/…

【智能算法】保姆级教程-如何使用CEC测试集,以及如何定义自己的优化问题

目录 1.准备工作2.使用CEC2005测试集3.自定义优化问题-无约束问题4.自定义优化问题-有约束问题5.代码实现 1.准备工作 一个CEC2005测试集 一个测试智能算法&#xff0c;比如麻雀搜索算法SSA 2.使用CEC2005测试集 以CEC2005测试集函数F7为例&#xff1a; 3.自定义优化问题…

solr/ES 分词插件Jcseg设置自定义词库

步骤&#xff1a; 1、找到配置文件jcseg-core/target/classes/jcseg.properties修改配置&#xff1a; 下载地址: https://gitee.com/lionsoul/jcseg#5-如何自定义使用词库 lexicon.path {jar.dir}/../custom-word 设置lexicon路径&#xff0c;我们这个配置可以自定义&#xf…