RISC-V体系结构的U-Boot引导过程 第一阶段

这篇具有很好参考价值的文章主要介绍了RISC-V体系结构的U-Boot引导过程 第一阶段。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

RISC-V体系结构的U-Boot引导过程 第一阶段

flyfish

.globl _start
_start:

.globl使符号对链接器可见相当于C语言中的Extern,声明此变量,并且告诉链接器此变量是全局变量,外部可以访问.u-boot.lds里的ENTRY(_start)也是这里的_start。
即指定入口为_start,_start就是整个start.S的开始的地方,是整个uboot的代码的开始
_start:表示其是一个标号Label,类似于C语言goto后面的标号

RISC-V体系结构的U-Boot引导过程 第一阶段

#if CONFIG_IS_ENABLED(RISCV_MMODE)
	csrr	a0, CSR_MHARTID
#endif

RISCV_MMODE 就是 machine mode
RISCV_SMODE就是supervisor mode
依据

choice
	prompt "Run Mode"
	default RISCV_MMODE

config RISCV_MMODE
	bool "Machine"
	help
	  Choose this option to build U-Boot for RISC-V M-Mode.

config RISCV_SMODE
	bool "Supervisor"
	help
	  Choose this option to build U-Boot for RISC-V S-Mode.
#define CSR_MHARTID		0xf14

执行该语句csrr a0, CSR_MHARTID之后a0寄存器存储了hartid
依据下表
RISC-V体系结构的U-Boot引导过程 第一阶段

la	t0, trap_entry

la t0, trap_entry
LA是Load Address,语法是LA rd, symbol
la指令的格式,将内存地址symbol加载到rd寄存器中
trap_entry 可以看mtrap.S
这里是将trap_entry加载到临时寄存器t0中

#include <common.h>
#include <asm/encoding.h>

#ifdef CONFIG_32BIT
#define LREG		lw
#define SREG		sw
#define REGBYTES	4
#else
#define LREG		ld
#define SREG		sd
#define REGBYTES	8
#endif

	.text

	/* trap entry */
	.align 2
	.global trap_entry
trap_entry:
	addi sp, sp, -32 * REGBYTES
	SREG x1,   1 * REGBYTES(sp)
	SREG x2,   2 * REGBYTES(sp)
	SREG x3,   3 * REGBYTES(sp)
	SREG x4,   4 * REGBYTES(sp)
	SREG x5,   5 * REGBYTES(sp)
	SREG x6,   6 * REGBYTES(sp)
	SREG x7,   7 * REGBYTES(sp)
	SREG x8,   8 * REGBYTES(sp)
	SREG x9,   9 * REGBYTES(sp)
	SREG x10, 10 * REGBYTES(sp)
	SREG x11, 11 * REGBYTES(sp)
	SREG x12, 12 * REGBYTES(sp)
	SREG x13, 13 * REGBYTES(sp)
	SREG x14, 14 * REGBYTES(sp)
	SREG x15, 15 * REGBYTES(sp)
	SREG x16, 16 * REGBYTES(sp)
	SREG x17, 17 * REGBYTES(sp)
	SREG x18, 18 * REGBYTES(sp)
	SREG x19, 19 * REGBYTES(sp)
	SREG x20, 20 * REGBYTES(sp)
	SREG x21, 21 * REGBYTES(sp)
	SREG x22, 22 * REGBYTES(sp)
	SREG x23, 23 * REGBYTES(sp)
	SREG x24, 24 * REGBYTES(sp)
	SREG x25, 25 * REGBYTES(sp)
	SREG x26, 26 * REGBYTES(sp)
	SREG x27, 27 * REGBYTES(sp)
	SREG x28, 28 * REGBYTES(sp)
	SREG x29, 29 * REGBYTES(sp)
	SREG x30, 30 * REGBYTES(sp)
	SREG x31, 31 * REGBYTES(sp)
	csrr a0, MODE_PREFIX(cause)
	csrr a1, MODE_PREFIX(epc)
	csrr a2, MODE_PREFIX(tval)
	mv a3, sp
	jal handle_trap
	csrw MODE_PREFIX(epc), a0

	LREG x1,   1 * REGBYTES(sp)
	LREG x3,   3 * REGBYTES(sp)
	LREG x4,   4 * REGBYTES(sp)
	LREG x5,   5 * REGBYTES(sp)
	LREG x6,   6 * REGBYTES(sp)
	LREG x7,   7 * REGBYTES(sp)
	LREG x8,   8 * REGBYTES(sp)
	LREG x9,   9 * REGBYTES(sp)
	LREG x10, 10 * REGBYTES(sp)
	LREG x11, 11 * REGBYTES(sp)
	LREG x12, 12 * REGBYTES(sp)
	LREG x13, 13 * REGBYTES(sp)
	LREG x14, 14 * REGBYTES(sp)
	LREG x15, 15 * REGBYTES(sp)
	LREG x16, 16 * REGBYTES(sp)
	LREG x17, 17 * REGBYTES(sp)
	LREG x18, 18 * REGBYTES(sp)
	LREG x19, 19 * REGBYTES(sp)
	LREG x20, 20 * REGBYTES(sp)
	LREG x21, 21 * REGBYTES(sp)
	LREG x22, 22 * REGBYTES(sp)
	LREG x23, 23 * REGBYTES(sp)
	LREG x24, 24 * REGBYTES(sp)
	LREG x25, 25 * REGBYTES(sp)
	LREG x26, 26 * REGBYTES(sp)
	LREG x27, 27 * REGBYTES(sp)
	LREG x28, 28 * REGBYTES(sp)
	LREG x29, 29 * REGBYTES(sp)
	LREG x30, 30 * REGBYTES(sp)
	LREG x31, 31 * REGBYTES(sp)
	LREG x2,   2 * REGBYTES(sp)
	addi sp, sp, 32 * REGBYTES
	MODE_PREFIX(ret)
