This chapter shows how to integrate the software and hardware components generated in the previous steps to create a Zynq® UltraScale+™ boot image. After reading this chapter, you will understand how to integrate and load boot loaders, bare-metal applications (for APU/RPU), and the Linux OS for a Zynq UltraScale+ system in different boot requirements: QSPI, SD card, JTAG, and so on.
The following key points are covered in this chapter:
- System software: FSBL, PMU firmware, U-Boot, Trusted Firmware-A (TF-A)
- Application processing unit (APU): configuring SMP Linux for APU
- Real-time processing unit (RPU): configuring bare-metal for RPU in lockstep
- Creating a boot image for the following boot sequence:
- APU
- RPU lockstep
- Creating and loading a secure boot image
Note
For more information on RPU lockstep, see the Zynq UltraScale+ Device Technical Reference Manual (UG1085).
While previous sections focused only on creating software blocks for each processing unit in the PS, this chapter explains how these blocks can be loaded as a part of a bigger system.
To create a boot image, you can either use the Create Boot Image wizard in the Vitis IDE, or the Bootgen command line tool (the Create Boot Image wizard calls the Bootgen tool as well). The principle function of the Create Boot Image wizard or Bootgen is to integrate the partitions (hardware-bitstream and software) in the proper format. It allows you to specify security options. It can also create cryptographic keys.
Functionally, Bootgen uses a BIF (Bootgen image format) file as an input, and generates a single file image in binary BIN or MCS format. It can be used to program non-volatile memories such as QSPI and SD cards. The Bootgen GUI facilitates the creation of the BIF input file.
This chapter makes use of a processing system block. :doc:`7-design1-using-gpio-timer-interrupts` covers the boot image which will include the PS partitions used in this chapter and a bitstream targeted for the PL fabric.
The following system software blocks cover most of the boot and configuration for this chapter. For detailed boot flow and various boot sequences, refer to the System Boot and Configuration chapter in the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137).
In non-secure boot mode, the platform management unit (PMU) releases the reset of the configuration security unit, and enters the PMU server mode to monitor power. At this stage, the configuration security unit loads the first stage boot loader (FSBL) into on-chip memory (OCM). The FSBL can be run from either APU A53_0, RPU R5_0, or RPU R5_lockstep. In this example, the FSBL is targeted for APU Cortex™-A53 Core 0. The last 512 bytes of this region are used by FSBL to share the hand-off parameters corresponding to the applications handed off by the TF-A.
The first stage boot loader initializes important blocks in the processing subsystem. This includes clearing the reset of the processors and initializing clocks, memory, UART, and so on before handing over the control of the next partition in DDR, to either the RPU or APU. In this example, the FSBL loads a bare-metal application in DDR and hands off to the RPU Cortex-R5F in lockstep mode, and then loads U-Boot to be executed by the APU Cortex-A53 Core-0. For more information, see the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137).
For this chapter, you can use the FSBL executable that you created in :doc:`Building Software for PS
Subsystems <4-build-sw-for-ps-subsystems>`. In the FSBL application, the xfsbl_translation_table.S
differs from the translation_table.S
of the Cortex-A53 in only one aspect, to mark the DDR region as reserved. This is to avoid speculative access to DDR memory controller before it is initialized. When the DDR initialization is completed in FSBL, the memory attributes for the DDR region are changed to “memory” so that they are cacheable.
The platform management unit (PMU) and the configuration security unit manage and perform the multi-staged booting process. The PMU primarily controls the pre-configuration stage that executes the PMU ROM to set up the system. The PMU handles all of the processes related to reset and wake-up. The Vitis IDE provides PMU firmware that can be built to run on the PMU. For more details on the platform management and PMU firmware, see the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137).
The PMU firmware can be loaded in the following ways:
- Using BootROM as described in :ref:`boot-sequence-for-sd-boot`.
- Using FSBL as described in :ref:`boot-sequence-for-qspi-boot-mode`.
- Using JTAG boot mode as described in :ref:`boot-sequence-for-qspi-boot-mode-using-jtag`.
For more information, see the PMU Firmware Xilinx Wiki.
The U-Boot acts as a secondary boot loader. After the FSBL handoff, the U-Boot loads Linux on the Arm® Cortex-A53 APU. After FSBL, the U-Boot configures the rest of the peripherals in the processing system based on board configuration. U-Boot can fetch images from different memory sources such as eMMC, SATA, TFTP, SD, and QSPI. For this example, U-Boot and all other images are loaded from the SD card. Therefore, for this example, the board will be set to SD-boot mode.
U-Boot can be configured and built using the PetaLinux tool flow. For this example, you can use the U-Boot image that you created in :doc:`Building Linux Software for PS Subsystems <./6-build-linux-sw-for-ps>`.
The TF-A is a transparent bare-metal application layer executed in Exception Level 3 (EL3) on the APU. The TF-A includes a Secure Monitor layer for switching between the secure and non-secure world. The Secure Monitor and the implementation of Trusted Board Boot Requirements (TBBR) make the TF-A layer a mandatory requirement to load Linux on an APU on Zynq UltraScale+.
FSBL loads the TF-A to be executed by the APU, which keeps running in EL3 awaiting a service request. The TF-A starts at 0xFFFEA000. FSBL also loads U-Boot in DDR to be executed by the APU, which loads the Linux OS in SMP mode on the APU. It is important to note that the PL bitstream should be loaded before the TF-A is loaded. This is because FSBL uses the OCM region, which is reserved by the TF-A as a temporary buffer for when the bitstream is present in the BIN file. Because of this, if the bitstream is loaded after the TF-A, FSBL overwrites the TF-A image with its temporary buffer, corrupting the TF-A image. The bitstream should therefore be positioned the in BIF before the TF-A and preferably immediately after FSBL and PMU firmware.
The TF-A (bl31.elf
) is built by default in PetaLinux and can be found in the PetaLinux project images directory.
For more details on TF-A, refer to the Arm Trusted Firmware section in the Security chapter of the Zynq UltraScale+ MPSoC: Software Developers Guide UG1137).
You already created the PetaLinux images in :doc:`Building Software for PS Subsystems <./4-build-sw-for-ps-subsystems>`. In this example, the PetaLinux is configured to build images for SD-boot with an initramfs
root file system. This is the default boot setting in PetaLinux.
The images can be found in the $<PetaLinux_Project>/images/linux/
directory. For loading Linux on the APU, the following images are used from PetaLinux:
- TF-A:
bl31.elf
- U-Boot:
u-boot.elf
- Linux images:
image.ub
, which contains:- Kernel image:
Image
- Device tree blob:
system.dtb
- Root file system:
rootfs.cpio.gz.u-boot
- Kernel image:
In addition to Linux on APU, this example also loads a bare-metal application on RPU Cortex-R5F in lockstep mode.
For this example, refer to the testapp_r5 application that you created in :ref:`creating-a-custom-bare-metal-application-for-an-arm-cortex-r5f-based-rpu-in-the-same-system-project`.
Now that all the individual images are ready, create the boot image to load all of these components on the Zynq UltraScale+ device. This can be done using the Create Boot Image wizard in the Vitis IDE by performing the following steps.
Launch the Create Boot Image wizard in the Vitis IDE:
- In the Vitis IDE, select Xilinx → Create Boot Image.
Select all the partitions referred to in earlier sections in this chapter, and set them as shown in the following figure.
Add the FSBL partition:
In the Create Boot Image wizard, click Add to open the Add Partition view.
In the Add Partition view, click Browse to select the FSBL executable.
For FSBL, ensure that the partition type is selected as boot loader and the correct destination CPU is selected by the tool. The tool is configured to make this selection based on the FSBL executable.
Note
Ignore the Exception Level drop down, because FSBL is set to EL3 by default. Also, leave the TrustZone setting unselected for this example.
Click OK to select FSBL and go back to Create Boot Image wizard.
Add the PMU and TF-A firmware partitions:
Click Add to open the Add Partition view, shown in the following figure.
Add the PMU firmware partition.
Browse to and select the PMU Firmware executable.
For this partition, select pmu as the partition type.
Leave the Exception Level and TrustZone settings unselected.
Click OK.
Click Add to open the Add Partition view.
Add the TF-A firmware
bl31.elf
partition.Note
TF-A Firmware (
bl31.elf
) can be found in<PetaLinux Project>/image/linux/
.- For this partition, select datafile as the partition type.
- Set the Destination Device as PS.
- Set the Destination CPU as A53 0.
- Set the Exception Level to EL3 and select Enable TrustZone.
Click OK.
Add the R5 executable and enable it in lockstep mode.
Now, add the U-Boot partition. You can find
u-boot.elf
for sd_boot mode in<PetaLinux_project>/images/linux/sd_boot
.
You can also create BOOT.bin
images using the BIF attributes and the Bootgen command. For this configuration, the BIF file contains the following attributes:
//arch = zynqmp; split = false; format = BIN the_ROM_image: { [bootloader, destination_cpu = a53-0]C:\edt\fsbl_a53\Debug\fsbl_a53.elf [pmufw_image]C:\edt\edt_zcu102_wrapper\export\edt_zcu102_wrapper\sw\edt_zcu102_wrapper\boot\pmufw.elf [destination_cpu = a53-0, exception_level = el-3, trustzone]C:\edt\sd_boot\bl31.elf [destination_cpu = r5-lockstep]C:\edt\testapp_r5\Debug\testapp_r5.elf [destination_cpu = a53-0, exception_level = el-2]C:\edt\sd_boot\u-boot.elf }
The Vitis IDE calls the following Bootgen command to generate the BOOT.bin image for this configuration:
bootgen -image sd_boot.bif -arch zynqmp -o C:\edt\sd_boot\BOOT.bin
Copy the
BOOT.bin
,image.ub
, andboot.scr
to the SD card. Hereboot.scr
is read by U-Boot to load the kernel and the root file system.Load the SD card into the ZCU102 board, in the J100 connector.
Connect a micro USB cable from the ZCU102 board USB UART port (J83) to the USB port on the host machine.
Configure the board to boot in SD-boot mode by setting switch SW6 to 1-ON, 2-OFF, 3- OFF, and 4-OFF, as shown in following figure.
Connect 12V Power to the ZCU102 6-Pin Molex connector.
Start a terminal session, using Tera Term or Minicom depending on the host machine being used, as well as the COM port and baud rate for your system, as shown in following figure.
For port settings, verify the COM port in device manager. There are four USB-UART interfaces exposed by the ZCU102 board.
Select the COM port associated with the interface with the lowest number. In this case, for UART-0, select the COM port with interface-0.
Similarly, for UART-1, select COM port with interface-1. Remember that the R5 BSP has been configured to use UART-1, and so R5 application messages appear on the COM port with the UART-1 terminal.
Turn on the ZCU102 Board using SW1, and wait until Linux loads on the board. At this point, you can see the initial boot sequence messages on your terminal screen representing UART-0.
You can see that the terminal screen configured for UART-1 also prints a message. This is the print message from the R5 bare-metal application running on the RPU, configured to use the UART-1 interface. This application is loaded by the FSBL onto the RPU.
The bare-metal application has been modified to include the UART interrupt example. This application now is now in a waiting for interrupt (WFI) state until user input is detected from the keyboard at the UART-1 terminal.
Meanwhile, the boot sequence continues on the APU and the images loaded can be understood from the messages appearing on the UART-0 terminal. The messages are highlighted in the following figure.
The U-Boot then loads the Linux kernel and other images on the Arm Cortex-A53 APU in SMP mode. The terminal messages indicate when the U-Boot loads the kernel image. When the kernel starts up, a user interface prompt is shown in the target Linux OS. The kernel loading and starting sequence can be seen in the following figure.
The ZCU102 board also comes with dual parallel QSPI flashes adding up to 128 MB in size. In this example, you will create a boot image and load the images on the Zynq UltraScale+ device in QSPI boot mode. The images can be configured using the Create Boot Image wizard in the Vitis IDE. This can be done by performing the following steps.
The earlier example highlighted creation of the Linux Images and Boot images to boot from an SD card. This section explains the configuration of PetaLinux to generate Linux images for QSPI flash. For more information about the dependencies for PetaLinux, see the PetaLinux Tools Documentation: Reference Guide (UG1144).
Before starting this example, create a backup of the boot images created for SD card setup using the following commands:
$ cd <Petalinux-project-path>/xilinx-zcu102-2022.2/images/linux/ $ mkdir sd_boot $ cp image.ub sd_boot/ $ cp u-boot.elf sd_boot/ $ cp BOOT.BIN sd_boot/
Change the directory to the PetaLinux project root directory:
$ cd <Petalinux-project-path>/xilinx-zcu102-2022.2
Launch the top-level system configuration menu:
$ petalinux-config
The Configuration wizard opens.
Select Subsystem AUTO Hardware Settings.
Under the advanced bootable images storage settings, do the following:
- Select boot image settings.
- Select image storage media.
- Select primary flash as the boot device.
Under the advanced bootable images storage settings submenu, do the following:
- Select kernel image settings.
- Select image storage media.
- Select primary flash as the storage device.
One level above (under Subsystem AUTO Hardware Settings) do the following:
Select Flash Settings and notice the entries listed in the partition table.
Note
Some memory (0x1E00000 + 0x40000) is set aside for initial boot partitions and U-Boot settings. These values can be modified on need basis.
Based on this, the offset for Linux images is calculated as 0x1E40000 in the QSPI Flash device. This will be used while creating the boot image for QSPI Boot-mode.
The following steps set the Linux system memory size to about 1.79 GB.
Under Subsystem AUTO Hardware Settings, do the following
- Select Memory Settings.
- Set System Memory Size to
0x6FFFFFFF
.
Save the configuration settings and exit the Configuration wizard.
Rebuild using the
petalinux-build
command.Take a backup of u-boot.elf and the other images. These will be used when creating boot images.
Note
For more information, refer to the PetaLinux Tools Documentation: Reference Guide (UG1144).
If the Vitis IDE is not already running, start it and set the workspace as indicated in :doc:`Build Software for PS Subsystems <4-build-sw-for-ps-subsystems>`.
Select Xilinx → Create Boot Image.
Select Zynq MP as the Architecture.
Select the Create new BIF file option.
Ensure that the Output format is set to BIN.
In the Basic page, browse to and select the Output BIF file path and output path.
Next, add boot partitions using the following steps:
Click Add to open the Add Partition view.
In the Add Partition view, click the Browse button to select the FSBL executable.
For FSBL, ensure that the Partition type is selected as boot loader and the correct destination CPU is selected by the tool. The tool is configured to make this selection based on the FSBL executable.
Ignore the Exception Level, as FSBL is set to EL3 by default. Also, leave the TrustZone setting unselected for this example.
Click OK to select the FSBL and go back to the Create Boot Image wizard.
Click Add to open the Add Partition window to add the next partition.
The next partition is the PMU firmware for the Platform Management Unit.
The next partition to be added is the TF-A firmware. For this, set the Partition type to datafile.
Click Add to add the R5 bare-metal executable.
Click Add to add the U-Boot partition. u-boot.elf can be found in
<PetaLinux_Project>/images/linux/
.Click Add to add the image.ub Linux image file.
- The image.ub image file can be found in PetaLinux project in the
images/Linux
directory. - For image.ub, make the following selections:
- Set Partition Type to datafile.
- Set the Destination Device to PS.
- Set the Destination CPU to A53 0.
- Enter
0xF00000
as the offset. - Leave Exception Level and TrustZone unselected.
- The image.ub image file can be found in PetaLinux project in the
Click Add to add the
boot.scr
script file.The
boot.scr
file is located in theimages/linux
directory of the PetaLinux project.For
boot.scr
, select the following:- Set the partition type to datafile.
- Set the Destination Device to PS.
- Set the Destination CPU to A53 0.
Enter 0x3e80000 as the offset.
Leave Exception Level and TrustZone unselected.
Click OK to go back to the Create Boot Image wizard.
Click Create Image to create the
qspi_BOOT.bin
image.You can also create qspi_BOOT.bin images using the BIF attributes and the Bootgen command. You can view the BIF attributes for this configuration by clicking Preview BIF Changes. For this configuration, the BIF file contains the following attributes:
//arch = zynqmp; split = false; format = BIN the_ROM_image: { [bootloader, destination_cpu = a53-0]C:\edt\fsbl_a53\Debug\fsbl_a53.elf [destination_cpu = pmu]C:\edt\edt_zcu102_wrapper\export\edt_zcu102_wrapper\sw\edt_zcu102_wrapper\boot\pmufw.elf [destination_cpu = a53-0, exception_level = el-3, trustzone]C:\edt\qspi_boot\bl31.elf [destination_cpu = r5-lockstep]C:\edt\testapp_r5\Debug\testapp_r5.elf [destination_cpu = a53-0, exception_level = el-2]C:\edt\qspi_boot\u-boot.elf [offset = 0xF00000, destination_cpu = a53-0]C:\edt\qspi_boot\image.ub [offset = 0x3e80000, destination_cpu = a53-0]C:\edt\qspi_boot\boot.scr }
The Vitis IDE calls the following Bootgen command to generate the qspi_BOOT.bin image for this configuration.
bootgen -image qspi_boot.bif -arch zynqmp -o C:\edt\qspi_BOOT.bin``
Note
In this boot sequence, the First Stage Boot Loader (FSBL) loads PMU firmware. This is because the PMU firmware was added as a datafile partition type. Ideally, the boot ROM code can load the PMU firmware for PMU as seen in the earlier section. For more details on PMU firmware, refer to the “Platform Management” chapter in the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137).
To test the image in this example, load the boot image (qspi_BOOT.bin
) onto QSPI on the ZCU102 board using the program flash utility in the Vitis IDE. Alternatively, you can use the XSDB debugger.
In the Vitis IDE, select Xilinx → Program Flash.
In the Program Flash wizard, browse to and select the
qspi_BOOT.bin
image file that was created as a part of this example.Select qspi-x8-dual_parallel as the Flash type.
Set the Offset as 0 and select the FSBL ELF file (fsbl_a53.elf)
Ensure that a USB cable is connected between the USB-JTAG connector on ZCU102 target and the USB port on the host machine using the following steps.
Click Program to start the process of programming the QSPI flash with the
qspi_BOOT.bin
.Wait until you see the message “Flash Operation Successful” in the console, as shown in the following image.
Connect the USB-UART on the board to the host machine. Connect the micro USB cable to micro USB port J83 on the ZCU102 board, and connect the other end to an open USB port on the host machine.
Configure the board to boot in QSPI boot mode by switching SW6 as shown in the following figure.
Connect 12V power to the ZCU102 6-Pin Molex connector.
Start a terminal session, using Tera Term or Minicom depending on the host machine being used, and the COM port and baud rate as shown in the following figure.
For port settings, verify the COM port in the device manager. There are four USB UART interfaces exposed by the ZCU102.
Select the COM port associated with the interface with the lowest number. In this case, for UART-0, select the COM port with interface-0.
Similarly, for UART-1, select COM port with interface-1.
Remember, R5 BSP has been configured to use UART-1, so R5 application messages will appear on the COM port with the UART-1 terminal.
Turn on the ZCU102 board using SW1.
At this point, you will see initial boot sequence messages on your terminal screen representing UART-0.
You can see that the terminal screen configured for UART-1 also prints a message. This is the print message from the R5 bare-metal application running on the RPU, configured to use the UART-1 interface. This application is loaded by the FSBL onto the RPU.
The bare-metal application has been modified to include the UART example. This application now waits in a WFI state until user input is detected from the keyboard at the UART-1 terminal.
Meanwhile, the boot sequence continues on the APU and the images loaded can be understood from the messages appearing on the UART-0 terminal. The messages are highlighted in the following figure.
The U-Boot then loads the Linux kernel and other images on the Arm Cortex-A53 APU in SMP mode. The terminal messages indicate when the U-Boot loads the kernel image. When the kernel starts up, a user interface prompt is shown in the Linux kernel. The kernel loading and starting sequence can be seen in the following figure.
The Zynq UltraScale+ MPSoC supports many methods of loading the boot image. One method is to use the JTAG interface. This example XSCT
session demonstrates how to download a boot image file (qspi_BOOT.bin
) in QSPI using the XSDB debugger. After the QSPI is loaded, the qspi_BOOT.bin
image executes in the same way as QSPI boot mode in Zynq UltraScale+ MPSoC. You can use the same XSCT session or the System Debugger for debugging similar boot flows.
The following sections demonstrate the basic steps involved in this boot mode.
Connect a USB cable between the USB-JTAG J2 connector on the target and the USB port on the host machine.
Set the board to JTAG boot mode by setting the SW6 switch, as shown in the following figure.
Power on the board using switch SW1. Open the XSCT console in the Vitis IDE by clicking the XSCT button. Alternatively, you can also open the XSCT console by selecting Xilinx → XSCT Console.
In the XSCT console, connect to the target over JTAG using the
connect
command:xsct% connect
The
connect
command returns the channel ID of the connection.The
targets
command lists the available targets and allows you to select a target using its ID. The targets are assigned IDs as they are discovered on the JTAG chain, so the IDs can change from session to session.Note
For non-interactive usage such as scripting, you can use the
-filter
option to select a target instead of selecting the target using its ID.xsct% targets
The targets are listed as shown in the following figure.
Download the U-Boot application on Cortex-A53 #0 using the following commands.
By default, JTAG security gates are enabled. Disable the security gates for DAP, PL TAP, and PMU (this makes the PMU MB target visible to the debugger).
xsct% targets -set -filter {name =~ "PSU"} xsct% mwr 0xffca0038 0x1ff xsct% targets
Verify if the PMU MB target is listed under the PMU device. Now, load and run the PMU firmware.
Reset APU Cortex-A53 Core 0 to load and run FSBL.
xsct% targets -set -filter {name =~ "Cortex-A53 #0"} xsct% rst -processor
Note
rst -processor
clears the reset on an individual processor core.This step is important, because when the Zynq UltraScale+ MPSoC boots up in JTAG boot mode, all the APU and RPU cores are held in reset. You must clear the resets on each core before performing debugging on these cores. You can use the
rst
command in XSCT to clear the resets.Note
The
rst -cores
command clears the resets on all the processor cores in the group (that is, the APU or RPU) of which the current target is a child. For example, when A53 #0 is the current target,rst -cores
clears resets on all the Cortex-A53 cores in the APU.Load and run FSBL.
xsct% dow {C:\edt\fsbl_a53\Debug\fsbl_a53.elf} xsct% con
Verify the FSBL messages on the Serial Terminal and stop FSBL after a couple of seconds.
xsct% stop
Load and run the TF-A.
xsct% dow {C:\edt\qspi_boot\bl31.elf} xsct% con xsct% stop
Configure a Serial Terminal (Tera Term, Minicom, or the Serial Terminal interface for a UART-0 USB-serial connection).
For Serial Terminal settings, see the following figure.
Load and run U-Boot.
xsct% dow {C:\edt\qspi_boot\u-boot.elf}
Run U-Boot, using the
con
command in XSDB.xsct% con
In the target Serial Terminal, press any key to stop the U-Boot auto-boot.
Stop the core using the
stop
command in XSDB.xsct% stop
Download the
boot.bin
binary into DDR on ZCU102. Use the sameboot.bin
created for QSPI boot mode.xsct% dow -data {C:\edt\qspi_boot\qspi_BOOT.bin} 0x2000000
Continue the U-Boot again, using the
con
command in XSDB.xsct% con
Execute the following commands in the U-Boot console on the target terminal. These commands erase QSPI and then write the
boot.bin
image from DDR to QSPI.ZynqMP> sf probe 0 0 0 ZynqMP> sf erase 0 0x4000000 ZynqMP> sf write 0x2000000 0 0x4000000
After successfully writing the image to QSPI, turn off the board and set up the ZCU102 board as described in :ref:`setting-up-the-zcu102-board`. You can see Linux loading on the UART-0 terminal and the R5F application executing in the UART-1 terminal.
Zynq UltraScale+ MPSoC also supports USB slave boot mode using the device firmware upgrade (DFU) for the device class specification of USB. Using a standard update utility such as OpenMoko's DFU-Util, you will be able to load the newly created image on the Zynq UltraScale+ MPSoC using the USB port. The following steps list the required configuration steps to load boot images using this boot mode. The DFU utility is also shipped with the Vitis unified software platform and PetaLinux.
A few changes are required in FSBL to enable USB boot mode. USB boot mode support increases the footprint of FSBL by approximately 10 KB. Because it is mostly intended to be used during the initial development phase, its support is disabled by default to conserve OCM space. In this section, you will modify the FSBL to enable USB boot mode. Considering the FSBL project is used extensively throughout this tutorial, do not modify the existing FSBL project. Instead, this section makes use of a new FSBL project.
In the Vitis IDE, select File → New → Application Project to open the New Project wizard.
Use the information in the table below to make your selections in the wizard.
Screen
System Properties
Settings
Platform
Select platform from repository
edt_zcu102_wrapper
Application project details
Application project name
fsbl_usb_boot
System project name
fsbl_usb_boot_system
Target processor
psu_cortexa53_0
Domain
Domain
standalone on psu_cortexa53_0
Templates
Available templates
Zynq MP FSBL
Click Finish.
In the Explorer view, expand the fsbl_usb_boot project and open xfsbl_config.h from fsbl_usb_boot→ src→xfsbl_config.h.
In
xfsbl_config.h
change or set following settings:#define FSBL_QSPI_EXCLUDE_VAL (1U) #define FSBL_SD_EXCLUDE_VAL (1U) #define FSBL_USB_EXCLUDE_VAL (0U)
Press Ctrl+S to save these changes.
Build FSBL (
fsbl_usb_boot
).
In this section, you will create the boot images to be loaded through a USB using the DFU utility. Device firmware upgrade (DFU) is intended to download and upload firmware to/from devices connected over USB. In this boot mode, the boot loader (FSBL) and the PMU firmware which are loaded by bootROM are copied to Zynq UltraScale+ on-chip memory (OCM) from the host machine USB port using the DFU utility. The size of the OCM (256 KB) limits the size of the boot image downloaded by bootROM in USB boot mode. Considering this, and subject to the size requirement being met, only FSBL and PMU firmware are stitched into the first boot.bin
, which is copied to the OCM. The remaining boot partitions will be stitched in another boot image and copied to DDR to be loaded by the FSBL which is already loaded and running at this stage. Follow these steps to create boot images for this boot mode.
In the Vitis IDE, select Xilinx → Create Boot Image.
Select
fsbl_usb_boot.elf
andpmufw.elf
partitions and set them as shown in the following figure.Ensure that the PMU partition is set to be loaded by bootROM.
Click Create Image to generate
BOOT.bin
.
Modify PetaLinux U-Boot so that it can load the image.ub
image. The device tree needs to be modified to set the USB in peripheral mode. The default PetaLinux configuration is set for the USB in host mode. Follow these steps to modify system-user.dtsi
in the PetaLinux project:
<PetaLinux-project>/project-spec/meta-user/recipes-bsp/device-tree/files/system-user.dtsi
Add the following to the
system-user.dtsi
file so that it looks like this:/include/ "system-conf.dtsi" / { gpio-keys { sw19 { status = "disabled"; }; }; }; &uart1 { status = "disabled"; }; &dwc3_0 { dr_mode = "peripheral"; maximum-speed = "super-speed"; };
The modified
system-user.dtsi
file can be found in ref_files/usb_boot released with this tutorial.Build PetaLinux with the following changes:
$ petalinux-build
The following steps describe how to create a usb_boot.bin
comprising rest of the partitions.
Note
Copy the newly generated U-Boot to C:\edt\usb_boot\
.
In the Vitis IDE, select Xilinx → Create Boot Image.
Select FSBL and rest of the partitions and set them as shown in the following figure. You can also choose to import the BIF file from the SD boot sequence.
Note
Ensure that you have set the correct exception levels for the TF-A (EL-3, TrustZone) and U-Boot (EL-2) partitions. These settings can be ignored for other partitions.
The PMU firmware partition is not required in this image because it will be loaded by the bootROM before this image (
usb_boot.bin
) is loaded.Click on Create Image to generate
usb_boot.bin
.Note
In addition to
BOOT.bin
andusb_boot.bin
, a Linux image such asimage.ub
is required to boot Linux. Thisimage.ub
is loaded by the DFU utility separately.
In this section you will load the boot images on the ZCU102 target using the DFU utility. Before you start, set the board connections as shown below:
Set ZCU102 for USB boot mode by setting SW6 (1-OFF, 2-OFF, 3-OFF, and 4-ON), as shown below:
Connect a USB 3.0 cable to a J96 USB 3 ULPI connector. Connect other end of the cable to a USB port on the host machine.
Connect a USB micro cable between the USB-UART port on the board (J83) and the host machine.
Start a terminal session, using Tera Term or Minicom depending on the host machine being used, as well as the COM port and baud rate for your system.
Power on the board.
The following steps load the boot images via USB using the DFU utility, which can be found at Vitis\2022.2\tps\lnx64\dfu-util-0.9
.
Alternatively, you can install the DFU utility on Linux using the Package Manager supported by Linux Distribution.
Check if the DFU can detect the USB target.
$ sudo dfu-util -l
The USB device should be enumerated with the vendor and product ID (
03fd:0050
). You should see something like the following message:Found DFU: [03fd:0050] ver=0100, devnum=30, cfg=1, intf=0, alt=0, name="Xilinx DFU Downloader", serial="2A49876D9CC1AA4"
Note
If you do not see the “Found DFU” message, verify the connection and retry.
Download the BOOT.bin that was created in :ref:`creating-boot-images-for-usb-boot`.
$ sudo dfu-util -d 03fd:0050 -D <USB_Boot_Image_Path>/Boot.bin
Verify from the Serial Terminal if FSBL has loaded successfully.
Download the
usb_boot.bin
. Before this, start another terminal session for the UART-1 serial console.$ sudo dfu-util -d 03fd:0050 -D <USB_Boot_Image_Path>/usb_boot.bin
Check the UART 0 terminal and wait until U-Boot loads.
On the U-Boot prompt, press Enter to terminate autoboot. Verify from the UART1 console that the R5 application has also loaded successfully.
Run the following commands to set up the DFU environment in the U-Boot command line:
$ setenv loadaddr 0x10000000 $ setenv kernel_addr 0x10000000 $ setenv kernel_size 0x1e00000 $ setenv dfu_ram_info "setenv dfu_alt_info image.ub ram $kernel_addr $kernel_size"
In the U-Boot console, start DFU_RAM to enable downloading Linux images:
U-boot\ run dfu_ram
Download the Linux image (
image.ub
) using the following command from the host machine terminal:$ sudo dfu-util -d 03fd:0300 -D <PetaLinux_project>/images/linux/image.ub -a 0
Execute Ctrl+C on the U-Boot console to stop dfu_ram.
Run the
bootm
command from the U-Boot console.U-boot\ bootm
Verify that Linux loads successfully on the target.
Note
In this example,
image.ub
is copied to the DDR location based on the#define DFU_ALT_INFO_RAM
settings in U-Boot configuration. These settings can be modified to copy other image files to the DDR location. Then, if required, these images can be copied to QSPI using U-Boot commands listed in :ref:`boot-sequence-for-qspi-boot-mode-using-jtag`.
In the Vitis IDE, select Xilinx → Launch Shell.
In the shell, verify if the DFU can detect the USB target:
dfu-util.exe -l
Note
dfu-util.exe
can be found in<Vitis installation path>\tps\Win64\dfu-util-0.9\dfu-util.exe
.The USB device should be enumerated with the vendor and product ID (
03fd:0050
).Note
If you do not see the message starting with “Found DFU…”, download and install the Zadig software. Open the software and click Options and select List all devices. Select device Xilinx Dfu Downloader and click Install driver.
Download the boot.bin that was created in :ref:`creating-boot-images-for-usb-boot`.
$ dfu-util.exe -d 03fd:0050 -D BOOT.bin
Verify from the Serial Terminal (UART 0) that FSBL is loaded successfully.
Download the
usb_boot.bin
. Before this, start another terminal session for the UART-1 serial console.$ dfu-util.exe -d 03fd:0050 -D usb_boot.bin``
On the U-Boot prompt, press Enter to terminate auto-boot. Verify from the UART1 console that the R5 application has also loaded successfully.
Note
At this point, use the Zadig utility to install drivers for the “USB download gadget” with device ID 03fd:0300. Without this, the Zadig software does not show “Xilinx DFU Downloader” after booting U-Boot on the target.
Run the following commands to set up the DFU environment in the U-Boot command line:
$ setenv loadaddr 0x10000000 $ setenv kernel_addr 0x10000000 $ setenv kernel_size 0x1e00000 $ setenv dfu_ram_info "setenv dfu_alt_info image.ub ram $kernel_addr $kernel_size"
In the U-Boot console, start DFU_RAM to enable downloading Linux images:
U-boot\ run dfu_ram
Download the Linux image
image.ub
using the following command from the host machine terminal:$ dfu-util.exe -d 03fd:0300 -D image.ub -a 0
Run the
bootm
command from the U-Boot console.U-boot\ bootm
Verify that Linux loads successfully on the target.