从 JTAG 启动 Zynq UltraScale+ 上的嵌入式 Linux 镜像:详细实战教程

文章来源:OpenFPGA

在之前文章中,我们介绍了如何使用 XSCT 工具通过 JTAG 在 Zynq SoC 上启动嵌入式 Linux 镜像(从 JTAG 启动 Zynq-7000 嵌入式 Linux:使用 XSCT 全流程教程)。本文则进一步讲解如何在 Zynq UltraScale+ MPSoC 平台上通过 JTAG 逐步启动 Linux,并提供了完整的过程与关键命令。只要按步骤操作,即使是复杂的 Linux 镜像也能成功通过 JTAG 启动。

所需条件与工具

要完成 JTAG 启动,你需要准备以下内容:

  • 支持 JTAG 调试的 Zynq UltraScale+ MPSoC 板

  • 与目标板连接的 JTAG 线缆(例如 SmartLynq / Platform Cable)

  • 安装了 Xilinx 工具(如 Vitis / SDK)的开发主机

  • 可用的 Linux 镜像、设备树、ATF、U-Boot 等组件

操作概要(步骤不可改变)

整体流程分为 8 个步骤,每一步都对最终启动至关重要:

  • 启动 XSCT 命令行

  • 配置 FPGA(下载 bitstream)

  • 下载并运行 PMU Firmware

  • 配置处理系统

  • 下载并执行第一阶段引导加载器(FSBL)

  • 下载第二阶段引导加载器(U-Boot)

  • 下载 ARM Trusted Firmware

  • 下载并启动 Linux 镜像

1、如何启动 XSCT

XSCT(Xilinx Software Commandline Tool)用于通过 JTAG 与设备通信:

<INSTALLATION_PATH>/Xilinx/Vitis/2021.1/bin/xsct

或者开始菜单里寻找。

启动后,会进入交互式命令行,等待你输入各种引导命令。

11:38:24 ~ > /opt/Xilinx/Vitis/2021.1/bin/xsct 
****** Xilinx Software Commandline Tool (XSCT) v2021.1
  **** SW Build 3246112 on 2021-06-09-14:19:56
    ** Copyright 1986-2021 Xilinx, Inc. All Rights Reserved.
xsct% help
Available Help Categories
breakpoints   - Target Breakpoints/Watchpoints.
connections   - Target Connection Management.
device        - Device Configuration System.
download      - Target Download FPGA/BINARY.
hsi           - HSI commands.
ipi           - IPI commands to Versal PMC.
jtag          - JTAG Access.
memory        - Target Memory.
miscellaneous - Miscellaneous.
petalinux     - Petalinux commands.
projects      - Vitis Projects.
registers     - Target Registers.
reset         - Target Reset.
running       - Program Execution.
streams       - Jtag UART.
svf           - SVF Operations.
tfile         - Target File System.
Type "help" followed by above "category" for more details or
help" followed by the keyword "commands" to list all the commands
xsct%

2、连接目标设备

在 XSCT 中使用 connect 命令建立 JTAG 连接,例如:

connect -url tcp:<DEVICE_IP>:3121

不同 JTAG 线缆的 IP 地址不同:

  • SmartLynq:通过板上显示的 IP

  • SmartLynq(USB 直连):通常是 10.0.0.2

  • Platform Cable(国内常用JTAG):通常是 127.0.0.1

默认端口是 3121。

3、列出连到 JTAG 链的设备

连接成功后,可以查看 JTAG 链上所有目标:

xsct% targets                                                                                             
  1  PS TAP
     2  PMU
     3  PL
  4  PSU
     5  RPU (Reset)
        6  Cortex-R5 
#0 (No Power)
        7  Cortex-R5 
#1 (No Power)
     8  APU
        9  Cortex-A53 
#0 (Running)
       10  Cortex-A53 
#1 (Running)
       11  Cortex-A53 
#2 (Running)
       12  Cortex-A53 
#3 (Running)

执行命令后看到的列表targets代表连接到 JTAG 链的每个设备。设备可以是单元、CPU 内核、FPGA 等。可以对每个设备进行管理。有时可能无法在目标设备和 JTAG 电缆之间建立可靠的连接。在这种情况下,应该检查错误消息并根据消息采取相应措施。例如,当没有 JTAG 连接或电路板断电时,将显示如下所示的错误提示。

xsct% targets
  1  whole scan chain (board power off)

