Flattened Image Tree Specification v0.8-25-g8f7d9a8

2. Acknowledgements

FIT (Flattened Image Tree) was developed in 2008 by Marian Balakowicz and Bartlomiej Sieka of Semihalf, under the guidance of Wolfgang Denk, founder of Denx Software Engineering and creator of U-Boot.

Since then, FIT has been maintained and extended by the U-Boot community to deal with the developing needs of Open Source firmware.

This specification builds on this previous work.

FIT has stood the test of time due to its simplicity and extensibility. This specification aims to build on this work and provide a means for further improvement with a wider group of collaborators.

3. Revision History

Table 3.1 Revision History

Revision

Date

Description

0.8

2023-AUG-9

Initial prerelease version. Imported text from U-Boot source tree.

4. Introduction

4.1. Purpose and Scope

The number of elements playing a role in the kernel booting process has increased over time and now typically includes the devicetree, kernel image and possibly a ramdisk image. Generally, all must be placed in the system memory and booted together.

For firmware images a similar process has taken place, with various binaries loaded at different addresses, such as ARM’s ATF, OpenSBI, FPGA and U-Boot itself.

FIT provides a flexible and extensible format to deal with this complexity. It provides support for multiple components. It also supports multiple configurations, so that the same FIT can be used to boot multiple boards, with some components in common (e.g. kernel) and some specific to that board (e.g. devicetree).

This specification, the Flattened Image Tree Specification (FITSpec), provides a suitable format which can be used to describe any set of files along with grouping and selection mechanisms.

  • Chapter 4 introduces the purpose and background of FITSpec.

  • Chapter 5 introduces the FIT concept and describes its logical structure and standard properties. certain classes of devices and specific device types.

  • Chapter 6 describes how FIT is used in bootloaders to handle booting Operating Systems as well as firmware.

Conventions Used in this Document

The word shall is used to indicate mandatory requirements strictly to be followed in order to conform to the standard and from which no deviation is permitted (shall equals is required to).

The word should is used to indicate that among several possibilities one is recommended as particularly suitable, without mentioning or excluding others; or that a certain course of action is preferred but not necessarily required; or that (in the negative form) a certain course of action is deprecated but not prohibited (should equals is recommended that).

The word may is used to indicate a course of action permissible within the limits of the standard (may equals is permitted).

Examples of devicetree constructs are frequently shown in Devicetree Syntax form. See [dtspec] for a description of this.

4.2. Relationship to Devicetree Specification

FITSpec is based on the Devicetree Specification, in that it uses the same structure and shares some concepts.

4.3. 32-bit and 64-bit Support

The FITSpec supports CPUs with both 32-bit and 64-bit addressing capabilities. Where applicable, sections of the FITSpec describe any requirements or considerations for 32-bit and 64-bit addressing.

4.4. Definition of Terms

DTB

Devicetree blob. Compact binary representation of the devicetree.

DTC

Devicetree compiler. An open source tool used to create DTB files from DTS files.

DTS

Devicetree syntax. A textual representation of a devicetree consumed by the DTC. See Appendix A Devicetree Source Format (version 1).

5. Flattened Image Tree (FIT) Format

5.1. Introduction

FIT consists of a devicetree blob with nodes and properties following a certain schema. Therefore this document defines FIT by providing FDT (Flat Device Tree) bindings. These describe the final form of the FIT at the moment when it is used. The user perspective may be simpler, as some of the properties (like timestamps and hashes) are filled in automatically by available tooling, such as mkimage.

To avoid confusion with the kernel FDT the following naming convention is used:

FIT

Flattened Image Tree

FIT is formally a flattened devicetree (in the libfdt meaning), which conforms to bindings defined in this document.

.its

image tree source

.fit

flattened image tree blob

This was previously known as .itb but has been renamed to .fit.

5.1.1. Image-building procedure

The following picture shows how the FIT is prepared. Input consists of image source file (.its) and a set of data files. Image is created with the help of standard U-Boot mkimage tool which in turn uses dtc (device tree compiler) to produce image tree blob (.fit). The resulting .fit file is the actual binary of a new FIT:

tqm5200.its
+
vmlinux.bin.gz     mkimage + dtc               xfer to target
eldk-4.2-ramdisk  --------------> tqm5200.fit --------------> boot
tqm5200.dtb                          /|\
                                      |
                                 'new FIT'

Steps:

  1. Create .its file, automatically filled-in properties are omitted

  2. Call mkimage tool on .its file

  3. mkimage calls dtc to create .fit image and assures that missing properties are added

  4. .fit (new FIT) is uploaded onto the target and used therein

5.1.2. Unique identifiers

To identify FIT sub-nodes representing images, hashes, configurations (which are defined in the following sections), the “unit name” of the given sub-node is used as its identifier as it assures uniqueness without additional checking required.

