Creating Boot Images

Boot Image Format (BIF)

The Xilinx® boot image layout has multiple files, file types, and supporting headers to parse those files by boot loaders. Bootgen defines multiple attributes for generating the boot images and interprets and generates the boot images, based on what is passed in the files. Because there are multiple commands and attributes available, Bootgen defines a boot image format (BIF) to contain those inputs. A BIF comprises of the following:

  • Configuration attributes to create secure/non-secure boot images
  • Bootloader
    • First stage bootloader (FSBL) for Zynq® devices and Zynq® UltraScale+™ MPSoCs
    • Platform loader and manager (PLM) for Versal™ ACAP
    • Note: It is recommended to use the same release version of bootloader (FSBL/PLM) and Bootgen together.
  • One or more partition images

Along with properties and attributes, Bootgen takes multiple commands to define the behavior while it is creating the boot images. For example, to create a boot image for a qualified FPGA device, a Zynq®-7000 SoC device, Versal™ ACAP, or a Zynq® UltraScale+™ MPSoC device, you should provide the appropriate arch command option to Bootgen. The following appendices list and describe the available options to direct Bootgen behavior.

The format of the boot image conforms to a hybrid mix of hardware and software requirements. The boot header is required by the BootROM loader which loads a single partition, typically the bootloader. The remainder of the boot image is loaded and processed by the bootloader. Bootgen generates a boot image by combining a list of partitions. These partitions can be:

  • FSBL or PLM
  • Secondary Stage Boot Loader (SSBL) like U-Boot
  • Bitstream PL CFrame data, .rcdo, and .rnpi
  • Linux
  • Software applications to run on processors
  • User data
  • Boot image generated by Bootgen. This is useful for appending new partitions to a boot image generated previously.

BIF Syntax and Supported File Types

The BIF file specifies each component of the boot image, in order of boot, and allows optional attributes to be applied to each image component. In some cases, an image component can be mapped to more than one partition if the image component is not contiguous in memory. For example, if an ELF file has multiple loadable sections which are non-contiguous, then each section can be a separate partition. BIF file syntax takes the following form:

new_bif:
{
  id = 0x5
  id_code = 0x04ca8093
  extended_id_code = 0x01
  image
  {
      name = pmc_subsys, id = 0x1c000001
      partition
      { 
          id = 0x11, type = bootloader,
          file = /path/to/plm.elf
      }
      partition
      {
         type = pmcdata, load = 0xf2000000,
         file = /path/to/pmc_cdo.bin
      }
  }
}
Note: The above format is for Versal™ devices only.
<image_name>:
{
	// common attributes
	[attribute1] <argument1>   
	 
	// partition attributes
	[attribute2, attribute3=<argument>] <elf>
	[attribute2, attribute3=<argument>, attibute4=<argument] <bit>
	[attribute3] <elf>
	<bin>
}  
  • The <image_name> and the {...} grouping brackets the files that are to be made into partitions in the ROM image.
  • One or more data files are listed in the {...} brackets.
  • Each partition data files can have an optional set of attributes preceding the data file name with the syntax [attribute, attribute=<argument>].
  • Attributes apply some quality to the data file.
  • Multiple attributes can be listed separated with a ',' as a separator. The order of multiple attributes is not important. Some attributes are one keyword, some are keyword equates.
  • You can also add a filepath to the file name if the file is not in the current directory. How you list the files is free form; either all on one line (separated by any white space, and at least one space), or on separate lines.
  • White space is ignored, and can be added for readability.
  • You can use C-style block comments of /*...*/, or C++ line comments of //.

The following example is of a BIF with additional white space and new lines for improved readability:

<bootimage_name>:
{
	/* common attributes */
	 [attribute1] <argument1>   
	 
	/* bootloader */
	 [attribute2, 
	  attribute3, 
	  attribute4=<argument>
	] <elf>
	 
	/* pl bitstream */ 
	[
		attribute2, 
		attribute3, 
		attribute4=<argument>,
		attibute=<argument>
	] <bit>
	 
	/* another elf partition */
	[
		attribute3
	] <elf>
 
	/* bin partition */
	<bin>
}

Bootgen Supported Files

The following table lists the Bootgen supported files.

