RISC-V体系结构的U-Boot引导过程

news2024/11/25 4:38:49

RISC-V体系结构的U-Boot引导过程

flyfish

BootLoader

Boot是Bootstrap(鞋带)的缩写,它来自于一句谚语:“Pull oneself up by one’s own bootstraps”,直译的意思是“拽着鞋带把自己拉起来”
干这件事,得先问问牛顿行不行?牛爵爷也只是看一眼就忙着炼金去了。
早期计算机的启动,存在这样一个问题:必须先运行程序,然后计算机才能启动,但是计算机不启动就不能运行程序。为了解决这个问题人们把一小段程序先刷入ROM,通电后,第一件事就是读取它,之后计算机就能正常运行了。这个过程称为“拉鞋带”,简称为Boot。BootLoader是Boot和Loader两个单词的组合。Boot是引导,Loader是加载器。

当计算机上电时,开始的时候RAM里是没有操作系统的,因为操作系统,存放在比如硬盘、CD、DVD、Flash存储卡、U盘等
这些叫非易失性存储设备上,加电后计算机会首先执行ROM中的小程序,之后才会访问非易失性存储设备中的操作系统和数据,并将其加载到RAM中。

在嵌入式系统中整个系统的加载启动任务就完全由BootLoader来完成。BootLoader是CPU上电后运行的第一段程序,它的作用就是对嵌入式系统中的硬件进行初始化,创建内核需要的参数并将这些参数传递给内核,最终启动了操作系统内核,起到引导和加载内核的作用。PC上用的可以是BIOS这样的固件程序。可以看传递参数的一个例子。
在这里插入图片描述

一个 Boot Loader加上了universal就成了宇宙级的Boot Loader,全宇宙通用的Boot Loader就是U-Boot(Universal Boot Loader),U-Boot也只是BootLoader其中的一种,还是其他的例如

LILO(LInux LOader)
GRUB(GRand Unified Boot loader)
blob(blob bootloader)
RedBoot
vivi

如果看到了Bootstrap Loader或者 Bootstrap都是BootLoader的意思

RISC-V

RISC-V发音 RISC five
RISC-V是基于精简指令集计算(RISC)原理的开源指令集体系结构(ISA)。

ISA:instruction set architecture 指令集体系结构
RISC:reduced instruction set computing 精简指令集计算,有的地方写作 Reduced Instruction Set Computer
简单与复杂相对 Complex Instruction Set Computer

RISC-V的寄存器
U-Boot将使用gp保存指向全局数据的指针

x0: hard-wired zero (zero)
x1: return address (ra)
x2:	stack pointer (sp)
x3:	global pointer (gp)
x4:	thread pointer (tp)
x5:	link register (t0)
x8:	frame pointer (fp)
x10-x11:	arguments/return values (a0-1)
x12-x17:	arguments (a2-7)
x28-31:	 temporaries (t3-6)
pc:	program counter (pc)

U-Boot可以在M模式或S模式下运行,具体取决于它是否在提供SBI的固件初始化之前运行。固件在RISC-V引导过程中是必需的,因为它充当SEE来处理S模式U-Boot或操作系统的异常。

SBI:Supervisor Binary Interface,SBI是Supervisor(S模式操作系统)和Supervisor执行环境(SEE,Supervisor Execution Environment)之间的调用约定,其调用风格就像System call一样。OpenSBI是一个SBI实现,可以在不同的模式下与U-Boot一起使用。
OpenSBI:RISC-V Open Source Supervisor Binary Interface。
SEE:Supervisor Execution Environment

看下SBI的位置
在这里插入图片描述

M-mode U-Boot

<-----------( M-mode )----------><--( S-mode )-->
+----------+   +--------------+    +------------+
|  U-Boot  |-->| SBI firmware |--->|     OS     |
+----------+   +--------------+    +------------+

S-mode U-Boot

<-------------( M-mode )----------><----------( S-mode )------->
+------------+   +--------------+    +----------+   +----------+
| U-Boot SPL |-->| SBI firmware |--->|  U-Boot  |-->|    OS    |
+------------+   +--------------+    +----------+   +----------+

在这里插入图片描述

在引导阶段之间,hartid通过a0寄存器,设备树的起始地址通过a1寄存器。hart是RISC-V使用的术语,指的是硬件线程(RISC-V hardware thread )。hart通常在其他上下文中称为核(core)或CPU。

一般的多阶段启动

在这里插入图片描述

常用的多引导阶段

在这里插入图片描述

具有有关下一引导阶段的动态信息的OpenSBI固件

在这里插入图片描述

