Bootstrap

Reindeer-RISCV学习笔记(1)

参考的这本书《基于FPGA与RISC-V的嵌入式系统设计》
在这里插入图片描述

modelsim仿真

首先在arduino里面写好代码,编译:
在这里插入图片描述
然后将elf文件复制到modelsim文件夹下,运行python脚本:

python dram_dat_gen.py test1.ino.elf > sdram_ISSI_SDRAM_test_component.dat

然后打开modelsim运行下面的代码就行了。

do build_lib.do
do build_soc.do
do run_sim.do
run 100us

这里我们用riscv gcc工具链对elf文件反汇编:

riscv-none-embed-objdump.exe -D test1.ino.elf > test1.ino.s

显示某一个段内容:https://blog.csdn.net/whatday/article/details/99154104

riscv-none-embed-objdump.exe -j .data -d test1.ino.elf

riscv启动过程

RegisterABIUse by conventionPreserved?
x0zerohardwired to 0, ignores writesn/a
x1rareturn address for jumpsno
x2spstack pointeryes
x3gpglobal pointern/a
x4tpthread pointern/a
x5t0temporary register 0no
x6t1temporary register 1no
x7t2temporary register 2no
x8s0 or fpsaved register 0 or frame pointeryes
x9s1saved register 1yes
x10a0return value or function argument 0no
x11a1return value or function argument 1no
x12a2function argument 2no
x13a3function argument 3no
x14a4function argument 4no
x15a5function argument 5no
x16a6function argument 6no
x17a7function argument 7no
x18s2saved register 2yes
x19s3saved register 3yes
x20s4saved register 4yes
x21s5saved register 5yes
x22s6saved register 6yes
x23s7saved register 7yes
x24s8saved register 8yes
x25s9saved register 9yes
x26s10saved register 10yes
x27s11saved register 11yes
x28t3temporary register 3no
x29t4temporary register 4no
x30t5temporary register 5no
x31t6temporary register 6no
pc(none)program countern/a

在这里插入图片描述

sp指针:8M空间:为什么少了8字节?
在这里插入图片描述
在这里插入图片描述
initial可以被综合吗
在这里插入图片描述

gp指针
在这里插入图片描述

arduino源码分析

第一条质量地址是0,但是sdram的总线地址是0x80000000。
在这里插入图片描述
可以看elf文件头也有入口地址:
在这里插入图片描述

arduino初始化代码

test1.ino.elf:     file format elf32-littleriscv

Disassembly of section .text:

80000000 <_start>:
80000000:	00002197          	auipc	gp,0x2 #0x2000=8KB空间
80000004:	c3818193          	addi	gp,gp,-968 # 80001c38 <__global_pointer$>
80000008:	80c18513          	addi	a0,gp,-2036 # 80001444 <_edata>
8000000c:	87018613          	addi	a2,gp,-1936 # 800014a8 <_end>
80000010:	40a60633          	sub	a2,a2,a0
80000014:	00000593          	li	a1,0 #立即数加载,x[a1]=0
#void *memset(void *s, int ch, size_t n);
80000018:	7e8000ef          	jal	ra,80000800 <memset> #参数情况:a0=80001444,a1=0,a2=64
8000001c:	00000517          	auipc	a0,0x0
80000020:	6ec50513          	addi	a0,a0,1772 # 80000708 <__libc_fini_array>
80000024:	698000ef          	jal	ra,800006bc <atexit>
80000028:	740000ef          	jal	ra,80000768 <__libc_init_array>
8000002c:	00012503          	lw	a0,0(sp)
80000030:	00410593          	addi	a1,sp,4
80000034:	00000613          	li	a2,0
80000038:	294000ef          	jal	ra,800002cc <main>
8000003c:	6940006f          	j	800006d0 <exit>

第一次ra指针
在这里插入图片描述
pc指针:
注意,上面汇编一次增加4字节,而16位bus的sdram地址一次增加2字节,因此sdram地址和pc地址有这样的关系:

sdram addr = (pc addr - 0x80000000)/4 * 2;

在这里插入图片描述
16位sdram数据合并成32位数据是用移位寄存器实现的。如上图所示。

memset跳转:
在这里插入图片描述

__do_global_dtors_aux和__do_global_ctors_aux
在这里插入图片描述

80000308 <main>:
80000308:	ff010113          	addi	sp,sp,-16
8000030c:	00112623          	sw	ra,12(sp)
80000310:	2e4000ef          	jal	ra,800005f4 <_Z12noInterruptsv>
80000314:	0001c5b7          	lui	a1,0x1c
80000318:	20058593          	addi	a1,a1,512 # 1c200 <_start-0x7ffe3e00>
8000031c:	83418513          	addi	a0,gp,-1996 # 80001494 <Serial>
80000320:	06c000ef          	jal	ra,8000038c <_ZN14HardwareSerial5beginEm>
80000324:	800007b7          	lui	a5,0x80000
80000328:	19078793          	addi	a5,a5,400 # 80000190 <__global_pointer$+0xffffe530>
8000032c:	30579073          	csrw	mtvec,a5
80000330:	e05ff0ef          	jal	ra,80000134 <_Z5setupv> #setup
80000334:	e05ff0ef          	jal	ra,80000138 <_Z4loopv> #loop
80000338:	ffdff06f          	j	80000334 <main+0x2c> #jump to loop

总结

总结一下,reindeer的内存管理还是比较简单的,而且因为使用串口配合python脚本,使得启动代码也十分简单。虽然还没有尝试过arduino下载程序运行,不过大致原理应该一样。
下一步尝试将其移植到vivado平台上。

;