最常遇到的问题与使用的 JTAG 频率有关。JTAG 链路的硬件结构对其最佳频率有显著影响。某些物理特性,例如电缆长度、目标数量等,都可能影响合适的 JTAG 频率。在这种情况下,XSCT 工具会生成一些错误消息,指示与目标的连接不稳定。可以在下方看到一些示例。

xsct% targets
  1  whole scan chain (Unknown device configuration)
xsct% targets
  1  whole scan chain (Unknown IR length)
xsct% targets
  1  whole scan chain (too many devices)

当出现此类输出时,应该重新调整 JTAG 频率,以建立可靠稳定的连接。可以通过调用jtag frequency -list以下方法查找 JTAG 电缆支持的频率。然后,可以从列表中选择合适的频率。也可以选择任意频率,该实用程序会自动处理舍入误差。

xsct% jtag targets 1
xsct% jtag frequency -list
125000 250000 500000 1000000 2000000 3000000 4000000 6000000 7500000 10000000 12000000 13000000 
15000000 20000000 30000000 40000000 50000000 60000000 70000000 80000000 90000000 100000000
xsct% jtag frequency 7500000
7500000
xsct% jtag frequency 7000000
7017543

4、中断系统

在开始操作之前,CPU必须中断并重置为初始状态。没有此步骤,将无法管理处理系统。Zynq SoC 中的此步骤有所不同。要重置系统:

xsct% targets -set -nocase -filter {name =~ "*PSU*"}
xsct% rst
xsct% Info: Cortex-A53 
#0 (target 9) Stopped at 0xffff0000 (Reset Catch)
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 
#0 (No Power)
        7  Cortex-R5 
#1 (No Power)
     8  APU
        9  Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       10  Cortex-A53 
#1 (Reset)
       11  Cortex-A53 
#2 (Reset)
       12  Cortex-A53 
#3 (Reset)

5、配置FPGA

由于 Zynq UltraScale+ SoC 实际上是一款 FPGA 芯片,因此需要硬件镜像才能访问其底层组件,例如 DDR、以太网、串行接口等。通过 JTAG 下载完整的 FPGA 镜像非常简单,只需使用fpga以下命令即可。

xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 
#0 (No Power)
        7  Cortex-R5 
#1 (No Power)
     8  APU
        9  Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       10  Cortex-A53 
#1 (Reset)
       11  Cortex-A53 
#2 (Reset)
       12  Cortex-A53 
#3 (Reset)
xsct% targets -set -nocase -filter {name =~ "*PS TAP*"}
xsct% fpga "system.bit"                                                                     
100%   25MB   1.2MB/s  00:21


下载 FPGA 镜像会清除现有的 PL 镜像并将其替换为新镜像。还可以通过向同一命令提供选项来管理可编程逻辑。按 Enter 键help fpga可查看更多信息。目前,将 FPGA 镜像下载到硬件就足够了,其余内容超出了本教程的范围。

6、PMU固件

Zynq UltraScale+ SoC 包含一个专用的 MicroBlaze 处理器,用于执行平台管理。PMU 代表平台管理单元。其主要职责是在启动前初始化部分系统组件、管理分配给各个电源岛的电源以及处理系统错误。固件能够与运行在处理系统单元 (Processing System Unit) 上的用户应用程序通信。用户可以创建请求来根据需要管理平台。此外,还可以使用 Vitis IDE 修改 PMU 固件。可以参考 Zynq UltraScale+ 的技术参考手册(即 UG1085 )来进一步了解 PMU 固件的详细信息和使用场景。

如果不禁用处理系统单元 (PSU) 上的某些安全门,就无法访问位于平台管理单元 (PMU) 内的 MicroBlaze 处理器。因此,我们的第一步是禁用这些安全门。然后,我们将 PMU 固件下载到目标处理器并运行它。为了确保安全,我们将重新启用这些安全门。

xsct% targets -set -nocase -filter {name =~ "*PSU*"}                                                      
xsct% targets                                                                                             
  1  PS TAP
     2  PMU
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 
#0 (No Power)
        7  Cortex-R5 
#1 (No Power)
     8  APU
        9  Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       10  Cortex-A53 
#1 (Reset)
       11  Cortex-A53 
#2 (Reset)
       12  Cortex-A53 
#3 (Reset)
xsct% mask_write 0xFFCA0038 0x1C0 0x1C0
xsct% targets                                                                                             
  1  PS TAP
     2  PMU
       13  MicroBlaze PMU (Sleeping. No clock)
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 
#0 (No Power)
        7  Cortex-R5 
