How to use U-boot with FIT image to load overlays

Last modified by Microchip on 2025/02/28 14:17

How it works

Using FIT with overlays

Since U-boot 2018.07, released with linux4sam_6.0, we have the feature of adding Device Tree overlays to the base Device Tree at boot time, from U-boot. To achieve this, we use a FIT image, which embeds the Kernel + Device Tree blobs in a single file.

Device Tree Overlays

Device Tree Overlays are available in our repository at Github. Compiling the Device Tree overlays with the corresponding kernel zImage results in a FIT image. The Makefile will do that for you.

Loading FIT image with U-boot

u-boot_load_fit The FIT image is a placeholder that has the zImage and the base Device Tree, plus additional overlays that can be selected at boot time.

The following steps are required to boot the FIT Image from U-boot:

  • Load the FIT image like you would normally load the uImage or zImage.
  • There is no need to load additional Device Tree Blob, the FIT image includes it
  • When booting the FIT image, specify the FIT configuration to use. Several configurations can be appended to the basic configuration, which we name 'kernel_dtb'

warning U-boot 2021.04 and newer cannot load FIT images created before linux4sam_2021.04. This is due to an incompatible change in the FIT image configuration check in U-boot.

Example:

bootm 0x24000000#kernel_dtb

This will load the FIT image from address 0x24000000 in memory and then run the configuration named 'kernel_dtb'. This configuration includes the kernel plus the base Device Tree Blob built with the kernel.

To load additional FIT configurations, just append another configuration to the command.

Example to load the image sensor controller Device Tree overlay + sensor omnivision 0v7740:

bootm 0x24000000#kernel_dtb#isc#ov7740

u-boot_load_fit u-boot_fit

Example

Further more, if we inspect the U-boot environment (just an example)

warning warning warning The default U-boot environment adds loading commands for the screens TM7000, TM7000B, TM5000 and TM4300. warning warning warning </br> warning warning warning If you have a different screen you need to similarly edit this environment and take your specific screen into consideration. warning warning warning

=> print
at91_pda_detect=run pda4300test; run pda7000test; run pda7000btest; run pda5000test; run hdmi_test;
at91_prepare_bootargs=test -n $display_var && setenv bootargs ${bootargs} ${at91_video_bootargs}
at91_prepare_overlays_config=test -n $display_var && setenv at91_overlays_config '#'${display_var}
at91_prepare_video_bootargs=test -n $display_var && setenv at91_video_bootargs video=${video_mode}
at91_set_display=test -n $pda && setenv display $pda
baudrate=115200
bootargs=console=ttyS0,115200 root=/dev/mmcblk0p1 rw rootfstype=ext4 rootwait atmel.pm_modes=standby,ulp1
bootcmd=run at91_set_display; run at91_pda_detect; run at91_prepare_video_bootargs; run at91_prepare_bootargs; run at91_prepare_overlays_config; run bootcmd_boot;
bootcmd_boot=ext4load mmc 0 0x24000000 boot/sama5d2_xplained.itb; bootm 0x24000000#kernel_dtb${at91_overlays_config}
bootdelay=1
ethaddr=fc:c2:3d:0d:1f:4b
fdtcontroladdr=3fb773c8
hdmi_test=test -n $display && test $display = hdmi && setenv display_var 'hdmi' && setenv video_mode ${video_mode_hdmi}
pda4300test=test -n $display && test $display = 4300 && setenv display_var 'pda4' && setenv video_mode ${video_mode_pda4}
pda5000test=test -n $display && test $display = 5000 && setenv display_var 'pda5' && setenv video_mode ${video_mode_pda5}
pda7000btest=test -n $display && test $display = 7000B && setenv display_var 'pda7b' && setenv video_mode ${video_mode_pda7b}
pda7000test=test -n $display && test $display = 7000 && setenv display_var 'pda7' && setenv video_mode ${video_mode_pda7}
stderr=serial@f8020000
stdin=serial@f8020000
stdout=serial@f8020000
video_mode_hdmi=HDMI-A-1:1152x768-16
video_mode_pda4=Unknown-1:480x272-16
video_mode_pda5=Unknown-1:800x480-16
video_mode_pda7=Unknown-1:800x480-16
video_mode_pda7b=Unknown-1:800x480-16 

