ZYNQ Alternate Boot Mode 设置
ZCU106 Alternate Boot Mode、System Reset 与 POR 指南
本文解释 Zynq UltraScale+ MPSoC 的 Alternate Boot Mode,并给出 Vitis 2022.1/XSDB 可直接执行的命令。核心结论是:
写入 Alternate Boot Mode 只是在寄存器中准备下一次启动模式,不会立即复位。随后执行
rst -system,CSU BootROM 才会在一次 system reset 中使用 alternate 模式;这不是 POR。
1. 三种复位要分开
| 操作 | 是否重新运行 CSU BootROM | 是否重新选择 boot mode | 是否等同 POR |
|---|---|---|---|
写BOOT_MODE_USER | 否 | 否,只准备配置 | 否 |
rst -processor | 否 | 否 | 否 |
rst -system | 是 | 是,使用USE_ALT或物理模式 | 否 |
| 断电重上电/POR 引脚 | 是 | 是,重新采样物理拨码 | 是 |
rst -processor只复位当前 A53/R5 核。例如 R5 在VINITHI=1时会回到0xFFFF0000;它不会重新加载 SD/QSPI 镜像,也不会再次执行 BootROM 的 XIP OCM 跳板。
rst -system会重建处理器/DAP target并重新执行 CSU BootROM,但不会产生真正的电源上电复位。已写入的BOOT_MODE_USER.USE_ALT/ALT_BOOT_MODE能在该流程中被 BootROM 使用。
POR 会重新采样板上启动拨码。冷启动验证、改变拨码后的验证以及怀疑 warm-reset 残留状态时,应断电重上电或使用明确的 POR 硬件信号。
2.BOOT_MODE_USER位域
寄存器:
CRL_APB_BOOT_MODE_USER = 0xFF5E0200 CRL_APB_BOOT_MODE_POR = 0xFF5E0204BOOT_MODE_USER:
bit[15:12] ALT_BOOT_MODE bit[8] USE_ALT bit[3:0] BOOT_MODE(当前物理启动引脚值)Alternate 写值计算:
value = (ALT_BOOT_MODE << 12) | (1 << 8)常用编码:
| 模式 | 编码 | 写入值 |
|---|---|---|
| JTAG | 0x0 | 0x00000100 |
| QSPI24 | 0x1 | 0x00001100 |
| QSPI32 | 0x2 | 0x00002100 |
| SD0 | 0x3 | 0x00003100 |
| SD1 | 0x5 | 0x00005100 |
| SD1 Low Speed | 0xE | 0x0000E100 |
ZCU106 当前 SD 卡路径实测使用SD1_LS=0xE;QSPI 当前物理模式实测为QSPI24=0x1。
写0xE100后,如果物理拨码仍是 QSPI24,读回可能是:
BOOT_MODE_USER = 0x0000E101如果物理低四位是 SD1-LS,则可能读回0x0000E10E。判断 alternate 模式要查看 bit[15:12] 和 bit[8],不能只看最低四位。
3. Alternate Boot 的实际时序
JTAG 写 BOOT_MODE_USER | | 此时 CPU 仍继续运行,BootROM 没有重新执行 v 执行 rst -system | | system reset,不是 POR v CSU BootROM 读取 USE_ALT | +-- USE_ALT=1:使用 ALT_BOOT_MODE | +-- USE_ALT=0:使用物理 boot pins v 从指定设备启动并释放 A53/R5Alternate Boot 适合在不改变拨码和不重新插拔 SD 卡的情况下,对比同一次上电中的 SD/QSPI/JTAG BootROM 路径。它不能完全代替冷启动验证,因为某些电源域、外设和寄存器只在 POR 后回到真正的初始状态。
4. 一键脚本
脚本:
build/zcu106_fsbl/boot_alt_mode.tcl强制 QSPI24 并 system reset:
cd F:\code\embeddedsw &'D:\App_Software\vivado\install\Vitis\2022.1\bin\xsdb.bat'`'.\build\zcu106_fsbl\boot_alt_mode.tcl'qspi24强制 ZCU106 SD1-LS:
&'D:\App_Software\vivado\install\Vitis\2022.1\bin\xsdb.bat'`'F:\code\embeddedsw\build\zcu106_fsbl\boot_alt_mode.tcl'sd1_ls强制 JTAG boot:
&'D:\App_Software\vivado\install\Vitis\2022.1\bin\xsdb.bat'`'F:\code\embeddedsw\build\zcu106_fsbl\boot_alt_mode.tcl'jtag清除 alternate 并按物理拨码 system reset:
&'D:\App_Software\vivado\install\Vitis\2022.1\bin\xsdb.bat'`'F:\code\embeddedsw\build\zcu106_fsbl\boot_alt_mode.tcl'physical脚本参数还支持qspi32、sd0和sd1。脚本会打印 reset 前后两个 boot mode 寄存器、RPU 配置和 target 状态。
5. XSCT Console 手工操作
在 Vitis 选择Xilinx -> XSCT Console。
QSPI24
connect -url tcp:127.0.0.1:3121 targets -set -nocase -filter {name =~ "PSU"} mwr 0xFF5E0200 0x00001100 mrd 0xFF5E0200 2 rst -system after 3000 targetsSD1-LS
targets -set -nocase -filter {name =~ "PSU"} mwr 0xFF5E0200 0x0000E100 rst -system after 3000 targets恢复物理拨码
targets -set -nocase -filter {name =~ "PSU"} mwr 0xFF5E0200 0x00000000 rst -system after 3000只执行mwr ... 0而不 reset,只会清除下一次启动的 alternate 选择;当前已经运行的程序不会改变。
6. Vitis IDE 操作
Vitis 2022.1 没有单独的 Alternate Boot 对话框,最稳定的 GUI 工作流是在 IDE 内使用 XSCT Console:
- Vivado Hardware Manager
Open Target -> Auto Connect,或启动本机hw_server。 - 打开 Vitis workspace。
Xilinx -> XSCT Console。- 输入上一节命令,或执行:
source F:/code/embeddedsw/build/zcu106_fsbl/boot_alt_mode.tcl脚本需要一个参数,因此推荐从 PowerShell 调用;在 XSCT Console 手工操作时直接使用mwr/rst命令更清楚。
- reset 后打开 Debug perspective,刷新 Targets,Attach 到新出现的 A53/R5。
- 不要让 Debug Configuration 再执行一次 system reset,否则可能覆盖刚完成的启动现场。
7. 实测对照
现有脚本compare_r5_mpu_alt_sd_qspi.tcl在同一次上电中依次执行 alternate SD1-LS 和 QSPI24:
&'D:\App_Software\vivado\install\Vitis\2022.1\bin\xsdb.bat'`'F:\code\embeddedsw\build\zcu106_fsbl\compare_r5_mpu_alt_sd_qspi.tcl'结果:
SD1-LS non-XIP: PC = 0xFFFC00E8 SCTLR.M = 0 QSPI24 XIP: PC = 0xC00400E8 SCTLR.M = 1 Region 1 = base 0xC0000000, attr 0x30B, size 0x39该实验使用的是两次rst -system,不是两次 POR。这一点正是 Alternate Boot 的价值:不用移动拨码即可让 BootROM走不同启动分支,并比较 OCM/CPU 上下文。
8. 什么情况下必须 POR
以下情况优先断电重上电:
- 刚改变物理拨码,需要验证真实冷启动模式。
- QSPI/SD 控制器因失败实验处于未知状态。
- DAP sticky error 无法通过普通 reset 清除。
- 电源域、PLL、DDR、OCM ECC 或安全状态可能保留 warm-reset 上下文。
- 要证明产品上电行为,而不是调试阶段的 BootROM 分支。
通过 JTAG 控制 POR 引脚属于硬件级操作,使用前应确认线缆支持并避免在 Flash 写入过程中触发。日常最可靠的 POR 方法仍是关闭板卡电源,等待电源完全下降后重新上电。
9. 常见误区
| 误区 | 正确理解 |
|---|---|
写0x1100后立刻变成 QSPI 启动 | 不会,必须再执行 system reset |
rst -system等于 POR | 不等于,它会重跑 BootROM,但不是电源上电复位 |
rst -processor会重跑 BootROM | 不会,只复位选中的 CPU 核 |
清除USE_ALT会立即切换当前程序 | 不会,只影响下一次 BootROM 启动 |
| alternate 结果可完全代表冷启动 | 不能,最终产品验证仍需 POR |
| 低四位就是 alternate 模式 | 低四位是物理 boot pins;alternate 看 bit[15:12] 和 bit[8] |
10.实际运行效果
PS F:\code\embeddedsw>&'D:\App_Software\vivado\install\Vitis\2022.1\bin\xsdb.bat' `>>'.\build\zcu106_fsbl\boot_alt_mode.tcl' qspi24 BOOT_MODE_USER before:FF5E0200:00000000BOOT_MODE_POR:FF5E0204:00000000Requested qspi24:ALT_BOOT_MODE=0x1USE_ALT=1write=0x00001100BOOT_MODE_USER armed:FF5E0200:00001101Issuing systemreset(not POR)...BOOT_MODE_USER after:FF5E0200:00001101BOOT_MODE_POR after:FF5E0204:00000000RPU_0_CFG:FF9A0100:00000005Targets after boot:1PS TAP2PMU3PL4*PSU5RPU6Cortex-R5 #0(Running)7Cortex-R5 #1(Reset)8APU(L2 Cache Reset)9Cortex-A53 #0(APU Reset)10Cortex-A53 #1(APU Reset)11Cortex-A53 #2(APU Reset)12Cortex-A53 #3(APU Reset)11. 附录
boot_alt_mode.tcl脚本的详细代码如下
if{$argc!=1}{puts"Usage: xsdb boot_alt_mode.tcl <qspi24|qspi32|sd0|sd1|sd1_ls|jtag|physical>"exit2}set requested[string tolower[lindex $argv0]]array set boot_codes{jtag0x0qspi240x1qspi320x2sd00x3sd10x5sd1_ls0xE}connect-url tcp:127.0.0.1:3121after400targets-set-nocase-filter{name=~"PSU"}puts"BOOT_MODE_USER before: [mrd -force 0xFF5E0200 1]"puts"BOOT_MODE_POR: [mrd -force 0xFF5E0204 1]"if{$requested eq"physical"}{#USE_ALT=0.The low BOOT_MODE bits remain the live physical pin value.mwr0xFF5E02000x00000000puts"Cleared USE_ALT; next system reset uses physical boot pins."}elseif{[info existsboot_codes($requested)]}{set code $boot_codes($requested)set value[expr{($code<<12)|(1<<8)}]mwr0xFF5E0200$value puts[format"Requested %s: ALT_BOOT_MODE=0x%X USE_ALT=1 write=0x%08X"\ $requested $code $value]}else{puts"Unknown mode: $requested"disconnect exit2}puts"BOOT_MODE_USER armed: [mrd -force 0xFF5E0200 1]"puts"Issuing system reset (not POR)..."rst-system after3000targets-set-nocase-filter{name=~"PSU"}puts"BOOT_MODE_USER after: [mrd -force 0xFF5E0200 1]"puts"BOOT_MODE_POR after: [mrd -force 0xFF5E0204 1]"puts"RPU_0_CFG: [mrd -force 0xFF9A0100 1]"puts"Targets after boot:"puts[targets]disconnect exit