告别Petalinux!用Vitis 2021.2手把手教你为ZynqMP黑金板子制作SD卡启动盘
在嵌入式开发领域,Xilinx的Zynq UltraScale+ MPSoC系列以其强大的处理能力和灵活的硬件可编程性赢得了众多工程师的青睐。然而,对于许多习惯了传统开发流程的开发者来说,Petalinux工具链的学习曲线和自动化程度可能会带来一定的不适应。本文将带你使用更底层的Vitis工具链,从零开始为黑金AXU2CGB开发板构建完整的SD卡启动方案,让你对ZynqMP的启动过程有更深入的理解和控制。
1. 开发环境准备与工程创建
在开始之前,我们需要确保开发环境配置正确。以下是所需的软件和硬件清单:
- 开发板:黑金AXU2CGB(基于Xilinx XCZU2CG芯片)
- 开发工具:
- Vivado 2021.2(用于硬件设计)
- Vitis 2021.2(用于软件开发)
- 交叉编译工具链(aarch64-linux-gnu-)
首先,在Vivado中创建一个基本的硬件工程。这个工程至少需要包含以下外设:
create_project zynqmp_boot . -part xczu2cg-sfvc784-1-e set_property board_part blackgold:axu2cgb:part0:1.0 [current_project]关键硬件配置包括:
| 外设 | 配置参数 | 备注 |
|---|---|---|
| DDR控制器 | 1GB容量 | 根据板载DDR芯片规格配置 |
| QSPI Flash | 支持x1/x2/x4模式 | 用于后续可能的Flash启动 |
| SD1接口 | 支持高速模式 | 主要启动介质 |
| UART1 | 115200波特率 | 调试输出 |
完成硬件设计后,导出XSA文件,这是Vitis工程的基础。在导出时,确保勾选"包含比特流"选项,以便后续生成完整的启动镜像。
2. 构建启动组件:FSBL与PMU固件
在Vitis中创建新的平台工程,选择刚才导出的XSA文件作为硬件规范。我们需要创建两个关键组件:
FSBL(First Stage Boot Loader):
- 这是ZynqMP启动的第一阶段代码
- 负责初始化DDR、外设等基础硬件环境
- 可通过Vitis模板"Zynq MP FSBL"快速创建
PMU(Platform Management Unit)固件:
- ZynqMP特有的系统管理单元
- 负责电源管理、复位控制和系统监控
- 使用"ZynqMP PMU Firmware"模板创建
编译这两个工程后,将分别生成fsbl.elf和pmu.elf文件。这些文件将被整合到最终的BOOT.bin镜像中。
注意:如果开发板使用特殊电源管理芯片,可能需要修改PMU固件的默认配置。黑金AXU2CGB通常不需要特殊调整。
3. 编译ARM可信固件(ATF)与U-Boot
ZynqMP的启动流程相比传统Zynq更为复杂,需要ARM可信固件(ATF)作为安全层。以下是详细步骤:
3.1 编译ARM可信固件(ATF)
获取Xilinx修改版的ATF源码(建议使用2021.2版本),然后执行:
git clone https://github.com/Xilinx/arm-trusted-firmware.git cd arm-trusted-firmware make CROSS_COMPILE=aarch64-linux-gnu- PLAT=zynqmp RESET_TO_BL31=1编译完成后,在build/zynqmp/release/bl31/目录下会生成bl31.elf文件。这个文件实现了ARM TrustZone安全扩展,为U-Boot提供安全运行环境。
3.2 编译U-Boot
对于黑金AXU2CGB开发板,我们需要适当修改设备树以匹配硬件配置。主要修改点包括:
- 网口PHY配置(黑金板通常使用RGMII接口)
- SD卡接口选择(使用SD1而非SD0)
- UART调试端口设置
编译命令如下:
export DEVICE_TREE="zynqmp-blackgold" make CROSS_COMPILE=aarch64-linux-gnu- xilinx_zynqmp_virt_defconfig make CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)编译完成后,将生成u-boot.elf文件。至此,我们已经准备好了BOOT.bin所需的所有组件:
- fsbl.elf(第一阶段引导加载程序)
- pmu.elf(平台管理单元固件)
- bl31.elf(ARM可信固件)
- u-boot.elf(第二阶段引导加载程序)
4. 构建启动镜像(BOOT.bin)与配置启动脚本
在Vitis中创建新的"Create Boot Image"工程,按照以下顺序添加组件:
- fsbl.elf(标记为bootloader)
- pmu.elf(标记为pmufw_image)
- bl31.elf(设置exception_level=el-3)
- u-boot.elf(设置exception_level=el-2)
对应的BIF文件内容如下:
//arch = zynqmp; split = false; format = BIN the_ROM_image: { [bootloader, destination_cpu = a53-0]fsbl.elf [pmufw_image]pmu.elf [destination_cpu = a53-0, exception_level = el-3]bl31.elf [destination_cpu = a53-0, exception_level = el-2]u-boot.elf }生成BOOT.bin后,我们还需要准备启动脚本。创建boot.cmd文件,内容如下:
setenv bootargs "earlycon console=ttyPS0,115200n8 clk_ignore_unused root=/dev/mmcblk0p2 rw rootwait" load mmc 0:1 0x18000000 Image.gz load mmc 0:1 0x40000000 zynqmp-blackgold.dtb booti 0x18000000 - 0x40000000使用以下命令将脚本转换为U-Boot可识别的格式:
mkimage -C none -A arm -T script -d boot.cmd boot.scr5. SD卡分区与系统部署
将SD卡插入读卡器,在Linux系统中使用fdisk进行分区:
sudo fdisk /dev/sdX创建两个分区:
- FAT32格式的启动分区(建议100MB)
- EXT4格式的根文件系统分区(剩余空间)
将以下文件复制到FAT32分区:
- BOOT.bin
- boot.scr
- Image.gz(压缩内核镜像)
- zynqmp-blackgold.dtb(设备树二进制文件)
根文件系统分区可以部署BusyBox或完整的Linux发行版文件系统。对于快速测试,可以使用预构建的ramdisk镜像:
load mmc 0:1 0x02100000 uramdisk.image.gz booti 0x18000000 0x02100000 0x400000006. 调试技巧与常见问题解决
在实际操作中,可能会遇到各种启动问题。以下是一些常见问题及解决方法:
- U-Boot无法加载:检查BOOT.bin组件顺序是否正确,特别是exception_level设置
- 内核崩溃:确认设备树是否正确匹配硬件,特别是内存地址和外设配置
- 文件系统挂载失败:检查bootargs中的root参数是否正确指向SD卡分区
调试时,可以通过UART观察启动日志。正常的启动流程应该显示:
Xilinx First Stage Boot Loader PMU Firmware 2021.2 NOTICE: ATF running on XCZU2CG U-Boot 2021.2对于网络启动调试,可以在U-Boot中配置TFTP:
setenv serverip 192.168.1.100 setenv ipaddr 192.168.1.10 tftpboot 0x18000000 Image.gz通过这种方法,你可以灵活地测试不同版本的内核和设备树,而无需反复烧写SD卡。