riscv引导程序及仿真记录

news2024/11/28 3:28:25

1.riscv基本的寄存器列表

这里只关注32个通用寄存器x0-x31

 2.引导程序代码

# 1 "iriscvboot.casm"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "iriscvboot.casm"

###define 0x52080000 0
# 29 "iriscvboot.casm"
 .section .text
 .org 0x0

_th0_reset:
 l.j _th0_main
 l.nop

_LOOP:
 l.j _LOOP   	

## === version info start at 0x80 ==
 .org 0x80
 .global _pack_version
 .global _build_date
 .global _api_version
_pack_version:
 .word 0x0171
_svn_version:
 .word 0x0367ad3
_build_date:
 .word 0x07e60701
_api_version:
 .word 0x0180
_silicon_version:
 .word 1000
## === version info end ===
###################################################################

_th0_main:
 l.addi x2,x0,0x0
 l.addi x3,x0,0x0
 l.addi x4,x0,0x0
 l.addi x5,x0,0x0
 l.addi x6,x0,0x0
 l.addi x7,x0,0x0
 l.addi x8,x0,0x0
 l.addi x9,x0,0x0
 l.addi x10,x0,0x0
 l.addi x11,x0,0x0
 l.addi x12,x0,0x0
 l.addi x13,x0,0x0
 l.addi x14,x0,0x0
 l.addi x15,x0,0x0
 l.addi x16,x0,0x0
 l.addi x17,x0,0x0
 l.addi x18,x0,0x0
 l.addi x19,x0,0x0
 l.addi x20,x0,0x0
 l.addi x21,x0,0x0
 l.addi x22,x0,0x0
 l.addi x23,x0,0x0
 l.addi x24,x0,0x0
 l.addi x25,x0,0x0
 l.addi x26,x0,0x0
 l.addi x27,x0,0x0
 l.addi x28,x0,0x0
 l.addi x29,x0,0x0
 l.addi x30,x0,0x0
 l.addi x31,x0,0x0
 l.lui  x2,0x52086


_init_cmem_done_th0:
 l.jal _mymain
 l.j _LOOP 

 3.引导代码含义,及相关指令。

.section .text表示下面的代码链接时放在.text段,.org设置当前代码的地址偏移(相对于链接时指定定.text段的起始地址)。

接下来定义了标签_th0_reset,riscv执行时从这儿开始执行指令,l.j  _th0_main表示跳转到
_th0_main标签处,
_th0_reset:
 l.j _th0_main
 l.nop

_th0_main标签处,连续的l.addi 指令可以理解为对32个通用寄存器的清操作。

但是注意 l.lui  x2,0x52086指令指定了sp寄存器(栈指针)的,开始地址。(lui 指令将 20 位立即数的值左移 12 位(低 12 位补 0)成为一个 32 位数,将此数写 回寄存器 x2 中。)