#1 (No Power)
     8  APU
        9  Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       10  Cortex-A53 
#1 (Reset)
       11  Cortex-A53 
#2 (Reset)
       12  Cortex-A53 
#3 (Reset)

禁用安全门后,MicroBlaze 内核立即出现在 JTAG 目标链上。通过获取处理器的访问权限,我们现在可以下载并运行 PMU 固件。

xsct% targets -set -nocase -filter {name =~ "*MicroBlaze PMU*"}
xsct% dow "pmufw.elf"                                                                       
Downloading Program -- pmufw.elf
 section, .vectors.reset: 0xffdc0000 - 0xffdc0007
 section, .vectors.sw_exception: 0xffdc0008 - 0xffdc000f
 section, .vectors.interrupt: 0xffdc0010 - 0xffdc0017
 section, .vectors.hw_exception: 0xffdc0020 - 0xffdc0027
 section, .text: 0xffdc0050 - 0xffdd1057
 section, .rodata: 0xffdd1058 - 0xffdd2287
 section, .data: 0xffdd2288 - 0xffdd639b
 section, .sdata2: 0xffdd639c - 0xffdd639f
 section, .sdata: 0xffdd63a0 - 0xffdd639f
 section, .sbss: 0xffdd63a0 - 0xffdd639f
 section, .bss: 0xffdd63a0 - 0xffdda0db
 section, .srdata: 0xffdda0dc - 0xffdda9f7
 section, .stack: 0xffdda9f8 - 0xffddb9f7
 section, .xpbr_serv_ext_tbl: 0xffddf6e0 - 0xffddfadf
100%    0MB   0.2MB/s  00:00                                                                              
Setting PC to Program Start Address 0xffdd0a04
Successfully downloaded pmufw.elf
xsct% Info: MicroBlaze PMU (target 13) Stopped at 0xffdc8534 (Stop)
xsct% con                                                                                                 
Info: MicroBlaze PMU (target 13) Running

如果一切顺利,我们可以重新启用安全门,以防止访问 MicroBlaze PMU,并继续进行 PSU 初始化。

xsct% targets -set -nocase -filter {name =~ "*PSU*"}
xsct% mask_write 0xFFCA0038 0x1C0 0x0
xsct% targets                                                                                             
  1  PS TAP
     2  PMU
     3  PL
  4* PSU
     5  RPU (Reset)
        6  Cortex-R5 
#0 (No Power)
        7  Cortex-R5 
#1 (No Power)
     8  APU
        9  Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       10  Cortex-A53 
#1 (Reset)
       11  Cortex-A53 
#2 (Reset)
       12  Cortex-A53 
#3 (Reset)

7、APU和PSU初始化

在将第一阶段引导加载程序下载到应用处理器单元 (APU) 之前,必须移除复位。此外,必须根据硬件映像(HDF/XSA 文件)初始化处理系统单元。从 Vivado 设计工具导出的硬件映像中包含一个名为“psu_init.tcl”的 TCL 脚本。以下是执行这些步骤的命令。

xsct% targets -set -nocase -filter {name =~ "*APU*"}
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  5  PSU
     6  RPU (Reset)
        7  Cortex-R5 
#0 (No Power)
        8  Cortex-R5 
#1 (No Power)
     9* APU
       10  Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       11  Cortex-A53 
#1 (Reset)
       12  Cortex-A53 
#2 (Reset)
       13  Cortex-A53 
#3 (Reset)
xsct% mwr 0xffff0000 0x14000000
xsct% mask_write 0xFD1A0104 0x501 0x0
xsct% source psu_init.tcl
xsct% psu_init


如果电源单元初始化成功,屏幕上将不会显示任何输出。完成此步骤后,我们便获得了对电源单元资源的访问权限。

8、第一阶段引导加载程序(FSBL)

FSBL 是Zynq UltraScale+ 启动时在应用处理器上运行的第一个程序(实际上是第二个,BootROM 首先运行) 。它负责在调用 SSBL (第二阶段引导加载程序)或所需的裸机应用程序之前配置硬件并初始化一些组件。可以使用自动生成的 FSBL,也可以编写自己的 FSBL。要下载并运行 FSBL,请调用以下命令。请注意,FSBL 必须在应用处理单元的第一个 Cortex-A53 内核上运行。因此,我们需要相应地选择目标内核。