Table 1. Bootgen Supported Files
Device Supported Extension Description Notes
Supported by all devices .bin Binary Raw binary file.
.dtb Binary Raw binary file.
image.gz Binary Raw binary file.
.elf Executable Linked File (ELF) Symbols and headers removed.
.int Register initialization file
.nky AES key
.pub/.pem RSA key
.sig Signature files Signature files generated by bootgen or HSM.
Versal .rcdo CFI Files For Versal devices only.
.cdo/.npi/ .rnpi CDO files Configuration Data Object files. For Versal devices only.
.bin/.pdi Boot image Boot image generated using Bootgen.
Zynq-7000/Zynq UltraScale+ MPSoC/FPGA .bit/.rbt Bitstream Strips the BIT file header.

BIF Syntax for Versal ACAP

The following example shows the detailed manner in which you can write a BIF while grouping the partitions together. The BIF syntax has changed for Versal ACAP to support the concept of subsystems, where multiple partitions can be combined to together to form an image, also called as subsystem with one image header.

new_bif:
{
	id_code = 0x04ca8093
	extended_id_code = 0x01
	id = 0x2
	image
	{
		name = pmc_subsys
		id = 0x1c000001
		partition
		{
			id = 0x01
			type = bootloader
			file = gen_files/executable.elf
		}
		partition
		{
			id = 0x09
			type = pmcdata, load = 0xf2000000
			file = topology_xcvc1902.v2.cdo
			file = gen_files/pmc_data.cdo
		}
	}
	image
	{
		name = lpd
		id = 0x4210002
		partition
		{
			id = 0x0C
			type = cdo
			file = gen_files/lpd_data.cdo
		}
		partition
		{
			id = 0x0B
			core = psm
			file = static_files/psm_fw.elf
		}
	}
	image
	{
		name = pl_cfi
		id = 0x18700000
		partition
		{
			id = 0x03
			type = cdo
			file = system.rcdo
		}
		partition
		{
			id = 0x05
			type = cdo
			file = system.rnpi
		}
	}
	image
	{
		name = fpd
		id = 0x420c003
		partition
		{
			id = 0x08
			type = cdo
			file = gen_files/fpd_data.cdo
		}
	}
}

The following example shows how you can write a BIF in a concise manner by grouping the partitions together.

new_bif:
{
	id_code = 0x04ca8093
	extended_id_code = 0x01
	id = 0x2
	image
	{
		name = pmc_subsys, id = 0x1c000001
		{ id = 0x01, type = bootloader, file = gen_files/executable.elf }
		{ id = 0x09, type = pmcdata, load = 0xf2000000, file = topology_xcvc1902.v2.cdo, file = gen_files/pmc_data.cdo }
	}
	image
	{
		name = lpd, id = 0x4210002
		{ id = 0x0C, type = cdo, file = gen_files/lpd_data.cdo }
		{ id = 0x0B, core = psm, file = static_files/psm_fw.elf }
	}
	image
	{
		name = pl_cfi, id = 0x18700000
		{ id = 0x03, type = cdo, file = system.rcdo }
		{ id = 0x05, type = cdo, file = system.rnpi }
	}
	image
	{
		name = fpd, id = 0x420c003
		{ id = 0x08, type = cdo, file = gen_files/fpd_data.cdo }
	}
}

Attributes

The following table lists the Bootgen attributes. Each attribute has a link to a longer description in the left column with a short description in the right column. The architecture name indicates which Xilinx® devices uses that attribute:

  • zynq: Zynq-7000 SoC device
  • zynqmp: Zynq® UltraScale+™ MPSoC device
  • fpga: Any 7 series and above devices
  • versal: Versal™ ACAP
For more information, see BIF Attribute Reference.
Table 2. Bootgen Attributes and Description
Option/Attribute Description Used By
aarch32_mode Specifies the binary file that is to be executed in 32-bit mode.
  • zynqmp
  • versal
aeskeyfile<aes_key_filepath> The path to the AES keyfile. The keyfile contains the AES key used to encrypt the partitions. The contents of the key file needs to written to eFUSE or BBRAM. If the key file is not present in the path specified, a new key is generated by Bootgen, which is used for encryption. For example: If encryption is selected for bitstream in the BIF file, the output is an encrypted bitstream.
  • All
alignment <byte> Sets the byte alignment. The partition will be padded to be aligned to a multiple of this value. This attribute cannot be used with offset.
  • zynq
  • zynqmp
auth_params <options> Extra options for authentication:
  • ppk_select: 0=1, 1=2 of two PPKs supported.
  • spk_id: 32-bit ID to differentiate SPKs.
  • spk_select: To differentiate spk and user efuses. Default will be spk-efuse.
  • header_auth: To authenticate headers when no partition is authenticated.
  • zynqmp
