zynq动态加载bit

zynq动态加载bit

前言

zynq作为一款集成arm与fpga的soc,在工业领域具有很大的用武之地,使用petalinux进行开发有很大的便利,但是编译的的系统,需要将fsbl,uboot,bit打包为BOOT.bin文件用于启动,对于fpga人员来说,更换bit需要进行一些列的linux的编译,实属麻烦,况且fpga人员可能一般不太熟悉linux,这会对linux的开发带来很多麻烦。下面介绍一种在petalinux下将bit分离出BOOT.bin中,可以单独替换bit的一种办法。

提示:以下是本篇文章正文内容,下面案例可供参考

一、petalinux编译流程

通常 PetaLinux 工具遵循顺序设计流程模型,如下表所示:
在这里插入图片描述
从上表可以看到,使用 Vivado 搭建好硬件平台后,通过几个命令就完成了 Linux 系统的
定制,极其方便。
需要说明的是以上设计流程不是按部就班的每一步都执行一遍,可以根据使用场景有选
择的执行。一般的设计流程如下:

  1. 通过 Vivado 创建硬件平台,得到 hdf 硬件描述文件;
  2. 运行 source <petalinux 安装路径>/settings.sh,设置 Petalinux 运行环境
  3. 通过 petalinux-create -t project 创建 petalinux 工程;
  4. 使用 petalinux-config --get-hw-description,将 hdf 文件导入到 petalinux 工程当中并配置 petalinux 工程;
  5. 使用 petalinux-config -c kernel 配置 Linux 内核;
  6. 使用 petalinux-config -c rootfs 配置 Linux 根文件系统;
  7. 配置设备树文件;
  8. 使用 petalinux-build 编译整个工程;
  9. 使用 petalinux-package --boot 制作 BOOT.BIN 启动文件;
  10. 制作 SD 启动卡,将 BOOT.BIN 和 image.ub 以及根文件系统部署到 SD 卡中;
  11. 将 SD 卡插入开发板,并将开发板启动模式设置为从 SD 卡启动;
  12. 开发板连接串口线并上电启动,串口上位机打印启动信息,登录进入 Linux 系统。

具体的编译命令

第一步:创建工程

在这里插入图片描述

petalinux-create -t project --template zynq -n zynq

即可创建一个名为zynq的一个petalinux工程。

第二步:拷贝hdf文件并且配置工程

进入工程目录zynq

cd zynq 

拷贝hdf到zynq目录下,并且使用命令配置工程

petalinux-config --get-hw-description ./

在这里插入图片描述

第三步:编译工程生成uboot与内核

petalinux-build

在工程目录的imag/linux下可看到对于的uboot.bin,system.bit,image.ub文件

第四步:打包生成BOOT.bin文件

ZYNQ 的启动文件 BOOT.BIN 一般包含 fsbl 文件、bitstream 文件和 uboot 文件。使用下面命令可生成 BOOT.BIN 文件:

petalinux-package --boot --fsbl --fpga --u-boot --force

第五步:启动linux

将BOOT.bin与内核文件image.ub拷贝到sd卡即可启动linux。

二、动态加载bit文件

以上的是正常的petalinux开发linux操作,不过boot.bin文件将fpga文件的bit一起打包在一起了,以下流程可将bit分离出来,实现动态加载,只需更替bit文件即可。

第一步:修改platform-top.h文件

在zynq目录project-spec/meta-user/recipes-bsp/u-boot/files下
在这里插入图片描述
platform-top.h文件是uboot配置的一些常数文件

修改前

在这里插入图片描述


#include <configs/platform-auto.h>
#define CONFIG_SYS_BOOTM_LEN 0xF000000
#define DFU_ALT_INFO_RAM \
                "dfu_ram_info=" \
        "setenv dfu_alt_info " \
        "image.ub ram $netstart 0x1e00000\0" \
        "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \
        "thor_ram=run dfu_ram_info && thordown 0 ram 0\0"

#define DFU_ALT_INFO_MMC \
        "dfu_mmc_info=" \
        "set dfu_alt_info " \
        "${kernel_image} fat 0 1\\\\;" \
        "dfu_mmc=run dfu_mmc_info && dfu 0 mmc 0\0" \
        "thor_mmc=run dfu_mmc_info && thordown 0 mmc 0\0"


/*Required for uartless designs */
#ifndef CONFIG_BAUDRATE
#define CONFIG_BAUDRATE 115200
#ifdef CONFIG_DEBUG_UART
#undef CONFIG_DEBUG_UART
#endif
#endif

/*Define CONFIG_ZYNQ_EEPROM here and its necessaries in u-boot menuconfig if you had EEPROM memory. */
#ifdef CONFIG_ZYNQ_EEPROM
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
#define CONFIG_SYS_I2C_EEPROM_ADDR             0x54
#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
#define CONFIG_SYS_EEPROM_SIZE                 1024 /* Bytes */
#define CONFIG_SYS_I2C_MUX_ADDR                0x74
#define CONFIG_SYS_I2C_MUX_EEPROM_SEL          0x4
#endif