xsct% targets -set -nocase -filter {name =~ "*A53 #0*"}
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  5  PSU
     6  RPU (Reset)
        7  Cortex-R5 
#0 (No Power)
        8  Cortex-R5 
#1 (No Power)
     9  APU
       10* Cortex-A53 
#0 (Reset Catch, EL3(S)/A64)
       11  Cortex-A53 
#1 (Reset)
       12  Cortex-A53 
#2 (Reset)
       13  Cortex-A53 
#3 (Reset)
xsct% dow "zynqmp_fsbl.elf"
Downloading Program -- zynqmp_fsbl.elf
    section, .text: 0xfffc0000 - 0xfffcf88b
    section, .note.gnu.build-id: 0xfffcf88c - 0xfffcf8af
    section, .init: 0xfffcf8c0 - 0xfffcf8f3
    section, .fini: 0xfffcf900 - 0xfffcf933
    section, .rodata: 0xfffcf940 - 0xfffcfe6f
    section, .sys_cfg_data: 0xfffcfe80 - 0xfffd0657
    section, .mmu_tbl0: 0xfffd1000 - 0xfffd100f
    section, .mmu_tbl1: 0xfffd2000 - 0xfffd3fff
    section, .mmu_tbl2: 0xfffd4000 - 0xfffd7fff
    section, .data: 0xfffd8000 - 0xfffd932f
    section, .sbss: 0xfffd9330 - 0xfffd933f
    section, .bss: 0xfffd9340 - 0xfffdb87f
    section, .heap: 0xfffdb880 - 0xfffdbc7f
    section, .stack: 0xfffdbc80 - 0xfffddc7f
    section, .dup_data: 0xfffddc80 - 0xfffdefaf
    section, .handoff_params: 0xfffe9e00 - 0xfffe9e87
    section, .bitstream_buffer: 0xffff0040 - 0xfffffc3f
100%    0MB   0.3MB/s  00:00
Setting PC to Program Start Address 0xfffc0000
Successfully downloaded zynqmp_fsbl.elf
xsct% con
Info: Cortex-A53 
#0 (target 10) Running
xsct% after 4000; stop
Info: Cortex-A53 
#0 (target 10) Stopped at 0xfffce2f0 (External Debug Request)

启动 FSBL 后,我们让它运行一段时间完成操作。然后,我们在交接点手动停止它。由于我使用的是定制板,其启动引脚被硬配置为 QSPI 启动模式,所以我修改了 FSBL 代码,强制其使用 JTAG 启动模式。以下是我的 UART 输出:

Xilinx Zynq MP First Stage Boot Loader (Modified)
Release 2021.1   Jun 20 2022  -  10:55:15
This FSBL has been modified in order to boot from the JTAG only!
Forcing the Boot Mode as JTAG! Check the xfsbl_initialization.c file.

9、第二阶段引导加载程序(U-Boot)

与常规启动流程类似,SSBL 遵循 FSBL。由于我们使用的是 PetaLinux 构建系统来生成镜像,因此我们将使用常用的 U-Boot 作为 SSBL 程序。也可以使用不同的引导加载程序,但流程应该类似。

U-Boot 需要一个设备树二进制文件,因此我们需要在启动 U-Boot 之前将其加载到内存中。该设备必须下载到内存中预先设定的地址。在 PetaLinux 项目中,此配置位于名为CONFIG_SUBSYSTEM_UBOOT_DEVICETREE_OFFSET的参数下。可以在我之前的文章中找到一个简单的单行 Bash 命令,可以更快地找到所需的配置。在我的示例中,该地址为0x100000 。请注意,由于该二进制文件不是可执行文件,因此我们使用-data选项来下载它。

xsct% targets -set -nocase -filter {name =~ "*A53 #0*"}
xsct% dow -data "system.dtb" 0x100000
100%    0MB   0.2MB/s  00:00
Successfully downloaded system.dtb

U-Boot 现在可以下载到内存中了。

