前言

(1)此系列文章是跟着汪辰老师的RISC-V课程所记录的学习笔记。

(2)该课程相关代码gitee链接;
(3)

(4)在配置RSIC-V工具链的时候,踩了很多坑,虽然网上也有同类型的文章,并且riscv-gnu-toolchain仓库的readme已经进行了讲解。但是我还是斗胆写一个小白能够看懂的RSIC-V工具链配置教程。
(5)强调两点:
<1>因为RSIC-V是比较前沿的产物,所以对汉语的支持并不高,因此建议在Linux环境中尽量使用英文路径处理RSIC-V相关文件。
<2>Windows和Linux的换行符是不一样的,可能因为换行符的不一致,导致编译过程产生很多奇奇怪怪的bug。所以千万不要像我一样,先在Windows中做完一些操作,然后再传递给Linux。

为什么需要交叉编译工具链

(1)在我们刚学习编程语言的时候,都是直接拿一个编译器,写入如下代码。然后点击编译器的执行按钮就可以了。我们会发现,这个过程中,编译此c文件,执行这个c文件的机器都是同一台电脑。这个被称之为本地编译

#include <stdio.h>
int main()
{
	printf("hello world\r\n");
	return 0;
}

(2)但是,在嵌入式开发过程中。我们都是在电脑端写好一个程序,之后利用编译器编译程序,之后再将可执行程序烧录进入开发板中。我们能够发现,程序的编译是在电脑端,最终的可执行文件是在开发板中。这种称之为交叉编译
(3)一般来说,我们的电脑都是X86架构的,当我们需要编译RSIC-V的程序时候,肯定是不能使用本地编译工具,因此,我们这个时候就需要使用到交叉编译工具链了。

如何让Linux拥有魔法

(1)因为RSIC-V很多操作是在外网,而且开发过程肯定要在Linux中开发。所以,我这里建议让Linux也拥有访问世界的能力。
(2)需要注意的一点是,你按如下博客进行操作,需要Windows有魔法,否则无力回天呀。
(3)Ubuntu虚拟机共享主机VPN(适用于NAT或桥接)

如何安装交叉编译工具链

方法1

(1)如果是Ubuntu 20.04 环境下,可以直接执行如下指令安装官方提供的 GNU工具链和 QEMU 模拟器。
(2)这里需要注意一点的是,此时安装的gcc-riscv64-unknown-elf工具链似乎还不能编译c库函数。所以要执行第三条指令,使用gcc-riscv64-linux-gnu工具链。
(3)可能会有人要问了,这两条工具链有什么区别呢?
<1>riscv32-unknown-elf-gcc,riscv64-unknown-elf-gcc:使用的riscv-newlib库(面向嵌入式的C库),而且只支持静态链接,不支持动态链接。
<2>riscv32-unknown-linux-gnu-gcc,riscv64-unknown-linux-gnu-gcc:使用的是glibc标准库,支持动态链接。

sudo apt update
sudo apt install build-essential gcc make perl dkms git gcc-riscv64-unknown-elf gdb-multiarch qemu-system-misc
sudo apt install gcc-riscv64-linux-gnu

方法2

安装工具链

(1)我们直接拉取官方仓库的工具链再次强调,进行如下操作不能有任何非英文的路径!!!

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

(2)拉取完仓库之后,需要安装依赖文件。不同的Linux发行版执行的操作是不一样的,这个需要自己根据版本执行对应的命令。

# Ubuntu 
sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev
# Fedora/CentOS/RHEL
sudo yum install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel gawk  bison flex texinfo patchutils gcc gcc-c++ zlib-devel expat-devel
# Arch Linux 
sudo pacman -Syyu autoconf automake curl python3 libmpc mpfr gmp gawk base-devel bison flex texinfo gperf libtool patchutils bc zlib expat
#  OS X
brew install python3 gawk gnu-sed gmp mpfr libmpc isl zlib expat texinfo flock