We can see that the variable 'bootcmd_boot' loads the FIT image from SD-Card, and then it boots it with the 'kernel_dtb' configuration, plus an additional configuration for a specific PDA if it's detected at boot-time

U-boot env explained

video_mode_hdmi=HDMI-A-1:1152x768-16
video_mode_pda4=Unknown-1:480x272-16
video_mode_pda5=Unknown-1:800x480-16
video_mode_pda7=Unknown-1:800x480-16
video_mode_pda7b=Unknown-1:800x480-16 

These are hardcoded variables that are written by default in the u-boot env that comes with the release.

at91_set_display=test -n $pda && setenv display $pda

This command will test to see if U-boot detected any screen and set the 'display' variable accordingly.

at91_pda_detect=run pda4300test; run pda7000test; run pda7000btest; run pda5000test; run hdmi_test;

This command will run a test on the display variable for each possible screen that we have.

The tests are detailed below:

hdmi_test=test -n $display && test $display = hdmi && setenv display_var 'hdmi' && setenv video_mode ${video_mode_hdmi}
pda4300test=test -n $display && test $display = 4300 && setenv display_var 'pda4' && setenv video_mode ${video_mode_pda4}
pda5000test=test -n $display && test $display = 5000 && setenv display_var 'pda5' && setenv video_mode ${video_mode_pda5}
pda7000btest=test -n $display && test $display = 7000B && setenv display_var 'pda7b' && setenv video_mode ${video_mode_pda7b}
pda7000test=test -n $display && test $display = 7000 && setenv display_var 'pda7' && setenv video_mode ${video_mode_pda7}

These tests check for the 'display' variable and configure the video mode correctly and the 'display_var' . This display_var is the actual name of the screen configuration for the overlays, that we pass to the overlay configuration.

at91_prepare_video_bootargs=test -n $display_var && setenv at91_video_bootargs video=${video_mode}

This command will prepare the bootargs that we need to pass to the kernel in case we are using video.

at91_prepare_bootargs=test -n $display_var && setenv bootargs ${bootargs} ${at91_video_bootargs}

This command will actually append the video bootargs to our default bootargs if the display is detected. In case we do not have any display, bootargs is not modified.

at91_prepare_overlays_config=test -n $display_var && setenv at91_overlays_config '#'${display_var}

This command will configure an overlay name , with the appended '#' that we just need to append to the bootm FIT image booting sequence.

bootcmd=run at91_set_display; run at91_pda_detect; run at91_prepare_video_bootargs; run at91_prepare_bootargs; run at91_prepare_overlays_config; run bootcmd_boot;

The new bootcmd will first run all the display tests , in order, and then run a new bootcommand, bootcmd_boot

bootcmd_boot=ext4load mmc 0 0x24000000 boot/sama5d2_xplained.itb; bootm 0x24000000#kernel_dtb${at91_overlays_config}

This is the actual boot command, that will load the FIT image and add the configured overlays in the FIT boot sequence.

Extract parts of the FIT image with U-boot

With the use of the imxtract command in U-boot, we can extract parts of the FIT image into the memory and use them.

The imxtract command uses the syntax:

imxtract <FIT addr> <FIT subimage> <address in DRAM>

</br> It will extract from the FIT image at FIT addr the subimage named FIT subimage and place it into the DRAM at address in DRAM </br> To obtain information about which subimages are in a FIT image, use the _iminfo_ command .</br> Here is an example:</br>

  • Step 1: load the FIT from a hardware media, in this example mmc:
=> fatload mmc 1:1 0x24000000 sama5d2_xplained.itb;
4430768 bytes read in 305 ms (13.9 MiB/s)

</br>

  • Step 2: Check possible images in this FIT we downloaded:
=> iminfo 0x24000000

