山东大学RISC-V公共开放平台开发记录2

山东大学RISC-V公共开放平台开发记录

risc-V 学习

1 构建符合 GNU 规范的工具链(GCC、LD、GDB、GLIBC)

1.1 GCC 工具链
RISC-V GCC 工具链种类
RISC-V GCC 工具链与普通的 GCC 工具链基本相同,用户可以遵照开源的 riscv-
gnu-toolchain 项目(请在 Github 中搜索 riscv-gnu-toolchain)中的说明自行生
成全套的 GCC 工具链。

由于 GCC 工具链支持各种不同的处理器架构,因此不同处理器架构的 GCC 工具
链会有不同的命名。遵循 GCC 工具链的命名规则,当前 RISC-V GCC 工具链有
如下几个版本:

  • 以“riscv64-unknown-linux-gnu-”为前缀的版本,譬如 riscv64-unknown-
    linux-gnu-gcc、riscv64-unknown-linux-gnu-gdb、riscv64-unknown-linux-
    gnu-ar 等。“riscv64-unknown-linux-gnu-”前缀表示该版本的工具链是 64 位
    架构的 Linux 版本工具链。注意:此 Linux 不是指当前版本工具链一定要运
    行在 Linux 操作系统的电脑上,此 Linux 是指该 GCC 工具链会使用 Linux 的
    Glibc 作为 C 运行库。同理,“riscv32-unknown-linux-gnu-”前缀的版本则是
    32 位架构。注意:此处的前缀 riscv64(还有 riscv32 的版本)与运行在 64 位
    或者 32 位电脑上毫无关系,此处的 64 和 32 是指如果没有通过-march 和-

mabi 选项指定 RISC-V 架构的位宽,默认将会按照 64 位还是 32 位的 RISC-
V 架构来编译程序。有关-march 和-mabi 选项的含义,请参见第 3 节。

  • 以“riscv64-unknown-elf-”为前缀的版本,则表示该版本为非 Linux(Non-
    linux)版本的工具链。注意:此 Non-Linux 不是指当前版本工具链一定不能
    运行在 Linux 操作系统的电脑上,此 Non-Linux 是指该 GCC 工具链会使用
    newlib 作为 C 运行库。同上理,此处的前缀 riscv64(还有 riscv32 的版本)
    与运行在 64 位或者 32 位电脑上毫无关系,此处的 64 和 32 是指如果没有通
    过-march 和-mabi 选项指定 RISC-V 架构的位宽,默认将会按照 64 位还是
    32 位的 RISC-V 架构来编译程序。有关-march 和-mabi 选项的含义,请参见
    第 3 节。

  • 以“riscv-none-embed-”为前缀的版本,则表示是最新为裸机(bare-
    metal)嵌入式系统而生成的交叉编译工具链,所谓裸机(bare-metal)是嵌
    入式领域的一个常见形态,表示不运行操作系统的系统。该版本使用新版本
    的 newlib 作为 C 运行库,并且支持 newlib-nano,能够为嵌入式系统生成更
    加优化的代码体积(Code Size)。开源的蜂鸟 E203 MCU 系统是典型的嵌入
    式系统,因此将使用“riscv-none-embed-”为前缀的版本作为 RISC-V GCC 交
    叉工具链。注意:

此版本编译器由于使用 newlib 和 newlib-nano 作为 C 运行库,所以必须对
newlib 底层的桩函数进行移植,否则无法正常使用调用底层桩函数的 C 函数
( 譬如 printf 会调用 write 桩函数)