5.1.3. External data

FIT is normally built initially with image data in the ‘data’ property of each image node. It is also possible for this data to reside outside the FIT itself. This allows the ‘FDT’ part of the FIT to be quite small, so that it can be loaded and scanned without loading a large amount of data. Then when an image is needed it can be loaded from an external source.

External FITs use ‘data-offset’ or ‘data-position’ instead of ‘data’.

The mkimage tool can convert a FIT to use external data using the -E argument, optionally using -p to specific a fixed position.

It is often desirable to align each image to a block size or cache-line size (e.g. 512 bytes), so that there is no need to copy it to an aligned address when reading the image data. The mkimage tool provides a -B argument to support this.

5.2. Root-node properties

The root node of the FIT should have the following layout:

/ o image-tree
    |- description = "image description"
    |- timestamp = <12399321>
    |- #address-cells = <1>
    |
    o images
    | |
    | o image-1 {...}
    | o image-2 {...}
    | ...
    |
    o configurations
      |- default = "conf-1"
      |
      o conf-1 {...}
      o conf-2 {...}
      ...

5.2.1. Optional property

description

Textual description of the FIT

5.2.2. Mandatory property

timestamp

Last image modification time being counted in seconds since 1970-01-01 00:00:00 - to be automatically calculated by mkimage tool.

5.2.3. Conditionally mandatory property

#address-cells

Number of 32bit cells required to represent entry and load addresses supplied within sub-image nodes. May be omitted when no entry or load addresses are used.

5.2.4. Mandatory nodes

images

This node contains a set of sub-nodes, each of them representing single component sub-image (like kernel, ramdisk, etc.). At least one sub-image is required.

configurations

Contains a set of available configuration nodes and defines a default configuration.

5.3. ‘/images’ node

This node is a container node for component sub-image nodes. Each sub-node of the ‘/images’ node should have the following layout:

o image-1
    |- description = "component sub-image description"
    |- data = /incbin/("path/to/data/file.bin")
    |- type = "sub-image type name"
    |- arch = "ARCH name"
    |- os = "OS name"
    |- compression = "compression name"
    |- load = <00000000>
    |- entry = <00000000>
    |
    o hash-1 {...}
    o hash-2 {...}
    o logo-info {...}
    o os-info {...}
    ...

5.3.1. Mandatory properties

description

Textual description of the component sub-image

type

Name of component sub-image type. Supported types are:

Sub-image type

Meaning

invalid

Invalid Image

aisimage

Davinci AIS image

atmelimage

ATMEL ROM-Boot Image

copro

Coprocessor Image

fdt_legacy

legacy Image with Flat Device Tree

filesystem

Filesystem Image

firmware

Firmware

firmware_ivt

Firmware with HABv4 IVT

flat_dt

Flat Device Tree

fpga

FPGA Device Image (bitstream file, vendor specific)

gpimage

TI Keystone SPL Image

imx8image

NXP i.MX8 Boot Image

imx8mimage

NXP i.MX8M Boot Image

imximage

Freescale i.MX Boot Image

kernel

Kernel Image

kernel_noload

Kernel Image (no loading done)

kwbimage

Kirkwood Boot Image

logo

Logo or other graphical image

lpc32xximage

LPC32XX Boot Image

mtk_image

MediaTek BootROM loadable Image

multi

Multi-File Image

mxsimage

Freescale MXS Boot Image

omapimage

TI OMAP SPL With GP CH

pblimage

Freescale PBL Boot Image

pmmc

TI Power Management Micro-Controller Firmware

ramdisk

RAMDisk Image

rkimage

Rockchip Boot Image

rksd

Rockchip SD Boot Image

rkspi

Rockchip SPI Boot Image

script

Script

socfpgaimage

Altera SoCFPGA CV/AV preloader

socfpgaimage_v1

Altera SoCFPGA A10 preloader

spkgimage

Renesas SPKG Image

standalone

Standalone Program

stm32image

STMicroelectronics STM32 Image

sunxi_egon

Allwinner eGON Boot Image

sunxi_toc0

Allwinner TOC0 Boot Image

tee

Trusted Execution Environment Image

tfa-bl31

Trusted Firmware-A BL31 Image

ublimage

Davinci UBL image

vybridimage

Vybrid Boot Image

x86_setup

x86 setup.bin

zynqimage

Xilinx Zynq Boot Image

zynqmpbif

Xilinx ZynqMP Boot Image (bif)

zynqmpimage

Xilinx ZynqMP Boot Image

compression

Compression used by included data. If no compression is used, the compression property should be set to “none”. If the data is compressed but it should not be uncompressed by the loader (e.g. compressed ramdisk <pair: ramdisk; compressed), this should also be set to “none”.

Supported compression types are:

Compression type

Meaning

none

uncompressed

bzip2

