• ZynqMP PL固件通过U-BOOT从指定位置加载FPGA BIT


    原因

    PL固件可能经常修改,而BOOT.BIN和文件系统、内核实际上基本不会变,在一个平台上可以用同一份。如果每次修改都要重新打包PL 固件到BOOT.BIN,操作起来非常麻烦。所以希望PL 的固件可以直接从指定位置加载。典型的可以从SD卡的FAT32分区加载。

    https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841847/Solution+ZynqMP+PL+Programming

    The Zynq UltraScale+ MPSoC Programmable Logic (PL) can be programmed either using First Stage Boot-loader(FSBL), U-Boot or through Linux.

    这里主要是说U-BOOT的方式以及它存在的问题。

    实施

    修改platform-top.h,从platform-auto.h中copy 如下字段:

    /* Extra U-Boot Env settings */
    #define CONFIG_EXTRA_ENV_SETTINGS \
    	SERIAL_MULTI \ 
    	CONSOLE_ARG \ 
    	DFU_ALT_INFO_RAM \ 
    	DFU_ALT_INFO_MMC \ 
    	PSSERIAL0 \ 
    	"nc=setenv stdout nc;setenv stdin nc;\0" \ 
    	"ethaddr=00:0a:35:00:22:01\0" \
    	"bootenv=uEnv.txt\0" \ 
    	"importbootenv=echo \"Importing environment from SD ...\"; " \ 
    		"env import -t ${loadbootenv_addr} $filesize\0" \ 
    	"loadbootenv=load mmc $sdbootdev:$partid ${loadbootenv_addr} ${bootenv}\0" \ 
    	"sd_uEnvtxt_existence_test=test -e mmc $sdbootdev:$partid /uEnv.txt\0" \ 
    	"uenvboot=" \ 
    		"if run sd_uEnvtxt_existence_test; then " \ 
    			"run loadbootenv; " \ 
    			"echo Loaded environment from ${bootenv}; " \ 
    			"run importbootenv; " \ 
    			"fi; " \ 
    		"if test -n $uenvcmd; then " \ 
    			"echo Running uenvcmd ...; " \ 
    			"run uenvcmd; " \ 
    		"fi\0" \ 
    	"autoload=no\0" \ 
    	"sdbootdev=0\0" \ 
    	"clobstart=0x10000000\0" \ 
    	"netstart=0x10000000\0" \ 
    	"dtbnetstart=0x23fff000\0" \ 
    	"loadaddr=0x10000000\0" \ 
    	"boot_img=BOOT.BIN\0" \ 
    	"load_boot=tftpboot ${clobstart} ${boot_img}\0" \ 
    	"update_boot=setenv img boot; setenv psize ${bootsize}; setenv installcmd \"install_boot\"; run load_boot ${installcmd}; setenv img; setenv psize; setenv installcmd\0" \ 
    	"install_boot=mmcinfo && fatwrite mmc ${sdbootdev} ${clobstart} ${boot_img} ${filesize}\0" \ 
    	"install_bootenv=mmcinfo && fatwrite mmc ${sdbootdev} ${clobstart} ${bootenv_img} ${filesize}\0" \ 
    	"jffs2_img=rootfs.jffs2\0" \ 
    	"load_jffs2=tftpboot ${clobstart} ${jffs2_img}\0" \ 
    	"update_jffs2=setenv img jffs2; setenv psize ${jffs2size}; setenv installcmd \"install_jffs2\"; run load_jffs2 test_img; setenv img; setenv psize; setenv installcmd\0" \ 
    	"sd_update_jffs2=echo Updating jffs2 from SD; mmcinfo && fatload mmc ${sdbootdev}:1 ${clobstart} ${jffs2_img} && run install_jffs2\0" \ 
    	"install_jffs2=sf probe 0 && sf erase ${jffs2start} ${jffs2size} && " \ 
    		"sf write ${clobstart} ${jffs2start} ${filesize}\0" \ 
    	"kernel_img=image.ub\0" \ 
    	"load_kernel=tftpboot ${clobstart} ${kernel_img}\0" \ 
    	"update_kernel=setenv img kernel; setenv psize ${kernelsize}; setenv installcmd \"install_kernel\"; run load_kernel ${installcmd}; setenv img; setenv psize; setenv installcmd\0" \ 
    	"install_kernel=mmcinfo && fatwrite mmc ${sdbootdev} ${clobstart} ${kernel_img} ${filesize}\0" \ 
    	"cp_kernel2ram=mmcinfo && fatload mmc ${sdbootdev} ${netstart} ${kernel_img}\0" \ 
    	"dtb_img=system.dtb\0" \ 
    	"load_dtb=tftpboot ${clobstart} ${dtb_img}\0" \ 
    	"update_dtb=setenv img dtb; setenv psize ${dtbsize}; setenv installcmd \"install_dtb\"; run load_dtb test_img; setenv img; setenv psize; setenv installcmd\0" \ 
    	"sd_update_dtb=echo Updating dtb from SD; mmcinfo && fatload mmc ${sdbootdev}:1 ${clobstart} ${dtb_img} && run install_dtb\0" \ 
    	"loadbootenv_addr=0x00100000\0" \ 
    	"fault=echo ${img} image size is greater than allocated place - partition ${img} is NOT UPDATED\0" \ 
    	"test_crc=if imi ${clobstart}; then run test_img; else echo ${img} Bad CRC - ${img} is NOT UPDATED; fi\0" \ 
    	"test_img=setenv var \"if test ${filesize} -gt ${psize}\\; then run fault\\; else run ${installcmd}\\; fi\"; run var; setenv var\0" \ 
    	"netboot=tftpboot ${netstart} ${kernel_img} && bootm\0" \ 
    	"default_bootcmd=run uenvboot; run cp_kernel2ram && bootm ${netstart}\0" \ 
    ""
    
    

    COPY并增加烧录指令:

    #define CONFIG_EXTRA_ENV_SETTINGS \
    	SERIAL_MULTI \ 
    	CONSOLE_ARG \ 
    	DFU_ALT_INFO_RAM \ 
    	DFU_ALT_INFO_MMC \ 
    	PSSERIAL0 \ 
    	"nc=setenv stdout nc;setenv stdin nc;\0" \ 
    	"ethaddr=00:0a:35:00:22:01\0" \
    	"bootenv=uEnv.txt\0" \ 
    	"importbootenv=echo \"Importing environment from SD ...\"; " \ 
    		"env import -t ${loadbootenv_addr} $filesize\0" \ 
    	"loadbootenv=load mmc $sdbootdev:$partid ${loadbootenv_addr} ${bootenv}\0" \ 
    	"sd_uEnvtxt_existence_test=test -e mmc $sdbootdev:$partid /uEnv.txt\0" \ 
    	"uenvboot=" \ 
    		"if run sd_uEnvtxt_existence_test; then " \ 
    			"run loadbootenv; " \ 
    			"echo Loaded environment from ${bootenv}; " \ 
    			"run importbootenv; " \ 
    			"fi; " \ 
    		"if test -n $uenvcmd; then " \ 
    			"echo Running uenvcmd ...; " \ 
    			"run uenvcmd; " \ 
    		"fi\0" \ 
    	"autoload=no\0" \ 
    	"sdbootdev=0\0" \ 
    	"clobstart=0x10000000\0" \ 
    	"netstart=0x10000000\0" \ 
    	"dtbnetstart=0x23fff000\0" \ 
    	"loadaddr=0x10000000\0" \
       	"bitstream_image=system.bit.bin\0" \
       	"mmc_loadbit_fat=echo Loading bistream from media to RAM..; && mmcinfo && fatload mmc ${sdbootdev} ${loadaddr} ${bitstream_image} && fpga load 0 ${loadaddr} ${filesize}\0" \  
    	"boot_img=BOOT.BIN\0" \ 
    	"load_boot=tftpboot ${clobstart} ${boot_img}\0" \ 
    	"update_boot=setenv img boot; setenv psize ${bootsize}; setenv installcmd \"install_boot\"; run load_boot ${installcmd}; setenv img; setenv psize; setenv installcmd\0" \ 
    	"install_boot=mmcinfo && fatwrite mmc ${sdbootdev} ${clobstart} ${boot_img} ${filesize}\0" \ 
    	"install_bootenv=mmcinfo && fatwrite mmc ${sdbootdev} ${clobstart} ${bootenv_img} ${filesize}\0" \ 
    	"jffs2_img=rootfs.jffs2\0" \ 
    	"load_jffs2=tftpboot ${clobstart} ${jffs2_img}\0" \ 
    	"update_jffs2=setenv img jffs2; setenv psize ${jffs2size}; setenv installcmd \"install_jffs2\"; run load_jffs2 test_img; setenv img; setenv psize; setenv installcmd\0" \ 
    	"sd_update_jffs2=echo Updating jffs2 from SD; mmcinfo && fatload mmc ${sdbootdev}:1 ${clobstart} ${jffs2_img} && run install_jffs2\0" \ 
    	"install_jffs2=sf probe 0 && sf erase ${jffs2start} ${jffs2size} && " \ 
    		"sf write ${clobstart} ${jffs2start} ${filesize}\0" \ 
    	"kernel_img=image.ub\0" \ 
    	"load_kernel=tftpboot ${clobstart} ${kernel_img}\0" \ 
    	"update_kernel=setenv img kernel; setenv psize ${kernelsize}; setenv installcmd \"install_kernel\"; run load_kernel ${installcmd}; setenv img; setenv psize; setenv installcmd\0" \ 
    	"install_kernel=mmcinfo && fatwrite mmc ${sdbootdev} ${clobstart} ${kernel_img} ${filesize}\0" \ 
    	"cp_kernel2ram=mmcinfo && run mmc_loadbit_fat && fatload mmc ${sdbootdev} ${netstart} ${kernel_img}\0" \ 
    	"dtb_img=system.dtb\0" \ 
    	"load_dtb=tftpboot ${clobstart} ${dtb_img}\0" \ 
    	"update_dtb=setenv img dtb; setenv psize ${dtbsize}; setenv installcmd \"install_dtb\"; run load_dtb test_img; setenv img; setenv psize; setenv installcmd\0" \ 
    	"sd_update_dtb=echo Updating dtb from SD; mmcinfo && fatload mmc ${sdbootdev}:1 ${clobstart} ${dtb_img} && run install_dtb\0" \ 
    	"loadbootenv_addr=0x00100000\0" \ 
    	"fault=echo ${img} image size is greater than allocated place - partition ${img} is NOT UPDATED\0" \ 
    	"test_crc=if imi ${clobstart}; then run test_img; else echo ${img} Bad CRC - ${img} is NOT UPDATED; fi\0" \ 
    	"test_img=setenv var \"if test ${filesize} -gt ${psize}\\; then run fault\\; else run ${installcmd}\\; fi\"; run var; setenv var\0" \ 
    	"netboot=tftpboot ${netstart} ${kernel_img} && bootm\0" \ 
    	"default_bootcmd=run uenvboot; run cp_kernel2ram && bootm ${netstart}\0" \ 
    ""
    
    

    其中主要增加 mmc_loadbit_fat 指令,指定u-boot 从指定位置加载指定的bit 文件。

    这里bit文件实际上是bin 格式,这是因为bin 文件包含了头文件信息,这样ZYNQ才能完成PL编程。

    BIT转BIN

    cd [get_property DIRECTORY [current_project]]/[current_project].runs/impl_1
    write_cfgmem -format bin -interface spix1 -loadbit "up 0x0 [get_property top [current_fileset]].bit" -file [get_property DIRECTORY [current_project]]/system.bit.bin -force

    BIN文件放在BOOT.BIN和IMAGE.UB同目录

    问题

    如果你的PL 固件使用了PS的复位信号作为系统复位,这种方式可能会导致复位不完全导致逻辑故障。所以使用该方式要保证你的逻辑复位正常,这通常应该通过修改设计结局。

    比如 我的CXP HOST采集和存储逻辑,当使用上述方式编程PL的时候会工作不正常,数据存储异常,但是直接打包到BOOT.BIN 通过FSBL加载则工作正常,这一点需要后续跟进debug ,这里也做一个记录。

  • 相关阅读:
    集群部署看过来,低代码@AWS智能集群的架构与搭建方案
    劝学:Android 14 Framework 引入了哪些“新”技术栈
    武汉大学计算机考研资料汇总
    CSRF漏洞
    【Web安全】文件上传漏洞
    完整、免费的把pdf转word文档
    【濡白的C语言】部分string.h库函数的实现
    【Qt】初识Qt&Qt Creator
    asp.net+sqlserver汽车4s店销售网站系统c#项目
    RpcProvider的网络服务,以及怎么发布服务方法
  • 原文地址:https://www.cnblogs.com/xingce/p/18249877