uboot启动流程-涉及_main汇编函数

一.  uboot启动流程涉及函数

本文简单分析一下 save_boot_params_ret调用的函数:_main汇编函数。

本文继之前文章的学习,地址如下:

uboot启动流程-涉及s_init汇编函数_凌肖战的博客-CSDN博客

二.  uboot启动流程涉及的 _main汇编函数

经过之前文章的分析,uboot启动流程的汇编函数调用关系:

下面来分析 _main 函数。

_main 函数定义在文件 arch/arm/lib/crt0.S 中,_main函数的前部分代码内容如下:

67 ENTRY(_main)
68 
69 /*
70 * Set up initial C runtime environment and call board_init_f(0).
71 */
72 
73 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
74 ldr sp, =(CONFIG_SPL_STACK)
75 #else
76 ldr sp, =(CONFIG_SYS_INIT_SP_ADDR)
77 #endif
78 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC 
destination */
79 mov r3, sp
80 bic r3, r3, #7
81 mov sp, r3
82 #else
83 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
84 #endif
85 mov r0, sp
86 bl board_init_f_alloc_reserve

76 行,设置 sp 指针为 CONFIG_SYS_INIT_SP_ADDR ,也就是 sp 指向 0X0091FF00
83 行, sp 8 字节对齐。
85 行,读取 sp 到寄存器 r0 里面,此时 r0=0X0091FF00
第 86 行,调用 board_init_f_alloc_reserve 函数 ,此函数有一个参数,参数为 r0 中的值,也 就是 0X0091FF00 ,此函数定义在文件 common/init/board_init.c 中,内容如下:
56 ulong board_init_f_alloc_reserve(ulong top)
57 {
58 /* Reserve early malloc arena */
59 #if defined(CONFIG_SYS_MALLOC_F)
60 top -= CONFIG_SYS_MALLOC_F_LEN;
61 #endif
62 /* LAST : reserve GD (rounded up to a multiple of 16 bytes) */
63 top = rounddown(top-sizeof(struct global_data), 16);
64
65 return top;
66 }

函数 board_init_f_alloc_reserve 主要是留出早期的 malloc 内存区域和 gd 内存区域,其中,CONFIG_SYS_MALLOC_F_LEN=0X400( 在文件 include/generated/autoconf.h 中定义 ) sizeof(struct global_data)=248(GD_SIZE 值),完成以后的内存分布如下:

board_init_f_alloc_reserve 是有返回值的,返回值为新的 top 值,从上面的内存分布 可知, 此时, top=0X0091FA00

继续分析_main 函数,如下是继以上代码:

87 mov sp, r0
88 /* set up gd here, outside any C code */
89 mov r9, r0
90 bl board_init_f_init_reserve
87 行,将 r0 写入到 sp 里面,r0 保存着 board_init_f_alloc_reserve 函数的返回值,所以这一句也就是设置 sp=0X0091FA00
89 行,将 r0 寄存器的值写到寄存器 r9 里面,因为 r9 寄存器存放着全局变量 gd 的地址, 在文件 arch/arm/include/asm/global_data.h 中。如下所示:

可以看出, uboot 中定义了一个指向 gd_t 的指针 gd gd 存放在寄存器 r9 里面的,因此 gd 是个全局变量。 gd_t 是个结构体,在 include/asm-generic/global_data.h 里面有定义, gd_ 定义如下:

27 typedef struct global_data {
28 bd_t *bd;
29 unsigned long flags;
30 unsigned int baudrate;
31 unsigned long cpu_clk; /* CPU clock in Hz! */
32 unsigned long bus_clk;
33 /* We cannot bracket this with CONFIG_PCI due to mpc5xxx */
34 unsigned long pci_clk;
35 unsigned long mem_clk;
36 #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
37 unsigned long fb_base; /* Base address of framebuffer mem */
38 #endif
......
121 #ifdef CONFIG_DM_VIDEO
122 ulong video_top; /* Top of video frame buffer area */
123 ulong video_bottom; /* Bottom of video frame buffer area */
124 #endif
125 } gd_t;

