Showing results for 
Show  only  | Search instead for 
Did you mean: 

PetaLinux Image Debug Series: Debugging ARM Trusted Firmware and U-boot in Vitis

Xilinx Employee
Xilinx Employee
6 0 2,358

In this blog entry we will discuss how we can debug the Zynq® UltraScale™ device boot images in Vitis™. These boot images include the ARM Trusted Firmware (ATF) and U-boot.

This Blog is part of a Series discussing how to debug various components in the Petalinux Images. 

You can find the other entries at the links below:


Boot image debug is a vital part of any custom board bring up, and hopefully this blog will allow users to fully debug a custom board  boot image. Even if you are using a development board, this blog will provide a useful insight into how the boot images work on Zynq UltraScale devices.

There are a number of ways to generate the boot images. Users can use PetaLinux/Yocto or build the images manually from the GiT sources.

In this blog entry I will show how to use PetaLinux 2020.1 to create the debug enabled boot images for a Zynq UltraScale device.

PetaLinux Flow:


I have used the ZCU104 board for this demo. However, the steps should be common for all Zynq UltraScale devices.

The u-boot.elf that is delivered in the images/Linux folder does not have the symbol information needed for debug in Vitis. Therefore, we will need to use the u-boot binary that is in the work directory in PetaLinux.

Also, PetaLinux removes its intermediate files in an effort to save disk space, so we will need to disable this feature in the PetaLinux project.

The steps below show how users can obtain the debug enabled ATF and U-boot:

petalinux-create -t project --template zynqMP -n linux_image
cd linux_image


Note: Unfortunately, there is a known issue in the PetaLinux where the debug=1 does not get passed to the makefile here. Users can use the work-around here to add this manually.

Users should also note the TMP directory:


Exit the Config screen and Save.

As I mentioned above, the u-boot executable file delivered by PetaLinux does not have the symbol information needed for debug. Users can prevent PetaLinux from removing intermediate build files by modifying the local.conf file in the build/conf folder.

The build folder is created when any build is created, so let's do a petalinux-build, followed by a  Ctrl + c to stop at the creation of this file. Open the local.conf file and comment out the line below:


Now just build the boot images, and use PetaLinux to create the bootable image (BOOT.BIN)

petalinux-build -c bootloader

Once this has been built, I copied over the u-boot (renamed to u-boot.elf) from the tmp folder into the images/linux folder:


Next, use PetaLinux to create the bootable image (BOOT.BIN)

cd images/linux
petalinux-package --boot --u-boot

As a sanity check, we can also test the executable files to make sure that they contain the symbol info:


Debugging in Vitis:

I find that the easiest way to debug the boot images is to load the boot image onto your SD/QSPI and debug on the running target. 

Launch Vitis, and close the welcome screen.

Create a new Debug Configuration:


Double Click on Single Application Debug:


Set the Debug Type to "Attach to Running Target":


Note: I am also doing a remote connection, so I set this up too.

Select Apply and Debug. This will open the debug perspective.

You should see the Cortex A53 running (our boot image)


Debug Pre Relocation:

Expand the XSCT (Xilinx Software Command-Line Tool) window.

Here, we want to pass the symbol files to the Cortex A53 #0 for both the ATF and the U-Boot.

We set the symbol files by using the memmap command in XSCT:


Then we can add a break-point in the ATF, and the U-Boot.

I set the break-point in the ATF at the bl31_main and a breakpoint in U-boot at board_init_f:


If we power cycle the board, we will see the break-point being hit in the ATF. 


Users can then resume, step into, step over, etc:


Users can step through the code here. For example, there is the setup_reloc function that users can use to find the uboot relocation address (or use bdinfo).

The relocation address in my case (and this will be different for different users) is 0x77DE5000.

Debug Post Relocation:

The uboot code will relocate itself, and because we have the symbol file memory mapped this will be incorrect.

As a result we need to pass the relocated address so that the debugger can compensate for this:


Let's take the board_init_r function.

This is the post relocation function:


The address of board_init_r after relocation will be 0x77DE5000 + 0x801A880 = 0x7FDFF880. 

If I add the breakpoint at board_init_r I see the actual address is as expected:


If we power cycle again, we will hit our break-points in the ATF and now the post relocated U-boot.