## Checking Image at 24000000 ...
  FIT image found
  FIT description: Microchip SAMA5D2 Xplained FIT Image
   Image 0 (kernel)
    Description:  Linux4SAM Linux kernel
    Type:         Kernel Image
    Compression:  uncompressed
    Data Start:   0x240000e0
    Data Size:    4360432 Bytes = 4.2 MiB
    Architecture: ARM
    OS:           Linux
    Load Address: 0x22000000
    Entry Point:  0x22000000
    Hash algo:    crc32
    Hash value:   ed62149a
    Hash algo:    sha1
    Hash value:   1cf2de3d85ee120240c0f2cb955327c607846a2c
   Image 1 (base_fdt)
    Description:  Flattened Device Tree blob
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x24428afc
    Data Size:    40797 Bytes = 39.8 KiB
    Architecture: ARM
    Load Address: 0x23000000
    Hash algo:    crc32
    Hash value:   86179ff1
    Hash algo:    sha1
    Hash value:   8a64ec5fc53f0a318c630387ed55e57f537b0061
   Image 2 (fdt_isc)
    Description:  Device Tree blob ISC overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x24432b64
    Data Size:    1074 Bytes = 1 KiB
    Architecture: ARM
    Load Address: 0x23100000
    Hash algo:    crc32
    Hash value:   ea22f84e
    Hash algo:    sha1
    Hash value:   6feab4a58949dd88593c8aba3ad6d73d8124403f
   Image 3 (fdt_ov7670)
    Description:  Device Tree blob Ov7670 overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x244330a4
    Data Size:    2045 Bytes = 2 KiB
    Architecture: ARM
    Load Address: 0x23110000
    Hash algo:    crc32
    Hash value:   44c22b8b
    Hash algo:    sha1
    Hash value:   8e319fc07d00806b866bfe60b9b87849813ecefd
   Image 4 (fdt_ov7740)
    Description:  Device Tree blob OV7740 overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x244339b0
    Data Size:    2045 Bytes = 2 KiB
    Architecture: ARM
    Load Address: 0x23120000
    Hash algo:    crc32
    Hash value:   cc72f933
    Hash algo:    sha1
    Hash value:   3c44d90fe915d0e1fb63dfc50038fb0fc861b8a5
   Image 5 (fdt_pda4)
    Description:  Device Tree blob pda4300 overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x244342c0
    Data Size:    4499 Bytes = 4.4 KiB
    Architecture: ARM
    Load Address: 0x23130000
    Hash algo:    crc32
    Hash value:   c9b532e8
    Hash algo:    sha1
    Hash value:   a7f75ea4a91884840d40b379e7b843a95b9b9da4
   Image 6 (fdt_pda5)
    Description:  Device Tree blob pda5000 overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x24435564
    Data Size:    4499 Bytes = 4.4 KiB
    Architecture: ARM
    Load Address: 0x23140000
    Hash algo:    crc32
    Hash value:   591d531b
    Hash algo:    sha1
    Hash value:   f9f3c25e8591f603492451b4e4eb369eba818ab2
   Image 7 (fdt_pda7)
    Description:  Device Tree blob pda7000 overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x24436808
    Data Size:    4507 Bytes = 4.4 KiB
    Architecture: ARM
    Load Address: 0x23150000
    Hash algo:    crc32
    Hash value:   3fc0c1ec
    Hash algo:    sha1
    Hash value:   d202bd4cc83aef48b33fae2a1b104c5bc597956c
   Image 8 (fdt_pda7b)
    Description:  Device Tree blob pda7000b overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x24437ab4
    Data Size:    4507 Bytes = 4.4 KiB
    Architecture: ARM
    Load Address: 0x23160000
    Hash algo:    crc32
    Hash value:   a27df839
    Hash algo:    sha1
    Hash value:   94f77b4afd7718cd309be34147c49753abf53375
   Image 9 (fdt_i2s0_proto)
    Description:  Device Tree blob PROTO Audio board overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x24438d6c
    Data Size:    1066 Bytes = 1 KiB
    Architecture: ARM
    Load Address: 0x23170000
    Hash algo:    crc32
    Hash value:   38a511f6
    Hash algo:    sha1
    Hash value:   74d5c3996811a9307097969d8fe3c5e63b9973a0
   Image 10 (fdt_qspi)
    Description:  Device Tree blob QSPI overlay
    Type:         Flat Device Tree
    Compression:  uncompressed
    Data Start:   0x244392a4
    Data Size:    461 Bytes = 461 Bytes
    Architecture: ARM
    Load Address: 0x23180000
    Hash algo:    crc32
    Hash value:   df13d1c0
    Hash algo:    sha1
    Hash value:   0abdc429d44d5f0fc7f97bea47e5c58308e8c5b1
   Default Configuration: 'kernel_dtb'
   Configuration 0 (kernel_dtb)
    Description:  Linux kernel and base FDT blob for SAMA5D2_XPLAINED board
    Kernel:       kernel
    FDT:          base_fdt
   Configuration 1 (base_dtb)
    Description:  Base FDT blob for SAMA5D2_XPLAINED board
    Kernel:       unavailable
    FDT:          base_fdt
   Configuration 2 (isc)
    Description:  FDT overlay blob for isc
    Kernel:       unavailable
    FDT:          fdt_isc
   Configuration 3 (ov7670)
    Description:  FDT overlay blob for ov7670 sensor
    Kernel:       unavailable
    FDT:          fdt_ov7670
   Configuration 4 (ov7740)
    Description:  FDT overlay blob for ov7740 sensor
    Kernel:       unavailable
    FDT:          fdt_ov7740
   Configuration 5 (pda4)
    Description:  FDT overlay blob for PDA TM4300 screen
    Kernel:       unavailable
    FDT:          fdt_pda4
   Configuration 6 (pda5)
    Description:  FDT overlay blob for PDA TM5000 screen
    Kernel:       unavailable
    FDT:          fdt_pda5
   Configuration 7 (pda7)
    Description:  FDT overlay blob for PDA TM7000 screen
    Kernel:       unavailable
    FDT:          fdt_pda7
   Configuration 8 (pda7b)
    Description:  FDT overlay blob for PDA TM7000B screen
    Kernel:       unavailable
    FDT:          fdt_pda7b
   Configuration 9 (i2s0_proto)
    Description:  FDT overlay blob for I2S0 PROTO audio board
    Kernel:       unavailable
    FDT:          fdt_i2s0_proto
   Configuration 10 (qspi)
    Description:  FDT overlay blob for QSPI memory
    Kernel:       unavailable
    FDT:          fdt_qspi