ZSBL:Zero Stage Boot Loader)
FSBL:First Stage Boot Loader,U-Boot SPL

在这里插入图片描述

M-mode : machine-mode
U-mode : user-mode
S-mode : supervisor-mode

u-boot.lds
buildroot/output/build/uboot-origin_master/u-boot.lds
ld就是The GNU linker
lds是The GNU linker script

ld为什么是linker呢,d哪里去了?
原文答案

意思是
Linux自带了自己的链接器,名为ld。(该名称实际上是“load”的缩写,而“loader”最初是在20世纪70年代Unix的第一个时代被称为链接器的名称.最初的操作系统中没有linker,都是操作系统loader干了所有的活。后来复杂了就有了linker,所以ld(loader)成了链接器的简写。

u-boot.lds内容

OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
 . = 0x42000000;
 . = ALIGN(4);
 .__image_copy_start : {
  *(.__image_copy_start)
 }
 .head :
 {
  arch/riscv/cpu/spare_head.o (.data*)
 }
 .text : {
  arch/riscv/cpu/start.o (.text)
 }
 .efi_runtime : {
  __efi_runtime_start = .;
  *(.text.efi_runtime*)
  *(.rodata.efi_runtime*)
  *(.data.efi_runtime*)
  __efi_runtime_stop = .;
 }
 .text_rest : {
  *(.text*)
 }
 . = ALIGN(4);
 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
 . = ALIGN(4);
 .data : {
  *(.data*)
 }
 . = ALIGN(4);
 .got : {
  __got_start = .;
  *(.got.plt) *(.got)
  __got_end = .;
 }
 . = ALIGN(4);
 .u_boot_list : {
  KEEP(*(SORT(.u_boot_list*)));
 }
 . = ALIGN(4);
 .efi_runtime_rel : {
  __efi_runtime_rel_start = .;
  *(.rel*.efi_runtime)
  *(.rel*.efi_runtime.*)
  __efi_runtime_rel_stop = .;
 }
 . = ALIGN(4);
 .image_copy_end : {
  *(.__image_copy_end)
 }
 /DISCARD/ : { *(.rela.plt*) }
 .rela.dyn : {
  __rel_dyn_start = .;
  *(.rela*)
  __rel_dyn_end = .;
 }
 . = ALIGN(4);
 .dynsym : {
  __dyn_sym_start = .;
  *(.dynsym)
  __dyn_sym_end = .;
 }
 . = ALIGN(4);
 ASSERT(. < 0x42000000 + 0x100000, "uboot size exceeds size limit")
 _end = .;
 .bss : {
  __bss_start = .;
  *(.bss*)
  . = ALIGN(8);
  __bss_end = .;
 }
}

解释

OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv")

输出可执行文件是elf格式, 64位riscv指令,小端
elf格式
在这里插入图片描述
大端 和 小端(Big-endian和Little-endian )
链接视图和执行视图

在这里插入图片描述
Section举例

.bss
.comment
.data
.data1
.debug
.dynamic
.dynstr
.dynsym
.fini
.got 
.hash 
.init 
.interp 
.line 
.note
.plt 
.relname 
.relaname
.rodata
.rodata1 
.shstrtab 
.strtab 
.symtab 
.text

ELF文件结构

ELF Header
Program Header Table
Sections
Section Header Table

在这里插入图片描述

OUTPUT_ARCH("riscv")

输出可执行文件的平台为riscv

ENTRY(_start)

输出可执行文件的起始代码段为_start

 . = 0x42000000;

指定可执行文件的全局入口点,地址是在0x42000000。

 .__image_copy_start : {
  *(.__image_copy_start)
 }

u-boot将自己copy到RAM,此为需要copy的程序的start

 . = ALIGN(4);

做完一件事之后,有可能4bytes不对齐了,所以看到多处ALIGN(4)

 .image_copy_end : {
  *(.__image_copy_end)
 }

u-boot自拷贝的数据完成了,包括的section有

.__image_copy_start
.head
.text
.efi_runtime
.text_rest
.rodata
.data 
.got 
.u_boot_list
.efi_runtime_rel
.image_copy_end

u-boot.map
从u-boot.map中可以查找地址 例如

image_copy_start	uboot copy的首地址
image_copy_end	        uboot copy的结束地址

rel_dyn_start	.rel.dyn 段起始地址
rel_dyn_end	.rel.dyn 段结束地址

bss_start	.bss 段起始地址
bss_end	        .bss 段结束地址

image_copy_start

                0x0000000042000000                . = 0x42000000
                0x0000000042000000                . = ALIGN (0x4)

