FIT Images: The Ideal Fit for Embedded Booting

As we all know, binaries are the final executable form of software after compilation. They are essential for:

  • Booting an operating system

  • Firmware updates

  • Application execution

  • Device configuration.

Without a proper storage and retrieval system, managing these binaries becomes complex and error-prone.

This article introduces the Flattened Image Tree (FIT) for multi-component files, which is a de facto standard used in Linux kernel booting in ARM-based systems.

Storage Methods for Binaries

There are multiple ways to store binaries depending on the use case:

  • Individual Binary Files

    • Each binary is stored separately in a filesystem.

    • Simple but can lead to dependency mismatches and manual coordination issues.

  • Archive Formats (TAR, ZIP, CPIO, SquashFS)

    • Binaries are compressed and packed together.

    • Useful for distribution but requires extraction before usage.

  • Partitioned Storage (Raw Flash Partitions, ext4, UBI)

    • Binaries are stored in dedicated partitions of storage media.

    • Efficient for structured systems but lacks flexibility for modular updates.

The Need for Structural Storage

As systems became more complex, new challenges emerged:

  • Managing multiple files separately increases complexity.

  • Ensuring integrity and compatibility between components is difficult.

  • Updating individual binaries requires careful coordination.

For example, embedded systems initially relied on separate binary components for booting. Typically, a kernel image (uImage), a device tree blob (DTB), and an optional initramfs were stored separately, requiring careful coordination during the boot process. This approach had limitations, such as complexity of managing multiple files, verifying integrity, and ensuring compatibility between components.

To address these challenges, FIT images (Flattened Image Tree) were introduced.

Why Use FIT Images?

FIT provides a structured way to package multiple binary components, such as kernel images, device trees, and ramdisks, into a single file. This simplifies booting and is widely used in embedded systems.

Creating a Basic FIT Image

In the following steps, we create a FIT image using text files instead of actual binary files. This approach simplifies the process and helps in understanding the FIT image structure before dealing with real kernel images or firmware binaries.

To create a FIT image, an Image Tree Source (.its) file is required. This file defines the structure and contents of the FIT image. The its file also follows same format as the Device Tree Source (DTS).Once the .its file is ready, the mkimage tool can be used to generate a FIT image (.itb).

Two placeholder files (file1 for the kernel image and file2 for the DTB) are created for demonstration.

user@linux:[fit-image]$ cat file1
Kernel Image
user@linux:[fit-image]$ cat file2
Device Tree Blob (DTB)
user@linux:[fit-image]$

Below is the .its file that specifies the components of the FIT image and includes the necessary binaries.

/dts-v1/;

/ {
        description = "Fit image version 1";
        images {
                file1 {
                        data = /incbin/("file1");
                } ;

                file2 {
                        data = /incbin/("file2");
                } ;
        } ;
} ;

Understanding the DTS Structure

Element Description

/dts-v1/;

Specifies that this is a Device Tree Source (DTS) version 1 file.

/ (Root Node)

Represents the root of the device tree structure.

description

Provides a brief description of the FIT image.

images

Defines the binary components included in the FIT image.

/incbin/("file1")

Embeds the contents of file1 directly into the FIT image.

/incbin/("file2")

Similarly, embeds the contents of file2 into the FIT image.

Now the .its file is ready, the mkimage tool is used to generate the FIT image.

user@linux:[fit-image]$ mkimage -f v1.its v1.itb
FIT description: Fit image version 1
Created:         Sun Mar 23 11:44:41 2025
 Image 0 (file1)
  Description:  unavailable
  Created:      Sun Mar 23 11:44:41 2025
  Type:         Unknown Image
  Compression:  Unknown Compression
  Data Size:    13 Bytes = 0.01 KiB = 0.00 MiB
 Image 1 (file2)
  Description:  unavailable
  Created:      Sun Mar 23 11:44:41 2025
  Type:         Unknown Image
  Compression:  Unknown Compression
  Data Size:    23 Bytes = 0.02 KiB = 0.00 MiB
user@linux:[fit-image]$

Once a FIT image (.itb file) is created, you may need to inspect its contents, especially if you only have the image file without the original source.

Inspecting a FIT Image

Several tools can help extract information about the structure and data stored within the FIT image.

The dumpimage tool lists the contents of a FIT image, showing its components and their sizes:

user@linux:[fit-image]$ dumpimage -l v1.itb
FIT description: Fit image version 1
Created:         Sun Mar 23 11:44:41 2025
 Image 0 (file1)
  Description:  unavailable
  Created:      Sun Mar 23 11:44:41 2025
  Type:         Unknown Image
  Compression:  Unknown Compression
  Data Size:    13 Bytes = 0.01 KiB = 0.00 MiB
 Image 1 (file2)
  Description:  unavailable
  Created:      Sun Mar 23 11:44:41 2025
  Type:         Unknown Image
  Compression:  Unknown Compression
  Data Size:    23 Bytes = 0.02 KiB = 0.00 MiB
user@linux:[fit-image]$

The dumpimage -p tool allows extracting data from a specific node inside the FIT image:

user@linux:[fit-image]$ dumpimage -T flat_dt -p 0 -o extracted1 v1.itb
Extracted:
 Image 0 (file1)
  Description:  unavailable
  Created:      Sun Mar 23 11:44:41 2025
  Type:         Unknown Image
  Compression:  Unknown Compression
  Data Size:    13 Bytes = 0.01 KiB = 0.00 MiB
user@linux:[fit-image]$ cat extracted1
Kernel Image
user@linux:[fit-image]$

The fdtdump tool provides a detailed look into the internal structure of the FIT image:

user@linux:[fit-image]$ fdtdump -s v1.itb

**** fdtdump is a low-level debugging tool, not meant for general use.
**** If you want to decompile a dtb, you probably want
****     dtc -I dtb -O dts <filename>

v1.itb: found fdt at offset 0
/dts-v1/;
// magic:               0xd00dfeed
// totalsize:           0x4e9 (1257)
// off_dt_struct:       0x38
// off_dt_strings:      0xe8
// off_mem_rsvmap:      0x28
// version:             17
// last_comp_version:   16
// boot_cpuid_phys:     0x0
// size_dt_strings:     0x1b
// size_dt_struct:      0xb0

/ {
    timestamp = <0x67dfa6d1>;
    description = "Fit image version 1";
    images {
        file1 {
            data = [4b 65 72 6e 65 6c 20 49 6d 61 67 65 0a];
        };
        file2 {
            data = [44 65 76 69 63 65 20 54 72 65 65 20 42 6c 6f 62 20 28 44 54 42 29 0a];
        };
    };
};
user@linux:[fit-image]$

The fdtget tool extracts specific elements from the FIT image. The -l option lists available nodes:

user@linux:[fit-image]$ fdtget -l v1.itb /
images
user@linux:[fit-image]$ fdtget -l v1.itb /images
file1
file2
user@linux:[fit-image]$

Conclusion

FIT image format is a versatile and powerful format which supports various features like multiple configurations for extractions, signing the images and verification of the contents. The introduction of FIT in this article leaves you with options to play around with FIT for various purposes like booting the kernel and sysupgrade images for firmware upgrades, etc.