HDROB > Software > Zynq booting

Boot process overview

Only CPU0 is used by the boot loaders and the “bare metal” user application. The Linux kernel initializes CPU1 and provides SMP support.

Without operating system

Power-on: Boot ROM -> First stage boot loader (FSBL) -> User application: System running

With operating system

Power-on: Boot ROM -> First stage boot loader (FSBL) -> Second stage boot loader (SSBL) -> Linux kernel: System running

Boot ROM

Fixed in the Zynq Silicon. Can read succeeding boot code from QSPI, NAND or SD card if they are of compatible type and attached to a fixed set of I/O pins.

First stage boot loader (FSBL): Xilinx proprietary

The FSBL is automatically created by Petalinux. It runs entirely on the SoC (e. g, using on-chip memory instead of DDR RAM). It is adapted to the Petalinux project settings (Console, boot devices, …) and to the hardware itself (by importing the hardware handoff file). The main task of the FSBL is to configure the FPGA from an included bitfile and start the processor and necessary peripherals, like the DDR RAM controller. Then, the user application (if running “bare metal” without operating system) or the next boot loader is loaded into RAM and executed.

Second stage boot loader (SSBL): Das U-Boot – the Universal Boot Loader

The SSBL contains far more features and allows to communicate with complex hardware (like Ethernet) and software (like TCP/IP) systems.
U-Boot is a widespread module on embedded systems. Apart from loading the Linux kernel from different sources to main memory and initiating its execution, it also allows to write firmware files from various sources to persistent destinations (SD-Card, NAND/NOR/QSPI flash, …).
U-Boot provides an interactive shell and persistent storage for environment variables.

Boot sources

To select between the different boot sources, set the boot mode DIP switches. As the switches pull down, the polarity is inverted compared to the Enclustra reference manual.

The switch positions are sampled at boot time only. Changing them without reset has no effect.

Source DIP1 DIP2

Booting via JTAG is possible even if the switches are set to other modes, although setting them them to JTAG prevents from using other boot medias.


Slowest boot mechanism as all data is transferred through the JTAG chain (use red/black Xilinx JTAG<->USB adapters), but necessary for blank (new, erased) devices. Typically, data is stored in RAM only, although JTAG can be used to write to flash devices.

As JTAG booting is slow, transferring the whole fileset is not recommended. For new devices, transfer bitfile, FSBL and SSBL, then use the U-Boot shell to load the files again via TFTP (Ethernet) and write everything to flash.

petalinux-package --prebuilt --clean
petalinux-boot --jtag --prebuilt 2 --fpga --bitstream /path/to/your/hdrob-petalinux-hw/hdrob-petalinux-hw.runs/impl_1/top.bit

The following command should boot without assembling the prebuilt files first, but does not work with Petalinux 2014.4/Vivado 2014.4.

petalinux-boot --jtag --fpga --bitstream /path/to/your/hdrob-petalinux-hw/hdrob-petalinux-hw.runs/impl_1/top.bit --u-boot --kernel

Attention: Although JTAG booting is always possible even if the boot source switch is set different, QSPI detection may fail with the following message if not set to JTAG mode:

SF: Unsupported flash IDs: manuf ff, jedec ffff, ext_jedec ffff
*** Warning - spi_flash_probe() failed, using default environment



The small NOR flash is attached via four parallel SPI lanes, hence the name Q(uad)SPI. It can be used to store the boot images, but as erase and write speed is low compared to NAND flash and the number of write cycles is limited, it should not be used as the main general purpose storage. NOR flash does not require error detection and correction mechanisms in the software layer, which makes it ideal for raw binary storage avoiding the complexity of file system layers.

The physical storage space is split in erase blocks, which dictate the smallest write sitze: If only one bit is changed, the whole erase block must be read out to a temporary storage, modified there, erased in flash and then the flash rewritten from temporary storage.

The logic flash space is split in parts, sometimes called “partitions”. The name of “partition” is misleading as there is no partition table written to the device, the boundaries are pure virtual addresses which are passed to the kernel as a boot command line argument. U-Boot as well as the Linux kernel enforce that these parts are aligned to the erase block size.

On the ZX-5 module, the QSPI flash holds 512 Mbit = 64 MBytes with an erase block size of 256 kByte.