xsct% targets -set -nocase -filter {name =~ "*A53 #0*"}
xsct% dow  "u-boot.elf"
Downloading Program -- u-boot.elf
 section, .text: 0x08000000 - 0x080001af
 section, .efi_runtime: 0x080001b0 - 0x080011bf
 section, .text_rest: 0x08001800 - 0x080c8c23
 section, .rodata: 0x080c8c28 - 0x080fa111
 section, .hash: 0x080fa118 - 0x080fa12f
 section, .data: 0x080fa130 - 0x0810863f
 section, .got: 0x08108640 - 0x08108647
 section, .got.plt: 0x08108648 - 0x0810865f
 section, .u_boot_list: 0x08108660 - 0x0810d3f7
 section, .efi_runtime_rel: 0x0810d3f8 - 0x0810d5a7
 section, .rela.dyn: 0x0810d5a8 - 0x08125877
 section, .bss_start: 0x08125878 - 0x08125877
 section, .bss: 0x08125880 - 0x0813e3c7
 section, .bss_end: 0x0813e3c8 - 0x0813e3c7
100%    1MB   0.3MB/s  00:04
Setting PC to Program Start Address 0x08000000
Successfully downloaded u-boot.elf


PS1:

  • 注意到了吗?这一步其实有点棘手,而且一旦出错就很难找出原因。与 FSBL 不同,我们并没有在将 U-Boot 下载到内存后立即启动它。这是因为 Zynq UltraScale+ 的架构与 Zynq SoC 相比,情况要复杂一些。Zynq UltraScale+ 的应用处理器基于 ARMv8 架构,而 Zynq 的应用处理器则基于 ARMv7 架构。

PS2:

  • 为了符合 ARVv8 拓扑结构,Linux 内核启动时运行在 ARM 异常级别 1/0。在该异常级别下,Linux 内核对系统或安全关键寄存器的访问受到硬件限制。Linux 与这些受限设备的所有交互都通过运行在异常级别 3 的 ARM 可信固件 (ATF) 进行路由。如果没有 ATF, Linux 镜像可能根本无法启动。

10、ARM 可信固件 (ATF)

如前所述,访问特权区域需要 ARM 可信固件 (ATF)。ATF 作为代理,代表操作系统修改系统关键设置。为了使操作系统(在本例中为 Linux)能够访问这些资源,必须对其进行修改,以支持 ATF 导出到操作系统自身的安全监控调用。这些步骤超出了本教程的范围。可以参考Zynq UltraScale+ 技术参考手册 UG1085 的第 16 章“16-System Protection Units”。接下来,我们将 ATF 下载到内存中。

xsct% targets -set -nocase -filter {name =~ "*A53 #0*"}
xsct% targets
  1  PS TAP
     2  PMU
     3  PL
  5  PSU
     6  RPU
        7  Cortex-R5 
#0 (No Power)
        8  Cortex-R5 
#1 (No Power)
     9  APU
       10* Cortex-A53 
#0 (External Debug Request, EL3(S)/A64)
       11  Cortex-A53 
#1 (Reset)
       12  Cortex-A53 
#2 (Reset)
       13  Cortex-A53 
#3 (Reset)
xsct% dow  "bl31.elf"
Downloading Program -- bl31.elf
 section, .text: 0xfffea000 - 0xffff1fff
 section, .rodata: 0xffff2000 - 0xffff2fff
 section, .data: 0xffff3000 - 0xffff679d
 section, stacks: 0xffff67c0 - 0xffff78bf
 section, .bss: 0xffff78c0 - 0xffff863f
 section, xlat_table: 0xffff9000 - 0xffffdfff
 section, coherent_ram: 0xffffe000 - 0xffffefff
100%    0MB   0.3MB/s  00:00
Setting PC to Program Start Address 0xfffea000
Successfully downloaded bl31.elf


我们没有重新启动处理器,因为还缺少一样东西,那就是 Linux 内核本身。

11、完整的 Linux 镜像

本教程的最后一步是将 Linux 内核镜像下载到 DDR 内存中,并通过 U-Boot 启动它。用于下载镜像的地址有限制。必须将镜像放置在 DDR 内存的空段中,并且不能损坏内存中已有的任何其他镜像。如果你已经创建了一个 PetaLinux 项目,可以在配置文件中通过带有 CONFIG_SUBSYSTEM_UBOOT_FIT_IMAGE_OFFSET 标记的配置项找到对应的地址

请注意,Linux 内核需要设备树二进制文件和可挂载的根文件系统才能完成启动过程。为了快速演示,我准备了一个 INITRAMFS 镜像,并使用 PetaLinux 工具将内核、根文件系统和设备树二进制文件打包到一个镜像文件中。也可以根据需要选择其他方法。

xsct% targets -set -nocase -filter {name =~ "*A53 #0*"}
xsct% dow -data  "image.ub" 0x10000000
100%   24MB   0.3MB/s  01:37
Successfully downloaded image.ub

