uboot启动——lowlevel_init函数详解

2023-10-29

1、将lr寄存器中的值压栈

push	{lr}

lr寄存器保存的是函数返回地址,每个模式下只有一个lr寄存器,如果涉及多重函数调用,则lr寄存器会被覆盖,导致返回地址丢失。在之前已经初始化栈,所以这里可以将lr寄存器压栈,将来函数返回的时候再弹栈。

2、检查复位的状态

	/* check reset status  */
	ldr	r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET) //0xE0100000 + 0xa000
	ldr	r1, [r0]
	bic	r1, r1, #0xfff6ffff
	cmp	r1, #0x10000
	beq	wakeup_reset_pre
	cmp	r1, #0x80000
	beq	wakeup_reset_from_didle

在这里插入图片描述>0xE010a000是寄存器的地址,查询数据手册可以得到该寄存器的描述。根据不同的复位状态调用不同的唤醒函数,实现快速启动。比如:启动是断电重启,那所以的初始化都必须做;从睡眠模式启动,则底层的某些初始化就可以跳过;

3、I/O相关的检查

	/* IO Retention release */
	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + OTHERS_OFFSET) //0xE0100000 + 0xe00
	ldr	r1, [r0]
	ldr	r2, =IO_RET_REL
	orr	r1, r1, r2
	str	r1, [r0]

这也是分析寄存器的值来检查I/O状态,不太熟悉,感兴趣的可以根据地址去数据手册查寄存器说明。

4、关看门狗

	/* Disable Watchdog */
	ldr	r0, =ELFIN_WATCHDOG_BASE	/* 0xE2700000 */
	mov	r1, #0
	str	r1, [r0]

关看门狗,不希望在启动阶段去喂狗,也不想因为看门狗导致重启。

5、SRAM和SROM相关的初始化

