ZYNQ MPSOC ZU2CG/ZU3EG/ZU4 U-BOOT流程(1)

10 篇文章 1 订阅
  这里不谈PETALINUX,就从源码开发说起,本文重点介绍XILINX ZYNQ MPSOC UBOOT流程:

在这里插入图片描述 (开发板照片,大家可以买一个便宜点的。)

一、链接脚本 u-boot.lds

    要分析 uboot 的启动流程,首先要找到“启动流程入口”,找到第一行程序在哪里
    程序的链接是由链接脚本来决定的,所以通过链接脚本可以找到程序的入口
    编译uboot完成以后才会在 uboot 根目录下生成 u-boot.lds文件
    下面打开 u-boot.lds看一下,如图一(部分)      

在这里插入图片描述
(图一)

第 3 行为代码当前入口点: _start, _start 在文件 arch/arm/lib/vectors.S 中有定义,图二
在这里插入图片描述 (图二)

_start 后面就是中断向量表,从图中的“.section “.vectors”,"ax”可知,此代码存放在.vectors 段里,接着看uboot.lds文件,如图三(部分)
在这里插入图片描述(图三)

u-boot.map 是 uboot 的映射文件,可以从此文件看到某个文件或者函数链接到了哪个地址,图四
在这里插入图片描述(图四)

下面对照图四,可以看到__image_copy_start 为 0x0000000008000000
图三的11 行是 vectors 段,.text 和 中断向量表的存放.vector 的起始地址也是0x0000000008000000
图三12 行将 arch/arm/cpu/armv7/start.s 编译出来的代码放到中断向量表后面
图三13 行为 text 段,其他的代码段就放到这里
有“开始”__image_copy_start就会有__image_copy_end“结束”,如图五
在这里插入图片描述(图五)

在__image_copy_start代码段和__image_copy_end代码段中间,就是镜像文件,uboot代码段会进行重定位,所以就会有“copy”,知道copy的起始和终止地址,就会知道需要拷贝什么了 end的地址需要编译之后才知道,因为不同的uboot、不同的配置,代码的不同,不同的优化等级,会导致整个uboot编译完之后的镜像结束地址是不一样的,所以,一切以实际值为准

二、reset 函数源码

    从 u-boot.lds 中知道了入口点是 arch/arm/lib/vectors.S 文件中的_start,看图六

在这里插入图片描述(图六)
48 行_start 开始的是中断向量表,其中 54~61 行就是中断向量表
54 行跳转到 reset 函数里面, reset 函数在 arch/arm/cpu/armv8/start.S 里面,看图七
在这里插入图片描述(图七)
35 行就是 reset 函数
37 行reset 函数跳转到 save_boot_params 函数,save_boot_params 函数也在start.S,图八在这里插入图片描述(图八)
save_boot_params 函数继续跳转在save_boot_params_ret,也在start.S
43 行,读取寄存器 cpsr 中的值,并保存到 r0 寄存器中
44 行,将寄存器 r0 中的值与 0X1F 进行与运算,结果保存到 r1 寄存器中
目的就是提取 cpsr 的 bit0~bit4 这 5 位,即 M4 M3 M2 M1 M0用来设置处理器的工作模式
在这里插入图片描述除了 User(USR)用户模式以外,其它 8 种运行模式都是特权模式。这几个运行模式可以通过软件进行任意切换,也可以通过中断或者异常来进行切换。但是用户模式是不能直接进行切换的,用户模式下需要借助异常来完成模式切换。
45 行,判断 r1 寄存器的值是否等于 0X1A(0b11010),即判断当前处理器模式是否是Hyp 模式
46 行,如果 r1 和 0X1A 不相等,也就是 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 处于 SVC32 模式, 并且关闭FIQ 和 IRQ 这两个中断
然后继续执行执行下面的代码,图十
在这里插入图片描述(图十)

56 行,如果没有定义 CONFIG_ARMV8__SPL_EXCEPTION_VECTORS和 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
在这里插入图片描述上图可以看出, bit13 为 V 位,此位是向量表控制位,当为 0 的时候向量表基地址为 0X00000000,软件可以重定位向量表。为 1 的时候向量表基地址为 0XFFFF0000
软件不能重定位向量表。这里将 V 清零,目的就是为了接下来的向量表重定位
60 行将 r0 寄存器的值重写写入到寄存器 SCTLR 中
63行设置r0寄存器的值为_start, _start就是整个uboot的入口地址,其值为0x0000000008000000
相当于 uboot 的起始地址,因此 0x0000000008000000也是向量表的起始地址
64 行将 r0 寄存器的值(向量表值)写入到 CP15 的 c12 寄存器中,也就是 VBAR 寄存器所以可以知道58~64 行就是设置向量表重定位的
继续往下执行代码,如图十一

在这里插入图片描述68 行如果没有定义 CONFIG_ARMV8_SET_SMPEN的话条件成立。
这没有定义,因此条件成立,执行下面的语句
分别调用函数 lowlevel_init、 _main

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值