修改后

在这里插入图片描述


#include <configs/platform-auto.h>
#define CONFIG_FPGA_ZYNQPL
#define CONFIG_SYS_BOOTM_LEN 0xF000000
#define DFU_ALT_INFO_RAM \
                "dfu_ram_info=" \
        "setenv dfu_alt_info " \
	"bitstream_bit=system.bit\0"	\
	"bitstream=system.bit\0"	\
	"loadbit_addr=0x100000\0"	\
	"mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \
		"mmcinfo && " \
		"load mmc 0 ${loadbit_addr} ${bitstream} && " \
		"fpga loadb 0 ${loadbit_addr} ${filesize}\0" \
        "image.ub ram $netstart 0x1e00000\0" \
        "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \
        "thor_ram=run dfu_ram_info && thordown 0 ram 0\0"

#define DFU_ALT_INFO_MMC \
        "dfu_mmc_info=" \
        "set dfu_alt_info " \
        "${kernel_image} fat 0 1\\\\;" \
        "dfu_mmc=run dfu_mmc_info && dfu 0 mmc 0\0" \
        "thor_mmc=run dfu_mmc_info && thordown 0 mmc 0\0"


/*Required for uartless designs */
#ifndef CONFIG_BAUDRATE
#define CONFIG_BAUDRATE 115200
#ifdef CONFIG_DEBUG_UART
#undef CONFIG_DEBUG_UART
#endif
#endif

/*Define CONFIG_ZYNQ_EEPROM here and its necessaries in u-boot menuconfig if you had EEPROM memory. */
#ifdef CONFIG_ZYNQ_EEPROM
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
#define CONFIG_SYS_I2C_EEPROM_ADDR             0x54
#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
#define CONFIG_SYS_EEPROM_SIZE                 1024 /* Bytes */
#define CONFIG_SYS_I2C_MUX_ADDR                0x74
#define CONFIG_SYS_I2C_MUX_EEPROM_SEL          0x4
#endif

#define CONFIG_BOOTCOMMAND	"run mmc_loadbit; run default_bootcmd"

主要做了几处修改

#define CONFIG_FPGA_ZYNQPL //开启uboot加载bit命令

增加加载bit命令,下面代码是从sd卡加载名字为system.bit文件名的bit文件,在uboot运行mmc_loadbit即可加载bit

"bitstream_bit=system.bit\0"	\
	"bitstream=system.bit\0"	\
	"loadbit_addr=0x100000\0"	\
	"mmc_loadbit=echo Loading bitstream from SD/MMC/eMMC to RAM.. && " \
		"mmcinfo && " \
		"load mmc 0 ${loadbit_addr} ${bitstream} && " \
		"fpga loadb 0 ${loadbit_addr} ${filesize}\0" \

下面的是启动命令,在启动内核前先调研run mmc_loadbit加载bit后再运行default_bootcmd,这是加载内核进入系统的命令。

#define CONFIG_BOOTCOMMAND	"run mmc_loadbit; run default_bootcmd"

在另外一个文件platform-auto.h文件中可看到,具体原因不详说了,这涉及到uboot具体启动方式,不是一两句可以说清楚,有兴趣的朋友可以自己研究
platform-auto.h在目录zynq/project-spec/meta-plnx-generated/recipes-bsp/u-boot/configs下
在这里插入图片描述

第二步:重新编译

petalinux-build

第三步:重新生成BOOT.BIN文件

这里去掉了fpga的文件,打包后的文件不会包含bit
修改后

petalinux-package --boot --fsbl  --u-boot --force

未修改前

petalinux-package --boot --fsbl --fpga --u-boot --force

第四步:拷贝文件到sd卡

在这里插入图片描述
这里与之前多拷贝了system.bit文件,改文件是fpga的文件,可以从hdf中得到,也可以使用vivado生成的bit文件,两者是等价的。

三、启动系统

使用uboot加载bit

在这里插入图片描述
uboot界面,可使用mmc_loadbit命令进行加载bit

run mmc_loadbit

在这里插入图片描述
可看到成功加载界面

上电自动加载bit

由于配置好了上电加载bit,系统启动期间只要不打断,让他自动加载系统即可自动加载bit
或者在uboot命令行使用bootcmd进入系统

run bootcmd

在这里插入图片描述

总结

希望对大家有所帮助