因此,_main函数的第 89 行代码就是设置 gd 所指向的位置,也就是 gd 指向 0X0091FA00

90 行调用函数 board_init_f_init_reserve ,此函数在文件common/init/board_init.c 中有定义,函数内容如下:
110 void board_init_f_init_reserve(ulong base)
111 {
112 struct global_data *gd_ptr;
113 #ifndef _USE_MEMCPY
114 int *ptr;
115 #endif
116
117 /*
118 * clear GD entirely and set it up.
119 * Use gd_ptr, as gd may not be properly set yet.
120 */
121
122 gd_ptr = (struct global_data *)base;
123 /* zero the area */
124 #ifdef _USE_MEMCPY
125 memset(gd_ptr, '\0', sizeof(*gd));
126 #else
127 for (ptr = (int *)gd_ptr; ptr < (int *)(gd_ptr + 1); )
128 *ptr++ = 0;
129 #endif
130 /* set GD unless architecture did it already */
131 #if !defined(CONFIG_ARM)
132 arch_setup_gd(gd_ptr);
133 #endif
134 /* next alloc will be higher by one GD plus 16-byte alignment */
135 base += roundup(sizeof(struct global_data), 16);
136
137 /*
138 * record early malloc arena start.
139 * Use gd as it is now properly set for all architectures.
140 */
141
142 #if defined(CONFIG_SYS_MALLOC_F)
143 /* go down one 'early malloc arena' */
144 gd->malloc_base = base;
145 /* next alloc will be higher by one 'early malloc arena' size */
146 base += CONFIG_SYS_MALLOC_F_LEN;
147 #endif
148 }

可以看出,此函数用于初始化 gd ,其实就是清零处理。另外,此函数还设置了 gd->malloc_base gd 基地址 +gd 大小 =0X0091FA00+248=0X0091FAF8 ,在做 16 字节对齐,最 gd->malloc_base=0X0091FB00 ,这个也就是 early malloc 的起始地址。

继续分析_main 函数,如下是继以上代码:

92 mov r0, #0
93 bl board_init_f
94 
95 #if ! defined(CONFIG_SPL_BUILD)
96 
97 /*
98 * Set up intermediate environment (new sp and gd) and call
99 * relocate_code(addr_moni). Trick here is that we'll return
100 * 'here' but relocated.
101 */
102
103 ldr sp, [r9, #GD_START_ADDR_SP] /* sp = gd->start_addr_sp */
104 #if defined(CONFIG_CPU_V7M) /* v7M forbids using SP as BIC 
destination */
105 mov r3, sp
106 bic r3, r3, #7
107 mov sp, r3
108 #else
109 bic sp, sp, #7 /* 8-byte alignment for ABI compliance */
110 #endif
111 ldr r9, [r9, #GD_BD] /* r9 = gd->bd */
112 sub r9, r9, #GD_SIZE /* new GD is below bd */

92 行设置 R0 0
93 行,调用 board_init_f 函数,此函数定义在文件 common/board_f.c 中!主要用来初始化 DDR ,定时器,完成代码拷贝等等,此函数我们后面在详细的分析。
第 103 行,重新设置环境(sp 和 gd)、获取 gd->start_addr_sp 的值赋给 sp,在函数 board_init_f 中会初始化 gd 的所有成员变量,其中 gd->start_addr_sp=0X9EF44E90, 所以这里相当于设置
sp=gd->start_addr_sp=0X9EF44E90。0X9EF44E90 是 DDR 中的地址,说明新的 sp 和 gd 将会存 放到 DDR 中,而不是内部的 RAM 了。
第 109 行,sp 做 8 字节对齐。
第 111 行,获取 gd->bd 的地址赋给 r9,此时 r9 存放的是老的 gd,这里通过获取 gd->bd 的地址来计算出新的 gd 的位置。GD_BD=0。
第 112 行,新的 gd 在 bd 下面,所以 r9 减去 gd 的大小就是新的 gd 的位置,获取到新的 gd 的位置以后赋值给 r9。

下一篇文章继续分析 _main函数。

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

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

相关文章

鞋类 整鞋试验方法 剥离强度

声明 本文是学习GB-T 3903.3-2011 鞋类 整鞋试验方法 剥离强度. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 GB/T 3903 的本部分规定了整鞋鞋底与鞋帮或外底与外中底之间剥离强度的试验方法。 本部分适用于采用模压、硫化、注塑、灌注、胶…

Springboot对MVC、tomcat扩展配置

Springboot在web层的开发基本都是采用Springmvc框架技术&#xff0c;但是Springmvc中的某些配置在boot是没有的&#xff0c;我们就应该根据自己的需求进行对mvc扩展配置 Springboot1.x版本如何配置 通过注解Configuration一个类&#xff0c;继承webmvcconfigureradapter&#…

macOS 14 Sonoma 如何删除不需要的 4k 动态壁纸

概览 在升级到 macOS 14&#xff08;Sonoma&#xff09;之后&#xff0c;小伙伴们惊喜发现  提供了诸多高清&#xff08;4k&#xff09;动态壁纸的支持。 现在&#xff0c;从锁屏到解锁进入桌面动态到静态的切换一气呵成、无比丝滑。 壁纸显现可谓是有了“天水相连为一色&…

【SpringBoot学习】收藏的学习资料,精!

文章目录 Spring实战&#xff08;第五版&#xff09;&#xff1a; https://potoyang.gitbook.io/spring-in-action-v5/di-er-bu-fen-ji-cheng-spring南京大学-软件体系架构,结合SpringBoot Spring实战&#xff08;第五版&#xff09;&#xff1a; https://potoyang.gitbook.io/…

【农业生产模拟】WOFOST模型与PCSE模型实践

查看原文>>>【农业生产模拟】WOFOST模型与PCSE模型实践 WOFOST&#xff08;WorldFoodStudies&#xff09;和PCSE&#xff08;PythonCropSimulationEnvironment&#xff09;是两个用于农业生产模拟的模型&#xff1a;WOFOST是一个经过多年开发和验证的模型&#xff0c…

ElementUI之增删改及表单验证

⭐⭐本文章收录与ElementUI原创专栏&#xff1a;ElementUI专栏 ⭐⭐ ElementUI的官网&#xff1a;ElementUI官网 目录 一.前言 二.使用ElementUI完成增删改 2.1 后台代码 2.2 前端代码 三.使用ElementUI完成表单验证 一.前言 本章是继上一篇的基础之上在做完善&#xff0…

多网卡场景数据包接收时ip匹配规则

多网卡场景数据包接收时ip匹配规则 mac地址匹配规则 接收数据包时数据包中的目的mac地址匹配接收网卡的mac地址后&#xff0c;数据包才会继续被传递到网络层处理 ip地址匹配规则 图1&#xff1a; 参见&#xff1a;https://zhuanlan.zhihu.com/p/529160026?utm_id0 图2&am…

Python 接口测试之接口关键字封装

引言 我们使用RF做UI自动化测试的时候&#xff0c;使用的是关键字驱动。同样&#xff0c;Python做接口自动化测试的时候&#xff0c;也可以使用关键字驱动。但是这里并不是叫关键字驱动&#xff0c;而是叫数据驱动。而接口测试的关键字是什么呢&#xff1f; 我们数据驱动的载体…

IDEA 配置 Maven(解决依赖下载缓慢)

IDEA 配置 Maven&#xff08;解决依赖下载缓慢&#xff09; 这一篇主要介绍 Maven 的基本用法。等我之后学习到框架知识时&#xff0c;会完善此部分内容。 一、Maven 简介 Maven 是专门用于管理和构建 Java 项目的工具&#xff0c;Apache Maven 是一个项目管理和构建工具&#…

掌动智能:替代JMeter的压力测试工具有哪些

JMeter是一个广泛使用的开源压力测试工具&#xff0c;但在实际应用中&#xff0c;也有一些其他优秀的替代品可供选择。本文将介绍几个可替代JMeter的压力测试工具&#xff0c;它们在功能、性能和易用性方面都具有独特优势&#xff0c;可以满足不同压力测试需求的选择。 一、Gat…

【图论C++】Floyd算法(多源最短路径长 及 完整路径)

>>>竞赛算法 /*** file * author jUicE_g2R(qq:3406291309)————彬(bin-必应)* 一个某双流一大学通信与信息专业大二在读 * * brief 一直在算法竞赛学习的路上* * copyright 2023.9* COPYRIGHT 原创技术笔记&#xff…

uniapp - 微信小程序实现腾讯地图位置标点展示,将指定地点进行标记选点并以一个图片图标展示出来(详细示例源码,一键复制开箱即用)

效果图 在uniapp微信小程序平台端开发,简单快速的实现在地图上进行位置标点功能,使用腾讯地图并进行标点创建和设置(可以自定义标记点的图片)。 你只需要复制代码,改个标记图标和位置即可。

[GWCTF 2019]我有一个数据库

一开始打开是乱码 之前题目做过修复乱码的&#xff0c;得到这个 用dirsearch扫一下 一开始我是看到robots.txt 访问一下 访问一下phpinfo 也没啥&#xff0c;看到phpmyadimin 访问一下 没啥思路&#xff0c;看了wp 看到phpMyAdmin 4.8.1后台文件包含漏洞&#xff08;CV…

css实现四角圆边框

摘要&#xff1a; 做大屏的项目时&#xff0c;遇到很多地方要用到不同尺寸的盒子需要圆角的效果&#xff0c;所以不可能要求ui弄那么多图片的&#xff0c;并且那么多图片加载速度很慢的&#xff0c;比较臃肿&#xff0c;大屏要求的就是流畅&#xff0c;所以这用css加载很快的&a…

Arduino ESP32/ESP8266 +ST7735 1.8“tft中秋小时钟

Arduino ESP32 ST7735 1.8"tft中秋小时钟 &#x1f33c;原作者B站视频&#xff1a; ESP32中秋小时钟&#xff0c;表盘自动切换&#xff0c;代码开源&#xff0c;原图可下载&#xff08;案例应用&#xff09; &#x1f39e;tft ST7735 128160 1.8" 显示效果:(由于原作…

读者写者问题—内含408真题

读者写者问题—含408 一、问题描述 一个数据问价或记录可以被多个进程共享&#xff0c;我们把只读该文件的进程称为“读者进程”&#xff0c;其他进程为“写者进程”。允许多个进程同时读一个共享对象&#xff0c;但不允许一个写者进程和其他写者进程或读者进程同时访问共享对…

【数据结构】堆排序和top-k问题

目录 1.堆排序 2.top-k问题 1.堆排序 我们已经介绍了向上调整算法和向下调整算法建堆&#xff0c;可以建一个小堆或大堆&#xff0c;对于这种方式建立的大堆或小堆&#xff0c;我们只能选出最大的和最小的数&#xff0c;对于次大或次小的数&#xff0c;只能重新建堆&#x…

详解Avast Driver Updater:电脑驱动更新工具的利器还是多余的软件?

亲爱的读者朋友们&#xff0c;你是不是经常为电脑的驱动问题而烦恼&#xff1f;如果是的话&#xff0c;你可能会对这款软件——Avast Driver Updater 电脑驱动更新工具感兴趣。但在你决定尝试之前&#xff0c;不妨先和我一起深入探讨一下它的优点、缺点以及它适用的使用场景。 …

UE5.1编辑器拓展【二、脚本化资产行为,快速更改资产名字,1.直接添加前缀或后缀2.通过资产类判断添加修改前缀】

目录 了解相关的函数 第一种做法&#xff1a;自定义添加选择资产的前缀或后缀 代码 效果 第二种做法&#xff1a;通过映射来获取资产类型添加前缀和修改前缀 映射代码 代码 效果 在之前一章中&#xff0c;我们创建了插件&#xff0c;用来扩展编辑器的使用&#xff1a; …

十八,镜面IBL-打印预过滤环境贴图

前面打印了各个级别的hdr环境贴图&#xff0c;也能看到预过滤环境贴图&#xff0c;现在进行打印各个级别的预过滤环境贴图。 运行结果如下 代码如下&#xff1a; #include <osg/TextureCubeMap> #include <osg/TexGen> #include <osg/TexEnvCombine> #…