zynq動态加載bit
文章目錄
- zynq動态加載bit
- 前言
- 一、petalinux編譯流程
-
- 第一步:建立工程
- 第二步:拷貝hdf檔案并且配置工程
- 第三步:編譯工程生成uboot與核心
- 第四步:打包生成BOOT.bin檔案
- 第五步:啟動linux
- 二、動态加載bit檔案
-
- 第一步:修改platform-top.h檔案
-
- 修改前
- 修改後
- 第二步:重新編譯
- 第三步:重新生成BOOT.BIN檔案
- 第四步:拷貝檔案到sd卡
- 三、啟動系統
-
- 使用uboot加載bit
- 上電自動加載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
總結
希望對大家有所幫助