ZYNQ7010的FSBL启动分析

一、ZYNQ启动流程简介

  1. 大致分为:BootROM、FSBL、Uboot、Linux,如果是裸机代码则执行BootROM、FSBL、UserAPP

二、万事开头难

  1. BootROM进行一些操作之后,将FSBL拷贝到OCM中,将还执行权交给FSBL
  2. BootROM固化在ROM中,每次上电就会到此ROM中执行

三、一样的汇编?

  1. 众所周知,执行main函数之前,需要执行一段汇编代码,用于初始化main函数需要的环境
  2. _vector_table中断向量表的第一项是_boot函数
  3. _boot函数中
    1> 如果运行核是CPU0,读取寄存器的处理器ID,判断是否是想要的CPU0,则执行CheckEFUSE,否则wfe,因此如果是启动CPU0,则CPU1直接休眠等待唤醒
    2> CPU0核运行CheckEFUSE,检查设备是否是单核,是则执行OKToRUN,否则复位CPU1(存在SLCR寄存器的解锁和加锁操作)
    3> 如果运行核是CPU1,读取寄存器的处理器ID,判断是否是想要的CPU1,则执行CheckEFUSE1,否则wfe
    4> CPU1核运行CheckEFUSE1,检查设备是否是单核,是则执行OKToRUN
    5> OKToRUN函数,配置中断模式、MMU、Cache、VFP、最后跳转到_start
  4. _start函数中
    1> 执行__cpu_init,清一些寄存器、复位并重启cycle计数
    2> 清除SBSS和BSS段
    3> 设置栈指针
    4> 复位GlobalTimer和TTC
    5> 跳转到main函数

四、永远的main函数

  1. ps7_init,根据PL端配置初始化MIO、PLL、CLK、DDR
    1> 每个配置选项保存在一个大块空间中,可以理解为数组,但是长度不定,格式如下:操作码+指令长度+地址+值+掩码
    2> 通过遍历这块空间,对寄存器值进行读写、清除等的操作,完成初始化,每个寄存器的值和意义暂且略过
  2. SlcrUnlock,写寄存器0xF8000008值为DF0D进入SLCR解锁
  3. Xil_DCacheFlush()、Xil_DCacheDisable(),保证了读写缓存的一致性
  4. RegisterHandlerrs注册异常服务函数,注册操作一般就是维护了一个大数组,往数据里边填充数据即为注册,注册的几种异常包括未定义指令、软中断、取指终止、数据终止、普通中断、快速中断(复位已经绑定了_boot函数),同时使能了IRQ,即修改了CPSR寄存器的IRQ的中断屏蔽位
    1> 此处mark一下register的GCC扩展语法,,直接映射寄存器到一个局部变量
  5. DDRInitCheck(),进行DDR的读写测试
  6. InitPcap(),PCAP是一个IP核,此处初始化略,和PCAP相关的略
  7. MarkFSBLIn(),标记进入FSBL,把寄存器0xF8000258的bit29、bit30置1
  8. 读取boot模式寄存器,读取寄存器0xF800025C的低4bit,判断是那种启动方式
  9. 此处进行启动操作

五、JTAG启动,最常用的启动方式

  1. ps7_post_config
  2. SlcrUnlock
  3. ClearFSBLIn
  4. SlcrLock
  5. FsblHandoffJtagExit,清空缓存和预测器、禁用I-cache和MMU,等待调试器传递一个正确的lr地址。

六、QSPI启动

  1. InitQspi(),初始化QSPI控制器
  2. MoveImage函数,为QspiAccess
  3. NOR启动,先InitNor(),再MoveImage函数为NorAccess
  4. SD卡或MMC启动,先InitSD,再MoveImage函数为SDAccess
  5. 执行LoadBootImage,加载bootImage
    1> 读取0xF800702C的低13bit并乘以0x8000得到镜像文件起始地址
    2> 函数GetParttitionHeaderInfo得到分区头的信息
    偏移0x40,大小是4,获得长度;偏移0x9C,大小是4,再加上起始地址,获得分区头表偏移地址;根据分区头表偏移地址,拷贝分区头信息到全局变量中
    根据分区头信息获得分区个数
    3> 对于MMC设备,分区从0开始,其他存储介质,分区从1开始,第一个分区存储FSBL信息
    4> 遍历分区,得到第一个PS存储分区,设置执行地址ExecAddress;得到PL分区,执行PartitionMove,拷贝PL代码到DDR,函数返回PS执行地址
  6. FsblHandoff函数,参数是执行地址号ExecAddress
    1> ps7_post_config
    2> SlcrUnlock
    3> ClearFSBLIn
    4> FsblHandoffExit,清空缓存和预测器、禁用I-cache和MMU,并准被跳转到应用程序地址
posted @ 2025-08-04 15:04  gramming  阅读(323)  评论(0)    收藏  举报