authentication <option> Specifies the partition to be authenticated.
  • Authentication for Zynq is done using RSA-2048.
  • Authentication for Zynq UltraScale+ MPSoCs is done using RSA-4096.
  • Authentication for Versal ACAP is done using RSA-4096, ECDSA-p384, and ECDSA-p521.
The arguments are:
  • none: Partition not signed.
  • ecdsa-p384: partition signed using ecdsa-p384 curve
  • ecdsa-p521: partition signed using ecdsa-p521 curve
  • rsa: Partition signed using RSA algorithm.
  • All

bbram_kek_iv<filename>

Specifies the IV that is used to encrypt the corresponding key. bbram_kek_iv is valid with keysrc=bbram_blk_key.
  • versal

bh_kek_iv <filename>

Specifies the IV that is used to encrypt the corresponding key. bh_kek_iv is valid with keysrc=bh_blk_key.
  • versal
bh_key_iv <filename>

Initialization vector used when decrypting the obfuscated key or a black key.

  • zynqmp
bh_keyfile= <filename>

256-bit obfuscated key or black key to be stored in the Boot Header. This is only valid when keysrc for encryption is bh_gry_key or bh_blk_key.

Note: Obfuscated key is not supported for Versal devices.
  • zynqmp
  • versal
bhsignature <filename> Imports Boot Header signature into authentication certificate. This can be used if you do not want to share the secret key PSK. You can create a signature and provide it to Bootgen. The file format is bootheader.sha384.sig.
  • zynqmp
  • versal
big_endian Specifies the binary file is in big endian format.
  • zynqmp
  • versal
blocks <block sizes> Specifies block sizes for key-rolling feature in Encryption. Each module is encrypted using its own unique key. The initial key is stored at the key source on the device, while keys for each successive blocks are encrypted (wrapped) in the previous module.
  • zynqmp
  • versal
boot_config<options> This attribute specifies the parameters that are used to configure the boot image.
  • versal
boot_device <options> Specifies the secondary boot device. Indicates the device on which the partition is present. Options are:
  • qspi32
  • qspi24
  • nand
  • sd0
  • sd1
  • sd-ls
  • emmc
  • usb
  • ethernet
  • pcie
  • sata
  • ospi
  • smap
  • sbi
  • sd0-raw
  • sd1-raw
  • sd-ls-raw
  • mmc-raw
  • mmc0
  • mmc0-raw
Note: These options are supported for various devices in Bootgen. For a list of secondary boot options, see the Versal ACAP System Software Developers Guide (UG1304) or the Zynq UltraScale+ MPSoC: Software Developers Guide (UG1137). For hardware/register/interface information and primary boot modes, refer to the corresponding TRM, such as the Zynq UltraScale+ Device Technical Reference Manual (UG1085), the Versal ACAP Technical Reference Manual (AM011), or the Versal ACAP Register Reference (AM012).
  • zynqmp
  • versal
bootimage <filename.bin> Specifies that the listed input file is a boot image that was created by Bootgen.
  • zynq
  • zynqmp
  • versal
bootloader <partition>

Specifies the partition is a bootloader (FSBL/PLM). This attribute is specified along with other partition BIF attributes.

  • zynq
  • zynqmp
  • versal
bootvectors <vector_values> Specifies the vector table for execute in place (XIP).
  • zynqmp
checksum <options> Specifies that the partition needs to be checksummed. This option is not supported along with more secure features like authentication and encryption. Checksum algorithms are:
  • none: No checksum operation.
  • md5: For Zynq®-7000 SoC devices only
  • sha3: For Zynq® UltraScale+™ MPSoC and Versal devices.
Note: Zynq devices do not support checksum for bootloaders. Zynq UltraScale+ MPSoC and Versal ACAP supports checksum operation for bootloaders.
  • zynq
  • zynqmp
  • versal
copy= <address> This attribute specifies that the image is to be copied to memory at specified address.
  • versal
core= <options> This attributes specifies which core executes the partition. The options are:
  • a72-0
  • a72-1
  • r5-0
  • r5-1
  • psm
  • aie
  • r5-lockstep
  • versal
delay_handoff This attribute specifies that the hand-off to the subsystem/image is delayed.
  • versal
delay_load This attribute specifies that the loading of the subsystem/image is delayed.
  • versal
destination_device <device_type> This specifies if the partition is targeted for PS or PL. The options are:
  • ps: the partition is targeted for PS (default).
  • pl: the partition is targeted for PL, for bitstreams.
  • zynqmp