bzip2 compressed

gzip

gzip compressed

lz4

lz4 compressed

lzma

lzma compressed

lzo

lzo compressed

zstd

zstd compressed

5.3.2. Conditionally mandatory properties

data

Path to the external file which contains this node’s binary data. Within the FIT this is the contents of the file. This is mandatory unless external data is used.

data-size

Size of the data in bytes. This is mandatory if external data is used.

data-offset

Offset of the data in a separate image store. The image store is placed immediately after the last byte of the device tree binary, aligned to a 4-byte boundary. This is mandatory if external data is used, with an offset.

data-position

Machine address at which the data is to be found. This is a fixed address not relative to the loading of the FIT. This is mandatory if external data is used with a fixed address.

os

OS name, mandatory for types “kernel”. Valid OS names are:

OS name

Meaning

invalid

Invalid OS

4_4bsd

4_4BSD

arm-trusted-firmware

ARM Trusted Firmware

dell

Dell

efi

EFI Firmware

esix

Esix

freebsd

FreeBSD

integrity

INTEGRITY

irix

Irix

linux

Linux

ncr

NCR

netbsd

NetBSD

openbsd

OpenBSD

openrtos

OpenRTOS

opensbi

RISC-V OpenSBI

ose

Enea OSE

plan9

Plan 9

psos

pSOS

qnx

QNX

rtems

RTEMS

sco

SCO

solaris

Solaris

svr4

SVR4

tee

Trusted Execution Environment

u-boot

U-Boot

vxworks

VxWorks

arch

Architecture name, mandatory for types: “standalone”, “kernel”, “firmware”, “ramdisk” and “fdt”. Valid architecture names are:

Architecture type

Meaning

invalid

Invalid ARCH

alpha

Alpha

arc

ARC

arm64

AArch64

arm

ARM

avr32

AVR32

blackfin

Blackfin

ia64

IA64

m68k

M68K

microblaze

MicroBlaze

mips64

MIPS 64 Bit

mips

MIPS

nds32

NDS32

nios2

NIOS II

or1k

OpenRISC 1000

powerpc

PowerPC

ppc

PowerPC

riscv

RISC-V

s390

IBM S390

sandbox

Sandbox

sh

SuperH

sparc64

SPARC 64 Bit

sparc

SPARC

x86_64

AMD x86_64

x86

Intel x86

xtensa

Xtensa

entry

Entry point address, address size is determined by ‘#address-cells’ property of the root node. Mandatory for types: “firmware”, and “kernel”.

load

Load address, address size is determined by ‘#address-cells’ property of the root node. Mandatory for types: “firmware”, and “kernel”.

compatible

Compatible method for loading image. Mandatory for types: “fpga”, and images that do not specify a load address. Supported compatible methods:

Compatible string

Meaning

u-boot,fpga-legacy

Generic fpga loading routine.

u-boot,zynqmp-fpga-ddrauth

Signed non-encrypted FPGA bitstream for Xilinx Zynq UltraScale+ (ZymqMP) device.

u-boot,zynqmp-fpga-enc

Encrypted FPGA bitstream for Xilinx Zynq UltraScale+ (ZynqMP) device.

Note

For fdt images, the node should not have a compatible for the model. The compatible here is not derived from the fdt, nor is it used to identify the fdt. Such usage belongs in the configuration node.

phase

U-Boot phase for which the image is intended.

“spl”

image is an SPL image

“u-boot”

image is a U-Boot image

5.3.3. Optional nodes

hash-1

Each hash sub-node represents a separate hash or checksum calculated for node’s data according to specified algorithm.

signature-1

Each signature sub-node represents a separate signature calculated for node’s data according to specified algorithm.

logo-info

Contains information about the logo image, to help describe characteristics such as image dimensions.

os-info

Contains information about the OS image, to help identify it. This can be useful for displaying a menu for the user. The information is generally only useful for image nodes which contain an OS.

5.4. Hash nodes

o hash-1
    |- algo = "hash or checksum algorithm name"
    |- value = [hash or checksum value]

5.4.1. Mandatory properties

algo

Algorithm name. Supported algorithms and their value sizes are:

Sub-image type

Size (bytes)

Meaning

crc16-ccitt

2

Cyclic Redundancy Check 16-bit (Consultative Committee for International Telegraphy and Telephony)

crc32

4

Cyclic Redundancy Check 32-bit

md5

16

Message Digest 5 (MD5)

sha1

20

Secure Hash Algorithm 1 (SHA1)

sha256

32

Secure Hash Algorithm 2 (SHA256)

sha384

48

Secure Hash Algorithm 2 (SHA384)

sha512

64

Secure Hash Algorithm 2 (SHA512)

value

Actual checksum or hash value.

5.5. Image-signature nodes