接着执行_init_cmem_done_th0标签处。此处就是我们定义的c程序的入口处。l.jal _mymain表示跳转到_mymain处,可以看下面c代码的汇编,其中会根据mymain函数创建_mymain标签。(jal 指令完成跳转并且将其下一条指令的 PC(即当前指令 PC+4)的值写入其结果寄存器 ra 中。注意:在实际的汇编程序编写中,跳转的目标往往使用汇编程序中的 label,汇编器 会自动根据 label 所在的地址计算出相对的偏移量赋予指令编码。

到_mymain中后就会执行c代码中内容了。 执行完c代码后,会根据ra寄存器的值返回来执行下一句,l.j _LOOP。这里是为了让riscv不乱跑,设置这个循环。

 4.c代码

C代码内容很简单,分别对0x1000这个地址写入次,第一次值100,第二次值0x202

void write32(int addr,int value) 
{
		int *addr_value;
		addr_value = (int*)addr;
		*addr_value = value;
}

void mymain()
{
	volatile int age=100;
	write32(0x1000,age);
	write32(0x1000,0x202);
}

C代码的汇编结果gcc -S:

	.file	"firmware.c"
	.option nopic
	.text
	.align	2
	.globl	_write32
	.type	_write32, @function
_write32:
	l.sw	a1,0(a0)
	l.ret
	.size	_write32, .-_write32
	.align	2
	.globl	_mymain
	.type	_mymain, @function
_mymain:
	l.add	sp,sp,-32
	l.li	a5,100
	l.sw	a5,12(sp)
	l.lw	a1,12(sp)
	l.li	a0,4096
	l.sw	ra,28(sp)
	call	_write32
	l.li	a1,514
	l.li	a0,4096
	call	_write32
	l.lw	ra,28(sp)
	l.add	sp,sp,32
	l.jr	ra
	.size	_mymain, .-_mymain
	.ident	"GCC: (GNU) 6.1.0"

5.链接

链接脚本

MEMORY
        {
        flash  : ORIGIN = 0x52040000, LENGTH = 0x00040000
        ram    : ORIGIN = 0x5b000000, LENGTH = 0x00006000
        glb    : ORIGIN = 0x52086000, LENGTH = 0x00032000
        rodata : ORIGIN = 0xa0000000, LENGTH = 0x00040000
        }
 
SECTIONS
{
      .text :
        {
        *(.text)
        } > flash
      .data :
        {
        *(.data)
        } > ram
      .bss :
        {
        *(.bss)
        } > ram

      .debug :
        {
        *(.debug_frame .zdebug_frame)
        *(.debug_abbrev)
        *(.debug_line)
        *(.debug_str)
        *(.debug_loc)
        *(.debug_macinfo)
        *(.debug_info)
        *(.debug_aranges)
        *(.debug_ranges)
        *(.comment)
        } > ram
      .rodata :
        {
        *(.rodata)
        } > rodata
}

链接结果,通过objdump工具进行反汇编注意使用-D选项,对所有段进行反汇编:


isp_firmware:     file format elf32-littleriscv


Disassembly of section .text:

52040000 <_th0_reset>:
52040000:	0940006f          	l.jal 	zero,52040094 <_th0_main>
52040004:	00000013          	l.addi 	zero,zero,0

52040008 <_LOOP>:
52040008:	0000006f          	l.jal 	zero,52040008 <_LOOP>
	...

52040080 <_pack_version>:
52040080:	00000171          	0x171

52040084 <_svn_version>:
52040084:	00367ad3          	l.fadd.s 	fs5,fa2,ft3

52040088 <_build_date>:
52040088:	07e60701          	0x7e60701

5204008c <_api_version>:
5204008c:	00000180          	0x180

52040090 <_silicon_version>:
52040090:	000003e8          	0x3e8

52040094 <_th0_main>:
52040094:	00000113          	l.addi 	sp,zero,0
52040098:	00000193          	l.addi 	gp,zero,0
5204009c:	00000213          	l.addi 	tp,zero,0
520400a0:	00000293          	l.addi 	t0,zero,0
520400a4:	00000313          	l.addi 	t1,zero,0
520400a8:	00000393          	l.addi 	t2,zero,0
520400ac:	00000413          	l.addi 	s0,zero,0
520400b0:	00000493          	l.addi 	s1,zero,0
520400b4:	00000513          	l.addi 	a0,zero,0
520400b8:	00000593          	l.addi 	a1,zero,0
520400bc:	00000613          	l.addi 	a2,zero,0
520400c0:	00000693          	l.addi 	a3,zero,0
520400c4:	00000713          	l.addi 	a4,zero,0
520400c8:	00000793          	l.addi 	a5,zero,0
520400cc:	00000813          	l.addi 	a6,zero,0
520400d0:	00000893          	l.addi 	a7,zero,0
520400d4:	00000913          	l.addi 	s2,zero,0
520400d8:	00000993          	l.addi 	s3,zero,0
520400dc:	00000a13          	l.addi 	s4,zero,0
520400e0:	00000a93          	l.addi 	s5,zero,0
520400e4:	00000b13          	l.addi 	s6,zero,0
520400e8:	00000b93          	l.addi 	s7,zero,0
520400ec:	00000c13          	l.addi 	s8,zero,0
520400f0:	00000c93          	l.addi 	s9,zero,0
520400f4:	00000d13          	l.addi 	s10,zero,0
520400f8:	00000d93          	l.addi 	s11,zero,0
520400fc:	00000e13          	l.addi 	t3,zero,0
52040100:	00000e93          	l.addi 	t4,zero,0
52040104:	00000f13          	l.addi 	t5,zero,0
52040108:	00000f93          	l.addi 	t6,zero,0
5204010c:	52086137          	l.lui 	sp,0x52086

52040110 <_init_cmem_done_th0>:
52040110:	010000ef          	l.jal 	ra,52040120 <_mymain>
52040114:	ef5ff06f          	l.jal 	zero,52040008 <_LOOP>

52040118 <_write32>:
52040118:	00b52023          	l.sw 	a1,0(a0)
5204011c:	00008067          	l.jalr 	zero,0(ra)

52040120 <_mymain>:
52040120:	fe010113          	l.addi 	sp,sp,-32 # 52085fe0 <_mymain+0x45ec0>
52040124:	06400793          	l.addi 	a5,zero,100
52040128:	00f12623          	l.sw 	a5,12(sp)
5204012c:	00c12583          	l.lw 	a1,12(sp)
52040130:	00001537          	l.lui 	a0,0x1
52040134:	00112e23          	l.sw 	ra,28(sp)
52040138:	fe1ff0ef          	l.jal 	ra,52040118 <_write32>
5204013c:	20200593          	l.addi 	a1,zero,514
52040140:	00001537          	l.lui 	a0,0x1
52040144:	fd5ff0ef          	l.jal 	ra,52040118 <_write32>
52040148:	01c12083          	l.lw 	ra,28(sp)
5204014c:	02010113          	l.addi 	sp,sp,32
52040150:	00008067          	l.jalr 	zero,0(ra)

Disassembly of section .debug:

5b000000 <.debug>:
5b000000:	3a434347          	l.fmsub.d 	ft6,ft6,ft4,ft7,rmm
5b000004:	4e472820          	0x4e472820
5b000008:	36202955          	l.c.setireg 	m18,m2,0x1b10
5b00000c:	302e312e          	0x302e312e
	...

 6.生成firmware

然后使用python脚本将,对应需要的段的地址和指令编码dump出来。使用的python脚本如下,输入文件是上面的反汇编结果:

#!/usr/bin/python

import sys
import re 

def replace_line(input_file, output_file): 
	input_f  = open(input_file, 'r')
	output_f = open(output_file, 'w')
	text=0;
	rodata=0;
	sdata=0;
	for line in input_f:
		line = line.rstrip() # removing right space
		#print(line)

		if("text" in line):
			text=1
			sdata=0
			rodata=0
		if("sdata" in line):
			sdata=1
			text=0
			rodata=0
		if("rodata" in line):
			rodata=1
			text=0
			sdata=0
		if(("debug" in line)):
			sdata=0;
			rodata=0;
			text=0;

		if (line.find('          	l.') != -1)&(text==1) : 
			line = line.replace (":", ",")
			words = line.split()
			output_f.write(words[0]+words[1]+'\n')

		if (re.findall(r'\d+:\s+\w+',line) != [])&(sdata==1) :  
			line = line.replace (":", ",")
			words = line.split()
			output_f.write(words[0]+words[1]+'\n')

		if (re.findall(r'\d+:\s+\w+',line) != [])&(rodata==1) :  
			line = line.replace (":", ",")
			words = line.split()
			output_f.write(words[0]+words[1]+'\n')



arg_list = sys.argv
print(arg_list[1])
print(arg_list[2])

if len(arg_list) != 3:
	print("need input file list")
	sys.exit()

replace_line(arg_list[1], arg_list[2])

dump出的firmware的文件如下,其中包含指令编码以及所放置的mem中的地址:

52040000,0940006f
52040004,00000013
52040008,0000006f
52040084,00367ad3
52040094,00000113
52040098,00000193
5204009c,00000213
520400a0,00000293
520400a4,00000313
520400a8,00000393
520400ac,00000413
520400b0,00000493
520400b4,00000513
520400b8,00000593
520400bc,00000613
520400c0,00000693
520400c4,00000713
520400c8,00000793
520400cc,00000813
520400d0,00000893
520400d4,00000913
520400d8,00000993
520400dc,00000a13
520400e0,00000a93
520400e4,00000b13
520400e8,00000b93
520400ec,00000c13
520400f0,00000c93
520400f4,00000d13
520400f8,00000d93
520400fc,00000e13
52040100,00000e93
52040104,00000f13
52040108,00000f93
5204010c,52086137
52040110,010000ef
52040114,ef5ff06f
52040118,00b52023
5204011c,00008067
52040120,fe010113
52040124,06400793
52040128,00f12623
5204012c,00c12583
52040130,00001537
52040134,00112e23
52040138,fe1ff0ef
5204013c,20200593
52040140,00001537
52040144,fd5ff0ef
52040148,01c12083
5204014c,02010113
52040150,00008067

 7.仿真结果

将上面dump出来的结果,进行仿真。结果如下所示。可以看见和C代码内容一样分别对0x1000这个地址写入次,第一次值100(0x64),第二次值0x202

pc指针的初始值值设置的是52040000,也就是.text的初始地址。

 

参考:

1.RISC-V架构与嵌入式开发快速入门

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/3790.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】进程间通信

文章目录1.进程间通信基础2.管道2.1匿名管道2.1.1匿名管道的原理2.2匿名管道的特点2.3匿名管道函数2.3.1用例2.3.2实现ps -ajx | grep bash指令2.4匿名管道的特点2.5管道的大小2.6管道的生命周期2.7进程池3.命名管道FIFO3.1命名管道的接口3.2命名管道和匿名管道的区别3.3用FIFO…

大数据面试重点之kafka(七)

大数据面试重点之kafka(七) Kafka的分区器、拦截器、序列化器&#xff1f; 问过的一些公司&#xff1a;ebay 参考答案&#xff1a; Kafka中&#xff0c;先执行拦截器对消息进行相应的定制化操作&#xff0c;然后执行序列化器将消息序列化&#xff0c;最后执行分 区器选择对应分…

python:基础知识

环境&#xff1a; window11python 3.10.6vscodejavascript、c/c/java/c#基础&#xff08;与这些语言对比&#xff09; 注释 一、数据类型 基础六大数据类型&#xff0c;可以使用 type()查看&#xff0c;如下图&#xff1a; 1.1 数字&#xff08;Number&#xff09; 支持 整…

联邦学习--记录

简介 联邦学习&#xff08;Federated Learning&#xff09;是一种新兴的人工智能基础技术&#xff0c;其设计目标是在保障大数据交换时的信息安全、保护终端数据和个人数据隐私、保证合法合规的前提下&#xff0c;在多参与方或多计算结点之间开展高效率的机器学习。其中&#…

【机器学习大杀器】Stacking堆叠模型-English

1. Introduction The stacking model is very common in Kaglle competitions. Why? 【机器学习大杀器】Stacking堆叠模型&#xff08;English&#xff09; 1. Introduction 2. Model 3: Stacking model 2.1 description of the algorithms: 2.2 interpretation of the es…

浅谈Vue中 ref、reactive、toRef、toRefs、$refs 的用法

&#x1f4ad;&#x1f4ad; ✨&#xff1a; 浅谈ref、reactive、toRef、toRefs、$refs   &#x1f49f;&#xff1a;东非不开森的主页   &#x1f49c;: 技术需沉淀&#xff0c;不要浮躁&#x1f49c;&#x1f49c;   &#x1f338;: 如有错误或不足之处&#xff0c;希望可…

Redhat(3)-Bash-Shell-正则表达式

1.bash脚本 2.bash变量、别名、算术扩展 3.控制语句 4.正则表达式 1.bash脚本 #!/bin/bash#this is basic bash script<< BLOCK This is the basic bash script BLOKC: This is the basic bash script echo "hello world!" 双引号、单引号只有在变量时才有区…

健身房信息管理系统/健身房管理系统

21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存储达到…

VCS 工具学习笔记(1)

目录 引言 平台说明 关于VCS 能力 Verilog 仿真事件队列 准备 VCS工作介绍 工作步骤 支持 工作机理 编译命令格式 编译选项 示例 仿真命令格式 仿真选项 示例 库调用 -y 总结 实践 设计文件 仿真文件 编译 仿真 关于增量编译 日志文件记录 编译仿真接续进…

链接脚本和可执行文件

几个重要的概念 摘取自知乎内容&#xff1a; 链接器与链接脚本 - 知乎 linker 链接器 链接器(linker) 是一个程序&#xff0c;这个程序主要的作用就是将目标文件(包括用到的标准库函数目标文件)的代码段、数据段以及符号表等内容搜集起来并按照 ELF或者EXE 等格式组合成一个…

【C++学习】string的使用

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; string的使用&#x1f640;模板&#x1f639;函数模板&#x1f639;类模板&#x1f640;string模板简…

【菜鸡读论文】Former-DFER: Dynamic Facial Expression Recognition Transformer

Former-DFER: Dynamic Facial Expression Recognition Transformer 哈喽&#xff0c;大家好呀&#xff01;本菜鸡又来读论文啦&#xff01;先来个酷炫小叮当作为我们的开场&#xff01; 粉红爱心泡泡有没有击中你的少女心&#xff01;看到这么可爱的小叮当陪我们一起读论文&am…

有了PySnooper,不用print、不用debug轻松查找问题所在!

PySnooper是一个非常方便的调试器&#xff0c;它是通过python注解的方式来对函数的执行过程进行监督的。 应用起来比较简单&#xff0c;不用一步一步的去走debug来查找问题所在&#xff0c;并且将运行过程中函数的变量值打印出来结果一目了然&#xff0c;相当于替代了print函数…

Boundary Loss 原理与代码解析

paper&#xff1a;Boundary loss for highly unbalanced segmentation Introduction 在医学图像分割中任务中通常存在严重的类别不平衡问题&#xff0c;目标前景区域的大小常常比背景区域小几个数量级&#xff0c;比如下图中前景区域比背景区域小500倍以上。 分割通常采用的交…

SpringBoot实践(三十三):Maven使用及POM详解

文章目录maven是什么maven怎么装settings.xml本地仓库地址&#xff1a;localRepository远程镜像&#xff1a;mirrorsJDK 版本&#xff1a;profile私服配置POM.xml中的常用标签projectmodelVersiongroupIdartifactIdversionpropertiesdependenciesbuild和pluginsresourcesdepend…

【学生管理系统】用户登录三种验证方式—图片验证、短信验证、邮件验证

目录 一、页面需求展示 二、验证方式—按钮组件 三、手机短信验证 四、邮件验证 五、图片验证邮件验证 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一下 一、页面需求展示 二、验证方式—按钮组件 2.1前端 <el-form-item labe…

【Linux】第十章 进程间通信(管道+system V共享内存)

&#x1f3c6;个人主页&#xff1a;企鹅不叫的博客 ​ &#x1f308;专栏 C语言初阶和进阶C项目Leetcode刷题初阶数据结构与算法C初阶和进阶《深入理解计算机操作系统》《高质量C/C编程》Linux ⭐️ 博主码云gitee链接&#xff1a;代码仓库地址 ⚡若有帮助可以【关注点赞收藏】…

工作流的例子

工作流的例子目录概述需求&#xff1a;设计思路实现思路分析1.配置bean2.examples3.no bean4.activiti-api-basic-process-example5.taskspringweb参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c…

C++ 多态类型

多态 C在面向对象中&#xff0c;多态就是不同对象收到相同消息&#xff0c;执行不同的操作。在程序设计中&#xff0c;多态性是名字相同的函数&#xff0c;这些函数执行不同或相似的操作&#xff0c;这样就可以用同一个函数名调用不同内容的函数。简而言之“一个接口&#xff…

2022 国赛postgresql

安装postgresql配置postgresql [root@linux3 ~]# postgresql-setup --initdb //初始化数据库Initializing database in ‘/var/lib/pgsql/data’Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log[root@linux3 ~]# systemctl enable postgresql.service Created …