Using FIT image and Device Tree Overlays

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

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, important 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

Example

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

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

=> 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>

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
To obtain information about which subimages are in a FIT image, use the iminfo command .
Here is an example:
  • 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)

  • 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+

  • 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

  • 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

  • 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
....
r19 - 24 Oct 2024 - 15:38:29 - NicolasFerre
 
Linux & Open Source for AT91 Microchip Microprocessors

Copyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.

Linux® is the registered trademark of Linus Torvalds in the U.S. and other countries.

Microchip and others, are registered trademarks or trademarks of Microchip Technology Inc. and its subsidiaries. This site is powered by the TWiki collaboration platform

Arm® and others are registered trademarks or trademarks of Arm Limited (or its affiliates). Other terms and product names may be trademarks of others.

Ideas, requests, contributions ? Connect to LinksToCommunities page.

Syndicate this siteRSS ATOM