o signature-1
    |- algo = "algorithm name"
    |- key-name-hint = "key name"
    |- value = [hash or checksum value]

5.5.1. Mandatory properties

FIT Algorithm:

algo

Algorithm name. Supported algorithms and their value sizes are shown below. Note that the hash is specified separately from the signing algorithm, so it is possible to mix and match any SHA algorithm with any signing algorithm. The size of the signature relates to the signing algorithm, not the hash, since it is the hash that is signed.

Sub-image type

Size (bytes)

Meaning

sha1,rsa2048

256

SHA1 hash signed with 2048-bit Rivest–Shamir–Adleman algorithm

sha1,rsa3072

384

SHA1 hash signed with 2048-bit RSA

sha1,rsa4096

512

SHA1 hash signed with 2048-bit RSA

sha1,ecdsa256

32

SHA1 hash signed with 256-bit Elliptic Curve Digital Signature Algorithm

sha256,…

sha384,…

sha512,…

key-name-hint

Name of key to use for signing. The keys will normally be in a single directory (parameter -k to mkimage). For a given key <name>, its private key is stored in <name>.key and the certificate is stored in <name>.crt.

sign-images

A list of images to sign, each being a property of the conf node that contains them. The default is “kernel,fdt” which means that these two images will be looked up in the config and signed if present. This is used by mkimage to determine which images to sign.

The following properties are added as part of signing, and are mandatory:

value

Actual signature value. This is added by mkimage.

hashed-nodes

A list of nodes which were hashed by the signer. Each is a string - the full path to node. A typical value might be:

hashed-nodes = "/", "/configurations/conf-1", "/images/kernel",
    "/images/kernel/hash-1", "/images/fdt-1",
    "/images/fdt-1/hash-1";
hashed-strings

The start and size of the string region of the FIT that was hashed. The start is normally 0, indicating the first byte of the string table. The size indicates the number of bytes hashed as part of signing.

The following properties are added as part of signing, and are optional:

timestamp

Time when image was signed (standard Unix time_t format)

signer-name

Name of the signer (e.g. “mkimage”)

signer-version

Version string of the signer (e.g. “2013.01”)

comment

Additional information about the signer or image

padding

The padding algorithm, it may be pkcs-1.5 or pss, if no value is provided we assume pkcs-1.5

5.6. Logo Information node

This node is mandatory for images of type ‘logo’.

Graphical logos can be used in boot menus to provide a visual indication of what is being booted. Logos are stored within the FIT as images, referred to by the logos property in the configuration node.

For the image, compression may be used, but if the file format itself supports compression this is not recommended.

The ‘logo-info’ node has the following structure:

o logo-info
   |- format = "bmp";
   |- width = <128>;
   |- height = <128>;
   |- depth-log2 = <4>;
   |- colour = "rgb";
   |- alpha-channel;

5.6.1. Mandatory properties

format

File format of the graphical image. This must be provided for images of type logo. See Logo Information node.

The following formats are defined. Support for logos is optional. If logos are supported, BMP must be supported. Other formats are optional.

Format type

Support

Meaning

bmp

Mandatory

Windows bitmap; see [windowsbmp]

png

Optional

Portable Network Graphics; see [png]

svg

Optional

Scalable Vector Graphics; see [svg]

5.6.2. Conditionally mandatory property

width:

Width of the logo in pixels. This property is mandatory for logos which contain bitmaps, i.e. BMP and PNG.

height

Height of the logo in pixels. This property is mandatory for logos which contain bitmaps, i.e. BMP and PNG.

depth-log2

log (base 2) of the logo depth. For example, for a 32bpp images this should be 5. This property is mandatory for logos which define a colour depth, i.e. BMP and PNG.

color

Type of color provided, as a string. This property is mandatory for logos which contain bitmaps, i.e. BMP and PNG.

Valid values are:

Color type

Meaning

indexed

A palette is used to define colours

grayscale

The image supports luminance only

rgb

The image supports red/green/blue true colour

alpha-channel

Indicates that the image has an alpha channel, i.e. supports transparency. This boolean property must be present if the image includes transparency information.

background

String indicateing the type of background the image targets.

Valid values are:

Background type

Meaning

light

The image looks best on a white or light background

dark

The image looks best on a black or dark background

5.7. OS Information node

The ‘os-info’ node provides information about an image, specifically targeting images which constitute an operation system. The properties are based on the freedesktop.org os-release specification [osrelease].

The ‘os-info’ node has the following structure:

o os-info
    |- ansi-color = "OS console presentation color"
    |- architecture = "OS userspace architecture"
    |- bug-report-url = "OS bug report URL"
    |- build-id = "OS build identifier"
    |- confext-level = "OS configuration extensions level"
    |- cpe-name = "OS Common Platform-Enumeration name"
    |- default-hostname = "OS default hostname"
    |- documentation-url = "OS documentation URL"
    |- home-url = "OS homepage URL"
    |- id = "OS identifier"
    |- id-like = "OS inherited from", ...
    |- image-id = "OS image identifier"
    |- image-version = "OS image version"
    |- logo-name = "OS logo icon name"
    |- name = "OS name"
    |- pretty-name = "OS pretty name"
    |- privacy-policy-url = "OS privacy policy URL"
    |- release-type = "OS release type"
    |- support-end = "OS support end date"
    |- support-url = "OS support URL"
    |- sysext-level = "OS system extensions level"
    |- variant = "OS variant"
    |- variant-id = "variant identifier"
    |- vendor-name = "OS vendor name"
    |- vendor-url = "OS vendor URL"
    |- version = "OS version"
    |- version-codename = "OS version codename"
    |- version-id = "OS version identifier"

5.7.1. Mandatory properties

If an ‘os-info’ node is included, these properties are mandatory:

name

A string identifying the operating system, without a version component, and suitable for presentation to the user.

Examples::

name = “Fedora Linux”;

name = “Ubuntu”;

version

A string identifying the operating system version, excluding any OS name information, possibly including a release code name, and suitable for presentation to the user.

Examples::

version = “32 (Workstation Edition)”;

version = “20.04.1 LTS (Focal Fossa)”;

5.7.2. Conditionally mandatory property

color

A suggested presentation color when showing the OS name on the console, in the format 0x00bbggrr. This is mandatory if ‘ansi-color’ is provided.

5.7.3. Optional properties

ansi-color