csrw	MODE_PREFIX(tvec), t0

根据定义

#if CONFIG_IS_ENABLED(RISCV_SMODE)
#define MODE_PREFIX(__suffix)	s##__suffix
#else
#define MODE_PREFIX(__suffix)	m##__suffix
#endif

MODE_PREFIX(tvec)就是mtvec或者stvec
mtvec(Machine Trap Vector)
中断(interrupt)和异常(exception)在RISCV里被统称为trap
RISC-V体系结构的U-Boot引导过程 第一阶段

csrw	MODE_PREFIX(ie), zero

机器模式中断使能控制寄存器(MIE)
机器模式中断使能控制寄存器(MIE)用于控制不同中断类型的使能和屏蔽。该寄存器的位长是 64 位,
寄存器的读写权限是机器模式可读写,即非机器模式访问都会导致非法指令异常。
MSIE-机器模式软件中断使能位:
• 当 MSIE 为 0 时,机器模式软件中断无效。
• 当 MSIE 为 1 时,机器模式软件中断有效

屏蔽所有中断。对于U-Boot,全局禁用中断(处于m/sstatus),但我们需要读取m/sip以确定是否获得IPI

MODE_PREFIX(ie) 就是mie或者sie
m/sstatus 表示mstatus和sstatus
mstatus表示Machine Status,M模式下的处理器状态寄存器
m/sip 表示 mip和sip
mip表示Machine Interrupt Pending, M模式下的中断待定寄存器
表示哪些中断处于待定(Pending,)状态
IPI,全称是Inter-Processor Interrupt,是在SoC内多个core之间触发的中断
RISC-V体系结构的U-Boot引导过程 第一阶段

li	t0, CONFIG_NR_CPUS
bge	tp, t0, hart_out_of_bounds_loop

缩写

Branch if equal (BEQ) 
Branch if not equal (BNE) 
Branch if less than (BLT)
Branch if less than unsigned (BLTU) 
Branch if greater than equal (BGE) 

语法

bge reg1, reg2, label   # if reg1 >= reg2, branch to label
beq reg1, reg2, label   # if reg1 == reg2, branch to label
bne reg1, reg2, label   # if reg1 != reg2, branch to label

tp寄存器里是hart id,t0寄存器里是Maximum number of CPUs
如果 tp >=t0 跳转 到 hart_out_of_bounds_loop

bge blt rs1,rs2,imm 如果rs1 >= rs2(有符号方式),跳转

此处跳转到hart_out_of_bounds_loop