## Checking hash(es) for FIT Image at 24000000 ...
  Hash(es) for Image 0 (kernel): crc32+ sha1+
  Hash(es) for Image 1 (base_fdt): crc32+ sha1+
  Hash(es) for Image 2 (fdt_isc): crc32+ sha1+
  Hash(es) for Image 3 (fdt_ov7670): crc32+ sha1+
  Hash(es) for Image 4 (fdt_ov7740): crc32+ sha1+
  Hash(es) for Image 5 (fdt_pda4): crc32+ sha1+
  Hash(es) for Image 6 (fdt_pda5): crc32+ sha1+
  Hash(es) for Image 7 (fdt_pda7): crc32+ sha1+
  Hash(es) for Image 8 (fdt_pda7b): crc32+ sha1+
  Hash(es) for Image 9 (fdt_i2s0_proto): crc32+ sha1+
  Hash(es) for Image 10 (fdt_qspi): crc32+ sha1+

</br>

  • Step 3: extract the kernel image, for example:
=> imxtract 0x24000000 kernel 0x21000000
## Copying 'kernel' subimage from FIT image at 24000000 ...
crc32+ sha1+    Loading part 0 ... OK

</br>

  • Step 4: extract a base device tree , for example:
=> imxtract 0x24000000 base_fdt 0x22000000
## Copying 'base_fdt' subimage from FIT image at 24000000 ...
crc32+ sha1+    Loading part 186 ... OK

</br>

  • Step 5: Boot the kernel with this device tree, for example:
=> bootz 0x21000000 - 0x22000000
## Flattened Device Tree blob at 22000000
  Booting using the fdt blob at 0x22000000
  Loading Device Tree to 3fb48000, end 3fb54f5c ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.19.0+ (eugen@eh-station) (gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05)) #6 Thu Nov 1 17:35:45 EET 2018
CPU: ARMv7 Processor [410fc051] revision 1 (ARMv7), cr=10c53c7d
....

Related Topics

Boards

Sama5d29Curiosity
Sam9x75Curiosity
Sam9x60Curiosity
Sama7g5-ek
Sama5d2icp
Sam9x60EK
Sama5d27WLSom1EK
Sama5d27Som1EK
Sama5d2PtcEK
Sama5d2Xplained
Sama5d3Xplained
Sama5d4Xplained

Components

U-Boot
Kernel

Summary

How to use U-boot with FIT image to load overlays