下载 Linux 内核需要一些时间,因为它是整个过程中最大的镜像文件。接下来,我们释放 APU,然后通过检查串口通道来观察设备上的情况。

首先,运行 ARM 可信固件。其输出如下所示。

NOTICE:  ATF running on XCZU9EG/silicon v4/RTL5.1 at 0xfffea000
NOTICE:  BL31: v2.4(release):v1.1-7609-g851523ea2
NOTICE:  BL31: Built : 08:27:07, Apr 28 2021

当 ATF 完成将安全监视器调用导出到操作系统后,就会发生 U-Boot 交接。

U-Boot 2021.01 (Jun 01 2021 - 11:54:06 +0000)
Board: Xilinx ZynqMP
DRAM:  4 GiB
PMUFW:  v1.1
EL Level:       EL2
Chip ID:        zu9eg
NAND:  0 MiB
MMC:   mmc@ff160000: 0, mmc@ff170000: 1
In:    serial
Out:   serial
Err:   serial
Bootmode: QSPI_MODE
Reset reason:   DEBUG
Net:
ZYNQ GEM: ff0b0000, mdio bus ff0b0000, phyaddr -1, interface rgmii-id
eth0: ethernet@ff0b0000
Hit any key to stop autoboot:  0
ZynqMP> 

当终端出现 U-Boot 提示符后,可以输入bootm 0x10000000来启动下载的 Linux 内核镜像。由于该镜像完整(包含内核、根文件系统和设备树),它将自动启动。

## Loading kernel from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Trying 'kernel-1' kernel subimage
     Description:  Linux kernel
     Created:      2021-06-04  15:57:16 UTC
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x100000f8
     Data Size:    9356113 Bytes = 8.9 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x00200000
     Entry Point:  0x00200000
     Hash algo:    sha256
     Hash value:   b4f7073afddc350f3c14f3e9ac1bf6ef8604c602951d13bbe58548bd0d415241
   Verifying Hash Integrity ... sha256+ OK
## Loading ramdisk from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Trying 'ramdisk-1' ramdisk subimage
     Description:  petalinux-image-minimal
     Created:      2021-06-04  15:57:16 UTC
     Type:         RAMDisk Image
     Compression:  uncompressed
     Data Start:   0x108fa12c
     Data Size:    16778258 Bytes = 16 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    sha256
     Hash value:   6fcf87930415873cac0aa2232786dace5b65379e68e42b0a6c30f77b870807bc
   Verifying Hash Integrity ... sha256+ OK
## Loading fdt from FIT Image at 10000000 ...
   Using 'conf-system-top.dtb' configuration
   Trying 'fdt-system-top.dtb' fdt subimage
     Description:  Flattened Device Tree blob
     Created:      2021-06-04  15:57:16 UTC
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x108ec55c
     Data Size:    56061 Bytes = 54.7 KiB
     Architecture: AArch64
     Hash algo:    sha256
     Hash value:   9bf95db6c5106f1f1945af67bbb43f2269539e514acadf88c4615f4ae7d6b595
   Verifying Hash Integrity ... sha256+ OK
   Booting using the fdt blob at 0x108ec55c
   Uncompressing Kernel Image
   Loading Ramdisk to 7cd11000, end 7dd11412 ... OK
   Loading Device Tree to 000000007cd00000, end 000000007cd10afc ... OK
Starting kernel ...
[    0.000000] Booting Linux on physical CPU 0x0000000000 [0x410fd034]
[    0.000000] Linux version 5.10.0-xilinx-v2021.1 (oe-user@oe-host) (aarch64-xilinx-linux-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.35.1) 
#1 SMP Fri Jun 4 15:57
:16 UTC 2021
[    0.000000] Machine model: xlnx,zynqmp
...............
<Skipped for readability>
...............
PetaLinux 2021.1 ZynqUS_Linux ttyPS0
root@ZynqUS_Linux:~ > uname -r
5.10.0-xilinx-v2021.1

现在,硬件上已经安装了完整的 Linux 镜像 :)

提示与经验总结

  • 流程顺序不可随意更改 — 每一步都有依赖

  • JTAG 启动非常强大 — 即使没有 SD/USB/网络也能引导系统

  • 要注意 JTAG 链路稳定性 — 线缆长度、频率设置会影响连接稳定性

  • ATF 必须支持 UltraScale+ 安全模式 — 否则内核可能不能正常访问安全级别寄存器