.__image_copy_start
                0x0000000042000000        0x0
 *(.__image_copy_start)
 .__image_copy_start
 ... ...

image_copy_end

... ...
.efi_runtime_rel
                0x00000000420c53a0        0x0
                0x00000000420c53a0                __efi_runtime_rel_start = .
 *(.rel*.efi_runtime)
 *(.rel*.efi_runtime.*)
                0x00000000420c53a0                __efi_runtime_rel_stop = .
                0x00000000420c53a0                . = ALIGN (0x4)

.image_copy_end
 *(.__image_copy_end)

查看编译之后生成的u-boot文件
buildroot/output/build/uboot-origin_master/u-boot

ELF 头:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              EXEC (可执行文件)
  系统架构:                          RISC-V
  版本:                              0x1
  入口点地址:               0x42000640
  程序头起点:          64 (bytes into file)
  Start of section headers:          10029872 (bytes into file)
  标志:             0x1, RVC, soft-float ABI
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         2
  Size of section headers:           64 (bytes)
  Number of section headers:         27
  Section header string table index: 26

程序头:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000001000 0x0000000042000000 0x0000000042000000
                 0x00000000000d6020 0x000000000010fa20  RWE    0x1000
  DYNAMIC        0x00000000000c4818 0x00000000420c3818 0x00000000420c3818
                 0x0000000000000110 0x0000000000000110  RW     0x8

 Section to Segment mapping:
  段节...
   00     .head .text .text_rest .rodata .dynstr .hash .gnu.hash .data .dynamic .got .u_boot_list .rela.dyn .dynsym .bss 
   01     .dynamic 

Dynamic section at offset 0xc4818 contains 13 entries:
  标记        类型                         名称/0x0000000000000004 (HASH)               0x420a1840
 0x000000006ffffef5 (GNU_HASH)           0x420a21a0
 0x0000000000000005 (STRTAB)             0x420a032c
 0x0000000000000006 (SYMTAB)             0x420d40d0
 0x000000000000000a (STRSZ)              5391 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000000000007 (RELA)               0x420c53a0
 0x0000000000000008 (RELASZ)             60720 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffb (FLAGS_1)            标志: PIE
 0x000000006ffffff9 (RELACOUNT)          2527
 0x0000000000000000 (NULL)               0x0

根据链接文件u-boot.lds找到入口文件start.S
buildroot/output/build/uboot-origin_master/arch/riscv/cpu/start.S

......
#ifdef CONFIG_32BIT
#define LREG			lw
#define SREG			sw
#define REGBYTES		4
#define RELOC_TYPE		R_RISCV_32
#define SYM_INDEX		0x8
#define SYM_SIZE		0x10
#else
#define LREG			ld
#define SREG			sd
#define REGBYTES		8
#define RELOC_TYPE		R_RISCV_64
#define SYM_INDEX		0x20
#define SYM_SIZE		0x18
#endif

.section .data
secondary_harts_relocation_error:
	.ascii "Relocation of secondary harts has failed, error %d\n"

.section .text
.globl _start
_start:
#if CONFIG_IS_ENABLED(RISCV_MMODE)
	csrr	a0, CSR_MHARTID
#endif

	/*
	 * Save hart id and dtb pointer. The thread pointer register is not
	 * modified by C code. It is used by secondary_hart_loop.
	 */
	mv	tp, a0
	mv	s1, a1

	/*
	 * Set the global data pointer to a known value in case we get a very
	 * early trap. The global data pointer will be set its actual value only
	 * after it has been initialized.
	 */
	mv	gp, zero

	/*
	 * Set the trap handler. This must happen after initializing gp because
	 * the handler may use it.
	 */
	la	t0, trap_entry
	csrw	MODE_PREFIX(tvec), t0

	/*
	 * Mask all interrupts. Interrupts are disabled globally (in m/sstatus)
	 * for U-Boot, but we will need to read m/sip to determine if we get an
	 * IPI
	 */
	csrw	MODE_PREFIX(ie), zero

#if CONFIG_IS_ENABLED(SMP)
	/* check if hart is within range */
	/* tp: hart id */
	li	t0, CONFIG_NR_CPUS
	bge	tp, t0, hart_out_of_bounds_loop

	/* set xSIE bit to receive IPIs */
#if CONFIG_IS_ENABLED(RISCV_MMODE)
	li	t0, MIE_MSIE
#else
	li	t0, SIE_SSIE
#endif
	csrs	MODE_PREFIX(ie), t0
#endif
......

命令

bootelf - Boot from an ELF image in memory