A suggested presentation color when showing the OS name on the console. This should be specified as string suitable for inclusion in the ESC [ m ANSI/ECMA-48 escape code for setting graphical rendition. See also color.

Examples::

// red ansi-color = “0;31”;

// light blue ansi-color = “1;34”;

// Fedora blue ansi-color = “0;38;2;60;110;180”;

architecture

A string that specifies the CPU architecture the userspace binaries require.

Examples::

architecture = “x86_64”;

architecture = “arm64”;

bug-report-url

Link to the main bug reporting page for the operating system, if there is one.

Example::

bug-report-url = “https://bugzilla.redhat.com/”;

build-id

A string uniquely identifying the system image originally used as the installation base. In most cases, VERSION_ID or IMAGE_ID are updated when the entire system image is replaced during an update. BUILD_ID may be used in distributions where the original installation image version is important.

Example::

build-id = “2013-03-20.3”;

confext-level

A lower-case string identifying the operating system configuration extensions support level, used to specify extension-release compatibility.

Examples::

confext-level = “2”;

confext-level = “15.14”;

cpe-name

A CPE name for the operating system, in URI binding syntax, following the Common Platform Enumeration Specification.

Example::

cpe-name = “cpe:/o:fedoraproject:fedora:17”;

default-hostname

A string specifying the hostname if hostname(5) is not present and no other configuration source specifies the hostname.

Example::

default-hostname = “localhost”;

documentation-url

Link to the main documentation page for this operating system.

Example::

documentation-url = “https://docs.fedoraproject.org/”;

home-url

Link to the homepage for the operating system, or alternatively a homepage of the specific version of the operating system.

Example::

home-url = “https://fedoraproject.org/”;

id

A lower-case string identifying the operating system, excluding version information and without spaces or other characters outside of 0-9, a-z, “.”, “_” and “-“.

Examples::

id = “fedora”;

id = “debian”;

id-like

A list of operating system identifiers in the same syntax as id. This should list identifiers of operating systems that are closely related to the local operating system in regards to packaging and programming interfaces.

Examples::

id-like = “rhel”, “centos”, “fedora”;

id-like = “debian”;

image-id

A lower-case string identifying a specific image of the operating system.

Examples::

image-id = “vendorx-cashier-system”;

image-id = “netbook-image”;

image-version

A lower-case string identifying the OS image version.

Example::

image-version = “33”;

image-version = “47.1rc1”

logo-name

A string specifying the name of an icon suitable to represent this operating system in a logo format. The file for the logo should be available within the root file system used by the operating system.

See the Icon Theme Specification [icontheme].

Examples::

logo-name = “fedora-logo-icon”;

logo-name = “ubuntu-logo”;

pretty-name

A pretty operating system name in a format suitable for presentation to the user. May or may not contain a release code name or OS version of some kind.

Examples::

pretty-name = “Fedora Linux 32 (Workstation Edition)”;

pretty-name = “Ubuntu 20.04.1 LTS”;

privacy-policy-url

Link to the privacy policy page for the operating system, if there is one.

Example::

privacy-policy-url = “https://fedoraproject.org/wiki/Legal:PrivacyPolicy”;

release-type

Describes the release type of the operating system. May be one of: stable, lts, development, experiment.

Examples::

release-type = “stable”;

release-type = “lts”;

release-type = “development”;

support-end

The time at which support for this version of the OS ends. When specified, this should be in 64-bit Unix time format, i.e. the number of seconds since 1.1.1970, 0:0:0.

Example::

support-end = /bits 64/ <1756212516>;

support-url

Link to the main support page for the operating system, if there is one.

Example::

support-url = “https://fedoraproject.org/wiki/Communicating_and_getting_help”;

sysext-level

A lower-case string identifying the operating system extensions support level, used to specify extension-release compatibility.

Examples::

sysext-level = “2”;

sysext-level = “15.14”;

variant

A string identifying a specific variant or edition of the operating system suitable for presentation to the user.

Examples::

variant = “Workstation Edition”;

variant = “Server Edition”;

variant-id

A lower-case string identifying a specific variant or edition of the operating system.

Examples::

variant-id = “workstation”;

variant-id = “server”;

vendor-name

The name of the operating system vendor.

Examples::

vendor-name = “Fedora Project”;

vendor-name = “Canonical Ltd.”;

vendor-url

Link to the vendor homepage.

Examples::

vendor-url = “https://fedoraproject.org/”;

vendor-url = “https://canonical.com/”;

version-codename

A lower-case string identifying the operating system release code name, excluding any OS name information or release version, and suitable for processing by scripts or usage in generated filenames.

Examples::

version-codename = “focal”;

version-codename = “jammy”;

version-id

A lower-case string identifying the operating system release, excluding any OS name information or release code name, and suitable for processing by scripts or usage in generated filenames.

Examples::

version-id = “32”;

version-id = “20.04”;

5.8. ‘/configurations’ node

The ‘configurations’ node creates convenient, labeled boot configurations, which combine together kernel images with their ramdisks and fdt blobs.

The ‘configurations’ node has the following structure:

o configurations
    |- default = "default configuration sub-node unit name"
    |
    o config-1 {...}
    o config-2 {...}
    ...

5.8.1. Optional property

default

Selects one of the configuration sub-nodes as a default configuration.

5.8.2. Mandatory nodes

configuration-sub-node-unit-name

At least one configuration sub-node is required.

5.8.3. Optional nodes

signature-1

Each signature sub-node represents a separate signature calculated for the configuration according to specified algorithm.

5.9. Configuration nodes

Each configuration has the following structure:

o config-1
    |- description = "configuration description";
    |- kernel = "kernel sub-node unit name";
    |- cmdline = "command line for next boot stage";
    |- fdt = "fdt sub-node unit-name" [, "fdt overlay sub-node unit-name", ...];
    |- ramdisk = "ramdisk sub-node unit-name";
    |- loadables = "loadables sub-node unit-name" [, ...];
    |- script = "script sub-node unit-name";
    |- compatible = "vendor,board-style device tree compatible string";
    |- logos = "log sub-node unit-name" [, ...];
    o signature-1 {...}

5.9.1. Mandatory properties

description

Textual configuration description.

kernel or firmware

Unit name of the corresponding kernel or firmware (u-boot, op-tee, etc) image. If both “kernel” and “firmware” are specified, control is passed to the firmware image.

5.9.2. Optional properties

cmdline

Command line passed to the next boot stage, e.g. the operating system kernel. The value is an UTF-8 encoded string.

fdt

Unit name of the corresponding fdt blob (component image node of a “fdt type”). Additional fdt overlay nodes can be supplied which signify that the resulting device tree blob is generated by the first base fdt blob with all subsequent overlays applied.

fpga

Unit name of the corresponding fpga bitstream blob (component image node of a “fpga type”).

loadables

Unit name containing a list of additional binaries to be loaded at their given locations. “loadables” is a comma-separated list of strings. U-Boot will load each binary at its given load address (see load) and may optionally invoke additional post-processing steps on this binary based on its component image node type.

ramdisk

Unit name of the corresponding ramdisk to be loaded at the given location.

script

The image to use when loading a U-Boot script (for use with the source command).

compatible

The root compatible string of the bootloader device tree that this configuration shall automatically match. If this property is not provided, the compatible string will be extracted from the fdt blob instead. This is only possible if the fdt is not compressed, so images with compressed fdts that want to use compatible string matching must always provide this property.

Note that U-Boot requires the CONFIG_FIT_BEST_MATCH option to be enabled for this matching to work.

logos

Unit names of the corresponding image blobs containing a logo for this operating system. Logos are listed in order of preference.

Multiple logos can be provided to ensure the widest possible bootloader support. If any logos are provide, at least one must be in BMP format. See Logo Information node.

The FDT blob is required to properly boot FDT-based kernel, so the minimal configuration for 2.6 FDT kernel is (kernel, fdt) pair.

Older, 2.4 kernel and 2.6 non-FDT kernel do not use FDT blob, in such cases ‘struct bd_info’ must be passed instead of FDT blob, thus fdt property must not be specified in a configuration node.

5.10. Configuration-signature nodes

o signature-1
    |- algo = "algorithm name"
    |- key-name-hint = "key name"
    |- sign-images = "path1", "path2";
    |- value = [hash or checksum value]
    |- hashed-strings = <0 len>

5.10.1. Mandatory properties

algo

See FIT Algorithm.

key-name-hint

Name of key to use for signing. The keys will normally be in a single directory (parameter -k to mkimage). For a given key <name>, its private key is stored in <name>.key and the certificate is stored in <name>.crt.

The following properties are added as part of signing, and are mandatory:

value

Actual signature value. This is added by mkimage.

The following properties are added as part of signing, and are optional:

timestamp

Time when image was signed (standard Unix time_t format)

signer-name

Name of the signer (e.g. “mkimage”)

signer-version

Version string of the signer (e.g. “2013.01”)

comment

Additional information about the signer or image

padding

The padding algorithm, it may be pkcs-1.5 or pss, if no value is provided we assume pkcs-1.5

6. Flattened Image Tree (FIT) Usage

6.1. Introduction

This section describes how FIT is typically used. This is not necessarily proscriptive but may be useful for those implementing this specification.

6.2. Boot process

At some point in the boot process, the bootloader select and boot an Operating System. To do this, it follows these steps:

  1. Load a FIT into memory

  2. Select a configuration to boot

  3. Load the images from the selected configuration

  4. Fix up the devicetree

  5. Jump to the OS

Each of these is now dealt with in turn.

6.2.1. Load a FIT into memory

The bootloader provides a way to select a FIT to load into memory. This is typically on boot media available to the bootloader, such as eMMC or UFS.

There may be multiple FITs available. The mechanism for locating and selecting a FIT is not defined by this specification. See for example [VBE].

The bootloader may load the entire FIT into memory at once, before processing it. For simple applications where there are just a few images, this is the easiest approach.

Where there are many configuration and several images, such that only a subset of the available images will actually be used on any one boot, it is inefficient to load the entire FIT, since most of the loaded data will not be used. In this case, an external-data FIT can be used. See External data.

In this case, the bootloader reads the FDT header (say 64 bytes), checks that it is valid, then reads enough more bytes to bring in totalsize bytes (totalsize is the second 32-bit word in the header). Typically this will be a few KB of data, consisting just of the FIT metadata. Later, the bootloader can read more data from the FIT as it needs to load each image.

Another case that sometimes comes up is loading images from a FIT into internal SRAM, which may be very limited. In that case it may be useful to align images on a storage-device’s block boundary (see -B flag in External data). The bootloader can then avoid needing bounce buffers and other complications.

6.2.2. Select a configuration to boot

The FIT typically contains more than one configuration. It is common to use a separate configuration for each supported model. The configuration contains a compatible stringlist which indicates which models the configuration is compatible with.

The bootloader itself typically has a compatible stringlist, indicating the model that it is running on. For U-Boot this is in the root node of the devicetree used by U-Boot, typically exactly the same devicetree as is used by Linux for that model. For other bootloaders, the stringlist may be hard-coded, or obtained by some other means.

The bootloader should loop through each configuration to find the best match to its own compatible string. The best match is the configuration which matches earliest string in the bootloader’s compatible stringlist.

For example, imagine the bootloader has compatible = "foo,bar", "bim,bam" and the FIT has two configurations:

config-1 {
    compatible = "foo,bar";
    fdt = "fdt-1";
    ...
};
config-2 {
    compatible = "bim,bam", "baz,biz";
    fdt = "fdt-2";
    ...
};

Here, the bootloader chooses config-1 since it is a better match. The first string in the bootloader’s compatible list, "foo,bar", matches a compatible string in the root of fdt1. Although "bim,bam" in fdt2 matches the second string, this isn’t as good a match as fdt1.

In U-Boot this algorithm is handled by fit_conf_find_compat() and enabled by the CONFIG_FIT_BEST_MATCH option.

Sometime models have multiple PCB revisions or different minor variants, often referred to as SKUs. For this reason, bootloaders may want to select configurations in a finer-grained way. In this case, rather than using the compatible stringlist in its devicetree, if any, it constructs a single string using the base name along with any available suffixes, each beginning with a hyphen. The best match algorithm is then run using that string.

The following compatible-string suffixes may be used to this end. They must be provided in this order (<n> is an integer >= 0):

-rev<n>

Board revision number, typically referring to a revision of the PCB to fix a problem or adjust component selection. The intention is that the board is the same design, just with some minor fixes or improvements. The first revision is typically rev0.

-sku<n>

Board variant, called a SKU (Stock-Keeping Unit) which is a unique code that identifies a model variant. This may encode differences in the display, WiFi and the like, but where the same PCB design (and revision) is used. The base SKU is typically sku0.

Examples:

compatible = "google,kevin-rev15";
compatible = "google,kevin-rev15-sku2";

When matching, the bootloader should build the most specific string it can using any available revision / SKU information, then try to match that. If the most specific string fails (e.g. "google,kevin-rev15-sku2"), it should fall back to just "google,kevin-rev15" and then "google,kevin-sku2". If nothing matches, then it should try without any additions, i.e. "google,kevin".

This multi-stage process uses the same ‘best match’ approach as above. Each attempt finds the best match given the compatible string being searched. Where a stage does not find any match, the next stage begins. As soon as a match is found, searching stops, using the best match found in the stage.

Other suffixes may be added in future.

6.2.3. Boot menu

In some cases it may desirable to show a menu of boot options and wait for the user to select one. In this case the OS Information node provides information which can be presented to the user to aid this choice. The logos property provides logos which can be shown in the case of a graphical menu.

The OS Information can also be useful for a fully automated boot, such as to select a particular version of the OS.

The bootloader must support at least logos in BMP format, if it supports a graphical display.

Logos should be selected based on the following criteria:

  1. The logo format must be supported by the bootloader

  2. SVG is preferred (if supported), followed by PNG (also if supported) and then BMP

  3. Larger logos are preferred, so long as they fit into the screen space available to the bootloader

  4. Color is preferred to grayscale, unless the bootloader knows that the display is not capable of showing color

  5. Logos with an alpha channel are preferred to those that lack one.

  6. Logos with a dark background are preferred when the background is dark. Logos with a light background are preferred when the background is light.

6.2.4. Load the images from the selected configuration

The configuration contains a number of images. One of these is the OS itself. Another is typically a devicetree blob, which provides information about available devices, useful for the OS as it boots and runs. Another image may be a ramdisk (or initrd) which provides an initial root disk for the OS to use, before it is able to access the real root disk.

The bootloader reads each image from the FIT and ‘loads’ it to the correct address. This address may be provided by the image’s load property (see load), but if not provided, the bootloader can load it to any suitable address. In some cases it may be possible to avoid loading the image and just refer to the image data within the FIT itself.

6.2.5. Fix up the devicetree

Many Operating Systems use devicetree blobs for configuration. As a result, most bootloaders provide a way to update the devicetree in the FIT before passing it to the OS. This may be used to pass command-line parameters to Linux, to select the console device to use, or to pass the ramdisk to the OS. It is also common to enable or disable certain devicetree nodes based on the hardware in use.

The fixups required depend on the OS and its expectations. The result is a devicetree slightly modified from the FIT version.

6.2.6. Jump to the OS

Once everything is ready, the bootloader jumps to the OS. At this point the FIT is no longer in use. The OS typically does not see the FIT itself and only cares about the images that were loaded. At this point, the FIT has served its purpose.

6.3. Firmware usage

As firmware has become more complex, with multiple binaries loaded at each phase of the boot, it has become common to use FIT to load firmware.

In this case, there is the concept of a boot phase (see phase), indicating which phase each image is for.

In this case the bootloader itself is likely split into multiple phases. For U-Boot, a common approach is for SPL (Secondary Program Loader) to load U-Boot proper, along with ATF and any other images required by U-Boot proper.

FIT processing for firmware images is no different from the approach described above, except that any image with a phase property is only loaded if the phase matches the phase being loaded. So, for example, SPL loads U-Boot proper so will only load images with a phase of “u-boot”. If TPL is in use (the phase before SPL), then TPL will only load images with a phase of “spl”. This allows all images to be provided in a single FIT, with each phase pulling out what is needed as the boot proceeds.

6.4. Security

FIT has robust security features. When enabled, each FIT configuration has one or more signatures. These protect the configuration and the images it refers to. The bootloader must check the signatures against a public key which it has stored elsewhere.

If any configuration fails its signature check, then it must be ignored. Images must each include a suitable hash node, so that images are actually protected against modification. Once each image is loaded, its hash must be computed and checked against the hash in the FIT.

For more information on FIT security, see U-Boot’s documentation. The mechanism is also widely covered in conference talks, some of which are listed at elinux.org.

7. References

[dtspec]

Devicetree Specification https://www.devicetree.org/specifications

[VBE]

Verified Boot for Embedded (VBE) https://docs.u-boot.org/en/latest/develop/vbe.html

[windowsbmp]

Windows Bitmap file format https://en.wikipedia.org/wiki/BMP_file_format

[svg]

Scalable Vector Graphics https://www.w3.org/TR/SVG11/

[osrelease]

os-release - Operating system identification https://www.freedesktop.org/software/systemd/man/latest/os-release.html

[icontheme]

Icon Theme Specification https://standards.freedesktop.org/icon-theme-spec/latest