当前位置: 首页 > news >正文

Xilinx ZYNQ FSBL解读:LoadBootImage()

篇首

最近突发奇想,Xilinx 的集成开发环境已经很好了,很多必要的代码都直接生成了,这给开发者带来了巨大便利的同时,也让人错过了很多代码的精彩,可能有很多人用了很多年了,都还无法清楚的理解其中过程。博主准备以FSBL为例,与大家深入探讨一番,从而加深对ZYNQ的加载过程的理解,以便大家作出更精彩的设计!


LoadBootImage() 解读

本文以Zynq7000 FSBL工程代码为基础,分析启动流程核心函数 L o a d B o o t I m a g e ( ) LoadBootImage() LoadBootImage()的执行逻辑与关键技术细节。

一、函数调用框架

int LoadBootImage(void) {FsblHookBeforeBitstreamDdr(); // 钩子函数Status = XFsbl_LoadPartitions(...); // 核心加载FsblHookBeforeHandoff(); // 移交前预处理return Status;
}

二、 函数执行全流程分解

** 函数入口与预处理**
int LoadBootImage(void) {u32 Status = XFSBL_SUCCESS;XTime tStart, tEnd;  // 64位计时器(若启用性能分析)
  • 硬件依赖
    • 依赖psu_init.c完成的PS端基础初始化(时钟、MIO、SLCR锁等)
    • DDR物理层已通过Xil_DDRInit()完成训练(psu_ddr_phyinit.c
** F s b l H o o k B e f o r e B i t s t r e a m D d r ( ) FsblHookBeforeBitstreamDdr() FsblHookBeforeBitstreamDdr() 钩子函数**
#ifdef FSBL_PERFXTime_GetTime(&tStart);  // 记录TSC起始值(AXI Timer 0)
#endif
/* 用户自定义扩展点:可插入DDR重配置代码 */
  • 关键寄存器操作
    • DDRC控制:通过Xil_Out32(0xFD070000, 0x00040010)设置DDRC_ADDRMAP0调整地址映射
    • OCM重映射:关闭OCM缓存(SLCR.OCM_CFG寄存器位3置1)
X F s b l L o a d P a r t i t i o n s ( ) XFsbl_LoadPartitions() XFsblLoadPartitions() 核心加载
阶段1:Boot Header解析
XFsblPs_BootHdr Header;
XFsbl_CheckBootHeader(ImageAddr, &Header); // 从QSPI/NAND读取头部
  • 头部结构体xfsbl_ps_boothdr.h):
    typedef struct {u32 ImageID;          // 魔数0xAA995566u32 NumPartitions;    // 分区总数(含PL比特流+应用)u32 AuthType;         // 加密类型:0=None, 1=RSA-2048u32 Checksum;         // 头部的CRC32校验// ... 其他字段(分区表偏移、证书偏移等)
    } XFsblPs_BootHdr;
    
阶段2:安全认证(以RSA-2048为例)
XSecure_Sha3Init(&Sha3Instance);  // 初始化SHA-3引擎
XSecure_Sha3Update(&Sha3Instance, (u8*)ImageAddr, Header.HashLength);
XSecure_Sha3Final(&Sha3Instance, CalculatedHash);  // 计算哈希
XSecure_VerifySignature(CalculatedHash, StoredSignature); // RSA验签
  • 硬件加速
    • 使用PS内置的CSU模块(Crypto Subsystem)
    • RSA密钥存储在eFUSE或BBRAM中(通过XSecure_GetEfuseKek()读取)
阶段3:分区加载循环
for (u8 i=0; i<Header.NumPartitions; i++) {XFsblPs_PartitionHdr PartHdr;XFsbl_ReadPartitionHdr(ImageAddr + Offset, &PartHdr);if (PartHdr.Attr & PART_ATTR_PL) {  // PL比特流分区XFsbl_LoadPlBitstream(PartHdr.LoadAddr, PartHdr.Size);} else {  // PS应用程序分区XFsbl_LoadElf(PartHdr.LoadAddr, PartHdr.Size); // ELF解析}
}
  • 关键操作细节
    • PL加载:通过DevCfg接口(XDcfg_CfgInitialize())写入PCAP
    • ELF加载:解析Program Headers,使用Xil_Out32()逐段写入DDR
    • 地址对齐:通过XLAT_FSBL_TABLE处理非32位对齐访问(触发Data Abort时自动转换)
F s b l H o o k B e f o r e H a n d o f f ( ) FsblHookBeforeHandoff() FsblHookBeforeHandoff() 移交前处理
Xil_DCacheFlush();  // 数据缓存刷新(确保DDR数据一致性)
Xil_Out32(CRL_APB_BASE + 0x24, 0x01000F00);  // 配置时钟分频
  • 寄存器详解
    • CRL_APB (0xFF5E0024): 设置RPLL_CTRL分频系数(CPU=1.3GHz, DDR=1066MHz)
    • SLCR_UNLOCK (0xF8000008): 写入0xDF0D解锁保护寄存器

三、关键子函数解析

  1. F s b l H o o k B e f o r e B i t s t r e a m D d r ( ) FsblHookBeforeBitstreamDdr() FsblHookBeforeBitstreamDdr()

    • 作用:DDR初始化前的预处理钩子
    • 执行内容:
      #ifdef FSBL_PERF
      XTime_GetTime(&tStart); // 性能计数器启动
      #endif
      
  2. X F s b l L o a d P a r t i t i o n s ( ) XFsbl_LoadPartitions() XFsblLoadPartitions()

    • 流程分解:
      • X F s b l C h e c k B o o t H e a d e r ( ) XFsbl_CheckBootHeader() XFsblCheckBootHeader()
        验证BIN文件头结构(含 s i z e o f ( X F s b l P s B o o t H d r ) sizeof(XFsblPs_BootHdr) sizeof(XFsblPsBootHdr)
      • X F s b l A u t h e n t i c a t i o n ( ) XFsbl_Authentication() XFsblAuthentication()
        执行RSA-2048签名验证(通过 X S e c u r e S h a 3 I n i t ( ) XSecure_Sha3Init() XSecureSha3Init()等加密API)
      • 分区加载循环
        遍历分区表加载:
        for(u8 PartNum=0; PartNum<Header.NumPartitions; PartNum++){XFsbl_LoadPartition(...); // 加载单个分区#ifdef FSBL_DEBUGxil_printf("Partition %d Loaded\r\n", PartNum);#endif
        }
        
  3. F s b l H o o k B e f o r e H a n d o f f ( ) FsblHookBeforeHandoff() FsblHookBeforeHandoff()

    • 执行DDR刷新操作( X i l D C a c h e F l u s h ( ) Xil_DCacheFlush() XilDCacheFlush()
    • 配置时钟分频器(通过 X i l O u t 32 ( ) Xil_Out32() XilOut32()写CRL_APB寄存器)

四、核心宏定义

  • $FSBL_DEBUG
    控制调试输出(默认关闭)
  • KaTeX parse error: Double subscript at position 15: XPAR_PSU_DDR_0_̲S_AXI_BASEADDR
    DDR控制器基地址宏(值 0 x 00100000 0x00100000 0x00100000
  • X L A T F S B L T A B L E XLAT_FSBL_TABLE XLATFSBLTABLE
    地址转换表(处理非对齐访问)

五、执行流程图

初始化硬件 → 验证头部 ↓ ↓ DDR预处理 → 加载分区 ↘ ↓ 移交控制权 \begin{array}{ccc} \text{初始化硬件} & \rightarrow & \text{验证头部} \\ \downarrow & & \downarrow \\ \text{DDR预处理} & \rightarrow & \text{加载分区} \\ & \searrow & \downarrow \\ & & \text{移交控制权} \end{array} 初始化硬件DDR预处理验证头部加载分区移交控制权

六、 关键数据流与硬件交互

数据加载路径

QSPI Flash → AXI Quad-SPI控制器 OCM缓存 → DMA DDR3 \text{QSPI Flash} \xrightarrow{\text{AXI Quad-SPI控制器}} \text{OCM缓存} \xrightarrow{\text{DMA}} \text{DDR3} QSPI FlashAXI Quad-SPI控制器 OCM缓存DMA DDR3

  • 性能优化
    • 启用DMA传输(XQspiPs_DmaTransfer()
    • 使用线性突发模式(QSPI配置为DDR模式,时钟速率83MHz)
安全认证流程

原始镜像 → SHA-3/384 哈希值 哈希值 → RSA-2048签名 验签结果 \begin{aligned} &\text{原始镜像} \xrightarrow{\text{SHA-3/384}} \text{哈希值} \\ &\text{哈希值} \xrightarrow{\text{RSA-2048签名}} \text{验签结果} \end{aligned} 原始镜像SHA-3/384 哈希值哈希值RSA-2048签名 验签结果

  • 抗攻击设计
    • 哈希计算前会清空CSU的密钥缓存(XSecure_CsuAesKcvClear()
    • 签名失败触发安全锁定(通过XSecure_SetTamperConfig()

七、调试与错误处理

调试宏启用
#define FSBL_DEBUG  // 启用调试输出
  • 典型输出
    XFsbl_Debug: Partition 0 Loaded at 0x00100000 (Size 1MB)
    XFsbl_Debug: PL Bitstream CRC Check Passed
    
** 错误码定义**
#define XFSBL_ERROR_BOOTHEADER   0x1000  // 头部校验失败
#define XFSBL_ERROR_AUTHFAIL     0x1001  // RSA验签错误
#define XFSBL_ERROR_PLLLOCK      0x1002  // 时钟锁相环失锁
  • 错误处理
    • 记录错误到PMU全局状态寄存器(XFsbl_WriteReg(PMU_GLOBAL_GLOB_GEN_STORAGE, errCode)
    • 触发系统复位(XFsbl_FallbackReset()

**八、 总结 **

L o a d B o o t I m a g e ( ) LoadBootImage() LoadBootImage()作为Zynq7000启动链的核心,其执行涵盖硬件初始化、安全认证、多阶段加载三大模块。函数首先通过 F s b l H o o k B e f o r e B i t s t r e a m D d r ( ) FsblHookBeforeBitstreamDdr() FsblHookBeforeBitstreamDdr()完成DDR时序微调与性能监控启动,随后 X F s b l L o a d P a r t i t i o n s ( ) XFsbl_LoadPartitions() XFsblLoadPartitions()深度解析Boot Header结构,利用CSU硬件模块实现RSA-2048/SHA-3安全认证,并依据分区属性(PL比特流或PS应用)选择PCAP配置或ELF加载机制。关键点包括:通过DevCfg接口的PL动态重配置、基于XLAT表的非对齐地址访问补偿、以及DMA加速的QSPI数据传输。移交控制权前,函数会强制刷新数据缓存(确保内存一致性)并通过CRL_APB寄存器组重配时钟域。调试方面,FSBL_DEBUG宏可实时输出分区加载状态,而错误处理机制将异常状态固化至PMU寄存器,为后续故障分析提供关键日志。该函数的设计充分体现了Zynq架构中PS-PL协同、硬件安全加速、以及多级启动链的技术特点。


:具体实现细节需参考对应版本的 f s b l _ h o o k s . c fsbl\_hooks.c fsbl_hooks.c x f s b l _ p a r t i t i o n l o a d . c xfsbl\_partition_load.c xfsbl_partitionload.c源码文件。

相关文章:

Xilinx ZYNQ FSBL解读:LoadBootImage()

篇首 最近突发奇想&#xff0c;Xilinx 的集成开发环境已经很好了&#xff0c;很多必要的代码都直接生成了&#xff0c;这给开发者带来了巨大便利的同时&#xff0c;也让人错过了很多代码的精彩&#xff0c;可能有很多人用了很多年了&#xff0c;都还无法清楚的理解其中过程。博…...

mysql中in和exists的区别?

大家好&#xff0c;我是锋哥。今天分享关于【mysql中in和exists的区别?】面试题。希望对大家有帮助&#xff1b; mysql中in和exists的区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 MySQL 中&#xff0c;IN 和 EXISTS 都用于进行子查询&#xff0c;但它…...

oracle 数据导出方案

工作中有遇到需要将oracle 数据库表全部导出&#xff0c;还需要去除表数据中的换行符。 方案 shell 设计 封装函数 1 function con_oracle() 用于连接oracle 2 function send_file() 用于发送文件 3 主程序 使用循环将所有表导出并发送到数据服务器 主程序 程序代码 #!…...

Apache Commons Lang3 和 Commons Net 详解

目录 1. Apache Commons Lang3 1.1 什么是 Apache Commons Lang3&#xff1f; 1.2 主要功能 1.3 示例代码 2. Commons Net 2.1 什么是 Commons Net&#xff1f; 2.2 主要功能 2.3 示例代码 3. 总结 3.1 Apache Commons Lang3 3.2 Commons Net 3.3 使用建议 4. 参考…...

从0开始的操作系统手搓教程33:挂载我们的文件系统

目录 代码实现 添加到初始化上 上电看现象 挂载分区可能是一些朋友不理解的——实际上挂载就是将我们的文件系统封装好了的设备&#xff08;硬盘啊&#xff0c;SD卡啊&#xff0c;U盘啊等等&#xff09;&#xff0c;挂到我们的默认分区路径下。这样我们就能访问到了&#xff…...

【Linux】36.简单的TCP网络程序

文章目录 1. TCP socket API 详解1.1 socket():打开一个网络通讯端口1.2 bind():绑定一个固定的网络地址和端口号1.3 listen():声明sockfd处于监听状态1.4 accept():接受连接1.5 connect():连接服务器 2. 实现一个TCP网络服务器2.1 Log.hpp - "多级日志系统"2.2 Daem…...

时序分析

1、基本概念介绍 1.1、 建立时间 T(su) 建立时间&#xff1a;setup time&#xff0c;它是指有效的边沿信号到来之前&#xff0c;输入端口数据保持稳定的时间。 1.1.1、 建立时间要求&#xff1a; 建立时间要求指的是 想要寄存器如期的工作&#xff0c;在有效时…...

doris:ClickHouse

Doris JDBC Catalog 支持通过标准 JDBC 接口连接 ClickHouse 数据库。本文档介绍如何配置 ClickHouse 数据库连接。 使用须知​ 要连接到 ClickHouse 数据库&#xff0c;您需要 ClickHouse 23.x 或更高版本 (低于此版本未经充分测试)。 ClickHouse 数据库的 JDBC 驱动程序&a…...

NLP常见任务专题介绍(1)-关系抽取(Relation Extraction, RE)任务训练模板

📌 关系抽取(Relation Extraction, RE)任务训练示例 本示例展示如何训练一个关系抽取模型,以识别两个实体之间的关系。 1️⃣ 任务描述 目标:从文本中提取两个实体之间的语义关系,例如 “人物 - 组织”、“药物 - 疾病”、“公司 - 创始人” 等。输入:句子 + 标注的实…...

大模型Transformer的MOE架构介绍及方案整理

前言&#xff1a;DeepSeek模型最近引起了NLP领域的极大关注&#xff0c;也让大家进一步对MOE&#xff08;混合专家网络&#xff09;架构提起了信心&#xff0c;借此机会整理下MOE的简单知识和对应的大模型。本文的思路是MOE的起源介绍、原理解释、再到现有MOE大模型的整理。 一…...

零基础掌握Linux SCP命令:5分钟实现高效文件传输,小白必看!

引言 “为什么我传个文件到服务器要折腾半小时&#xff1f;” 如果你也曾在Linux系统中为文件传输抓狂&#xff0c;今天这篇保姆级教程就是你的救星&#xff01;SCP命令——一个基于SSH协议的高效传输工具&#xff0c;只需5分钟&#xff0c;彻底告别FTP客户端和繁琐操作&#…...

分类评价指标

基础概念解释 TP、TN、FP、FN 这里T是True&#xff0c;F是False&#xff0c;P为Positive&#xff0c;N为Negative TP&#xff1a;被模型正确地预测为正样本&#xff08;原本为正样本&#xff0c;预测为正样本&#xff09; TN&#xff1a;被模型正确地预测为负样本&#xff0…...

Python项目-基于Django的在线教育平台开发

1. 项目概述 在线教育平台已成为现代教育的重要组成部分&#xff0c;特别是在后疫情时代&#xff0c;远程学习的需求显著增加。本文将详细介绍如何使用Python的Django框架开发一个功能完善的在线教育平台&#xff0c;包括系统设计、核心功能实现以及部署上线等关键环节。 本项…...

子数组问题——动态规划

个人主页&#xff1a;敲上瘾-CSDN博客 动态规划 基础dp&#xff1a;基础dp——动态规划-CSDN博客多状态dp&#xff1a;多状态dp——动态规划-CSDN博客 目录 一、解题技巧 二、最大子数组和 三、乘积最大子数组 四、最长湍流子数组 五、单词拆分 一、解题技巧 区分子数组&…...

linux设置pem免密登录和密码登录

其实现在chatgpt 上面很多东西问题都可以找到比较好答案了&#xff0c;最近换了一个服务器&#xff0c;记录一下。 如果设置root用户&#xff0c;就直接切换到cd .ssh目录下生成ssh key即可&#xff0c;不需要创建用户创建用户的ssh文件夹了 比如说我要让danny这个用户可以用p…...

什么是Flask

Flask是Python中一个简单、灵活和易用的Web框架&#xff0c;适合初学者使用。它提供了丰富的功能和扩展性&#xff0c;可以帮助开发者快速构建功能完善的Web应用程序。 以下是Python Flask框架的一些特点和功能&#xff1a; Flask 是一个使用 Python 编写的轻量级 WSGI 微 Web…...

Spark(8)配置Hadoop集群环境-使用脚本命令实现集群文件同步

一.hadoop的运行模式 二.scp命令————基本使用 三.scp命令———拓展使用 四.rsync远程同步 五.xsync脚本集群之间的同步 一.hadoop的运行模式 hadoop一共有如下三种运行方式&#xff1a; 1. 本地运行。数据存储在linux本地&#xff0c;测试偶尔用一下。我们上一节课使用…...

【cocos creator】热更新

一、介绍 试了官方的热更新功能&#xff0c;总结一下 主要用于安卓包热更新 参考&#xff1a; Cocos Creator 2.2.2 热更新简易教程 基于cocos creator2.4.x的热更笔记 二、使用软件 1、cocos creator v2.4.10 2、creator热更新插件&#xff1a;热更新manifest生成工具&…...

黑金风格人像静物户外旅拍Lr调色教程,手机滤镜PS+Lightroom预设下载!

调色教程 针对人像、静物以及户外旅拍照片&#xff0c;运用 Lightroom 软件进行风格化调色工作。旨在通过软件中的多种工具&#xff0c;如基本参数调整、HSL&#xff08;色相、饱和度、明亮度&#xff09;调整、曲线工具等改变照片原本的色彩、明度、对比度等属性&#xff0c;将…...

部署vue+django项目(初版)

1.准备 vscode 插件Remote SSH&#xff0c;连接远程&#xff0c;打开远程中home文件夹。 镜像和容器的一些常用命令 docker images docker ps 查看所有正在运行的容器 docker ps -a docker rmi -f tk-django-app 删除镜像 docker rm xxx 删除容器 docker start xxxx …...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...