bootp - boot image via network using BOOTP/TFTP protocol

dhcp - boot image via network using DHCP/TFTP protocol

diskboot - boot from ide device

nboot - boot from NAND device

nfs - boot image via network using NFS protocol

rarpboot - boot image via network using RARP/TFTP protocol

scsiboot - boot from SCSI device

tftpboot - boot image via network using TFTP protocol

usbboot - boot from USB device

参考
部分图片来自Western Digital Corporation or its affiliates.
https://www.thegoodpenguin.co.uk/blog/an-overview-of-opensbi/
https://github.com/riscv-software-src/opensbi
https://github.com/u-boot
https://linux-sunxi.org/U-Boot
https://u-boot.readthedocs.io/en/latest/

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

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

相关文章

文心一言 VS 讯飞星火 VS chatgpt (33)-- 算法导论5.2 5题

五、设A[1…n]是由n个不同数构成的数列。如果i<j且A[i]>A[j]&#xff0c;则称(i&#xff0c;j)对为A的一个逆序对(inversion)。(参看思考题2-4 中更多关于逆序对的例子。)假设A的元素构成(1&#xff0c;2&#xff0c;… &#xff0c;n)上的一个均匀随机排列。请用指示器随…

Win11配置Anaconda-Cuda-Pytorch-Tenserflow环境

之前搞了一个月左右时间用WSL2跑模型&#xff0c;后来发现还是不太习惯&#xff08;其实用不明白&#xff09;&#xff0c;就转成Windows了。这次也是记录一下自己配环境的过程&#xff0c;以免下次还需要 安装Anaconda 下载方式 Anaconda官网清华镜像下载 tip&#xff1a;…

OpenHarmony源码解析(11): hiview维测平台

作者: 鸿湖万联(武汉) 许文龙 1、概述 Hiview是一个跨平台的终端设备维测服务集,由插件管理平台和基于平台上运行的服务插件来构成整套系统。Hiview维测服务是由HiSysEvent事件驱动的,其核心为分布在系统各处的HiSysEvent桩点,格式化的事件会通过HiSysEvent打点API上报至H…

Tomcat【尚硅谷】

一、Tomcat基础 1、常见的web服务器 概念 服务器&#xff1a;安装了服务器软件的计算机服务器软件&#xff1a;接收用户的请求&#xff0c;处理请求&#xff0c;做出响应web服务器软件&#xff1a;在web服务器软件中&#xff0c;可以部署web项目&#xff0c;让浏览器来访问这…

【模块系列】DHT11时序理论

前言 基于stm32f103C6T6核心板STM32CubeMX的DHT11的使用。其实吧&#xff0c;要不是网上关于stm32调用DHT11的代码大多数用不了或者乱七八糟的&#xff0c;我也不想推时序的&#xff0c;嘎嘎麻烦。写着写着就发现&#xff0c;本章的篇幅有点长了&#xff0c;所以本文就先介绍DH…

Fiddler抓包返回的Response中总是出现“Response body is encoded. Click to decode. “的解决办法

在进行网页开发和接口调试时&#xff0c;我们经常会用到Fiddler这个工具。 但是&#xff0c;有时候我们会遇到一个非常头疼的问题&#xff0c;就是在抓取网页返回的Response时总是出现“Response body is encoded. Click to decode.”的提示。 这种情况下我们可能无法正常查看…

【Web服务应用】Nginx七层反向代理与四层反向代理

Nginx七层反向代理与四层反向代理 一、代理1.1什么是代理1.2正向代理1.3反向代理1.4反向代理的适用场景1.5正向代理与反向代理的区别 二、反向代理2.1负载均衡2.2动静分离 三、Nginx实战3.1七层反向代理&#xff0c;负载均衡&#xff0c;动静分离3.2四层反向代理 一、代理 1.1…

测试复习(自用)

测试复习 通识/基础/概念 什么是软件测试 验证软件特性是否满足用户的需求 专业名词 需求 满足用户期望或正式文档&#xff08;合同、标准、规范&#xff09;所具备的条件和权能&#xff0c;包含用户需求和软件需求 用户需求软件需求 是测试人员开展软件测试工作的依据 如…

【Mysql】基础入门篇

文章目录 什么是数据库见见数据库服务器、数据库、表之间的关系数据逻辑存储MySQL架构SQL分类存储引擎 什么是数据库 存储数据用文件就可以了&#xff0c;为什么还需要数据库&#xff0c;文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题 文件不利于数据查询和管理 文…

五年后,你是什么档次

