uboot启动流程涉及reset汇编函数

一.   uboot启动流程中函数

之前了解了uboot链接脚本文件 u-boot.lds。

从 u-boot.lds 中我们已经知道了入口点是 arch/arm/lib/vectors.S 文件中的 _start

本文了解 一下,uboot启动过程中涉及的 reset 函数。本文继上一篇文章学习,地址如下:

uboot启动流程-uboot链接脚本u-boot.lds_凌肖战的博客-CSDN博客

二.   reset 函数源码详解

u-boot.lds 中,我们已经知道了入口点是 arch/arm/lib/vectors.S 文件中的 _start,代码如下: 

38 /*
39 *************************************************************
40 *
41 * Exception vectors as described in ARM reference manuals
42 *
43 * Uses indirect branch to allow reaching handlers anywhere in 
44 * memory.
45 **************************************************************
46 */
47
48 _start:
49
50 #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
51 .word CONFIG_SYS_DV_NOR_BOOT_CFG
52 #endif
53
54 b reset
55 ldr pc, _undefined_instruction
56 ldr pc, _software_interrupt
57 ldr pc, _prefetch_abort
58 ldr pc, _data_abort
59 ldr pc, _not_used
60 ldr pc, _irq
61 ldr pc, _fiq

48 _start 开始的是中断向量表,其中 54~61 行就是中断向量表,和我们裸机例程里面一样。

1.   start.S 文件中的 reset 函数

第 54 行跳转到 reset 函数里面, reset 函数在 arch/arm/cpu/armv7/start.S 里面,代码如下:
32 .globl reset
33 .globl save_boot_params_ret
34
35 reset:
36 /* Allow the board to save important registers */
37 b save_boot_params

start.S 文件的第 35 行就是 reset 函数。

37 行从 reset 函数跳转到了 save_boot_params 函数,而 save_boot_params 函数同样定义start.S 里面,定义如下:

100      ENTRY ( save_boot_params )
101       b save_boot_params_ret @ back to my caller

2.   start.S文件中的save_boot_params_ret 函数

save_boot_params 函数也是只有一句跳转语句,跳转到 save_boot_params_ret 函数,
save_boot_params_ret 函数代码如下:
38 save_boot_params_ret:
39 /*
40 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 
41 * mode, except if in HYP mode already
42 */
43 mrs r0, cpsr
44 and r1, r0, #0x1f @ mask mode bits
45 teq r1, #0x1a @ test for HYP mode
46 bicne r0, r0, #0x1f @ clear all mode bits
47 orrne r0, r0, #0x13 @ set SVC mode
48 orr r0, r0, #0xc0 @ disable FIQ and IRQ
49 msr cpsr,r0

save_boot_params_ret 函数中,第43行~49行,将处理器设置为SVC模式,并且关闭FIQ和IRQ。

继续分析 start.S 下面的代码:

56 #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
57 /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
58 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 SCTLR Register
59 bic r0, #CR_V @ V = 0
60 mcr p15, 0, r0, c1, c0, 0 @ Write CP15 SCTLR Register
61
62 /* Set vector address in CP15 VBAR register */
63 ldr r0, =_start
64 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
65 #endif

56 行,如果没有定义 CONFIG_OMAP44XX CONFIG_SPL_BUILD 的话条件成立,此处条件成立。
58 行读取 CP15 c1 寄存器的值到 r0 寄存器中,根据 17.1.4 小节可知,这里是读取 SCTLR 寄存器的值。

59 行,CR_V arch/arm/include/asm/system.h 中有如下所示定义:

#define CR_V (1 << 13) /* Vectors relocated to 0xffff0000 */

因此,第 59 行的目的就是清除 SCTLR 寄存器中的 bit13 SCTLR 寄存器结构 如下:

可以看出, bit13 V 位,此位是向量表控制位,当为 0 的时候向量表基地址为 0X00000000 ,软件可以重定位向量表。为 1 的时候向量表基地址为 0XFFFF0000 ,软件不能 重定位向量表。这里将 V 清零,目的就是为了接下来的向量表重定位。

