09_Uboot启动流程_1

news2024/11/26 0:31:29

目录

链接脚本u-boot.lds详解

U-Boot启动流程详解

 reset函数源码详解

lowlevel_init函数详解

s_init函数详解


链接脚本u-boot.lds详解

要分析uboot的启动流程,首先要找到“入口”,找到第一行程序在哪里。程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口。如果没有编译过uboot的话链接脚本为arch/arm/cpu/u-boot.lds。但是这个不是最终使用的链接脚本,最终的链接脚本是在这个链接脚本的基础上生成的。编译一下 uboot,编译完成以后就会在 uboot 根目录下生成 u-boot.lds文件,如图所示: 

 打开u-boot.lds内容如下:

 第3行为代码当前入口点:_start, _start在文件arch/arm/lib/vectors.S中有定义,如图所示:

 

从图中的代码可以看出, start后面就是中断向量表,从图中的".section ".vectors","ax"可以得到,此代码存放在.vectors段里面。

使用如下命令在uboot中查找“_image_copy_start”:

grep -nR"_image_copy_start"

 打开u-boot.map,找到如图所示位置:

 u-boot.map是uboot的映射文件,可以从此文件看到某个文件或者函数链接到了哪个地址,从图932行可以看到_image_copy_start为0X87800000,而.text的起始地址也是0X87800000

继续回到u-boot.lds示例代码中,第11行是vectors段,vectors段保存中断向量表,从图_start文件示例代码中我们知道了vectors.S的代码是存在vectors段中的。从图u-boot.map文件示例代码可以看出,vectors段的起始地址也是0X87800000,说明整个uboot的起始地址就是0X87800000。

第12行将arch/arm/cpu/armv7/start.s编译出来的代码放到中断向量表后面。

第13行为text段,其他的代码段就放到这里

在u-boot.lds中有一些跟地址有关的“变量”需要我们注意一下,后面分析u-boot源码的时候会用到,这些变量要最终编译完成才能确定的!!!比如我编译完成以后这些“变量”的值如表所示:

 表中的“变量”值可以在u-boot.map文件中查找,表中除了_image_copy_start,以外,其他的变量值每次编译的时候可能会变化,如果修改了uboot代码、修改了uboot配置、选用不同的优化等级等等都会影响到这些值。所以,一切以实际值为准!

 

U-Boot启动流程详解

 reset函数源码详解

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

第35行就是reset 函数。

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

第43行,读取寄存器cpsr中的值,并保存到r0寄存器中。

第44行,将寄存器r0中的值与Ox1F进行与运算,结果保存到r1寄存器中,目的就是提取cpsr的bit0-bit4这5位,这5位为M4 M3 M2 M1 M0, M[4:0]这五位用来设置处理器的工作模式,如表所示:

 

第45行,判断r1寄存器的值是否等于 0X1A(0b11010),也就是判断当前处理器模式是否处于 Hyp模式。

第46 行,如果r1和Ox1A不相等,也就是CPU不处于Hyp模式的话就将r0寄存器的bit0-5进行清零,其实就是清除模式位

第47行,如果处理器不处于Hyp模式的话就将r0的寄存器的值与0x13进行或运算,0x13=0b10011,也就是设置处理器进入SVC模式。

第48行, r0寄存器的值再与0xC0进行或运算,那么r0寄存器此时的值就是0xD3, cpsr的I为和F位分别控制IRQ和FIQ这两个中断的开关,设置为1就关闭了FIQ和IRQ!

第49行,将r0寄存器写回到cpsr寄存器中。完成设置CPU处于SVC模式,并且关闭FIQ和IRQ这两个中断。

继续执行执行下面的代码:

 

第56行,如果没有定义CONFIG_OMAP44XX和CONFIG_SPL_BUILD的话条件成立,此处条件成立。

第58行读取CP15中c1寄存器的值到r0寄存器中,这里是读取SCTLR 寄存器的值。

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

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

