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 系统的 定制,极其方便。 需要说明的是以上设计流程不是按部就班的每一步都执行一遍,可以根据使用场景有选 择的执行。一般的设计流程如下:
- 通过 Vivado 创建硬件平台,得到 hdf 硬件描述文件;
- 运行 source <petalinux 安装路径>/settings.sh,设置 Petalinux 运行环境
- 通过 petalinux-create -t project 创建 petalinux 工程;
- 使用 petalinux-config --get-hw-description,将 hdf 文件导入到 petalinux 工程当中并配置 petalinux 工程;
- 使用 petalinux-config -c kernel 配置 Linux 内核;
- 使用 petalinux-config -c rootfs 配置 Linux 根文件系统;
- 配置设备树文件;
- 使用 petalinux-build 编译整个工程;
- 使用 petalinux-package --boot 制作 BOOT.BIN 启动文件;
- 制作 SD 启动卡,将 BOOT.BIN 和 image.ub 以及根文件系统部署到 SD 卡中;
- 将 SD 卡插入开发板,并将开发板启动模式设置为从 SD 卡启动;
- 开发板连接串口线并上电启动,串口上位机打印启动信息,登录进入 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
总结
希望对大家有所帮助
|