1.2 GCCGCC 工具链的(–march=march=)和(–mabi=mabi=)选项
  • (–march=)选项
    由于 RISC-V 的指令集是模块化的指令集,因此在为目标 RISC-V 平台进行交
    叉编译之时,需要通过选项指定目标 RISC-V 平台所支持的模块化指令集组
    合,该选项为(-march=),有效的选项值如下:
    • rv32i[m][a][f[d]][c]
    • rv32g[c]
    • rv64i[m][a][f[d]][c]
    • rv64g[c]
    注意:在上述选项中 rv32 表示目标平台是 32 位架构,rv64 表示目标平台是
    64 位架构,其他 i/m/a/f/d/c/g 分别代表了 RISC-V 模块化指令子集的字母简
    称。请参见 RISC-V 中文书籍《手把手教你设计 CPU——RISC-V 处理器篇》
    中附录 A.1 节中关于 RISC-V 架构指令集的详细中文介绍。

  • (–mabi=)选项
    由于 RISC-V 的指令集是模块化的指令集,因此在为目标 RISC-V 平台进行交
    叉编译之时,需要通过选项指定嵌入式 RISC-V 目标平台所支持的 ABI 函数调
    用规则(有关 ABI 函数调用规则的相关信息请参见 RISC-V 中文书籍《手把手
    教你设计 CPU——RISC-V 处理器篇》中附录 A 的图 A-1)。RISC-V 定义了
    两种整数的 ABI 调用规则和三种浮点 ABI 调用规则,通过选项(-abi=)指明,
    有效的选项值如下:
    • ilp32
    • ilp32f
    • ilp32d
    • lp64
    • lp64f
    • lp64d
    在上述选项中两种前缀(ilp32 和 lp64)表示的含义如下:
    • 前缀 ilp32 表示目标平台是 32 位架构,在此架构下,C 语言的“int”
    和“long”变量长度为 32 比特,“long long”变量为 64 位;
    • 前缀 lp64 表示目标平台是 64 位架构,C 语言的“int”变量长度为 32
    比特,而“long”变量长度为 64 比特。

RISC-V的32位和64位架构下更多的数据类型宽度如下图所示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBOF1Irl-1654330874389)(C:\Users\Jeremiah\AppData\Roaming\Typora\typora-user-images\image-20220604145455086.png)]

上述选项中的三种后缀类型(无后缀、后缀f、后缀d)表示的含义如下:

· 无后缀:在此架构下,如果使用了浮点类型的操作,直接使用RISC-V浮点指令进行支持。但是当浮点数作为函数参数进行传递之时,无论单精度浮点数还是双精度浮点数均需要通过存储器中的堆栈进行传递。

· f:表示目标平台支持硬件单精度浮点指令。在此架构下,如果使用了浮点类型的操作,直接使用RISC-V浮点指令进行支持。但是当浮点数作为函数参数进行传递之时,单精度浮点数可以直接通过寄存器传递,而双精度浮点数需要通过存储器中的堆栈进行传递。

· d:表示目标平台支持硬件双精度浮点指令。在此架构下,如果使用了浮点类型的操作,直接使用RISC-V浮点指令进行支持。当浮点数作为函数参数进行传递之时,无论单精度还是双精度浮点数都可以直接通过寄存器传递。

1.3c运行库

c语言标准主要分为描述C的语法和描述C标准库两部分。C标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类型声明和宏实现,例如printf函数。由于C语言标准仅仅定义了C标准库函数原型,并没有提供实现,因此C语言编译器通常需要一个C****运行库的支持。

glibc
linux下面的C标准的实现库有很多种,例如uclibc、klibc、linux libc等待,glibc (GNU C library)是其中的一种。

glibc本身是GNU旗下的C标准库,后逐渐成为了linux的标准库,通常被视为操作系统和用户程序的接口。例如glibc不仅实现标准C语言中的函数,还封装了操作系统提供的系统服务,及系统调用的封装。通常情况下,每个特定的系统调用对应了至少一个glibc封装的库函数,而一个glibc的API也有可能由多个系统调用

newlib
嵌入式系统中使用较多的实现库是Newlib,由redhat公司维护,最新的版本时newlib-nano。与glibc相比,newlib实现了大部分的功能函数,但体积小很多。newlib独特的体系结构将功能实现与具体的操作系统分层,使之能够很好的进行配置,以满足嵌入式系统的要求。根据嵌入式系统的特性,newlib具有可移植性强、轻量级、速度快、功能完备等特点。