li是 Load Immediate
加载立即数
CONFIG_NR_CPUS是预定义的,表示Maximum number of CPUs

CONFIG_NR_CPUS=32

或者

#define CONFIG_NR_CPUS		1

SMP, Symmetric Multi-Processor

#if CONFIG_IS_ENABLED(RISCV_MMODE)
	li	t0, MIE_MSIE
#else
	li	t0, SIE_SSIE
#endif
	csrs	MODE_PREFIX(ie), t0
#endif

根据条件编译 加载立即数 MIE_MSIE 还是SIE_SSIE到t0
SIE (Interrupt Enable)
SIP (Interrupt Pending)

#define MIE_MSIE		(_AC(0x1, UL) << IRQ_M_SOFT)
#define SIE_SSIE		(_AC(0x1, UL) << IRQ_S_SOFT)
#define IRQ_S_SOFT		1
#define IRQ_M_SOFT		3

_AC的意思

用于处理常量的宏

#ifdef __ASSEMBLY__
#define _AC(X,Y)	X
#define _AT(T,X)	X
#else
#define __AC(X,Y)	(X##Y)
#define _AC(X,Y)	__AC(X,Y)
#define _AT(T,X)	((T)(X))
#endif

在C语言里

#define CONNECT(x,y) x##y

表示连接

int n = CONNECT(12,34);

n的值是1234
RISC-V 程序计数器 (PC)程序计数寄存器(Program Counter Register)
RISC-V 引入了一个特殊的通用寄存器 X0 。

RISC-V 通用寄存器 X0 的的特性就是:读出来的值永远为 0 ,写入的值将会被丢弃
RISC-V 将 PC 单独拿出来作为一个特殊的寄存器来对待.

RISC-V 很多伪指令的实现都是通过 X0 通用寄存器与常用的普通指令相结合而实现的
每当完成取指令操作后,PC = PC + 1 这里的 +1 是增加【一条指令的长度 ÷ 寻址粒度】

初始堆栈指针地址

/*
 * Set stackpointer in internal/ex RAM to call board_init_f
 */
call_board_init_f:
	li	t0, -16
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
	li	t1, CONFIG_SPL_STACK
#else
	li	t1, SYS_INIT_SP_ADDR
#endif
	and	sp, t1, t0		/* force 16 byte alignment */

加法指令

and	and rd,rs1,rs2

将rs1寄存器的值 和 rs2寄存器的值相加,将结果写入到rd寄存器中

and sp, t1, t0
sp栈指针寄存的初始化

对于我们的初始堆栈指针地址,最常见的情况是,我们定义了一个静态初始RAM地址位置(CFG_SYS_INIT_RAM_ADDR)和大小(CFG_SYS_INIT_RAM_SIZE),并从中减去生成的全局数据(GENERATED_GBL_DATA_SIZE)大小。

