ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vitis 2020.1创建Boot Image报错?Bootgen命令行生成BOOT.BIN实操指南

Vitis 2020.1创建Boot Image报错?Bootgen命令行生成BOOT.BIN实操指南 搞Zynq的兄弟们应该都有过这种经历硬件工程在Vivado 2020.1里综合、布局布线、生成比特流一路绿灯结果到Vitis这边点一下Create Boot Image直接蹦出来一个“尝试复制启动文件失败”心态当场就崩了。这个报错我在Vivado 2020.1搭配Vitis做Zynq开发的时候踩过不止一次每次群里也都有人问。今天就把这个报错的来龙去脉、根因分析和绕开的实操方案一次讲清楚。先交代环境。我这边主力工具是Vivado 2020.1加同一版本的Vitis芯片是Zynq-7000系列工程里要用QSPI Flash做启动介质所以需要Vitis把FSBL、比特流和应用程序打包成BOOT.BIN。这个BIN文件最终烧到QSPI Flash里上电之后Zynq的BootROM才能把它读出来跑起来。整个过程看着就是点几下鼠标的事但中间只要有一个环节不对报错信息就会非常劝退。这篇文章适合正在用Vivado 2020.1和Vitis生成QSPI启动文件的FPGA开发者尤其是刚接触Zynq启动流程、对Bootgen机制还不熟的朋友。我把报错机理、命令行生成方案、常见问题速查表都整理好了按步骤操作基本都能解决。1. 先把问题定性QSPI启动文件到底卡在哪一步1.1 为什么Zynq必须要QSPI启动文件Zynq-7000是Xilinx推出的异构SoC内部有两个ARM Cortex-A9硬核加上一块可编程逻辑PL。它跟纯FPGA不一样上电之后不是直接从比特流启动的而是由片内BootROM先启动BootROM再去读外部非易失存储介质里的启动镜像最后才把操作系统或者裸机程序跑起来。QSPI Flash就是这些非易失介质里非常常用的一种。它体积小、管脚少、读取速度快板子上贴一颗Winbond或Micron的QSPI NOR Flash就能把BOOT.BIN存进去。跟SD卡启动比QSPI的优势是启动速度快、不容易松动适合工业现场跟NAND比QSPI的驱动简单BootROM原生支持不用额外做坏块管理。这里要理解一个关键点不是把比特流直接丢进Flash就能启动的。Zynq的启动镜像必须按照BootROM要求的格式组织这个格式就是BOOT.BIN。一个典型的BOOT.BIN包含三部分内容镜像组成部分作用来源FSBLFirst Stage Boot Loader初始化DDR、时钟、MIO加载后续镜像Vitis里用Zynq FSBL模板编译生成比特流.bit配置PL部分逻辑Vivado综合生成应用程序/SSBL裸机程序或U-Boot等二级引导Vitis应用工程或第三方编译FSBL、比特流、应用程序这三样东西被Bootgen工具按一定顺序打包成BOOT.BIN。Vitis的GUI集成了Bootgen但要命的是它经常在这个环节出各种奇怪的报错。1.2 报错发生的典型场景与现场还原这个报错的触发路径非常固定基本都是这么操作的先在Vivado里导出一个硬件平台文件XSA然后在Vitis里用这个XSA创建Platform Project再新建一个Application Project选Zynq FSBL模板生成FSBL.elf之后还要有一个存放实际应用的工程。等到所有elf和bit文件都编译完右键Application Project在菜单中选择Create Boot ImageVitis会弹出一个Boot Image窗口让你添加分区、选输出路径。很多人就是在点了Generate Image之后看到类似这样的报错ERROR: Failed to copy file(s) from C:\Xilinx\Vitis\2020.1\bin\bootgen.exe to C:\Users\xxx\workspace\test\Debug或者中文界面直接显示“尝试复制启动文件失败”。我第一次见到这个报错时还以为是自己权限不够换管理员身份运行也没用。后来发现这不是权限问题那么简单而是Vitis 2020.1在Windows环境下调用Bootgen时的一个典型坑。还有一类报错也很常见弹出的信息是cannot open file D:\project\my_board\BOOT.BIN这种情况通常是BOOT.BIN已经被其他程序占用或者输出目录根本不存在导致Bootgen写不进去。报错样式五花八门但根子都在Bootgen的调用机制上。2. 为什么Vitis会提示“启动文件复制失败”2.1 理解Vitis生成BOOT.BIN的工作机制要解决这个报错先得明白Vitis点一下Create Boot Image之后后台到底干了什么事。其实流程不复杂Vitis先根据你在Boot Image窗口里填的分区信息生成一个BIF文件Boot Image Format。这个BIF文件是文本格式记录着镜像的分区布局、加载地址、文件名等关键信息。然后Vitis会调用它内置的Bootgen工具读取BIF文件把各个输入文件打包成BOOT.BIN。问题就出在这个调用过程上。Windows下Bootgen不是直接以独立进程启动的Vitis会先尝试把Bootgen相关的可执行文件复制到工程的临时目录或者工作目录下再从那里执行。如果这个复制动作被中断、被安全软件拦截、或者目标目录已存在同名文件且属性为只读就会报“尝试复制启动文件失败”。更细一步说Vitis 2020.1在生成镜像时默认会把几个关键文件复制到workspace根目录下包括bootgen相关的依赖文件。如果你的workspace路径很深、很长或者包含了中文、空格、特殊字符复制操作也会失败。这是Windows路径解析的麻烦Linux下基本不会有这个问题。2.2 排查下来最常见的5个原因我实战中把能踩的坑都踩了一遍整理下来最常遇到的原因就是下面这几个。第一输出目录存在同名BOOT.BIN且文件属性是只读。之前生成过一次后来再用GUI重新生成Vitis要覆盖旧文件但旧文件被只读属性挡住了复制目标不可写。第二workspace路径或工程路径包含中文、空格、括号等字符。Bootgen内部有路径拼接逻辑对这类字符处理得很粗糙经常解析失败。有次我工程放在D:\FPGA开发板\新工程 (2024)目录下怎么生成都报错换到纯英文路径立刻就好。第三杀毒软件或系统Defender拦截了Bootgen。Xilinx的工具经常会被安全软件误杀Bootgen.exe试图执行时被拦截Vitis就认为复制失败或启动失败。这个问题在Windows 10、Windows 11上都见过。第四Vitis工作空间里有残留的旧版本Bootgen。之前装过Vivado 2019.2或更早版本PATH环境变量里指向了旧的bootgen导致Vitis 2020.1调用了错误版本呼出失败或BIF解析失败。第五workspace目录的写入权限不足。Vitis安装在C盘默认位置workspace也在C盘如果当前用户对这个文件夹没有完全控制权限复制的目标目录不可写。2.3 版本适配与工具链选型的一个大坑除了上述原因使用Vivado 2020.1这套工具有个很隐蔽的问题。2020.1是Vitis刚取代SDK的早期版本Boot Image生成逻辑跟之前SDK时代有一些差异官方文档却不太跟得上。你会发现Vitis 2020.1创建Boot Image时生成的BIF文件有时会双重嵌套比如BIF里引用的路径又带着一层相对路径解析导致Bootgen找不到输入文件。另外XSA文件版本和Vitis版本必须匹配。如果你用Vivado 2020.2导出的XSA去Vitis 2020.1里建工程或者反过来Vitis在生成引导镜像时会出现更离奇的错误不一定是复制失败但时常表现为Bootgen报各种找不到文件、无法初始化分区。所以做项目前最好先确认整个工具链版本统一哪怕是小版本升级也要保证Vivado、Vitis、XSA三者配套。如果你用的是Zynq UltraScale MPSoC还要额外注意Boot ROM支持的镜像分区类型和Zynq-7000不一样Bootgen版本太旧会不认识某些分区属性。2020.1的Bootgen对新MPSoC的支持已经比较完善但如果你之前安装过旧版SDK改变了环境变量Bootgen实际调用的可能还是旧版。这时候必须强制指定Bootgen路径。3. 五分钟绕开GUI报错手动生成BOOT.BIN的完整流程3.1 准备三样关键文件既然GUI靠不住最稳妥的办法就是绕开它手动用Bootgen命令行生成BOOT.BIN。前提是你得先凑齐输入文件。第一个是FSBL.elf。在Vitis里新建Application Project操作系统选standalone硬件平台选你的Platform模板选择Zynq FSBL编译后会在Debug目录下生成FSBL.elf。如果没有这个模板确认一下你的Platform Project是否正常XSA是否导入成功。第二个是比特流文件system.bit。这个从Vivado那边拿。Vivado工程综合布线之后生成比特流时勾选生成bin文件或不勾选都行关键是拿到那个.bit文件。通常在工程的工程名.runs/impl_1/目录下。第三个是应用程序或者二级引导。如果是Linux开发这里放U-Boot的u-boot.elf如果是裸机程序放你自己应用程序的elf文件。把这三个文件都放在一个干净的英文目录下比如D:\qspi_boot\后续操作会方便很多。注意FSBL.elf、bit文件、应用elf三者的体系结构都必须匹配不能一个32位一个64位混着用。Zynq-7000是32位ARM这个问题不突出MPSoC就要格外小心FSBL和U-Boot的编译选项得一致。3.2 手写BIF文件完整示例下一步是手写BIF文件。BIF是Bootgen的输入描述文件内容不复杂格式非常固定。下面是我常用的Zynq-7000裸机启动BIF模板the_ROM_image: { [bootloader] ./image/fsbl.elf ./image/system.bit ./image/app.elf }把这三行内容保存为boot.bif放到D:\qspi_boot\下。注意[bootloader]前缀被用来标记FSBL它在生成的BOOT.BIN中会放到起始位置是BootROM最先执行的代码。后面的bit文件和app.elf按顺序排列BootROM执行完FSBL后FSBL会解析并加载它们。如果你的需求是QSPI支持双镜像启动两套镜像交替或者需要配置安全引导、加密分区BIF格式会更复杂。但常规开发用上面这个三行版本就够了它能跑通整个流程之后再根据需求加属性。还有一种情况你希望在启动时将比特流的一部分在FSBL阶段就加载到PL端而应用程序另一段时间再加载那可以在BIF里给bit文件指定不同的加载属性。这个我建议等基础流程跑通之后再研究避免一上来就把问题复杂化。3.3 用Bootgen命令一键生成BIF文件准备好之后打开命令行窗口。如果你没有把Bootgen路径加入PATH需要先切换到Bootgen所在目录cd C:\Xilinx\Vitis\2020.1\bin然后执行bootgen -image D:\qspi_boot\boot.bif -o i D:\qspi_boot\BOOT.BIN -w on参数解释一下-image指定BIF文件-o i表示输出格式为BIN文件-w on表示覆盖已存在的输出文件这个参数特别重要避免因为旧文件存在而中断。如果还想同时生成BIF格式的镜像描述文件可以加-o i,bif但普通情况下不需要。执行成功后命令行会打印Bootgen的版本信息和处理摘要不会像GUI那样弹出乱七八糟的错误。然后用dir D:\qspi_boot\BOOT.BIN或者资源管理器查看能看到一个几百KB到几MB不等的BIN文件取决于你的比特流和应用程序大小。如果你用的是Vivado 2020.1但没有单独安装Vitis那Bootgen位于Vivado安装目录下的bin中。如果是Vivado和Vitis都装了强烈建议使用Vitis目录下的Bootgen它对BIF新特性的支持更完整。提示如果你的工程涉及PMU固件或U-Boot启动MPSoC平台BIF文件需要增加[pmufw_image]等分区描述。Zynq UltraScale的启动镜像格式和Zynq-7000不同千万别把7000的BIF模板直接套到MPSoC上。3.4 怎么确认生成的BOOT.BIN是有效的Bootgen执行成功不代表生成的镜像一定没问题还得做基本验证。最直接的验证方法是看Bootgen的日志输出如果哪个输入文件找不到它会明确提示。比如缺FSBL它会报“File not found: fsbl.elf”。还可以用Bootgen的-log参数生成日志文件方便排查bootgen -image D:\qspi_boot\boot.bif -o i D:\qspi_boot\BOOT.BIN -w on -log D:\qspi_boot\bootgen.log拿到BOOT.BIN之后我习惯再用Hex工具打开文件头看一眼。一个正常的BOOT.BIN文件头会有一段特定的ARM异常向量表起始字节通常是00 00 00 EA之类的跳转指令。如果文件头是白的或者全零大概率是Bootgen没有正常工作。另一个更严谨的验证方式是用Vivado的program_flash工具直接把BOOT.BIN烧到QSPI Flash里然后设置板卡为QSPI启动模式上电看串口输出。只要FSBL能打印出启动信息整条链路就算通了。4. 高频报错速查表与两个排查细节4.1 一键速查表把我在多个项目里积累的报错信息整理成一张速查表按图索骥会省很多事报错信息或现象可能原因快速解决办法尝试复制启动文件失败 / Failed to copy file(s) from bootgen.exeworkspace路径含中文、空格或杀毒软件拦截换纯英文短路径临时关闭Defender实时防护手动命令行生成ERROR: [BootGen 66-70] Cannot open BIF fileBIF文件路径写错或目标不存在在BIF里改用绝对路径确认boot.bif已保存cannot open file BOOT.BIN / Permission denied输出文件被占用或目录不可写关闭文件预览、烧写工具使用-w on覆盖检查目录权限WARNING: Bootgen version mismatchPATH环境变量指向旧版Bootgen在命令行显式切换到Vitis 2020.1目录再用.\bootgen.bat调用ERROR: [Common 17-55] get_property expects at least one objectXSA与Vitis工程版本不匹配删除Vitis工程重新用正确版本的XSA创建PlatformGenerate Image按钮灰色不可点工程里没有FSBL或应用工程确保Application Project使用了FSBL模板且编译成功BIF解析失败 / syntax errorBIF文件格式错误比如少了冒号或分号对照我的模板逐行检查留意编码格式必须无BOM这张表并不能覆盖所有报错但覆盖了我见过的90%以上的情况。剩下的要么是版本严重不匹配要么是系统环境坏了重装工具之前建议先试试下面的排查细节。4.2 打开完整日志看Bootgen到底在干什么Vitis GUI在出错时给的信息太精简有时候只有一行话根本不知道根因。这时我推荐绕开GUI直接用命令行跑Bootgen因为它会把错误信息完整地打印出来谁找不到、哪个路径解析失败、哪个文件被占用一目了然。命令行的排查姿势是这样的。先把Vitis那个失败的工程里的_ide/临时目录打开你会在里面发现Vitis生成了一半的BIF文件。这个BIF有时就是导致失败的元凶它记录的路径是相对路径而相对基准目录Vitis自己都搞混了。拿到这个BIF手动改成绝对路径再用Bootgen命令行执行基本都能成。再配合一个操作在命令行里执行set或echo %PATH%查看环境变量里有没有挂着多个Xilinx版本路径。如果发现有C:\Xilinx\SDK\2019.1\bin之类的残留建议把它从系统PATH里移掉只保留Vitis 2020.1的bin目录。这个细节能解决一批“Bootgen回退到旧版本”的诡异问题。4.3 烧写环节的注意事项BOOT.BIN生成成功之后还有烧写环节。如果你用Vivado的Hardware Manager烧写QSPI需要先确认连接正常然后添加配置存储设备。选Flash型号时要注意你的板子上具体是哪一家的哪一颗选错型号虽然也能写但上电读取会失败。烧写命令推荐用program_flash在Vitis的xilinx路径下执行示例program_flash -f D:\qspi_boot\BOOT.BIN -offset 0x0 -flash_type qspi-x4-single -fsbl D:\qspi_boot\fsbl.elf -cable port xilinx_tcf-flash_type的值要根据Flash实际位宽调整qspi-x4-single还是qspi-x8取决于硬件设计。另外不要把BOOT.BIN写到非零偏移位置除非你配置了FSBL从其他位置启动。QSPI Flash的启动地址就是0x0BootROM固定从这里开始读。烧写完成后把板卡的启动模式拨码开关拨到QSPI模式。Zynq-7000的启动模式引脚是MIO[4:5]不同的拨码组合对应不同启动介质。拨错的话上电之后完全没有输出很多新手会误以为烧写失败了实际上是启动模式没对。5. 实操心得我后来是怎么避开这个坑的5.1 我现在的标准工作流踩过几次坑之后我现在做Zynq启动镜像已经不再依赖Vitis的GUI了整个流程固化成了命令行流水线。第1步Vivado导出的XSA保持不变Vitis里只做两件事编译FSBL工程、编译应用工程。第2步把编译产物拷贝到一个专门维护的镜像输出目录里比如D:\deploy\image\。第3步直接用Bootgen命令行读取我维护好的BIF模板生成BOOT.BIN。第4步用脚本把BOOT.BIN拷贝到烧写目录或者打包给生产。这套流程的好处是稳定、可重复、好交接。哪怕换一台电脑只要Bootgen版本一致脚本扔过去就能跑。GUI的Create Boot Image我再也不点直接把那个报错扼杀在摇篮里。如果你经常做多板卡量产这个思路尤其重要。把BIF模板和生成脚本用git管理起来版本变化一目了然。新来的同事不用理解Vitis那个复杂的Boot Image窗口会跑脚本就行。5.2 给新手的提醒如果你是第一次接触Zynq启动流程我的建议是不要急着用GUI。先花半小时把Bootgen命令行用熟你会对这个工具有完全不同的理解。即使不手动生成遇到报错时也能通过命令行去诊断而不是面对一个孤零零的GUI弹窗发愁。还有一件事值得注意Vivado和Vitis的安装路径尽量保持默认的C:\Xilinx下不要装在带中文或空格的目录里。很多玄学报错其实是安装路径不干净导致的这个成本最低的规范能帮你避开一大半问题。另外遇到报错先搜索再重装工具。Xilinx论坛、各种技术社区里关于“Vitis QSPI启动文件报错”的内容非常多很多都附带了完整日志。你遇到的坑大概率别人也踩过而且已经有了成熟解法。动不动就卸载重装Vivado是SDK时代遗留下来的不良习惯2020.1这个版本工具链重装一次成本太高时间不划算。最后说一个我最近才悟到的点Bootgen其实比很多人想象的要智能它会把BIF里的所有文件校验一遍包括文件大小、对齐方式、甚至ELF文件的段信息。如果某个输入文件本身是坏的Bootgen会在最后关头报一个很莫名的错误。遇到这种情况把所有输入文件重新编译一次往往就解决了。所以排错顺序应该是检查输入文件是否有效、检查路径、检查权限、最后才怀疑工具本身。
返回列表