文档共60页。主要向初学者提供了Zynq开发的技术方向,针对不同应用给出了基本的参考文档;同时对Zynq双核AMP加载方式做了详细描述,对Zynq的fsbl启动流程做了简单介绍。章节如下: Zynq User Guide 1 介绍 4 2 快速上手指南 4 3 多核开发教程 4 3.1 AMP开发说明 6 3.1.1 快速生成amp工程 6 3.1.2 Generating Boot File 8 3.1.3 烧写程序 9 3.1.4 启动 10 3.1.5 调试 10 3.1.6 总结 11 3.2 SMP开发说明 11 4 ZC706启动代码分析 11 4.1 启动代码 12 4.2 FSBL流程(FOR AMP) 13 4.3 CPU0启动CPU1流程 14 5 程序在线烧写方案及流程 14 5.1 程序烧写需求 14 5.2 提出该需求的原因 14 5.3 程序烧写方案 14 5.3.1 BOOT.BIN组成 14 5.3.2 BOOT.BIN生成方法 15 5.4 FSBL.BIN和APP.BIN等的生成 15 5.5 制作*BIN及烧写的具体步骤 15 5.5.1 制作*bin流程 15 5.5.2 BOOT.bin制作过程 15 5.5.3 FSBL.bin和APP.bin等的生成过程 22 5.6 烧写BOOT.BIN步骤 26 5.6.1 通过SDK工具烧写步骤 26 5.6.2 通过上位机烧写软件的烧写步骤 29 5.6.3 通过串口调试助手烧写步骤 29 6 Zynq Qspi控制器 30 6.1 基本特性 30 6.2 I/O接口 31 6.3 QSPI控制器模式 33 6.3.1 I/O模式 33 6.3.2 线性地址(linear address)模式 33 6.3.3 传统(legacy)SPI模式 34 6.4 QSPI 例程 34 6.5 QSPI控制器支持访问32MB方法 35 6.5.1 Bank地址寄存器(Bank address register) 35 6.5.2 扩展地址模式(Extended address mode) 35 6.5.3 使用新写命令(New commands) 35 6.6 QSPI FLASH选择 35 6.7 作为BOOT器件考虑 35 7 µC/OS系统启动指南 36 7.1 INTRODUCTION 36 7.1.1 Software Requirements 36 7.1.2 Hardware Requirements 36 7.2 HARDWARE DESIGN 37 7.2.1 Step 1. Invoke the Vivado IDE and Create a project 37 7.2.2 Step 2. Create an IP Integrator Design 39 7.2.3 Step 3. Add and setup the Zynq processor system IP block 39 7.2.4 Step 4. Customize the Zynq block for our design 41 7.2.5 Step 5. Add the soft peripherals 45 7.2.6 Step 6. Generate HDL Design Files 47 7.2.7 Step 7. Synthesis, Implement and Generate Bitstream 48 7.3 SOFTWARE DESIGN 49 7.3.1 Step 1. Installation of the µC/OS Repository 49 7.3.2 Step 2. Generate the µC/OS BSP 50 7.3.3 Step 3. Build and Debug the Demonstration Project 54 7.3.4 Step 4. Program the AXI Timer 0 with the ucos_axitimer Driver 55 7.3.5 Step 5. Program the AXI Timer 1 with the Xilinx tmrctr Driver 58 7.4 CONCLUSION 59 8 Linux系统启动指南 59
### Zynq PS 加载地址配置方法及参数 #### 配置加载地址的方式 对于Zynq系列器件,在PS(处理系统)加载过程中,可以通过多种途径设置加载地址。通常情况下,加载过程涉及从外部存储器读取数据并将其传输至内部内存或DDR中特定的位置。 当通过SD卡或者Flash启动时,FSBL(First Stage Boot Loader)负责初始化必要的硬件资源,并将后续阶段所需的代码复制到指定的目标地址[^1]。具体来说: - **初始引导加载程序(Boot ROM)**:在上电复位之后自动运行,它会依据预定义的规则去寻找合法的启动源。一旦找到合适的启动设备,则继续执行相应的操作来加载第二级引导加载程序即FSBL。 - **FSBL的作用**:此部分主要职责在于完成基本外围接口初始化工作以及准备用于传递给应用程序处理器核(Cortex-A9) 的上下文环境;同时也会把PL比特流映射进系统的物理地址空间内以便于稍后的下载动作能够顺利开展。 为了使PS能正确解析这些指令和数据,必须确保它们被放置在一个已知且固定的起始位置之上。例如,在某些应用场景下,可能会采用如下所示的方法来进行设定: ```bash make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm zynq_zc702_defconfig ``` 上述命令中的`zynq_zc702_defconfig`选项指定了目标板的具体型号及相关配置细节,而编译工具链前缀则表明了交叉编译所针对的操作系统架构类型[^2]。 至于实际的加载地址,这取决于具体的项目需求和技术文档的规定。一般而言,Linux内核镜像会被安排存放在较低范围内的RAM区域里,比如0x8000处开始的一段连续区间;而对于用户自定义的应用程序或其他固件组件,则可以根据实际情况灵活调整其安置地点。 另外值得注意的是,在涉及到动态重配PL的情况下,还需要考虑如何有效地管理不同版本之间可能存在的冲突问题。此时可借助于专门设计好的API函数库如`xdecfg_polled_example.c`所提供的功能来简化这一流程,从而允许开发者更加便捷地控制整个更新过程。 最后,有关bit文件转换成适合加载的形式,可以使用带有`-split`参数的相关工具,该参数将会生成`.bit.bin`这样的二进制格式文件,便于进一步部署到目标平台上[^3]。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值