因此这一行的目的就是清除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行就是设置向量表重定位的。

代码继续往下执行:

 

第68行如果没有定义CONFIG_SKIP_LOWLEVEL_INIT的话条件成立。我们没有定义CONFIG_SKIP_LOWLEVEL_INIT,因此条件成立,执行下面的语句。

示例代码中的内容比较简单,就是分别调用函数cpu_init_cp15、 cpu_init_crit和_main。

函数cpu_init_ep15用来设置CP15相关的内容,比如关闭MMU啥的,此函数同样在start.S文件中定义的,代码如下:

函数cpu_init_cp15都是一些和CP15有关的内容,我们不用关心,有兴趣的可以详细的看一下。

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

可以看出函数cpu_init_crit内部仅仅是调用了函数lowlevel_init,接下来就是详细的分析一下lowlevel_init和_main这两个函数。 

lowlevel_init函数详解

函数lowlevel_init在文件arch/arm/cpu/armv7/lowlevel_init.S中定义,内容如下: 

 第22行设置sp指向CONFIG_SYS_INIT_SP_ADDR,CONFIG_SYS_INIT_SP_ADDR在include/configs/mx6ullevk.h文件中,在 mx6ullevk.h中有如下所示定义:

示例代码中的IRAM-BASE-ADDR和IRAM-SIZE在文

件.arch/arm/include/asm/arch-mx6/imx-regs.h中有定义,如下所示,其实就是IMX6UL/IM6ULL内部ocram的首地址和大小。

 

如果408行的条件成立的话IRAM_SIZE=0X40000,当定义了CONFIG_MX6SX、CONFIG_MX6U、CONFIG_MX6SLL和CONFIG_MX6SL中的任意一个的话条件就不成立,在.config中定义了CONFIG MX6UL,所以条件不成立,因此IRAM SIZE=0X20000-128KB,

结合示例代码,可以得到如下值:

CONFIG_SYS_INIT_RAM_ADDR = IRAM_BASE_ADDR = 0x00900000.

CONFIG_SYS_INIT_RAM_SIZE= 0x00020000 = 128KB

 还需要知道GENERATED_GBL_DATA_SIZE的值,在文件include/generated/generic-asm-offsets.h中有定义,如下:

 GENERATED_GBL_DATA_SIZE-256, GENERATED_GBL_DATA_SIZE的含义为(sizeof(struct global_data) + 15) & ~15。

综上所述,CONFIG_SYS_INIT_SP_ADDR值如下: 

CONFIG_SYS_INIT_SP_OFFSET= 0x00020000 - 256 = 0x1FF00

CONFIG_SYS_INIT_SP_ADDR = 0x00900000 + 0X1FF00 = 0x0091FF00,

 结果如下图所示:

 

此时sp指向0X91FF00,这属于IMX6UL/IMX6ULL的内部ram。

继续回到文件lowlevel_init.S,第23行对sp指针做8字节对齐处理!

第34行, sp指针减去GD_SIZE, GDSIZE同样在generic-asm-offsets.h中定了,大小为248,见示例代码generic-asm-offsets.h第11行。

第35行对sp做8字节对齐,此时sp的地址为0x0091FF00-248-0X0091FE08,此时sp位置如图所示:

第36行将sp地址保存在r9寄存器中。

第42行将ip和Ir压栈

第57行调用函数s_init,得,又来了一个函数。

第58行将第36行入栈的ip和Ir进行出栈,并将Ir赋给pc

s_init函数详解