(3)执行完上述两步骤之后,我们要根据需求安装gcc编译器。如果是想搞RISC-V的嵌入式开发,安装Newlib 库,只要执行一个make即可。如果是进行大型RSIC-V项目开发,使用Linux cross-compiler,那么编译时候输入make linux

cd riscv-gnu-toolchain/
mkdir build
cd build/
# 下面部分,需要你看需求来执行
# --------------------------------------------------------
# 如果只要进行64位的RISC-V的嵌入式系统开发,执行如下命令
../configure --prefix=/opt/riscv
# 这里的N是数字,表示多少核同时编译,N越大编译速度越快。
# 如果超出了虚拟机所分配的最大内核数量,将只会依据最大内核数量编译
sudo make -JN
# --------------------------------------------------------
# 如果还要进行32位的RISC-V的嵌入式系统开发,执行如下命令。
# 这个既可以进行64位开发,也可进行32位开发
../configure --prefix=/opt/riscv --enable-multilib
# 这里的N是数字,表示多少核同时编译,N越大编译速度越快。
# 如果超出了虚拟机所分配的最大内核数量,将只会依据最大内核数量编译
sudo make -JN
# --------------------------------------------------------
# 如果只要64位大型RSIC-V项目开发,执行如下命令
../configure --prefix=/opt/riscv
# 这里的N是数字,表示多少核同时编译,N越大编译速度越快。
# 如果超出了虚拟机所分配的最大内核数量,将只会依据最大内核数量编译
sudo make Linux -JN
# --------------------------------------------------------
# 如果还要进行32位大型RSIC-V项目开发,执行如下命令
# 这个既可以进行64位开发,也可进行32位开发
../configure --prefix=/opt/riscv --enable-multilib
# 这里的N是数字,表示多少核同时编译,N越大编译速度越快。
# 如果超出了虚拟机所分配的最大内核数量,将只会依据最大内核数量编译
sudo make Linux -JN
修改 ubunu 的环境变量

(1)安装完交叉工具链之后,我们还需要设置他的环境变量才可以执行交叉工具链。
(2)添加ubunu 的环境变量的方法有两种:
<1>直接在命令行输入如下指令,即可添加环境变量。缺点是,当你关闭当前的终端,重新打开终端的时候,又需要再次输入如下命令。因此,如下方法是临时添加环境变量的方式。

export PATH=$PATH:/opt/riscv/bin

<2>修改 .bashrc 文件:进入vim —> 按下Shift+g跳转到最后一行 —> 输入o,进入编辑模式 —> 输入添加环境变量的指令 —> 按下Esc键 —> 按下’:'键,输入wq —> 更新.bashrc 文件

vim ~/.bashrc
# 进入vim,按下Shift+g跳转到最后一行,输入o,进入编辑模式。
# 最后一行写入下面这个命令
export PATH=$PATH:/opt/riscv/bin
# 修改完 .bashrc 文件之后,输入下面这一句更新一下.bashrc 文件
source ~/.bashrc

虚拟机的内核数量相关信息

如何查看并且设置虚拟机内核数量

(1)关闭虚拟机—>编辑虚拟机—>设置内核数量

RSIC-V工具链介绍及其安装教程_环境变量

RSIC-V工具链介绍及其安装教程_工具链_02

虚拟机内核数量一般设置多大

(1)一般来说,虚拟机的内核数量最多为实际电脑的内核数量的一半。
(2)我们可以按照如下方式查看实际电脑内核数量

RSIC-V工具链介绍及其安装教程_工具链_03

RSIC-V工具链介绍及其安装教程_bash_04

执行RSIC-V架构的C程序

编译

(1)根据需求按照下图编译工程

#include <stdio.h>
int main()
{
	printf("hello world\r\n");
	return 0;
}

RSIC-V工具链介绍及其安装教程_工具链_05

执行

RSIC-V工具链介绍及其安装教程_工具链_06

参考文章

(1)RISC-V GNU编译环境搭建与运行实践;
(2)Ubuntu虚拟机共享主机VPN(适用于NAT或桥接)