Booting with U-Boot SPL on ZynqMP, a step forward

A long-standing issue in the ZynqMP users community has been the loading of a PMU firmware configuration object when U-Boot SPL is used. A recent patch to U-Boot addresses the problem at its root.

The “configuration object”

The Platform Management Unit (PMU) needs a configuration object to know how to operate the SoC: which power domains to enable, which peripherals should be accessible by each CPU core, etc.

A configuration object is produced by the Xilinx tools in the form of a C file (pm_cfg_obj.c), which contains values to be passed at runtime to the PMU firmware. It is design-specific, so it has to be regenerated when the design is modified.

The Xilinx workflow: FSBL

When using the workflow supported by Xilinx, the Xilinx FSBL (First Stage Bootloader) has a role similar to the U-Boot SPL: initializing DDR an other low-level setups, then loading ATF and U-Boot proper. FSBL is generated with a built-in configuration object, and passes it to the PMUFW at runtime before jumping to ATF and U-Boot proper.

Xilinx workflow booting: the PMUFW configuration object is loaded by FSBL at runtime

The Community workflow: U-Boot SPL

Many users prefer using U-Boot SPL over the Xilinx FSBL. So far these users had to face a problem: there is no code in U-Boot to load the configuration object in the PMU firmware.

Community workflow booting, so far: the configuration object is hard-coded in the PMUFW

The best workaround for U-Boot SPL users is to apply a patch to the PMUFW itself to have the configuration object built-in and self-load it. This approach works but has drawbacks: among others, it forces to use a different PMUFW binary for each hardware and hardware configuration. It also makes it impossible to change the configuration after boot.

More troubles with meta-xilinx

The mentioned patch has never been included in the meta-xilinx Yocto layer. Many newcomers of ZynqMP have downloaded meta-xilinx, followed its instructions and come up with a non-booting board. They have had a hard time in discovering they need to patch the pmu-firmware in their own layer to be able to boot.

The problem got worse with the Yocto 2.6 (Thud) version of meta-xilinx. In previous versions there was a hack to build a (Microblaze) PMU firmware within an ARM64 build. That hack has been removed from meta-xilinx Thud and replaced with a multiconfig-based setup. Now there are two different configurations: a Microblaze one to build the PMU firmware and an ARM64 one to build all the rest.

This has been a good cleanup, but with an unwanted side-effect: now it is impossible to build two different PMU firmware binaries for two different MACHINEs.

Solving the problem at its root

These increasing difficulties triggered me to try and solve the problem at its very root: the inability of U-Boot SPL to load the configuration object into the PMU firmware at runtime, like the FSBL does.

And it turned out not to be that complex in the end. The communication between the ARM core where SPL runs and the PMU happens via a mailbox. I studied the protocol mostly in the FSBL and ARM Trusted Firmware source code and came up with a simple implementation that is enough for the SPL needs. SPL then uses the mailbox in board_init() to send the configuration object to the PMU firmware.

New Community workflow booting: the PMUFW configuration object is loaded by SPL at runtime

With these changes U-Boot SPL now behaves like FSBL. No need to patch PMU firmware anymore!

With this feature in U-Boot SPL there is no more need for a different PMU firmware binary for each different board configuration. A single PMU firmware binary image can be used to boot any ZynqMP board. Only U-Boot SPL will need to be rebuilt to use a different configuration object. Patching the PMU firmware to hard-code its configuration will not be needed anymore.


I sent a patch with this new feature to the U-Boot mailing list. It took a few iterations to have it in a good shape, and finally the maintainer Michal Simek accepted it at its fifth iterations a few days ago. It should be merged in mainline U-Boot version 2019.10.

Using this new booting process is simple: just set the ZYNQMP_SPL_PM_CFG_OBJ_FILE configuration variable to the location of your configuration object. It will be automatically linked in U-Boot SPL and loaded during board initialization. Leaving the variable empty will leave the old behavior, which can still be used as before.

However note that the configuration object file must be in binary format. The C file produced by the Xilinx tools is not directly usable by U-Boot SPL. In order to convert the file to the proper format I also wrote a tool that automates the process. A patch adding this tool to U-Boot has been accepted together with the first one.

Together these two patches will allow a better booting process for ZynqMP users wanting to use U-Boot SPL, automating the whole building process in their buildsystem from mainline U-Boot and their pm_cfg_obj.c file to bootable images.

6 thoughts on “Booting with U-Boot SPL on ZynqMP, a step forward”

  1. Hi Luca,

    Thank you for the in depth analysis and patch for U-boot! Been trying to figure something like this out for a while but I’m glad you’ve fixed the root issue. I’ve been struggling with Xilinx’s tools lately and it’s funny how the FOSS community is more helpful than Xilinx ever could/would be

    Quick question; do you still recommend using Xilinxs official U-boot fork? It looks like they’ve also merged your changes into it but I’d prefer to use the main project.

    • Hi Andrew,

      thanks for your appreciation.

      For a new project using the community workflow I would try mainline U-Boot first. It probably still lacks some drivers and features, but if it has support for the devices you need for booting, than it should be enough. If it only lacks one or two simple ones you can try to port them from the Xilinx fork. Only if that turns out to be too hard I’d switch to Xilinx U-Boot.

      Also I’d use the latest master branch from mainline U-Boot, to catch even the most recent improvements.

      Asking on the U-Boot mailing list would also be a good idea. Mention the devices you need along with any non-obvious needs you have. People there knows if your needs are already covered or not.


  2. So I’ve been trying to understand how to build spl, u-boot and the config object. I feel like I should use the zynqmp-pmufw-builder without doing the patch step. It is also worth trying to boot the embeddsw repo has to something newer than 2018.3/ Does this sound like the write thing to do?

    • Hi Philip,

      you got it, the patch step is not needed anymore as you can have the config object loaded by U-Boot SPL.

      Unfortunately I haven’t been working on this project recently so it got a bit outdated. Should it not work on modern embeddedsw versions I’d be glad to receive patches to get it up-to-date.

      And yes, unless there are better tools around nowadays, I’d preferably go for the u-boot + SPL + PMUFW boot scheme.

  3. Hi Luca

    Since your patch is already on u-boot, I understand that the example board that you committed to buildroot, zynqmp_zcu106, could be upgraded so as not to use the prebuilt PMUFW image on your github but instead use only u-boot? I don’t think I’ve completely understand all about the ZynqMP booting system :/


    • Hi Alvaro,

      first: don’t worry if you still don’t understand completely the ZynqMP booting system, it’s very complex.

      Regarding your question: with current mainline U-Boot you still need a PMUFW binary. The patch that I sent allows to use a PMUFW without a configuration object hard-coded and have the configuration object loaded into PMUFW by U-Boot SPL. In other words you could use one of the generic pmufw images (pmufw-v2018.3.bin) instead of one of the board-specific ones (pmufw-zcu106-default-v2017.4.bin) from my zynqmp-pmufw-binaries repo.

      Actually the Buildroot defconfig could be upgraded to do that.



Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

By continuing to use the site, you agree to the use of cookies. more information

The cookie settings on this website are set to "allow cookies" to give you the best browsing experience possible. If you continue to use this website without changing your cookie settings or you click "Accept" below then you are consenting to this.