/* SRAM(2MB) init for SMDKC110 */
	/* GPJ1 SROM_ADDR_16to21 */
	ldr	r0, =ELFIN_GPIO_BASE
	
	ldr	r1, [r0, #GPJ1CON_OFFSET]
	bic	r1, r1, #0xFFFFFF
	ldr	r2, =0x444444
	orr	r1, r1, r2
	str	r1, [r0, #GPJ1CON_OFFSET]

	ldr	r1, [r0, #GPJ1PUD_OFFSET]
	ldr	r2, =0x3ff
	bic	r1, r1, r2
	str	r1, [r0, #GPJ1PUD_OFFSET]

	/* GPJ4 SROM_ADDR_16to21 */
	ldr	r1, [r0, #GPJ4CON_OFFSET]
	bic	r1, r1, #(0xf<<16)
	ldr	r2, =(0x4<<16)
	orr	r1, r1, r2
	str	r1, [r0, #GPJ4CON_OFFSET]

	ldr	r1, [r0, #GPJ4PUD_OFFSET]
	ldr	r2, =(0x3<<8)
	bic	r1, r1, r2
	str	r1, [r0, #GPJ4PUD_OFFSET]


	/* CS0 - 16bit sram, enable nBE, Byte base address */
	ldr	r0, =ELFIN_SROM_BASE	/* 0xE8000000 */
	mov	r1, #0x1
	str	r1, [r0]

SRAM和SROM相关的初始化,不熟,想了解根据地址去数据手册查寄存器说明。

6、看发板供电锁存

	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + PS_HOLD_CONTROL_OFFSET)
	ldr	r1, [r0]
	orr	r1, r1, #0x300	
	orr	r1, r1, #0x1	
	str	r1, [r0]

参考博客:《开发板的上电锁存》

7、判断当前运行在iRAM还是DDR

	ldr	r0, =0xff000fff
	bic	r1, pc, r0		/* r0 <- current base addr of code */
	ldr	r2, _TEXT_BASE		/* r1 <- original base addr in ram */
	bic	r2, r2, r0		/* r0 <- current base addr of code */
	cmp     r1, r2                  /* compare r0, r1                  */
	beq     1f			/* r0 == r1 then skip sdram init   */
	/* init system clock */
	bl system_clock_init
	/* Memory initialize */
	bl mem_ctrl_asm_init
1:
	/* for UART */
	bl uart_asm_init
	bl tzpc_init //不熟,跳过

把当前地址和链接地址进行比较,判断当前是在iRAM还是在DDR中。
(1)_TEXT_BASE 是链接地址,pc是当前运行地址,通过比较地址的几个高位判断当前所处位置。
(2)如果比较相等则说明已经重定位,此时代码是在链接地址处,本次启动是热启动,跳过后面的时钟和内存初始化;
(3)如果不相等则说明此次是冷启动,要执行时钟和内存的初始化;
(4)冷启动可以理解成断电重启;热启动可以理解成从低功耗或者休眠状态启动;
判断的依据:
(1)首先此段代码是在BL1中,此时还没有执行BL2的重定位,也没有执行内存初始化代码;
(2)链接地址是指向内存的,PC的值和链接地址比较相等说明此时代码运行在内存,说明已经完成BL2的重定位,内存也初始化完成,本次启动肯定不是冷启动;
(3)如果本次代码都运行在内存中,说明内存依据可用,那就没有必要再去初始化内存和时钟,这样可以缩短启动时间。

8、外设控制器初始化

	/* init system clock */
	bl system_clock_init

	/* Memory initialize */
	bl mem_ctrl_asm_init
	
1:
	/* init UART */
	bl uart_asm_init //该函数会串口输出大写的O,和后面输出的K组成成OK,是调试用的

	//不熟,跳过
	bl tzpc_init

9、再次检查复位状态和禁止ABB

	/* check reset status  */	
	ldr	r0, =(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
	ldr	r1, [r0]
	bic	r1, r1, #0xfffeffff
	cmp	r1, #0x10000
	beq	wakeup_reset_pre

	/* ABB disable */
	ldr	r0, =0xE010C300
	orr	r1, r1, #(0x1<<23)
	str	r1, [r0]

	/* Print 'K' */
	ldr	r0, =ELFIN_UART_CONSOLE_BASE
	ldr	r1, =0x4b4b4b4b
	str	r1, [r0, #UTXH_OFFSET]

10、函数返回

pop	{pc}

将之前保存的lr寄存器的值出栈,写到PC寄存器,实现函数返回。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

uboot启动——lowlevel_init函数详解 的相关文章

  • java串行程序转化成并行执行

    在程序开发过程当中 往往存在这样一种情况 程序首先执行完method1得到结果result1之后 在执行method2获得结果result2 然后再按照result1和result2的结果来判定程序下一步的执行 在这里method1和met
  • 发送http请求,获取返回的zip包并读取包内的文件

    需要引入jar包 httpclient httpmime httpcore javax servlet api import javax servlet http HttpServletResponse import java io Fil
  • 例说数据结构&STL(六)——heap

    1 白话队列 queue heap并不归属于STL容器组件 不像队列queue它们拥有自己独立的类定义 它只能借助其他诸如数组 vector等数据结构完成堆的构造操作 但是heap实际当中有很重要的应用 像大家最熟悉的堆排序 所以STL中还
  • Anaconda 离线安装环境/PackagesNotFoundError报错

    Anaconda 离线安装环境 直接从镜像下载或者从网上下载都存在各种问题 错误一 PackagesNotFoundError TSpy37 D AnacondaWS pkgs gt conda install pytorch 1 8 0

随机推荐

  • 3DMAX、C4D、Maya导出fbx到Unity设置

    3DMAX 1 选中需要导出的模型 在Hierarchy面板Adjust Pivot中点击Affect Pivot Only 2 接着在下方的Alignment中点击Align to World 3 按F12弹出TransformType窗
  • 怎么给python文件重命名_Python os.rename()函数:重命名文件或目录

    os 模块提供了重命名文件和目录的函数 rename 如果指定的路径是文件 则重命名文件 反之 如果执行的路径是目录 则重命名目录 rename 函数的基本语法格式如下 os rename src dst 其中 src 参数用于指定要进行重
  • LeetCode刷题——第一题 (两数之和)

    1 两数之和 题目描述 思路一 思路二 思路二 代码实现 题目描述 给定一个整数数组 nums 和一个目标值 target 请你在该数组中找出和为目标值的那 两个 整数 并返回他们的数组下标 你可以假设每种输入只会对应一个答案 但是 你不能
  • 为create-react-app 创建的应用, 添加less

    npm run eject 暴露webpack配置 修改webpack config js 配置 1 添加 less 正则 const lessRegex less const lessModuleRegex module less 2 添
  • 文件服务器fuse,FUSE 扩展

    FUSE扩展 在Seafile系统上文件被分割成数据块 这意味着在你的Seafile服务器上存储的并不是完整的文件而是数据块 这种设计能够方便有效的运用数据去重技术 然而 有时系统管理员想要直接访问服务器上的文件 你可以使用seaf fus
  • 解决微信小程序报[ app.json 文件内容错误] app.json: app.json 未找到,未找到入口 app.json 文件,或者文件读取失败,请检查后重新编译。小程序app.json报错

    编译报错 app json 文件内容错误 app json app json 未找到 原因 由于project config json文件的miniprogramRoot小程序根目录属性找不到aap json的路径 可能是错误的路径 也可能
  • 刷脸支付始于支付不止于支付

    始于支付 不止于支付 支付宝和微信的战争早已延伸至城市生活的方方面面 让办事不再复杂 今年6月 中国政务服务平台同时在支付宝和微信上线 用户可在线办理查询 缴费 申领证件 投诉等200多项政务服务 还与时俱进地上线了高考分数查询 垃圾分类指
  • C语言的三子棋,也就是井字棋。

    三子棋 程序员入门必须写的东西 包含了C语言初级阶段所有的知识点 比如 do while 循环 while循环 for循环 if else语句 switch语句 二维数组 函数等等 如果要写出三子棋 这些知识点必不可少 三子棋可以分成五步
  • 【QT】——多线程的使用

    目录 基本概念 1 线程类QThread 1 1信号和槽 1 2静态函数 1 3 任务处理函数 2 实例 第一种方式 第二种方式 基本概念 默认的线程在Qt中称之为窗口线程 也叫主线程 负责窗口事件处理或者窗口控件数据的更新 子线程负责后台
  • 阿里云8888端口设置安全组,宝塔控制台显示链接失败

    问题 阿里云8888端口设置安全组 宝塔控制台显示链接失败 解决思路 在服务器ssh执行 etc init d bt restart 重启宝塔服务 刷新页面以能正常访问
  • CephFS 介绍及使用经验分享

    目录 Ceph架构介绍 NFS介绍 分布式文件系统比较 CephFS介绍 MDS介绍 5 1 单活MDS介绍 5 2 单活MDS高可用 CephFS遇到的部分问题 6 1 客户端缓存问题 6 2 务端缓存不释放 6 3 客户端夯住或者慢查询
  • Socket 中级篇(一)Socket断开后要自动重连的常用几种方法:Connected、心跳包、recv()返回值==-1等等。

    第一章 简介 抛出问题 参考 https www cnblogs com youxin p 4056041 html 功能方面比较简单就是client端与server端建立连接 然后发送消息给server 我在server端会使用专门的线程
  • OLED透明屏安装指南:准备工作、步骤和注意事项

    随着科技的不断发展 OLED透明屏作为一种新型的显示技术 逐渐得到了广泛的应用 OLED透明屏具有高透明度 高亮度和广视角等优势 可以实现透明显示效果 为商业展示 户外广告等领域提供了更广阔的空间 然而 正确的安装方法对于保证OLED透明屏
  • 自动火焰识别项目总结

    步骤分为图像获取 gt 图像预处理 gt 火焰图像分割 gt 火焰图像特征提取 gt 火焰识别 1 图像获取 视频或图片 2 图像预处理 预处理过程一般有数字化 几何变换 归一化 平滑 复原和增强等步骤 图像变换 图像增强 图像去噪 图像压
  • java实现文件下载功能

    目录 单个下载 流 1 设置响应类型和头信息 2 实现文件输出 单个下载 本地文件 1 文件读取 2 设置响应类型和头信息 3 实现文件输出 单个下载 网络文件 1 与服务器建立连接 2 设置响应类型和头信息 3 实现文件输出 压缩ZIP下
  • 第十二届蓝桥杯大赛模拟赛(网上最后一题题解大部分是错的)

    第十题 问题描述 小蓝在一个 n 行 m 列的方格图中玩一个游戏 开始时 小蓝站在方格图的左上角 即第 1 行第 1 列 小蓝可以在方格图上走动 走动时 如果当前在第 r 行第 c 列 他不能走到行号比 r 小的行 也不能走到列号比 c 小
  • 2020年,为什么你该学PHP?!!

    1676对于编程初学者来说一个开发顺手的代码编辑器很重要 可大多数人不了解代码编辑器有哪些 网上有很多种代码编辑器推荐 但是不知道这些代码编辑器哪个好用 所以 今天php中文网就为初学者推荐2020最好用的8个代码编辑器 代码编辑器排行榜
  • 聚类算法——KMeans算法(机器学习)

    KMeans算法 一 输入参数 n clusters 数据集将被划分成 n clusters个 簇 即k值以及 int optional default 8 一般需要选取多个k值进行运算 并用评估标准判断所选k值的好坏 以获得较好的聚类效果
  • 基于消息中间件解决分布式事务的开源框架Myth

    基于消息中间件的解决分布式事务框架 https github com yu199195 myth 1 rpc框架支持 dubbo motan springcloud 2 消息中间件支持 jms activimq amqp rabbitmq
  • uboot启动——lowlevel_init函数详解

    1 将lr寄存器中的值压栈 push lr lr寄存器保存的是函数返回地址 每个模式下只有一个lr寄存器 如果涉及多重函数调用 则lr寄存器会被覆盖 导致返回地址丢失 在之前已经初始化栈 所以这里可以将lr寄存器压栈 将来函数返回的时候再弹