destination_cpu <device_core> Specifies the core on which the partition should be executed.
  • a53-0
  • a53-1
  • a53-2
  • a53-3
  • r5-0 (default)
  • r5-1
  • pmu
  • r5-lockstep
  • zynqmp
early_handoff This flag ensures that the handoff to applications that are critical immediately after the partition is loaded; otherwise, all the partitions are loaded sequentially first, and then the handoff also happens in a sequential fashion.
  • zynqmp
efuse_kek_iv= <filename> Specifies the IV that is used to encrypt the corresponding key. efuse_kek_iv is valid with keysrc=efuse_blk_key.
  • versal
efuse_user_kek0_iv= <filename> Specifies the IV that is used to encrypt the corresponding key. efuse_user_kek0_iv is valid with keysrc=efuse_user_blk_key0.
  • versal
efuse_user_kek1_iv= <filename> Specifies the IV that is used to encrypt the corresponding key. efuse_user_kek1_iv is valid with keysrc=efuse_user_blk_key1.
  • versal
encryption= <option> Specifies the partition to be encrypted. Encryption algorithms are: zynq uses AES-CBC, while zynqmp and Versal use AES-GCM.
The partition options are:
  • none: Partition not encrypted.
  • aes: Partition encrypted using AES algorithm.
  • All
exception_level <options> Exception level for which the core should be configured.
Options are:
  • el-0
  • el-1
  • el-2
  • el-3
  • zynqmp
  • versal
familykey <key file> Specifies the family key.
  • zynqmp
  • fpga
file= <path/to/file> This attribute specifies the file for creating the partition.
  • versal
fsbl_config <options> Specifies the sub-attributes used to configure the bootimage. Those sub-attributes are:
  • bh_auth_enable: RSA authentication of the boot image is done excluding the verification of PPK hash and SPK ID.
  • auth_only: boot image is only RSA signed. FSBL should not be decrypted.
  • opt_key: Operational key is used for block-0 decryption. Secure Header has the opt key.
  • pufhd_bh: PUF helper data is stored in Boot Header (Default is efuse).
  • PUF helper data file is passed to Bootgen using the [puf_file] option.
  • puf4kmode: PUF is tuned to use in 4k bit configuration (Default is 12k bit).
  • shutter = <value>: 32 bit PUF_SHUT register value to configure PUF for shutter offset time and shutter open time. Note that this shutter value must match the shutter value that was used during PUF registration.
  • zynqmp
headersignature= <signature_file> Imports the header signature into an Authentication Certificate. This can be used in case the user does not want to share the secret key, The user can create a signature and provide it to Bootgen.
  • zynq
  • zynqmp
  • versal
hivec Specifies the location of exception vector table as hivec (Hi-Vector). The default value is lovec (Low-Vector). This is applicable with A53 (32 bit) and R5 cores only.
  • hivec: exception vector table at 0xFFFF0000.
  • lovec: exception vector table at 0x00000000.
  • zynqmp
id= <id> This attribute specifies the following IDs based on the place its defined:
  • pdi id - within outermost/PDI parenthesis
  • image id - within image parenthesis
  • partition id - within partition parenthesis
  • versal
image Defines a subsystem/image.
  • versal
init <filename> Register initialization block at the end of the bootloader, built by parsing the init (.int) file specification. A maximum of 256 address-value init pairs are allowed. The init files have a specific format.
  • zynq
  • zynqmp
  • versal
keysrc Specifies key source for encryption for Versal ACAP. The keysrc can be specified for individual partitions.
  • efuse_red_key
  • efuse_blk_key
  • bbram_red_key
  • bbram_blk_key
  • bh_blk_key
  • user_key0
  • user_key1
  • user_key2
  • user_key3
  • user_key4
  • user_key5
  • user_key6
  • user_key7
  • efuse_user_key0
  • efuse_user_blk_key0
  • efuse_user_key1
  • efuse_user_blk_key1
  • versal
keysrc_encryption Specifies the key source for encryption. The keys are:
  • efuse_gry_key: Grey (Obfuscated) Key stored in eFUSE. See Gray/Obfuscated Keys
  • bh_gry_key: Grey (Obfuscated) Key stored in boot header.
  • bh_blk_key: Black Key stored in boot header. See Black/PUF Keys
  • efuse_blk_key : Black Key stored in eFUSE.
  • kup_key: User Key.
  • efuse_red_key: Red key stored in eFUSE. See Rolling Keys.
  • bbram_red_key: Red key stored in BBRAM.
  • zynq
  • zynqmp
load= <partition_address> Sets the load address for the partition in memory.
  • zynq
  • zynqmp
  • versal
