Skip to content

Commit c19b1ff

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 3011760 commit c19b1ff

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed

boot/bootutil/src/loader.c

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

30563189
fill_rsp(state, rsp);
30573190

3191+
#if (BOOT_IMAGE_NUMBER == 1) && defined(MCUBOOT_RAM_LOAD)
3192+
rc = process_sub_images(rsp->br_hdr->ih_load_addr, rsp);
3193+
#endif
3194+
30583195
close:
30593196
boot_close_all_flash_areas(state);
30603197

0 commit comments

Comments
 (0)