FIT images don't work without having to explicitly specify physical
load addresses. Digging into that it looks like a flaw in
bootm_load_os().
It duplicates images->os for convenience. However, the code handling
"kernel_noload" images then updates the load address in the copy with
the value lmb_alloc_mem() returned. Later there's another call to
lmb_alloc_mem() that uses the old value. This leads to havoc due
to subsequent calls of lmb_alloc_mem() picking too low addresses.

The "fix" is to mark the local variable const to avoid accidental
assignments. This works but IMO the logic is still flawed somehow as
this leads to overlapping lmb reservations. I guess the fixed
reservation should only be done when the noload path wasn't hit.

Without the change:
+ bootm 0x40200000#qemu-arm 0x40200000#qemu-arm 0x40000000
   Using 'qemu-arm' configuration
   Verifying Hash Integrity ... OK
   Trying 'kernel' kernel subimage
     Description:  Linux kernel
     Created:      2026-02-24  14:10:09 UTC
     Type:         Kernel Image (no loading done)
     Compression:  gzip compressed
     Data Start:   0x402000b8
     Data Size:    12227440 Bytes = 11.7 MiB
     Hash algo:    sha256
     Hash value:   7ea661fdecdd1127edd419cfbf8bff52e2d5ac55c...
   Verifying Hash Integrity ... sha256+ OK
   Using 'qemu-arm' configuration
   Verifying Hash Integrity ... OK
   Trying 'ramdisk' ramdisk subimage
     Description:  Initial ramdisk
     Created:      2026-02-24  14:10:09 UTC
     Type:         RAMDisk Image
     Compression:  uncompressed
     Data Start:   0x40da9528
     Data Size:    1067114 Bytes = 1 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    sha256
     Hash value:   2a711dcb5f58615187645ccec615c67eddcfbb3138...
   Verifying Hash Integrity ... sha256+ OK
   Booting using the fdt blob at 0x40000000
Working FDT set to 40000000
   Uncompressing Kernel Image (no loading done) to 13a400000
   Loading Ramdisk to 400fb000, end 401ff86a ... OK
device tree - allocation error
FDT creation failed!
resetting ...
Bloblist at 0 not found (err=-2)
alloc space exhausted ptr 400 limit 0
Bloblist at 0 not found (err=-2)
[reset]

After:
+ bootm 0x40200000#qemu-arm 0x40200000#qemu-arm 0x40000000
   Using 'qemu-arm' configuration
   Verifying Hash Integrity ... OK
   Trying 'kernel' kernel subimage
     Description:  Linux kernel
     Created:      2026-02-24  14:10:09 UTC
     Type:         Kernel Image (no loading done)
     Compression:  gzip compressed
     Data Start:   0x402000b8
     Data Size:    12227440 Bytes = 11.7 MiB
     Hash algo:    sha256
     Hash value:   7ea661fdecdd1127edd419cfbf8bff52e2d5ac55ce...
   Verifying Hash Integrity ... sha256+ OK
   Using 'qemu-arm' configuration
   Verifying Hash Integrity ... OK
   Trying 'ramdisk' ramdisk subimage
     Description:  Initial ramdisk
     Created:      2026-02-24  14:10:09 UTC
     Type:         RAMDisk Image
     Compression:  uncompressed
     Data Start:   0x40da9528
     Data Size:    1067114 Bytes = 1 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: unavailable
     Entry Point:  unavailable
     Hash algo:    sha256
     Hash value:   2a711dcb5f58615187645ccec615c67eddcfbb3138...
   Verifying Hash Integrity ... sha256+ OK
   Booting using the fdt blob at 0x40000000
Working FDT set to 40000000
   Uncompressing Kernel Image (no loading done) to 13a400000
   Loading Ramdisk to 13a2fb000, end 13a3ff86a ... OK
   Loading Device Tree to 000000013a1f8000, end 000000013a2fafff ... OK
Working FDT set to 13a1f8000

Starting kernel ...

Signed-off-by: Ludwig Nussel <[email protected]>
---
 boot/bootm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/boot/bootm.c b/boot/bootm.c
index 4bdca22ea8c..280efb26e90 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -602,7 +602,7 @@ static int handle_decomp_error(int comp_type, size_t 
uncomp_size,
 #ifndef USE_HOSTCC
 static int bootm_load_os(struct bootm_headers *images, int boot_progress)
 {
-       struct image_info os = images->os;
+       const struct image_info os = images->os;
        ulong load = os.load;
        ulong load_end;
        ulong blob_start = os.start;
@@ -631,7 +631,7 @@ static int bootm_load_os(struct bootm_headers *images, int 
boot_progress)
                        return 1;
 
                load = (ulong)addr;
-               os.load = (ulong)addr;
+               images->os.load = (ulong)addr;
                images->ep = (ulong)addr;
                debug("Allocated %lx bytes at %lx for kernel (size %lx) 
decompression\n",
                      req_size, load, image_len);
-- 
2.43.0

Reply via email to