60 行将 r0 寄存器的值重写写入到寄存器 SCTLR 中。

63 行设置 r0 寄存器的值为 _start _start 就是整个 uboot 的入口地址,其值为 0X87800000 相当于 uboot 的起始地址,因此 0x87800000 也是向量表的起始地址。
64 行将 r0 寄存器的值 ( 向量表值 ) 写入到 CP15 c12 寄存器中,也就是 VBAR 寄存器。
因此,第 58~64 行就是设置向量表重定位的。

继续分析 start.S 下面的代码:

67 /* the mask ROM code should have PLL and others stable */
68 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
69 bl cpu_init_cp15
70 bl cpu_init_crit
71 #endif
72
73 bl _main
68 行如果没有定义 CONFIG_SKIP_LOWLEVEL_INIT 的话条件成立。我们没有定义
CONFIG_SKIP_LOWLEVEL_INIT ,因此条件成立,执行下面的语句。
68 行~ 73行的内容比较简单,就是分别调用函数 cpu_init_cp15 cpu_init_crit _main
函数 cpu_init_cp15 用来设置 CP15 相关的内容,比如关闭 MMU 啥的,此函数同样在 start.S
文件中定义的。可以自行查看, 函数 cpu_init_cp15 都是一些和 CP15 有关的内容,我们不用关心,有兴趣的可以详细的看 一下。

函数 cpu_init_crit 也在是定义在 start.S 文件中,函数内容如下:

268 ENTRY(cpu_init_crit)
269 /*
270 * Jump to board specific initialization...
271 * The Mask ROM will have already initialized
272 * basic memory. Go here to bump up clock rate and handle
273 * wake up conditions.
274 */
275 b lowlevel_init @ go setup pll,mux,memory
276 ENDPROC(cpu_init_crit)
可以看出函数 cpu_init_crit 内部仅仅是调用了函数 lowlevel_init ,接下来就是详细的分析一
lowlevel_init _main 这两个函数。

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

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

相关文章

统计模型----决策树

决策树 &#xff08;1&#xff09;决策树是一种基本分类与回归方法。它的关键在于如何构建这样一棵树。决策树的建立过程中&#xff0c;使用基尼系数来评估节点的纯度和划分的效果。基尼系数是用来度量一个数据集的不确定性的指标&#xff0c;其数值越小表示数据集的纯度越高。…

揭秘:机构招生电子传单制作的五个黄金法则

机构招生微传单制作一直都是让很多人在意的事情。一款好的微传单不仅可以吸引更多的学生&#xff0c;还可以省去很多招生工作的时间和精力。但是&#xff0c;很多人却不知道如何制作一款精美的微传单。下面就让我们来学习一下如何制作一款机构招生的微传单吧。 首先&#xff0c…

Egg 封装接口返回信息