#ifdef CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR
#define SYS_INIT_SP_ADDR	CONFIG_CUSTOM_SYS_INIT_SP_ADDR
#else
#ifdef CONFIG_MIPS
#define SYS_INIT_SP_ADDR	(CFG_SYS_SDRAM_BASE + CFG_SYS_INIT_SP_OFFSET)
#else
#define SYS_INIT_SP_ADDR	\
	(CFG_SYS_INIT_RAM_ADDR + CFG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
#endif
#endif

CONFIG_SPL_BUILD和CONFIG_SPL_STACK配置的情况下
不同的板子配置也是不同的文章来源地址https://www.toymoban.com/news/detail-497301.html

#define CONFIG_SPL_TEXT_BASE		0x60		/* sram start+header */
#define CONFIG_SPL_MAX_SIZE		0x5fa0		/* 24KB on sun4i/sun7i */
#define LOW_LEVEL_SRAM_STACK		0x00008000	/* End of sram */
#define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK

到了这里,关于RISC-V体系结构的U-Boot引导过程 第一阶段的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OSI体系结构和TCP/IP体系结构

     在第一章( 计网第一章 )的时候,曾经提到过OSI体系结构和TCP/IP体系结构,并对它们进行了简单的对比。这篇博客在其基础上进行更深层次的理解。 计算机网络在逻辑功能上可以分为通信子网和资源子网两部分。 事实上,OSI将低三层称为通信子网,即为了联网而附加的通

    2024年02月07日
    浏览(72)
  • 【体系结构】山东大学计算机体系结构知识点清单

    涵盖所有考点,复习绝对高效,点赞+留邮箱获取pdf版本 1. 计算机系统的层次结构 语言实现的两种基本技术: 翻译:先把 N+1 级程序全部转换成 N 级程序后,再去执行新产生的 N 级程序,在执行过程中 N+1 级程序不再被访问。 解释:每当一条 N+1 级指令被译码后,就直接去执

    2024年02月11日
    浏览(65)
  • 计算机网络七层体系结构(OSI七层结构)、TCP/IP四层模型、网络五层体系结构

    计算机网络七层体系结构(OSI七层结构)、TCP/IP四层模型、网络五层体系结构 七层体系结构(OSI七层结构) :为了使全世界不同体系结构的计算机能够互联,国际化标准组织ISO提出开放系统互联基本参考模型,简称OSI,即所谓的7层协议体系结构。 TCP/IP四层模型 :是由实际

    2024年02月06日
    浏览(59)
  • 计算机网络——计算机网络体系结构(2/4)-分层的必要性(五层协议原理体系结构)

    目录 物理层 数据链路层 网络层 运输层 应用层 计算机网络是个非常复杂的系统。 早在最初的ARPANET设计时就提出了分层的设计理念。 \\\"分层\\\"可将庞大而复杂的问题,转化为若干较小的局部问题,而这些较小的局部问题就比较易于研究和处理。 下面,我们以五层原理结构体系

    2024年02月07日
    浏览(55)
  • 计算机体系结构

    目录 第一章 基本概念 1.虚拟计算机 2.计算机系统结构的定义 3.佛林(Flynn)分类法 4.Amdahl定律 5.CPU性能公式 6.程序访问的局部性原理 第二章 指令系统 1.数据表示与数据类型 2.浮点数的表示方式 3.编址方式 4.寻址方式 5.指令系统的优化设计  6.Huffman编码法 7.拓展编码 8.两种方

    2024年02月06日
    浏览(57)
  • Spring的体系结构

    【Spring技术】Spring的体系结构 【Spring技术】Spring之IOC和DI入门案例 【Spring技术】Spring之Bean的配置与实例 【Spring技术】Spring依赖注入(DI配置) 【Spring技术】Spring第三方资源配置管理 【Spring技术】Spring容器技术 【Spring技术】Spring注解开发 【Spring技术】Spring整合MybatisJunit单元测

    2023年04月22日
    浏览(40)
  • JVM 体系结构

    JVM: 跨平台语言 需要不同语言由自己编译器,生成符合 JSR-292 JVM规范的字节码文件,即可在 Java 虚拟机中运行  多语言混合编程: Java 平台上的多语言混合编程正成为主流,通过特定领域的语言去解决特定领域的问题是当前软件开发应对日趋复杂的项目需求的一个方向 每个应

    2024年02月03日
    浏览(47)
  • 集合体系结构

    List系列集合:添加的元素有序,可重复,有索引 Collection:是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的 set系列集合:添加的元素无序,不重复,无索引   方法名 说明 public boolean add(E e) 把给定的对象添加到当前集合中 public void clear() 清空集合中所有的

    2024年02月09日
    浏览(46)
  • 冯诺依曼体系结构

    冯·诺依曼体系结构(von Neumann architecture)是现代计算机体系结构的基础,也是目前广泛应用的计算机体系结构之一。它是由物理学家、数学家冯·诺依曼在1945年提出的,被认为是现代计算机的奠基之作。冯·诺依曼体系结构具有存储程序和通用性的特点,这意味着计算机的指

    2023年04月23日
    浏览(40)
  • 了解 PostgreSQL 体系结构

    PostgreSQL 是客户端/服务器关系数据库管理系统 (RDMS)。 PostgreSQL 还支持各种扩展插件,例如 Azure Database for PostgreSQL 超大规模 Citus 选项中的 Citus 扩展插件。 将扩展插件加载到数据库中后,它将像任何内置功能一样正常运行。 PostgreSQL 也有自己的查询语言,称为 pgsql。 此外,

    2024年02月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包