Skip to content

Commit 42abee1

Browse files
committed
boot: bootutils: Add image in image support
This is source code update to provide images in images feature support. As mentioned in prev commit: MCUBoot multi image support mode requires each image be procedded individually that requires multiple signature check during boot. If there be 4 imageis it requires 4 times signature validatation. This feature increase boot time. Depend on the project requirement long boot time may not be accapted. In this commit the loader.c file update to search subimages and copy them in the related load_address. By this solution: - Image update will be handled as regularly - Signature check will be executed for combined image - Boot time will be decreased This featue only support for (BOOT_IMAGE_NUMBER == 1 && MCUBOOT_RAM_LOAD) case. Signed-off-by: Sadik Ozer <sadik.ozer@analog.com>
1 parent 69c55d8 commit 42abee1

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

boot/bootutil/src/loader.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* Copyright (c) 2016-2019 JUUL Labs
66
* Copyright (c) 2019-2023 Arm Limited
77
* Copyright (c) 2024-2025 Nordic Semiconductor ASA
8+
* Portions Copyright (c) 2025 Analog Devices Inc.
89
*
910
* Original license:
1011
*
@@ -2990,6 +2991,130 @@ boot_update_hw_rollback_protection(struct boot_loader_state *state)
29902991
#endif
29912992
}
29922993

2994+
2995+
#if (BOOT_IMAGE_NUMBER == 1) && defined(MCUBOOT_RAM_LOAD)
2996+
2997+
static int
2998+
read_image_info(uint32_t addr, struct image_header *hdr,
2999+
uint32_t *total_size, uint32_t *footer_size)
3000+
{
3001+
struct image_tlv_info info;
3002+
uint32_t off;
3003+
uint32_t protect_tlv_size;
3004+
3005+
memcpy(hdr, (unsigned char *)addr, sizeof(struct image_header));
3006+
if (hdr->ih_magic != IMAGE_MAGIC) {
3007+
BOOT_LOG_INF("IMAGE_MAGIC not correct.");
3008+
return BOOT_EBADIMAGE;
3009+
}
3010+
3011+
off = BOOT_TLV_OFF(hdr);
3012+
3013+
memcpy(&info, (unsigned char *)(addr + off), sizeof(info));
3014+
3015+
protect_tlv_size = hdr->ih_protect_tlv_size;
3016+
if (info.it_magic == IMAGE_TLV_PROT_INFO_MAGIC) {
3017+
if (protect_tlv_size != info.it_tlv_tot) {
3018+
return BOOT_EBADIMAGE;
3019+
}
3020+
3021+
memcpy(&info, (unsigned char *)(addr + off + info.it_tlv_tot), sizeof(info));
3022+
} else if (protect_tlv_size != 0) {
3023+
return BOOT_EBADIMAGE;
3024+
}
3025+
3026+
if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
3027+
return BOOT_EBADIMAGE;
3028+
}
3029+
3030+
*footer_size = protect_tlv_size + info.it_tlv_tot;
3031+
*total_size = off + *footer_size;
3032+
3033+
return 0;
3034+
}
3035+
3036+
/**
3037+
* Check the main image and find sub images, then copy them to the target addr.
3038+
* Set boot image address with the first image that found in the list.
3039+
*
3040+
* -------------------------
3041+
* | Header |
3042+
* -------------------------
3043+
* | SubImage (optional) |
3044+
* | (Header+Data+Footer) |
3045+
* -------------------------
3046+
* | SubImage (optional) |
3047+
* | (Header+Data+Footer) |
3048+
* -------------------------
3049+
* | ..... |
3050+
* -------------------------
3051+
* | Footer |
3052+
* -------------------------
3053+
*
3054+
* @param addr Image start address
3055+
* @param rsp On success, indicates how booting should occur.
3056+
*
3057+
* @return 0 on success; nonzero on failure.
3058+
*/
3059+
static int
3060+
process_sub_images(uint32_t addr, struct boot_rsp *rsp)
3061+
{
3062+
int rc = 0;
3063+
bool first_subimage = true;
3064+
uint32_t main_image_size;
3065+
struct image_header hdr;
3066+
uint32_t img_total_size;
3067+
uint32_t img_footer_size;
3068+
3069+
/* read main image info */
3070+
rc = read_image_info(addr, &hdr, &img_total_size, &img_footer_size);
3071+
if (rc != 0) {
3072+
/* No valid image header, main image format not correct. */
3073+
return rc;
3074+
}
3075+
3076+
/* Set main image size */
3077+
main_image_size = img_total_size;
3078+
/* Decrease image header size and footer size */
3079+
main_image_size -= (hdr.ih_hdr_size + img_footer_size);
3080+
3081+
/* Pass image header */
3082+
addr += hdr.ih_hdr_size;
3083+
3084+
while (main_image_size) {
3085+
/* read sub image info */
3086+
rc = read_image_info(addr, &hdr, &img_total_size, &img_footer_size);
3087+
if (rc != 0) {
3088+
/* No valid sub-image header, so it migth be single image return 0 */
3089+
rc = 0;
3090+
break;
3091+
}
3092+
3093+
/* copy image to target addr */
3094+
if (hdr.ih_flags & IMAGE_F_RAM_LOAD) {
3095+
/*
3096+
* For heterogenous system that have multi core on same IC.
3097+
* Assuming main core that execute MCUBoot able to access other cores ITCM/DTCM
3098+
*/
3099+
memcpy((unsigned char *)(hdr.ih_load_addr), (unsigned char *)addr, img_total_size);
3100+
BOOT_LOG_INF("Copying image from 0x%x to 0x%x is succeeded.", addr, hdr.ih_load_addr);
3101+
}
3102+
3103+
/* Execute first sub image */
3104+
if ((first_subimage) && !(hdr.ih_flags & IMAGE_F_NON_BOOTABLE)) {
3105+
first_subimage = false;
3106+
rsp->br_hdr = (struct image_header *)hdr.ih_load_addr;
3107+
}
3108+
3109+
/* go next image */
3110+
main_image_size -= img_total_size;
3111+
addr += img_total_size;
3112+
}
3113+
3114+
return rc;
3115+
}
3116+
#endif // #if (BOOT_IMAGE_NUMBER == 1) && defined(MCUBOOT_RAM_LOAD)
3117+
29933118
fih_ret
29943119
context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
29953120
{
@@ -3055,6 +3180,10 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
30553180

30563181
fill_rsp(state, rsp);
30573182

3183+
#if (BOOT_IMAGE_NUMBER == 1) && defined(MCUBOOT_RAM_LOAD)
3184+
(void) process_sub_images(rsp->br_hdr->ih_load_addr, rsp);
3185+
#endif
3186+
30583187
close:
30593188
boot_close_all_flash_areas(state);
30603189

0 commit comments

Comments
 (0)