Flash “partitions”

  • boot FSBL, SSBL (U-Boot) and FPGA bitfile

    • File: BOOT.BIN
    • Start addess: 0x0
    • Size: 0x500000 = 20 blocks = 5 MB
  • bootenv Stored environment of U-Boot

    • Start address: 0x500000
    • Size: 0x40000 = 1 block = 256 kB
  • kernel Linux kernel

    • File: image.ub
    • Start address: 0x540000
    • Size: 0xA00000 = 40 blocks = 10 MB
  • dtb Compiled device tree blob

    • File: system.dtb (if the in-kernel device tree is not used)
    • Start address: 0xF40000
    • Size: 0x40000 = 1 block = 256 kB
  • rootfs JFFS2 root file system

    • File: rootfs.jffs2
    • Start address: 0xF80000
    • Size: 0x3080000 = 194 blcks = 49.664 MB (remaining space)

Updating the QSPI contents for flash boot

For new/erased devices, load the FSBL and SSBL as stated above using the JTAG cable. If both of them are already loaded to flash, you can skip the JTAG step.

After the FSBL has handed over control to the SSBL/U-Boot, there is a 3 second countdown prior to launch of the autoboot command. Interrupt the countdown with a random keypress which leads to the U-Boot prompt.

  • Set up IP addresses for the TFTP transfer, assuming the TFTP listening at and .2 for the HDROB

    setenv ipaddr
    setenv serverip
  • To store the IP addresses for further updates, write them to flash

  • To clear the saved environment, erase the memory block

    run eraseenv
  • Load FSBL/SSBL/FPGA bitfile

    run update_boot
  • Load device tree blob, if the in-kernel device tree is not used

    run update_dtb
  • Load Linux kernel

    run update_kernel
  • Load root file system

    run update_jffs2
  • Different parts can be combined to be flashed at once. To overwrite all stored data, issue

    run update_boot update_dtb update_jffs2 update_kernel

It is not necessary to execute all steps, for example to update the FPGA bitfile, run update_boot is sufficient. Remember to hard-reset the HDROB after the update or you might keep using an outdated bootloader or bitfile.

SD card


Booting from SD card is slower than from QSPI, but allows for easier updating by transferring the firmware files on a regular desktop computer. The SD card holds both the firmware images as well as the root file system; the U-Boot environment however cannot be stored to the SD card.

U-BOOT environment

As the U-Boot environment is not stored on the SD card, special care must be taken when switching between boot modes, e. g. between QSPI and SD card, because the environment also includes the bootcmd command. Hence it is not sufficient to switch between the modes with the DIP setting, but also the environment must be rewritten or reset (using the run eraseenv command at the U-Boot prompt).

SD card layout

The boot ROM can only access a MBR/classic DOS partition table. Take care not to partition using others, like GPT.

  • boot FSBL, SSBL (U-Boot) and FPGA bitfile, Linux kernel

    • Files: BOOT.BIN, image.ub, system.dtb (if the in-kernel device tree is not used)
    • Partition type: primary
    • Partition format: FAT16/32 (type id 0xb, Win95 FAT32)
  • rootfs root file system

    • File: -
    • Partition type: primary
    • Partition format: Ext4 (type id 0x83, Linux)

The root file system resides in the build/linux/rootfs/targetroot subdirectory of the PetaLinux project on the build host. There is no binary disk image available, so it must be transferred keeping links, special files and permissions intact (e. g., with rsync -aHAX).

Two build scripts build_sdcard_wrapper.sh and build_sdcard_wrapper.sh (the main script and a special wrapper) are available in the utils subdirectory of the Git repository

Creating/updating the SD card

In order to access the raw SD card device, the script must be run as root user or with the sudo command. If the root user cannot access the place where the PetaLinux project files are located (e. g. because they are on an NFS share with root access disabled), a wrapper script build_sdcard_wrapper.sh is used to copy the relevant file set to a temporary location prior to the execution of the main script.

By calling the build_sdcard.sh or build_sdcard_wrapper.sh script, a bootable SD card is created with the files from the first parameter on the device specified with the second parameter.

build_sdcard.sh /path/to/your/hdrob-petalinux-sw /dev/sdb
Latest revision: 10.05.2016