gpt4 book ai didi

riscv - 如何编译 C 代码以获得最小 RISC-V 汇编程序的裸机框架?

转载 作者:行者123 更新时间:2023-12-04 00:44:04 31 4
gpt4 key购买 nike

我有以下简单的 C 代码:

   void main(){
int A = 333;
int B=244;
int sum;
sum = A + B;
}

当我编译这个
$riscv64-unknown-elf-gcc code.c -o code.o

如果我想查看我使用的汇编代码
$riscv64-unknown-elf-objdump -d code.o 

但是当我探索汇编代码时,我发现这会生成很多代码,我认为这些代码是为了支持代理内核(我是 riscv 的新手)。但是,我不希望这段代码支持代理内核,因为这个想法是在 FPGA 中只实现这个简单的 C 代码。

我读到 riscv 提供了三种类型的编译:裸机模式、newlib 代理内核和 riscv Linux。根据之前的研究,我应该做的那种编译是裸机模式。这是因为我想要一个不支持操作系统或内核代理的最小程序集。不需要作为系统调用的汇编函数。

但是,我还没有找到,因为我可以编译 C 代码以获得最小 riscv 汇编程序的骨架。如何在裸机模式下编译上面的 C 代码或获得最小 riscv 汇编代码的骨架?

最佳答案

警告:这个答案在最新的 RISC-V Privileged Spec v1.9 中有些过时,其中包括删除 tohost控制/状态寄存器 (CSR),它是非标准主机目标接口(interface) (HTIF) 的一部分,现已被删除。当前(截至 2016 年 9 月)riscv-tests而是执行内存映射存储到 tohost内存位置,在联机环境中由 front-end server 监控.

如果你 真的真的需要/想要运行 RISC-V 代码裸机,那么这里是这样做的说明。你会丢失一堆有用的东西,比如 riscv-pk(代理内核)提供的 printf 或 FP-trap 软件仿真。

首先要做的事情 - Spike 在 0x200 启动。由于 Spike 是黄金 ISA 模拟器模型,您的内核也应该在 0x200 启动。

( 咳嗽 ,截至 2015 年 7 月 13 日,riscv-tools 的“master”分支( https://github.com/riscv/riscv-tools )正在使用旧的 pre-v1.7 特权 ISA,因此从 0x2000 开始。这篇文章将假设您使用的是 v1.7+,这可能需要使用 riscv-tools 的“new_privileged_isa”分支)。

所以当你反汇编你的裸机程序时,最好
从 0x200 开始!!!如果你想在代理内核之上运行它,它
最好从 0x10000 开始(如果是 Linux,它会更大……)。

现在,如果你想运行裸机,你就强制自己写下
处理器启动代码。呸。但是,让我们赌上这一点,假装那不是
必要的。

(你也可以查看 riscv-tests/env/p,对于“虚拟机”
物理寻址机器的描述。你会发现链接描述文件
您需要和一些 macros.h 来描述一些初始设置代码。或更好
然而,在 riscv-tests/benchmarks/common.crt.S)。

无论如何,有了上述(令人困惑的)知识,让我们抛开一切
离开并从头开始我们自己...

hello.s:
.align 6
.globl _start
_start:
# screw boot code, we're going minimalist
# mtohost is the CSR in machine mode
csrw mtohost, 1;
1:
j 1b

和链接.ld:
 OUTPUT_ARCH( "riscv" )
ENTRY( _start )
SECTIONS
{
/* text: test code section */
. = 0x200;
.text :
{
*(.text)
}
/* data: Initialized data segment */
.data :
{
*(.data)
}
/* End of uninitalized data segement */
_end = .;
}

现在编译这个…

riscv64-unknown-elf-gcc -nostdlib -nostartfiles -Tlink.ld -o hello hello.s

这编译为(riscv64-unknown-elf-objdump -d hello):
 hello: file format elf64-littleriscv

Disassembly of section .text:

0000000000000200 <_start>:
200: 7810d073 csrwi tohost,1
204: 0000006f j 204 <_start+0x4>

并运行它:
spike hello

这是一件美丽的事情。

链接脚本将我们的代码放置在 0x200。斯派克将从
0x200,然后将 #1 写入控制/状态寄存器
“tohost”,它告诉 Spike “停止运行”。然后我们旋转一个地址
(1: j 1b) 直到前端服务器收到消息并杀死我们。

如果您能弄清楚如何
告诉编译器自己将 <_start> 移动到 0x200。

对于其他示例,您可以仔细阅读以下存储库:

riscv-tests 存储库包含非常少的 RISC-V ISA 测试
( https://github.com/riscv/riscv-tests)。

这个 Makefile 有编译器选项:
https://github.com/riscv/riscv-tests/blob/master/isa/Makefile

许多“虚拟机”描述宏和链接器脚本可以
可以在 riscv-tests/env ( https://github.com/riscv/riscv-test-env) 中找到。

您可以在 ( riscv-tests/isa/rv64ui-p-simple.dump) 上查看“最简单”的测试。

您可以查看 riscv-tests/benchmarks/common用于运行裸机的启动和支持代码。

关于riscv - 如何编译 C 代码以获得最小 RISC-V 汇编程序的裸机框架?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31390127/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com