知道lowlevel_init函数后面会调用s_init函数, s_init函数定义在文件arch/arm/cpu/army7/mx6/soc.c中,如下所示:

 在第816行会判断当前CPU类型,如果CPU为MX6SX、MX6UL、MX6ULL或MX6SLL中的任意一种,那么就会直接返回,相当于s_init函数什么都没做。所以对于I.MX6UL/I.MX6ULL来说,s_init就是个空函数。从s_init函数退出以后进入函数lowlevel_init,但是lowlevel_init函数也执行完成了,返回到了函数cpu_init_crit,函数cpu_init_crit 也执行完成了,最终返回到save_boot_params_ret,函数调用路径如图所示:

 从图可知,接下来要执行的是save_boot_params_ret中的_main函数,下一章分析_main函数。

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

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

相关文章

【射影几何08】仿射映射

一、说明 简单来说&#xff0c;“仿射变换”就是&#xff1a;“线性变换”“平移”&#xff0c;但这是在笛卡尔坐标下的表现&#xff0c;然而在射影几何中&#xff0c;其中有更合乎逻辑的解释。本文讲仿射映射的定义&#xff0c;以及仿射不变性的特点。 二、仿射映射 2.1 直线…

2022 年全国硕士研究生入学统一考试英语(二)试题

2022年全国硕士研究生入学统一考试英语&#xff08;二&#xff09;试题 SectionⅠUse of English Directions: Read the following text. Choose the best word(s) for each numbered blank and mark A, B, C or D on the ANSWER SHEET. (10 points) Harlan Coben believes tha…

ChatGPT诞生的新岗位:提示工程师(Prompt Engineer)

ChatGPT诞生的新岗位&#xff1a;提示工程师&#xff08;Prompt Engineer&#xff09; Prompt 工程师是什么? 是识别人工智能的错误和隐藏功能&#xff0c;以便开发者可以对这些发现进行处理。 如果你正在寻找科技领域最热门的工作&#xff0c;你可以尝试了解如何与AI聊天机…

分布式文件存储系统Minio使用总结

分布式文件存储系统Minio使用总结 1.分布式文件系统应用: 1.1、Minlo 介绍&#xff1a; Minlo 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、…

一篇文章带你了解抖音来客功能的使用方法和注意事项

抖音是近年来备受欢迎的社交媒体平台之一&#xff0c;其中的“来客”功能更是让许多人喜爱。那么什么是抖音来客呢&#xff1f;抖音来客是指在直播过程中&#xff0c;可以邀请其他抖音用户进行互动和参与&#xff0c;从而增加直播的热度和粉丝数量。下面不若与众科技就来介绍一…

FPGA - 7系列 FPGA内部结构之CLB -03- CLB相关原语以及应用

前言 本文节选UG474的第二章&#xff0c;进行整理翻译。CLB资源被FPGA综合工具自动有效地使用&#xff0c;不需要任何特殊的FPGA专用编码。一些HDL编码建议和技术可以帮助优化设计以获得最大效率。 设计检查清单 这些指南是为有效使用7系列CLB的设计建议提供的快速核对表。7…

阿里云服务器公网带宽计费模式选择方法(一篇搞定)

阿里云服务器公网带宽计费模式按固定带宽和按使用流量哪个划算&#xff1f;阿里云百科以北京地域为例&#xff0c;按固定带宽计费1M带宽一个月23元&#xff0c;按使用流量计费1GB流量0.8元&#xff0c;如果云服务器带宽使用率低于10%&#xff0c;那么首选按使用流量计费&#x…