在嵌入式操作系统中,OS和底层硬件具有多样性,为了将C/C++需要的运行库与具体的操作系统和底层硬件分层,newlib的所有库函数都建立在20个桩函数的基础上,这20个桩函数完成具体操作系统和底层硬件的如下功能:
1)I/O和文件系统访问(open、close、read、write、lseek、stat、fstat、fcntl、link、unlink、rename)
2)扩大内存堆的需求(sbrk)
3)获得当前系统的日期和时间(gettimeofday、times)
4)各种类型的任务管理函数(execve、fork、getpid、kill、wait、exit)

1.4GDB

GDB既是一种本地调试器,也是常用的远程调试工具,可以用于对程序进行调试。与本地编译和交叉编译同理,当平台自身无法运行完整的调试器时,就需要PC上的调试器对其进行远程调试;本地调试可以在平台自身上进行调试。

对于远程调试,一般采用GDB+GDBServer的方式,即GDBServer在目标硬件上运行,而GDB在PC上运行。

GDB 是 GNU Project debug 调试工具,它可以查看另一个程序在执行过程中正在执行的操作或者查看该程序崩溃时正在执行的操作。GDB 调试的程序可能与GDB(本机)在同一台计算机上执行,在另一台计算机(远程)上或在模拟器上执行。GDB可以在不同平台中使用,常见的 linux 与 windows 均可[21]。GDB 可以做四种主要的事情(以及支持这些事情的其他事情)来帮助您获取程序中的错误:v 启动程序,并指定可能影响其行为的所有内容;v 在规定条件下,程序触发条件并停止执行; v 当程序停止时,检查发生了什么; v 更改程序中的内容,以便可以尝试修改一个错误的影响,然后继续学习另一个错误。

GDB 的功能非常强大,基本上可以调试任何程序。下面简单说明本次工作使用gdb 调试的主要命令:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VlqK7LFI-1654330874390)(C:\Users\Jeremiah\AppData\Roaming\Typora\typora-user-images\image-20220604145553491.png)]

1.5 binutils工具

GNU Binary Utilities或binutils是一整套的编程语言工具程序,用来处理许多格式的目标文件。当前的版本原本由在Cygnus Solutions的程序员以Binary File Descriptor library(libbfd)所撰写。这个工具程序通常搭配GCC、make、和GDB这些程序来使用。

刚开始时,这个包内只有几支程序,但后来,由于功能需求近似,陆续加入了GNU汇编器(GAS)和GNU链接器(GLD)。一般来说,这些程序都很简单,大部分的复杂性都存在于Binary File Descriptor library和libopcodes这些库里头。

原来的BFD版本由David Henkel-Wallace和Steve Chamberlain所撰写。Ken Raeburn和Ian Lance Taylor曾维护过。目前则是由Nick Clifton负责维护此版本。至于Linux上的版本,由H.J. Lu在维护。

As汇编器
Ld链接器
gprof性能分析工具程序
Addr2line从目标文件的虚拟地址获取文件的行号或符号
Ar可以对静态库做创建、修改和取出的操作。
c++filt解码C++ 的符号
dlltool创建Windows动态库
Gold另一种链接器
nlmconv可以转换成NetWare Loadable Module目标文件格式
Nm显示目标文件内的符号
Objcopy复制目标文件,过程中可以修改
Objdump显示目标文件的相关信息,亦可反汇编
Ranlib产生静态库的索引
Readelf显示ELF文件的内容
Size列出总体和section的大小
Strings列出任何二进制档内的可显示字符串
Strip从目标文件中移除符号
windmc产生Windows消息资源
rings列出任何二进制档内的可显示字符串
Strip从目标文件中移除符号
windmc产生Windows消息资源
windresWindows 资源档编译器
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值