如何建立自己的RISC-V编译环境–汇编?
1.RISC-V编译环境框架
这是我RISC-V编译环境的架构:
build case common toolchain
| 一级目录 | 二级目录 | 说明 |
|---|---|---|
| build | - | xx.hex、xx.bin、xx.dump & xx.elf生成的目录。 |
| - | Makefile | 编译脚本。 |
| - | add(例子) | 生成文件,根据test.c生成的xx.hex、xx.bin、xx.dump & xx.elf |
| project | - | 各个目录的源代码。 |
| - | add(例子) | 放add项目的S文件。 |
| common | - | 各个项目公用的文件。 |
| - | encoding.h | /riscv-tests/env目录中的H文件。 |
| - | asm.h | /riscv-tests/env/p/riscv_test.h文件,只是我改为asm.h。 |
| - | asm.ld | /riscv-tests/env/p/link.ld文件,用于链接物理地址和汇编,我改名字为asm.ld了。 |
| toolchain | - | 工具链。我在/riscv-tools/riscv-gnu-toolchain/的工具链上提取了对我有用的部分。 |
2.各目录内容介绍
2.1 toolchain:工具链目录我不打算介绍,如果有不明白的,可以看我的这个博客:
rocket-chip工具链的编译与使用(https://blog.youkuaiyun.com/a_weiming/article/details/84801051)
2.2 project:这个目录就是放你的项目代码的。每个项目建立一个目录。在这个例子中,我放的是add目录,add的源代码如下(全为汇编代码):
此外,RISC-V汇编不熟悉的可以参考以下链接:
https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md
https://mp.weixin.qq.com/s/-syKN0DibKGGPCllaeNqMg
https://mp.weixin.qq.com/s/jyI-SSm_5Gg-KQyjKsIj5Q
https://mp.weixin.qq.com/s/3RHss3vhfK004-TtM8fpeA
https://mp.weixin.qq.com/s/Ln4qBYvSsgRvdiK1IJqI6Q
下面贴图为.section的说明。

注意,下文中使用“###”形式的均是我添加的注释,原代码中没有。
#*****************************************************************************
# add.S
#-----------------------------------------------------------------------------
#
# Test add instructions.
#
#屏蔽了原来的include "riscv_test.h"
######include "riscv_test.h"
#使用我自己的asm.h
#include "asm.h"
###使用RVTEST_RV32U段内容
RVTEST_RV32U
###使用RVTEST_CODE_BEGIN段内容
RVTEST_CODE_BEGIN
###按2^2字节(4字节)数据对齐
.align 2
###“.option push”伪操作暂时将当前的选项设置保存起来,
###从而允许之后使用.option伪操作指定新的选项;
###而“.option pop”伪操作将最近保存的选项设置恢复出来重新生效。
###通过“.option push”和“.option pop”的组合,便可以在汇编程序中在不影响全
###局选项设置的情况下,为其中嵌入的某一段代码特别地设置不同的选项。
###意思就是:
###在add.S这个汇编文件中,将前面其他.S/.h文件中的配置选项保存起来,
###然后在add.S文件中设置一些新的选项,新的选项就是下面的.option norvc
.option push
###伪操作表示接下来的汇编程序不可以被汇编生成16位宽的压缩指令。
.option norvc
###定义标签asm_start
asm_start:
###将0xAAAAAAAA赋给a1
li a1, 0xAAAAAAAA
###将0x22222222赋给a1
li a0, 0x22222222
###将a0和a1相加,并出入a2中
add a2, a1, a0
###将0x7000_0000存入a4中
lui a4, 0x70000
###将a4的值+4并存入a6中
addi a6, a4, 4
###将a2的结果存到总线为0x7000_0004的memory中
sw a2, 0(a6)
###将0xFF存到a5中
li a5, 255
###将a5的结果存到总线为0x7000_0000的memory中,用于停止VCS仿真
sw a5, 0(a4)
###恢复原选项配置
.option pop
###使用RVTEST_CODE_END段内容
RVTEST_CODE_END
###数据段.data:已初始化的C程序全局变量和静态局部变量。
.data
###使用RVTEST_DATA_BEGIN段内容
RVTEST_DATA_BEGIN
###使用RVTEST_DATA_END段内容
RVTEST_DATA_END
以下的定义在asm.h中有详细的说明。
RVTEST_RV32U
RVTEST_CODE_BEGIN
RVTEST_CODE_END
RVTEST_DATA_BEGIN
RVTEST_DATA_END
2.3 common:这个目录放的是通用的内容,例如asm.h和asm.lk。
2.3.1 encoding.h:这个文件不解释,就是RISC-V各重要CSR寄存器的定义。
2.3.2 asm.h:这个我是根据/riscv-tests/env/p/riscv_test.h文件进行修改的,下面简单说明一下里面各汇编的含义。
此外,我修改的是p目录下的文件,p目录下是单核的,而且是没有MMU的。具体env中各目录的差异大家可以看:
https://github.com/riscv/riscv-tests/tree/7ef425b4aea0a93568c788e68acebcc2f08da8d6

// See LICENSE for license details.
#ifndef _ENV_PHYSICAL_SINGLE_CORE_H
#define _ENV_PHYSICAL_SINGLE_CORE_H
#include "./encoding.h"
//-----------------------------------------------------------------------
// Begin Macro
//-----------------------------------------------------------------------
###定义宏init
#define RVTEST_RV64U \
.macro init; \
.endm
###定义宏init,同时运行RVTEST_FP_ENABLE段
#define RVTEST_RV64UF \
.macro init; \
RVTEST_FP_ENABLE; \
.endm
###定义宏init
#define RVTEST_RV32U

本文详细介绍了如何搭建RISC-V编译环境,包括环境框架、目录结构、Makefile脚本及工具链使用。通过具体示例,如汇编代码生成与链接,帮助读者理解RISC-V编译流程。
最低0.47元/天 解锁文章
2397

被折叠的 条评论
为什么被折叠?