springboot+vue心灵治愈交流平台(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的心灵治愈交流平台。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

【DAY48】移动端布局

const autoprefixer require(‘autoprefixer’) const pxtoviewport require(‘postcss-px-to-viewport’)module.exports { css: { loaderOptions: { postcss: { postcssOptions: { plugins: [ autoprefixer(), pxtoviewport({ viewportWidth: 375, // 视窗宽度&#xff0c…

MySql命令报错:Duplicate entry ‘10‘ for key ‘PRIMARY‘解决方案

MySql命令报错&#xff1a;Duplicate entry ‘10‘ for key ‘PRIMARY‘解决方案 翻译错误先正常制作表格错一遍&#xff08;体验报错&#xff09;找到报错原因&#xff0c;并改正其他可能造成报错的情况总结解决方案 翻译错误 经常遇到这个问题&#xff0c;今天我把这个问题记…

基于session实现共享登录

基于session实现登录 1.发送短信验证码 Override public Result sendCode(String phone, HttpSession session) {//1.校验手机号是否合规if (RegexUtils.isPhoneInvalid(phone)) {//2.不合规直接返回 错误信息return Result.fail("手机号错误");}//3.如果合规生成验…

Ubuntu 安装Samba

每次装ubuntu虚拟机搞开发都要装Samba&#xff0c;记录一下Samba安装方法&#xff1a; 1.输入安装指令 需要使用root权限进行samba的安装操作&#xff1b; 输入指令 &#xff1a; apt-get update apt-get install samba samba-common 2.配置Samba 输入指令修改 Samba配置 &…

GEE:变异系数法在遥感影像分析中的应用及权重计算

作者:CSDN @ _养乐多_ 本文介绍了在Google Earth Engine(GEE)平台上基于变异系数法的多指标加权遥感影像分析方法。该方法通过计算每个指标的平均值和标准差,进而计算变异系数来评估指标的变化程度。利用变异系数,我们可以计算每个指标的权重,并将其应用于加权和指数的计…

jieba分词(2):倒排索引算法

1 字典树 1.1问题描述 通过上一篇的案例我孟可以看出&#xff0c;我们的一句话会分出来很多的关键字&#xff0c;都给他建立<K,List<Id>> 我们的Map 里面将容纳非常多的元素&#xff01; 那我们往Map 集合里面放元素时&#xff0c;将有29 个被放进去&#xff01;…

leetcode:234.回文链表(详解)

前言&#xff1a;内容包括-题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 题目&#xff1a; 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&…

ZZS-7系列分闸、合闸、电源监视综合控制装置ZZS-7/1 ac220v

ZZS-7系列分闸、合闸、电源监视综合控制装置 系列型号&#xff1a; ZZS-7/1分闸、合闸、电源监视综合控制装置 ZZS-7/11分闸、合闸、电源监视综合控制装置 ZZS-7/12分闸、合闸、电源监视综合控制装置 ZZS-7/13分闸、合闸、电源监视综合控制装置 ZZS-7/14分闸、合闸、电源…

<Linux开发>系统移植 -之-使用buildroot构建BusyBox根文件系统

&#xff1c;Linux开发&#xff1e;系统移植 -之-使用buildroot构建BusyBox根文件系统 一、前言二、 buildroot 下载三、配置buildroot基础参数3.1 配置Target options3.2 配置Toolchain3.3 配置System configuration3.4 配置Filesystem images3.5 禁止编译 Linux 内核和 uboot…

音频大模型导读

1 介绍 本次分享包含音频压缩&#xff0c;语音识别&#xff0c;语音合成&#xff0c;以及近两年来大模型在音频领域的应用&#xff0c;涉及八篇论文和一个近期github霸榜的语音合成工具。 结果如下图所示&#xff1a;&#xff08;图链接&#xff1a;audio_llm&#xff09; 共…

Grafana 系列-统一展示-2-Prometheus 数据源

系列文章 Grafana 系列文章 Grafana Prometheus 数据源 Grafana 提供了对 Prometheus 的内置支持。本文会介绍 Grafana Prometheus&#xff08;也包括 Prometheus 的兼容实现&#xff0c;如 Thanos, Mimir 等&#xff09; 数据源的部分选项、变量 (Variable)、查询 (Query) …

API接口获取商品数据

作为一名技术爱好者&#xff0c;我们总会遇到各种各样的技术问题&#xff0c;需要寻找合适的技术解决方案。而在互联网时代&#xff0c;我们可以快速通过搜索引擎获取丰富的技术资源和解决方案。然而&#xff0c;在不同的技术分享中&#xff0c;我们常常会遇到质量参差不齐的文…