One of the beautiful things about FPGAs and heterogeneous SoC like the Zynq is that we can reprogram them in the field, often remotely.
This is great when we want to update algorithms, increase performance or fix a bug; however, what happens if in a remote update goes wrong?
The last thing we want to do is brick the system, if an update goes wrong. This is where MultiBoot comes into play. In the simplest manner, MultiBoot enables us to have multiple boot images in the configuration memory.
When using a Zynq, there are three MultiBoot options:
Golden Image Search — If no boot header is found at the bottom of flash memory, the BootROM will search for a valid boot header at 32KB offsets.
BootROM MultiBoot — Works under control of the FSBL. This allows the FSBL to load an application and then a follow on application. This is useful if you wish to run a self test application before executing the main application.
Fallback MultiBoot — If an error occurs during loading of the application, the FSBL does a fallback and enables the BootROM to load the next good image.
In this blog, it is fallback MultiBoot and its implementation that we are going to be examining.
This lets us update the initial application, but should it fail, the golden image will be loaded — exactly what we want to happen if the update goes wrong.
In this post, we are going to target a MicroZed board.
The first thing we need to do is to create two complete applications. One application will be the one which can be updated and over written, and the other is the golden image.
To keep it simple, both applications will report ‘hello world’ and image type, e.g. if they are golden or updatable images.
Both projects will be based off the same hardware design — in this case, a simple Zynq Processing system with nothing in the PL.
Each application will consist of:
Golden / Updatable Image Application
Golden / Updatable Image Application Board Support Package (BSP)
Golden / Updatable Image First Stage Boot Loader
Golden / Updatable Image First Stage Boot Loader BSP
To provide visibility about what is happening in the boot process, we can set the FSBL_DEBUG_INFO symbol on the updatable image FSBL.
We can then use these files to produce two bin files, one golden and one updatable.
To flash these bin files into the QSPI, we will use Vivado’s hardware manager.
The first thing we need to do is to add in a configuration memory. For the MicroZed board, select s25fl128s-3.3v-qspi-x4-single.
For the initial updatable image that is written at offset 0 in the memory, we should erase the entire device and then load in the updatable boot.bin file.
For loading in the golden image, we use the following settings. This will write in the golden image to the desired fallback location (0x80_0000).
Power cycling the MicroZed will cause the board to boot, and as there are no errors in the updatable image, you will see the first image loading.
Of course, while this works we want to ensure the golden image will be used if an error occurs. Therefore, we need to spoof a failure in the updatable image.
To spoof a failure in the update image, we are going to make a modification to the updatable FSBL. Within main() in main.c, we are going to comment out the FSBL hand off and implement a fallback.
Instead of handing off to the application, it will simulate a failure of the loading process and ensure a fallback to the golden image.
Once this has been completed, we need to rebuild the boot.bin image and update the QSPI flash.
When power cycled, observing the output in a terminal will show very clearly the fallback occurring.
Which culminates in the loading of the golden image FSBL and application.
This is the pattern we follow when we are working with a Zynq device.
If we have a pure FPGA-based solution, we can still use a fallback solution. I will cover this in a future blog.
Consider the reset type — SW2 RST on the MicroZed will perform a soft reset not power on reset so the handoff address will be already set for the fallback golden image.
When planning the location of the BIN files in the QSPI, ensure you space them sufficiently to prevent one image accidentally corrupting the other.
When planning the QSPI memory layout, leave sufficient space between the images to allow for application growth.
Ensure the fallback image is located on a 32KB address boundary.