metaheader This attribute is used to define encryption and authentication attributes for meta headers like keys, key sources, and so on.
  • versal
name= <name> This attribute specifies the name of the image/subsystem.
  • versal
offset <offset> Sets the absolute offset of the partition in the boot image.
  • zynq
  • zynqmp
  • versal
parent_id This attribute specifies the ID for the parent PDI. This is used to identify the relationship between a partial PDI and its corresponding boot PDI.
  • versal
partition This attribute is used to define a partition. It is an optional attribute to make the BIF short and readable.
  • versal
partition_owner, owner <option> Owner of the partition which is responsible to load the partition. Options are:
For Zynq/Zynq UltraScale+ MPSoC:
  • fsbl: Partition is loaded by FSBL.
  • uboot: Partition is loaded by U-Boot.
For Versal:
  • plm: partition loaded by PLM.
  • non-plm: partition is not loaded by PLM, but it is loaded by another entity like U-Boot.
  • zynq
  • zynqmp
  • versal
pid <ID> Specifies the Partition ID. PID can be a 32-bit value (0 to 0xFFFFFFFF).
  • zynqmp
pmufw_image <image_name> PMU firmware image to be loaded by BootROM, before loading the FSBL.
  • zynqmp
ppkfile <key filename> Primary Public Key (PPK). Used to authenticate partitions in the boot image.

See Using Authentication for more information.

  • zynq
  • zynqmp
  • versal
presign <sig_filename> Partition signature (.sig) file.
  • zynq
  • zynqmp
  • fpga
pskfile <key filename> Primary Secret Key (PSK). Used to authenticate partitions in the boot image.

See the Using Authentication for more information.

  • zynq
  • zynqmp
  • versal
puf_file <filename> PUF helper data file. PUF is used with black key as encryption key source. PUF helper data is of 1544 bytes.1536 bytes of PUF HD + 4 bytes of HASH + 3 bytes of AUX + 1 byte alignment.
  • zynqmp
  • versal
reserve <size in bytes> Reserves the memory, which is padded after the partition.
  • zynq
  • zynqmp
  • versal
spk_select <SPK_ID> Specify an SPK ID in user eFUSE.
  • zynqmp
spkfile <filename> Keys used to authenticate partitions in the boot image. See Using Authentication for more information.
  • All
spksignature <signature_file> Imports the SPK signature into an Authentication Certificate. See Using Authentication. This can be used in case the user does not want to share the secret key PSK, The user can create a signature and provide it to Bootgen.
  • zynq
  • zynqmp
  • versal
split <options> Splits the image into parts, based on the mode. Split options are:
  • Slaveboot: Supported for Zynq UltraScale+ MPSoC only. Splits as follows:
  • Boot Header + Bootloader
  • Image and Partition Headers
  • Rest of the partitions
  • normal: Supported for zynq, zynqmp, and versal. Splits as follows:
  • Bootheader + Image Headers + Partition Headers + Bootloader
  • Partition1
  • Partition2 and so on

Along with the split mode, output format can also be specified as bin or mcs.

Note: The option split mode normal is same as the command line option split. This command line option is deprecated. Split ulaveboot is supported only for Zynq UltraScale+ MPSoC.
  • zynq
  • zynqmp
  • versal
sskfile <key filename> Secondary Secret Key (SSK) key authenticates partitions in the Boot Image. The primary keys authenticate the secondary keys; the secondary keys authenticate the partitions.
  • All
startup <address> Sets the entry address for the partition, after it is loaded. This is ignored for partitions that do not execute.
  • zynq
  • zynqmp
  • versal
trustzone <option>
The trustzone options are:
  • secure
  • nonsecure
  • zynqmp
  • versal
type= <options> This attribute specifies the type of partition. The options are:
  • bootloader
  • pmcdata
  • cdo
  • cfi
  • cfi-gsc
  • bootimage
  • versal
udf_bh <data_file> Imports a file of data to be copied to the user defined field (UDF) of the Boot Header. The UDF is provided through a text file in the form of a hex string. Total number of bytes in UDF are: zynq = 76 bytes; zynqmp= 40 bytes.
  • zynq
  • zynqmp
udf_data <data_file> Imports a file containing up to 56 bytes of data into user defined field (UDF) of the Authentication Certificate.
  • zynq
  • zynqmp
userkeys= <filename> The path to the user keyfile.
  • versal
xip_mode Indicates eXecute In Place (XIP) for FSBL to be executed directly from QSPI flash.
  • zynq
  • zynqmp