每晚一到两篇的阅读 1.认清现实&#xff0c;她就是喜欢钱 2.不要再找理由&#xff0c;自卑才是你最大的动力 3.提高自己的任性指数 4.尽量把钱花在有营养的地方 5.不要成为一条被溺死的鱼 6.总有一天&#xff0c;卫生纸比钞票值钱 7.穷忙的人&#xff0c;不要开Toyota 8.目标就…

easypoi模板导出文件,支持Liunx系统(自用)

springboot使用easypoi通过使用模板导出文件 第一步:导入poi以及easypoi的maven坐标 首先&#xff0c;easypoi是依赖于Apache的poi实现的&#xff0c;因此需要先引入poi <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifac…

智慧加油站解决方案,提高加油区和卸油区的安全性和效率

英码科技智慧加油站解决方案是一个综合应用了AI智能算法的视觉分析方案&#xff0c;旨在提高加油区和卸油区的安全性和效率。 加油区算法&#xff1a; 吸烟检测&#xff1a;通过AI算法分析视频流&#xff0c;检测是否有人在加油区域吸烟&#xff0c;以防止火灾风险。 打电话…

Web Scoket简述

Web Socket 简介 初次接触 Web Socket 的人&#xff0c;我们已经有了 HTTP 协议&#xff0c;为什么还需要另一个协议&#xff1f;它能带来什么好处&#xff1f; 因为 HTTP 协议有一个缺陷&#xff1a;通信只能由客户端发起。http基于请求响应实现。 &#xff08;准确来说HTTP…

使用Cloudflare Zaraz 可让同意管理变得简单明了

视您的居住地而定&#xff0c;在首次造访网站时&#xff0c;可能会要求您同意使用Cookie。如果您曾经点选过「核准」以外的其他选项&#xff0c;您就会注意到&#xff0c;关于应该或不应该允许哪些服务使用Cookie 的选项清单可能非常长。这是因为网站通常会整合许多第三方工具进…

陕西省赛2023-部分Reverse复现

目录 我的upx -d怎么坏了 动调脱upx壳&#xff1a; babypython BadCoffee ob混淆&#xff1a; 我的upx -d怎么坏了 打开附件&#xff0c;发现是upx壳&#xff0c;应该是修改了区段名或者特征码 但是修改过还是不对.....(哭.jpg)应该还是改了其他 好学长告诉我直接动态调试…

【Matter】Nordic Mattter(开发大纲)

nRF Connect SDK 支持Mattter Nordic提供的Matter用户指南 子页面&#xff1a; Matter概况开始使用Matter如何创建 Matter 最终产品 Matter网络拓扑结构 Thread&#xff1a;Thread是一种开放的低功耗无线通信协议&#xff0c;旨在为物联网设备提供安全、稳定、高效的IPv6连接。…

混合动力汽车耐久测试

一 背景 整车厂可通过发动机和电机驱动的结合为多款车型提供混合动力驱动技术。汽车集成电机驱动可大大减少二氧化碳的排放&#xff0c;不仅如此&#xff0c;全电动驱动或混合动力驱动的汽车还将使用户体验到更好的驾驶感受&#xff0c;且这种汽车可通过电动机来实现更快的加速…

机器学习 | 降维问题

目录 一、主成分分析 二、奇异值分解 2.1 奇异值分解原理 2.2 奇异值分解实践 三、特征值与特征向量 一、主成分分析 主成分有如下特征&#xff1a; 每个主成分是原变量的线性组合&#xff1b;各个主成分之间互不相关&#xff1b;主成分按照方差贡献率从大到小依次排列&…

【诗视野文学社】五一特刊|本期诗人:胭脂茉莉 李本 薛宏 文爱艺 唐根金 王宁 迪夫 东楠灵

【诗视野文学社】五一特刊 本期诗人&#xff1a;胭脂茉莉 李本 薛宏 文爱艺 唐根金 王宁 迪夫 东楠灵 脂茉莉简介&#xff1a;刘彦芹&#xff0c;女&#xff0c;作家、诗人&#xff0c;江苏人&#xff0c;年少习诗&#xff0c;评论及随笔见诸媒体及报刊&#xff0c;诗歌被选入海…

中国人民大学与加拿大女王大学金融硕士引领你走出职场困境,勇往直前!

走到一定职位时&#xff0c;想更进一步基本无望&#xff0c;到了自己事业的瓶颈期。从底层一路冲到中层靠的是能力&#xff0c;靠的是忠诚&#xff0c;靠的是勤奋&#xff0c;而再向上走&#xff0c;该凭借什么&#xff0c;完全找不到方向。而那些极个别的人却在自己看不到的地…