[PATCH RFC v2] image: apply FDTOs on FDT image node without a load property

Quentin Schulz quentin.schulz at cherry.de
Tue Jan 21 09:25:33 CET 2025


Hi Marek,

On 1/21/25 12:55 AM, Marek Vasut wrote:
> On 1/16/25 12:46 PM, Quentin Schulz wrote:
>> From: Quentin Schulz <quentin.schulz at cherry.de>
>>
>> A FIT image which is NOT using -E when created by mkimage - that is with
>> image data within the FIT - will fail to apply FDTO if the base FDT
>> image node does not specify a load property (which points to an address
>> in DRAM). This is because we check that the FDT address we want to apply
>> overlay to (i.e. modify and likely increase in size) is not inside the
>> FIT and give up otherwise. This is assumed necessary because we may then
>> overwrite other data when applying in-place.
>>
>> However, we can do better than giving up: relocating the FDT in another
>> place in DRAM where it's safe to increase its size and apply FDTOs.
>>
>> While at it, do not discriminate anymore on whether the data is within
>> the FIT data address space - that is FIT images created with mkimage -E
>> - as that still may be susceptible to unintended data overwrites as
>> mkimage -E simply concatenates all blobs after the FIT. If the FDT blob
>> isn't the last, it'll result in overwriting later blobs when resizing.
>>
>> The side effect is that the load property in the FIT is only
>> temporarily used to load the FDT but then relocated right before we
>> start applying overlays.
>>
>> Suggested-by: Marek Vasut <marex at denx.de>
>> Signed-off-by: Quentin Schulz <quentin.schulz at cherry.de>
>> ---
>> This actually forces the base FDT to always be relocated whenever FDTO
>> are expected to be applied, regardless of the presence of the load
>> property in the base FDT image node.
>>
>> Tested with extlinux with:
>> - conf node with multiple fdt entries (scenario A)
>> - conf node with base fdt + conf node with fdto (stored in fdt property)
>>    (scenario B)
>> - conf node with multiple fdt entries with base fdt with load property
>>    (scenario C)
>> - conf node with base fdt + conf node with fdto (stored in fdt property)
>>    with base fdt with load property (scenario D)
>>
>> """fit.its
>> /dts-v1/;
>>
>> / {
>>     description = "Kernel fitImage for Jaguar";
>>     #address-cells = <1>;
>>
>>     images {
>>         kernel-1 {
>>             description = "Linux kernel";
>>             data = /incbin/("arch/arm64/boot/Image.gz");
>>             type = "kernel";
>>             arch = "arm64";
>>             os = "linux";
>>             compression = "gzip";
>>             load = <0x06000000>;
>>             entry = <0x06000000>;
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>         fdt-rk3588-jaguar.dtb {
>>             description = "Flattened Device Tree blob";
>>             data = /incbin/("arch/arm64/boot/dts/rockchip/rk3588- 
>> jaguar.dtb");
>>             type = "flat_dt";
>>             arch = "arm64";
>>             compression = "none";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>         fdt-rk3588-jaguar.dtb-load {
>>             description = "Flattened Device Tree blob";
>>             data = /incbin/("arch/arm64/boot/dts/rockchip/rk3588- 
>> jaguar.dtb");
>>             type = "flat_dt";
>>             arch = "arm64";
>>             compression = "none";
>>             load = <0x12000000>;
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>         fdt-rk3588-jaguar-pre-ict-tester.dtbo {
>>             description = "Flattened Device Tree blob";
>>             data = /incbin/("arch/arm64/boot/dts/rockchip/rk3588- 
>> jaguar-pre-ict-tester.dtbo");
>>             type = "flat_dt";
>>             arch = "arm64";
>>             compression = "none";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>     };
>>
>>     configurations {
>>         default = "conf-rk3588-jaguar.dtb";
>>         conf-rk3588-jaguar.dtb {
>>             description = "1 Linux kernel, FDT blob";
>>             kernel = "kernel-1";
>>             fdt = "fdt-rk3588-jaguar.dtb";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>
>>         conf-rk3588-jaguar.dtb-and-dtbo {
>>             description = "1 Linux kernel, FDT blob";
>>             kernel = "kernel-1";
>>             fdt = "fdt-rk3588-jaguar.dtb", "fdt-rk3588-jaguar-pre-ict- 
>> tester.dtbo";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>
>>         conf-rk3588-jaguar.dtb-load {
>>             description = "1 Linux kernel, FDT blob";
>>             kernel = "kernel-1";
>>             fdt = "fdt-rk3588-jaguar.dtb-load";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>
>>         conf-rk3588-jaguar.dtb-load-and-dtbo {
>>             description = "1 Linux kernel, FDT blob";
>>             kernel = "kernel-1";
>>             fdt = "fdt-rk3588-jaguar.dtb-load", "fdt-rk3588-jaguar- 
>> pre-ict-tester.dtbo";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>
>>         conf-rk3588-jaguar-pre-ict-tester.dtbo {
>>             description = "0 FDT blob";
>>
>>             fdt = "fdt-rk3588-jaguar-pre-ict-tester.dtbo";
>>
>>             hash-1 {
>>                 algo = "sha256";
>>             };
>>         };
>>     };
>> };
>> """
>>
>> """extlinux.conf (scenario A)
>> LABEL rk3588-jaguar
>> LINUX /boot/fit#conf-rk3588-jaguar.dtb-and-dtbo
>> APPEND root=PARTLABEL=debos-rootfs rw rootwait net.ifnames=0
>> """
>>
>> Log:
>> """
>>
>>     Using 'conf-rk3588-jaguar.dtb-and-dtbo' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'kernel-1' kernel subimage
>>       Description:  Linux kernel
>>       Type:         Kernel Image
>>       Compression:  gzip compressed
>>       Data Start:   0x020000cc
>>       Data Size:    11862415 Bytes = 11.3 MiB
>>       Architecture: AArch64
>>       OS:           Linux
>>       Load Address: 0x06000000
>>       Entry Point:  0x06000000
>>       Hash algo:    sha256
>>       Hash value:   
>> 51a2b828aec49d9ede09a2de2cd05226def258dedcc8e4c4098fa2ba38fb9690
>>     Verifying Hash Integrity ... sha256+ OK
>>
>>     Using 'conf-rk3588-jaguar.dtb-and-dtbo' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'fdt-rk3588-jaguar.dtb' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02b50370
>>       Data Size:    168750 Bytes = 164.8 KiB
>>       Architecture: AArch64
>>       Hash algo:    sha256
>>       Hash value:   
>> 96213ce3930a5f926b27c90671ca779fc327e2e62c2135f7ed7d8b6dd659b973
>>     Verifying Hash Integrity ... sha256+ OK
>>     Loading Device Tree to 00000000ece9d000, end 00000000ecec9fff ... OK
>> Working FDT set to ece9d000
>>
>>     Trying 'fdt-rk3588-jaguar-pre-ict-tester.dtbo' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02ba2bb4
>>       Data Size:    2753 Bytes = 2.7 KiB
>>       Architecture: AArch64
>>       Hash algo:    sha256
>>       Hash value:   
>> e5eb1fe225d03b04e9bb27c04fe3278f294b48c6ab6757292c9650f6d3ce9f34
>>     Verifying Hash Integrity ... sha256+ OK
>>     Booting using the fdt blob at 0xece9d000
>> Working FDT set to ece9d000
>>     Uncompressing Kernel Image to 6000000
>>     Loading Device Tree to 00000000ece70000, end 00000000ece9c62d ... OK
>> Working FDT set to ece70000
>> """
>>
>> """extlinux.conf (scenario B)
>> LABEL rk3588-jaguar
>> LINUX /boot/fit#conf-rk3588-jaguar.dtb-load-and-dtbo
>> APPEND root=PARTLABEL=debos-rootfs rw rootwait net.ifnames=0
>> """
>>
>> Log:
>> """
>>
>>     Using 'conf-rk3588-jaguar.dtb-load-and-dtbo' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'kernel-1' kernel subimage
>>       Description:  Linux kernel
>>       Type:         Kernel Image
>>       Compression:  gzip compressed
>>       Data Start:   0x020000cc
>>       Data Size:    11862415 Bytes = 11.3 MiB
>>       Architecture: AArch64
>>       OS:           Linux
>>       Load Address: 0x06000000
>>       Entry Point:  0x06000000
>>       Hash algo:    sha256
>>       Hash value:   
>> 51a2b828aec49d9ede09a2de2cd05226def258dedcc8e4c4098fa2ba38fb9690
>>     Verifying Hash Integrity ... sha256+ OK
>>
>>     Using 'conf-rk3588-jaguar.dtb-load-and-dtbo' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'fdt-rk3588-jaguar.dtb-load' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02b79784
>>       Data Size:    168750 Bytes = 164.8 KiB
>>       Architecture: AArch64
>>       Load Address: 0x12000000
>>       Hash algo:    sha256
>>       Hash value:   
>> 96213ce3930a5f926b27c90671ca779fc327e2e62c2135f7ed7d8b6dd659b973
>>     Verifying Hash Integrity ... sha256+ OK
>>     Loading fdt from 0x02b79784 to 0x12000000
>>     Loading Device Tree to 00000000ece9d000, end 00000000ecec9fff ... OK
>> Working FDT set to ece9d000
>>
>>     Trying 'fdt-rk3588-jaguar-pre-ict-tester.dtbo' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02ba2bb4
>>       Data Size:    2753 Bytes = 2.7 KiB
>>       Architecture: AArch64
>>       Hash algo:    sha256
>>       Hash value:   
>> e5eb1fe225d03b04e9bb27c04fe3278f294b48c6ab6757292c9650f6d3ce9f34
>>     Verifying Hash Integrity ... sha256+ OK
>>     Booting using the fdt blob at 0xece9d000
>> Working FDT set to ece9d000
>>     Uncompressing Kernel Image to 6000000
>>     Loading Device Tree to 00000000ece70000, end 00000000ece9c62d ... OK
>> Working FDT set to ece70000
>> """
>>
>> """extlinux.conf (scenario C)
>> LABEL rk3588-jaguar
>> LINUX /boot/fit#conf-rk3588-jaguar.dtb#conf-rk3588-jaguar-pre-ict- 
>> tester.dtbo
>> APPEND root=PARTLABEL=debos-rootfs rw rootwait net.ifnames=0
>> """
>>
>> Log:
>> """
>>
>>     Using 'conf-rk3588-jaguar.dtb' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'kernel-1' kernel subimage
>>       Description:  Linux kernel
>>       Type:         Kernel Image
>>       Compression:  gzip compressed
>>       Data Start:   0x020000cc
>>       Data Size:    11862415 Bytes = 11.3 MiB
>>       Architecture: AArch64
>>       OS:           Linux
>>       Load Address: 0x06000000
>>       Entry Point:  0x06000000
>>       Hash algo:    sha256
>>       Hash value:   
>> 51a2b828aec49d9ede09a2de2cd05226def258dedcc8e4c4098fa2ba38fb9690
>>     Verifying Hash Integrity ... sha256+ OK
>>
>>     Using 'conf-rk3588-jaguar.dtb' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'fdt-rk3588-jaguar.dtb' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02b50370
>>       Data Size:    168750 Bytes = 164.8 KiB
>>       Architecture: AArch64
>>       Hash algo:    sha256
>>       Hash value:   
>> 96213ce3930a5f926b27c90671ca779fc327e2e62c2135f7ed7d8b6dd659b973
>>     Verifying Hash Integrity ... sha256+ OK
>>     Loading Device Tree to 00000000ece9d000, end 00000000ecec9fff ... OK
>> Working FDT set to ece9d000
>>
>>     Using 'conf-rk3588-jaguar-pre-ict-tester.dtbo' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'fdt-rk3588-jaguar-pre-ict-tester.dtbo' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02ba2bb4
>>       Data Size:    2753 Bytes = 2.7 KiB
>>       Architecture: AArch64
>>       Hash algo:    sha256
>>       Hash value:   
>> e5eb1fe225d03b04e9bb27c04fe3278f294b48c6ab6757292c9650f6d3ce9f34
>>     Verifying Hash Integrity ... sha256+ OK
>>     Booting using the fdt blob at 0xece9d000
>> Working FDT set to ece9d000
>>     Uncompressing Kernel Image to 6000000
>>     Loading Device Tree to 00000000ece70000, end 00000000ece9c62d ... OK
>> Working FDT set to ece70000
>> """
>>
>> """extlinux.conf (scenario D)
>> LABEL rk3588-jaguar
>> LINUX /boot/fit#conf-rk3588-jaguar.dtb-load#conf-rk3588-jaguar-pre- 
>> ict-tester.dtbo
>> APPEND root=PARTLABEL=debos-rootfs rw rootwait net.ifnames=0
>> """
>>
>> Log:
>> """
>>
>>     Using 'conf-rk3588-jaguar.dtb-load' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'kernel-1' kernel subimage
>>       Description:  Linux kernel
>>       Type:         Kernel Image
>>       Compression:  gzip compressed
>>       Data Start:   0x020000cc
>>       Data Size:    11862415 Bytes = 11.3 MiB
>>       Architecture: AArch64
>>       OS:           Linux
>>       Load Address: 0x06000000
>>       Entry Point:  0x06000000
>>       Hash algo:    sha256
>>       Hash value:   
>> 51a2b828aec49d9ede09a2de2cd05226def258dedcc8e4c4098fa2ba38fb9690
>>     Verifying Hash Integrity ... sha256+ OK
>>
>>     Using 'conf-rk3588-jaguar.dtb-load' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'fdt-rk3588-jaguar.dtb-load' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02b79784
>>       Data Size:    168750 Bytes = 164.8 KiB
>>       Architecture: AArch64
>>       Load Address: 0x12000000
>>       Hash algo:    sha256
>>       Hash value:   
>> 96213ce3930a5f926b27c90671ca779fc327e2e62c2135f7ed7d8b6dd659b973
>>     Verifying Hash Integrity ... sha256+ OK
>>     Loading fdt from 0x02b79784 to 0x12000000
>>     Loading Device Tree to 00000000ece9d000, end 00000000ecec9fff ... OK
>> Working FDT set to ece9d000
>>
>>     Using 'conf-rk3588-jaguar-pre-ict-tester.dtbo' configuration
>>     Verifying Hash Integrity ... OK
>>     Trying 'fdt-rk3588-jaguar-pre-ict-tester.dtbo' fdt subimage
>>       Description:  Flattened Device Tree blob
>>       Type:         Flat Device Tree
>>       Compression:  uncompressed
>>       Data Start:   0x02ba2bb4
>>       Data Size:    2753 Bytes = 2.7 KiB
>>       Architecture: AArch64
>>       Hash algo:    sha256
>>       Hash value:   
>> e5eb1fe225d03b04e9bb27c04fe3278f294b48c6ab6757292c9650f6d3ce9f34
>>     Verifying Hash Integrity ... sha256+ OK
>>     Booting using the fdt blob at 0xece9d000
>> Working FDT set to ece9d000
>>     Uncompressing Kernel Image to 6000000
>>     Loading Device Tree to 00000000ece70000, end 00000000ece9c62d ... OK
>> Working FDT set to ece70000
>> """
>>
>> Cc: Heiko Stuebner <heiko at sntech.de>
>> ---
>> Changes in v2:
>> - Indiscriminately relocate, regardless of location of FDT to be on the
>>    safe side wrt data overlap/overwrite,
>> - print return value of boot_relocate_fdt when it fails,
>> - Link to v1: https://eur02.safelinks.protection.outlook.com/? 
>> url=https%3A%2F%2Flore.kernel.org%2Fr%2F20241219-extlinux-relocate- 
>> dtb-when-dtbo-v1-1- 
>> fe5eeb8fd4f1%40cherry.de&data=05%7C02%7Cquentin.schulz%40cherry.de%7Cddabd8c9406e494742e008dd39af7af3%7C5e0e1b5221b54e7b83bb514ec460677e%7C0%7C0%7C638730148066938337%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=v44rSH1FkKZuW3vR%2FZjsRDMlzAEnDXtTwwJpg46Unrk%3D&reserved=0
>> ---
>>   boot/image-fit.c | 17 +++++++++--------
>>   1 file changed, 9 insertions(+), 8 deletions(-)
>>
>> diff --git a/boot/image-fit.c b/boot/image-fit.c
>> index 
>> db7fb61bca948e42a4136b9ceb263a53362ad3f8..f3df8e2393559596f5100ea54a7ede77407713ac 100644
>> --- a/boot/image-fit.c
>> +++ b/boot/image-fit.c
>> @@ -2348,10 +2348,10 @@ int boot_get_fdt_fit(struct bootm_headers 
>> *images, ulong addr,
>>       char *next_config = NULL;
>>       ulong load, len;
>>   #ifdef CONFIG_OF_LIBFDT_OVERLAY
>> -    ulong image_start, image_end;
>>       ulong ovload, ovlen, ovcopylen;
>>       const char *uconfig;
>>       const char *uname;
>> +    char *of_flat_tree;
> 
> Can this be void * instead ?
> 

The compiler seems happy with that. FWIW, map_sysmem() returns a void*, 
and boot_relocate_fdt() expects a char** and we anyway cast it to a 
ulong later.

The question I have is why? What does this bring? Maybe there's 
something I can learn here :)

Cheers,
Quentin


More information about the U-Boot mailing list