中间件封装 代码 const msgArr {"200":成功,"401":token失效 } module.exports (option, app) > {return async function(ctx, next) {try{//成功是返回的信息ctx.emit(code,data,msg)>{console.log(1111,code,data,msg)ctx.body {code,data:dat…

springboot 简单配置mongodb多数据源

准备工作&#xff1a; 本地mongodb一个创建两个数据库 student 和 student-two 所需jar包&#xff1a; # springboot基于的版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId>&l…

C++之std::atomic解决多线程7个问题(二百四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

竞赛选题 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习多目标跟踪 …

uniapp使用scroll-into-view实现锚点定位和滚动监听功能【楼层效果 / 侧边导航联动效果】

大佬网址&#xff1a; https://blog.csdn.net/weixin_47136265/article/details/132303570 效果 代码 <template><!-- 这里面有2个bug&#xff0c;已经解决&#xff0c;需要知道的地方1.methods里的scrollEvt(e)方法里面的 this.tabIndex index ! -1 ? index :…

MySQL - DML数据增删改

功能介绍&#xff1a; DML&#xff08;Data Manipulation Language&#xff09;数据操作语言&#xff0c;用来对数据库中表的数据记录进 行增、删、改操作。 添加数据&#xff08;INSERT&#xff09; 基本语法&#xff1a;insert into 表名(字段列表) values (值列表); …

el-collapse 嵌套中 el-checkbox作为标题,选中复选框与el-tree联动

<el-drawertitle"应用授权":visible.sync"menuDrawer"><el-collapse accordion style"padding: 15px"><el-collapse-item v-for"item in platList"><template slot"title"><el-checkbox v-model…

Mysql各种锁

一.不同存储引擎支持的锁机制 Mysql数据库有多种数据存储引擎&#xff0c;Mysql中不同的存储引擎支持不同的锁机制 MyISAM和MEMORY存储引擎采用的表级锁 InnoDB存储引擎支持行级锁&#xff0c;也支持表级锁&#xff0c;默认情况下采用行级锁 二.锁类型的划分 按照数据操作…

postgresql-管理数据表

postgresql-管理数据表 创建表数据类型字段约束表级约束模式搜索路径 修改表添加字段删除字段添加约束删除约束修改字段默认值修改字段数据类型重命名字段重命名表 删除表 创建表 在 PostgreSQL 中&#xff0c;使用 CREATE TABLE 语句创建一个新表&#xff1a; CREATE TABLE …

深度学习笔记_1、定义神经网络

1、使用了PyTorch的nn.Module类来定义神经网络模型;使用nn.Linear来创建全连接层。(CPU) import torch.nn as nn import torch.nn.functional as F from torchsummary import summary# 定义神经网络模型 class Net(nn.Module):def __init__(self):super(Net, self).__init__()…

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试   软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言&#xff0c;功能测试会对软件的所有功能进行测试&#xff0c;以确保其满足用户的需求和预期。在进行功能测试时&#xff0c;根据需求规格说明书编写测试用例&#xff0c;并在测试…

std::initializer_list详解

std::initializer_list介绍 initializer_list是C11提供的一种新类型&#xff0c;其定义于头文件<initializer_list>中&#xff0c;此头文件是工具库的一部分&#xff0c; <initializer_list>定义如下&#xff1a; namespace std {template<class E> class…

ubuntu22.04使用共享文件设置

从ubuntu20.04开始&#xff0c;设置共享文件就很麻烦 第一步&#xff1a; 安装samba&#xff1a; sudo apt install samba第二步; 创建一个共享文件夹 我以桌面Desktop为例子 第三步&#xff1a; 设置密码&#xff1a; sudo smbpasswd -a ygc第四步&#xff1a; sudo vim …

Pikachu靶场——XXE 漏洞

文章目录 1. XXE1.1 查看系统文件内容1.2 查看PHP源代码1.3 查看开放端口1.4 探测内网主机 1. XXE 漏洞描述 XXE&#xff08;XML External Entity&#xff09;攻击是一种利用XML解析器漏洞的攻击。在这种攻击中&#xff0c;攻击者通过在XML文件中插入恶意实体来触发解析器加载…

亲测可用国产GPT人工智能

分享一些靠谱、可用、可以白嫖的GPT大模型。配合大模型&#xff0c;工作效率都会极大提升。 清华大学ChatGLM 官网&#xff1a; 智谱清言中国版对话语言模型&#xff0c;与GLM大模型进行对话。https://chatglm.cn/开源的、支持中英双语的1300亿参数的对话语言模型&#xff0…

CSP-J第二轮试题-2020年-1.2题

文章目录 参考&#xff1a;总结 [CSP-J2020] 优秀的拆分题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 #2样例输入 #2样例输出 #2 提示样例 1 解释数据规模与约定 答案1答案2 [CSP-J2020] 直播获奖题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 样例 …

第80步 时间序列建模实战:GRNN回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们使用Matlab进行GRNN模型的构建。 使用的数据如下&#xff1a; 采用《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrom…

java web+Mysql e-life智能生活小区物业管理系统

本项目为本人自己书写&#xff0c;主要服务小区业主和管理人员。 e-life智能生活小区涉及多个方面的智能化和便利化服务&#xff1a; 1. 用户模块&#xff1a;包含基本的登入登出操作&#xff0c;查看个人信息中用户可以查看 自己的个人资料但不可以修改个人信息。 a) 用户…