From e50ee1acd4a519cb0320d7227581b7a7841e8a47 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 4 Jun 2026 22:41:35 +0200 Subject: [PATCH 1/6] boot: fit: fix FIT verification in SPL Align the behavior of fit_image_verify() called in SPL to the one in full U-Boot. In particular, this function is called when both CONFIG_SPL_LOAD_FIT_FULL and CONFIG_SPL_FIT_SIGNATURE are set (which can happen e.g. in case of secure falcon boot). Reviewed-by: Simon Glass Signed-off-by: Francesco Valla --- boot/image-fit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boot/image-fit.c b/boot/image-fit.c index b0fcaf6e17f..6723a5e659f 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1439,7 +1439,7 @@ int fit_image_verify(const void *fit, int image_noffset) size_t size; char *err_msg = ""; - if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) { + if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && strchr(name, '@')) { /* * We don't support this since libfdt considers names with the * name root but different @ suffix to be equal From 2a70a7e2252ecf01057592bb163a11cd337bcc95 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 4 Jun 2026 22:41:36 +0200 Subject: [PATCH 2/6] spl: fit: fix loadables load under sandbox Align the fit_image_load() call done for the loadables to the ones for other artifatcs (firmware, kernel, fdt), calling virt_to_phys() on the pointer that contains the FIT location. This is needed to support the 'sandbox' environment. Signed-off-by: Francesco Valla --- common/spl/spl_fit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 46ebcabe56a..229eda0582f 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -1024,7 +1024,7 @@ int spl_load_fit_image(struct spl_image_info *spl_image, #ifdef CONFIG_SPL_FIT_SIGNATURE images.verify = 1; #endif - ret = fit_image_load(&images, (ulong)header, + ret = fit_image_load(&images, virt_to_phys((void *)header), &uname, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1, FIT_LOAD_OPTIONAL_NON_ZERO, From fffbb6f428ff81236d6092bec0d161904ca50335 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 4 Jun 2026 22:41:37 +0200 Subject: [PATCH 3/6] spl: fit: rework the FDT load hack U-Boot proper expects its FDT to be right after its binary image; the "full" FIT image loader thus adopts an hack to relocate it, ignoring the specified load address. Rework the current form of the hack to: - support the 'sandbox' environment with a sysmem-aware memcpy; - use the ALIGN() macro instead of raw alignment logic; - align the FDT to 8-byte boundary as per FDT specifications; - fix the debug print (which was reporting the source address for the relocation instead of the destination one). Signed-off-by: Francesco Valla --- common/spl/spl_fit.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 229eda0582f..1f3f7e54950 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -1000,14 +1000,15 @@ int spl_load_fit_image(struct spl_image_info *spl_image, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1, FIT_LOAD_OPTIONAL, &dt_data, &dt_len); if (ret >= 0) { - spl_image->fdt_addr = (void *)dt_data; - if (spl_image->os == IH_OS_U_BOOT) { /* HACK: U-Boot expects FDT at a specific address */ - fdt_hack = spl_image->load_addr + spl_image->size; - fdt_hack = (fdt_hack + 3) & ~3; - debug("Relocating FDT to %p\n", spl_image->fdt_addr); - memcpy((void *)fdt_hack, spl_image->fdt_addr, dt_len); + fdt_hack = ALIGN(spl_image->load_addr + spl_image->size, 8); + debug("Relocating FDT to %p\n", (void *)fdt_hack); + memcpy(map_sysmem(fdt_hack, dt_len), + map_sysmem(dt_data, 0), dt_len); + spl_image->fdt_addr = (void *)fdt_hack; + } else { + spl_image->fdt_addr = (void *)dt_data; } } From cd9c7bc3b4d2bac01c9dbe39171acedf281506cb Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 4 Jun 2026 22:41:38 +0200 Subject: [PATCH 4/6] spl: fit: drop the 'standalone' load attempt The 'standalone =' config property has been deprecated for ~5 years [1], with the loud warn about the deprecation lasting much more than the foreseen couple of releases. Remove the attempt to load the primary image through this property to save some boot time and code complexity. [1] https://lore.kernel.org/u-boot/20210401182531.2147653-5-mr.nuke.me@gmail.com/ Signed-off-by: Francesco Valla --- common/spl/spl_fit.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 1f3f7e54950..e1c8b1c9b69 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -959,18 +959,9 @@ int spl_load_fit_image(struct spl_image_info *spl_image, images.verify = 1; #endif ret = fit_image_load(&images, virt_to_phys((void *)header), - NULL, &fit_uname_config, - IH_ARCH_DEFAULT, IH_TYPE_STANDALONE, -1, - FIT_LOAD_OPTIONAL, &fw_data, &fw_len); - if (ret >= 0) { - printf("DEPRECATED: 'standalone = ' property."); - printf("Please use either 'firmware =' or 'kernel ='\n"); - } else { - ret = fit_image_load(&images, virt_to_phys((void *)header), - NULL, &fit_uname_config, IH_ARCH_DEFAULT, - IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL, - &fw_data, &fw_len); - } + NULL, &fit_uname_config, IH_ARCH_DEFAULT, + IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL, + &fw_data, &fw_len); if (ret < 0) { ret = fit_image_load(&images, virt_to_phys((void *)header), From 99b9223948a4361daff09bc973c2d283e48d8bd6 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 4 Jun 2026 22:41:39 +0200 Subject: [PATCH 5/6] spl: fit: use CONFIG_IS_ENABLED whenever possible Replace #ifdef directives with the CONFIG_IS_ENABLED() for better coverage and cleaner code. In the mean time, convert the last IS_ENABLED() to CONFIG_IS_ENABLED(). Signed-off-by: Francesco Valla --- common/spl/spl_fit.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index e1c8b1c9b69..d89384449b3 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -775,7 +775,7 @@ static int spl_simple_fit_parse(struct spl_fit_info *ctx) if (ctx->conf_node < 0) return -EINVAL; - if (IS_ENABLED(CONFIG_SPL_FIT_SIGNATURE)) { + if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) { printf("## Checking hash(es) for config %s ... ", fit_get_name(ctx->fit, ctx->conf_node, NULL)); if (fit_config_verify(ctx->fit, ctx->conf_node)) @@ -955,9 +955,8 @@ int spl_load_fit_image(struct spl_image_info *spl_image, int idx, conf_noffset; int ret; -#ifdef CONFIG_SPL_FIT_SIGNATURE - images.verify = 1; -#endif + images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE); + ret = fit_image_load(&images, virt_to_phys((void *)header), NULL, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FIRMWARE, -1, FIT_LOAD_OPTIONAL, @@ -984,9 +983,8 @@ int spl_load_fit_image(struct spl_image_info *spl_image, debug(PHASE_PROMPT "payload image: %32s load addr: 0x%lx size: %d\n", spl_image->name, spl_image->load_addr, spl_image->size); -#ifdef CONFIG_SPL_FIT_SIGNATURE - images.verify = 1; -#endif + images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE); + ret = fit_image_load(&images, virt_to_phys((void *)header), NULL, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_FLATDT, -1, FIT_LOAD_OPTIONAL, &dt_data, &dt_len); @@ -1013,9 +1011,8 @@ int spl_load_fit_image(struct spl_image_info *spl_image, FIT_LOADABLE_PROP, idx, NULL), uname; idx++) { -#ifdef CONFIG_SPL_FIT_SIGNATURE - images.verify = 1; -#endif + images.verify = CONFIG_IS_ENABLED(FIT_SIGNATURE); + ret = fit_image_load(&images, virt_to_phys((void *)header), &uname, &fit_uname_config, IH_ARCH_DEFAULT, IH_TYPE_LOADABLE, -1, From e41a770f3800f9c0d2f74fedc04eea09a29a3776 Mon Sep 17 00:00:00 2001 From: Francesco Valla Date: Thu, 4 Jun 2026 22:41:40 +0200 Subject: [PATCH 6/6] test: spl: add unit test for the "full" FIT loader Following what is already done for the "simple" FIT loader, add a unit test for the "full" loader. Signed-off-by: Francesco Valla --- arch/sandbox/cpu/spl.c | 37 ++++++++++++++++++++++++++++++++++ arch/sandbox/include/asm/spl.h | 14 +++++++++++++ test/image/spl_load_os.c | 11 ++++++++++ 3 files changed, 62 insertions(+) diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index 7ee4975523e..1668b58d3fb 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -265,6 +265,43 @@ int sandbox_spl_load_fit(char *fname, int maxlen, struct spl_image_info *image) return 0; } +int sandbox_spl_load_fit_full(char *fname, int maxlen, + struct spl_image_info *image) +{ + struct legacy_img_hdr *header; + long long size; + int ret; + int fd; + + ret = sandbox_find_next_phase(fname, maxlen, true); + if (ret) { + printf("%s not found, error %d\n", fname, ret); + return log_msg_ret("nph", ret); + } + + log_debug("reading from %s\n", fname); + fd = os_open(fname, OS_O_RDONLY); + if (fd < 0) { + printf("Failed to open '%s'\n", fname); + return log_msg_ret("ope", -errno); + } + + if (os_get_filesize(fname, &size)) + return log_msg_ret("fis", -ENOENT); + + header = spl_get_load_buffer(0, size); + + if (os_read(fd, header, size) != size) + return log_msg_ret("rea", -EIO); + os_close(fd); + + ret = spl_load_fit_image(image, header); + if (ret) + return log_msg_ret("slf", ret); + + return 0; +} + static int upl_load_from_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { diff --git a/arch/sandbox/include/asm/spl.h b/arch/sandbox/include/asm/spl.h index d824b2123a2..49a613ba92d 100644 --- a/arch/sandbox/include/asm/spl.h +++ b/arch/sandbox/include/asm/spl.h @@ -46,4 +46,18 @@ int sandbox_find_next_phase(char *fname, int maxlen, bool use_img); */ int sandbox_spl_load_fit(char *fname, int maxlen, struct spl_image_info *image); +/** + * sandbox_spl_load_fit_full() - Load the next phase from a FIT with the "full" loader + * + * Loads a FIT containing the next phase and sets it up for booting, using the + * "full" FIT loader + * + * @fname: Returns filename loaded + * @maxlen: Maximum length for @fname including \0 + * @image: Place to put SPL-image information + * Return: 0 if OK, -ve on error + */ +int sandbox_spl_load_fit_full(char *fname, int maxlen, + struct spl_image_info *image); + #endif diff --git a/test/image/spl_load_os.c b/test/image/spl_load_os.c index d17cf116a0e..ba9d7979a09 100644 --- a/test/image/spl_load_os.c +++ b/test/image/spl_load_os.c @@ -21,3 +21,14 @@ static int spl_test_load(struct unit_test_state *uts) } SPL_TEST(spl_test_load, 0); +static int spl_test_load_fit_full(struct unit_test_state *uts) +{ + struct spl_image_info image; + char fname[256]; + + ut_assertok(sandbox_spl_load_fit_full(fname, sizeof(fname), &image)); + + return 0; +} +SPL_TEST(spl_test_load_fit_full, 0); +