diff --git a/boot/bootutil/include/bootutil/bootutil_public.h b/boot/bootutil/include/bootutil/bootutil_public.h index 933553f9f..421d854b1 100644 --- a/boot/bootutil/include/bootutil/bootutil_public.h +++ b/boot/bootutil/include/bootutil/bootutil_public.h @@ -295,6 +295,12 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm); /** * Attempts to load image header from flash; verifies flash header fields. * + * The selected update method (i.e. swap move) may impose additional restrictions + * on the image size (i.e. due to the presence of the image trailer). + * Such restrictions are not verified by this function. + * These checks are implemented as part of the boot_image_validate(..) that uses + * sizes from the bootutil_max_image_size(..). + * * @param[in] fa_p flash area pointer * @param[out] hdr buffer for image header * diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 9f88aad78..3f774b664 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -42,6 +42,10 @@ #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" #endif +#if defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET) || \ + defined(MCUBOOT_SWAP_USING_SCRATCH) +#include "swap_priv.h" +#endif #if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO) || defined(MCUBOOT_SWAP_USING_SCRATCH) #include "swap_priv.h" @@ -240,8 +244,7 @@ int boot_header_scramble_off_sz(const struct flash_area *fa, int slot, size_t *o * status during the swap of the last sector from primary/secondary (which * is the first swap operation) and thus only requires space for one swap. */ -static uint32_t -boot_scratch_trailer_sz(uint32_t min_write_sz) +uint32_t boot_scratch_trailer_sz(uint32_t min_write_sz) { return boot_status_entry_sz(min_write_sz) + boot_trailer_info_sz(); } @@ -427,44 +430,6 @@ boot_write_enc_key(const struct flash_area *fap, uint8_t slot, } #endif -#ifdef MCUBOOT_SWAP_USING_SCRATCH -size_t -boot_get_first_trailer_sector(struct boot_loader_state *state, size_t slot, size_t trailer_sz) -{ - size_t first_trailer_sector = boot_img_num_sectors(state, slot) - 1; - size_t sector_sz = boot_img_sector_size(state, slot, first_trailer_sector); - size_t trailer_sector_sz = sector_sz; - - while (trailer_sector_sz < trailer_sz) { - /* Consider that the image trailer may span across sectors of different sizes */ - --first_trailer_sector; - sector_sz = boot_img_sector_size(state, slot, first_trailer_sector); - - trailer_sector_sz += sector_sz; - } - - return first_trailer_sector; -} - -/** - * Returns the offset to the end of the first sector of a given slot that holds image trailer data. - * - * @param state Current bootloader's state. - * @param slot The index of the slot to consider. - * @param trailer_sz The size of the trailer, in bytes. - * - * @return The offset to the end of the first sector of the slot that holds image trailer data. - */ -static uint32_t -get_first_trailer_sector_end_off(struct boot_loader_state *state, size_t slot, size_t trailer_sz) -{ - size_t first_trailer_sector = boot_get_first_trailer_sector(state, slot, trailer_sz); - - return boot_img_sector_off(state, slot, first_trailer_sector) + - boot_img_sector_size(state, slot, first_trailer_sector); -} -#endif /* MCUBOOT_SWAP_USING_SCRATCH */ - uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct flash_area *fap) { #if defined(MCUBOOT_SINGLE_APPLICATION_SLOT) || \ @@ -472,61 +437,10 @@ uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct f defined(MCUBOOT_SINGLE_APPLICATION_SLOT_RAM_LOAD) (void) state; return boot_status_off(fap); -#elif defined(MCUBOOT_SWAP_USING_SCRATCH) - size_t slot_trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - size_t slot_trailer_off = flash_area_get_size(fap) - slot_trailer_sz; - - /* If the trailer doesn't fit in the last sector of the primary or secondary slot, some padding - * might have to be inserted between the end of the firmware image and the beginning of the - * trailer to ensure there is enough space for the trailer in the scratch area when the last - * sector of the secondary will be copied to the scratch area. - * - * The value of the padding depends on the amount of trailer data that is contained in the first - * trailer containing part of the trailer in the primary and secondary slot. - */ - size_t trailer_sector_primary_end_off = - get_first_trailer_sector_end_off(state, BOOT_PRIMARY_SLOT, slot_trailer_sz); - size_t trailer_sector_secondary_end_off = - get_first_trailer_sector_end_off(state, BOOT_SECONDARY_SLOT, slot_trailer_sz); - - size_t trailer_sz_in_first_sector; - - if (trailer_sector_primary_end_off > trailer_sector_secondary_end_off) { - trailer_sz_in_first_sector = trailer_sector_primary_end_off - slot_trailer_off; - } else { - trailer_sz_in_first_sector = trailer_sector_secondary_end_off - slot_trailer_off; - } - - size_t trailer_padding = 0; - size_t scratch_trailer_sz = boot_scratch_trailer_sz(BOOT_WRITE_SZ(state)); - - if (scratch_trailer_sz > trailer_sz_in_first_sector) { - trailer_padding = scratch_trailer_sz - trailer_sz_in_first_sector; - } - - return slot_trailer_off - trailer_padding; -#elif defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET) +#elif defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET) \ + || defined(MCUBOOT_SWAP_USING_SCRATCH) (void) fap; - - /* The slot whose size is used to compute the maximum image size must be the one containing the - * padding required for the swap. */ -#ifdef MCUBOOT_SWAP_USING_MOVE - size_t slot = BOOT_PRIMARY_SLOT; -#else - size_t slot = BOOT_SECONDARY_SLOT; -#endif - - const struct flash_area *fap_padded_slot = BOOT_IMG_AREA(state, slot); - assert(fap_padded_slot != NULL); - - size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - size_t sector_sz = boot_img_sector_size(state, slot, 0); - size_t padding_sz = sector_sz; - - /* The trailer size needs to be sector-aligned */ - trailer_sz = ALIGN_UP(trailer_sz, sector_sz); - - return flash_area_get_size(fap_padded_slot) - trailer_sz - padding_sz; + return app_max_size(state); #elif defined(MCUBOOT_OVERWRITE_ONLY) (void) state; return boot_swap_info_off(fap); diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index b62af146c..964a80e7c 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -381,18 +381,14 @@ int boot_read_enc_key(const struct flash_area *fap, uint8_t slot, struct boot_status *bs); #endif -#ifdef MCUBOOT_SWAP_USING_SCRATCH -/** - * Finds the first sector of a given slot that holds image trailer data. - * - * @param state Current bootloader's state. - * @param slot The index of the slot to consider. - * @param trailer_sz The size of the trailer, in bytes. - * - * @return The index of the first sector of the slot that holds image trailer data. +#if MCUBOOT_SWAP_USING_SCRATCH +/* + * Similar to `boot_trailer_sz` but this function returns the space used to + * store status in the scratch partition. The scratch partition only stores + * status during the swap of the last sector from primary/secondary (which + * is the first swap operation) and thus only requires space for one swap. */ -size_t -boot_get_first_trailer_sector(struct boot_loader_state *state, size_t slot, size_t trailer_sz); +uint32_t boot_scratch_trailer_sz(uint32_t min_write_sz); #endif /** diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 9349cde37..8b7bcab13 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -227,29 +227,6 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz) return off; } -static int app_max_sectors(struct boot_loader_state *state) -{ - uint32_t sz = 0; - uint32_t sector_sz; - uint32_t trailer_sz; - uint32_t first_trailer_idx; - - sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); - trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - /* subtract 1 for swap and at least 1 for trailer */ - first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 2; - - while (1) { - sz += sector_sz; - if (sz >= trailer_sz) { - break; - } - first_trailer_idx--; - } - - return first_trailer_idx; -} - int boot_slots_compatible(struct boot_loader_state *state) { @@ -258,19 +235,16 @@ boot_slots_compatible(struct boot_loader_state *state) size_t sector_sz_pri = 0; size_t sector_sz_sec = 0; size_t i; - size_t num_usable_sectors_pri; num_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT); num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT); - num_usable_sectors_pri = app_max_sectors(state); if ((num_sectors_pri != num_sectors_sec) && - (num_sectors_pri != (num_sectors_sec + 1)) && - (num_usable_sectors_pri != (num_sectors_sec + 1))) { + (num_sectors_pri != (num_sectors_sec + 1))) { BOOT_LOG_WRN("Cannot upgrade: not a compatible amount of sectors"); BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable slot0 sectors: %d", (int)num_sectors_pri, (int)num_sectors_sec, - (int)(num_usable_sectors_pri - 1)); + (int)(num_sectors_pri - 1)); return 0; } else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) { BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed"); @@ -280,7 +254,7 @@ boot_slots_compatible(struct boot_loader_state *state) /* Optimal says primary has one more than secondary. Always. Both have trailers. */ if (num_sectors_pri != (num_sectors_sec + 1)) { BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors (%d assigned) " - "but slot1 has %d assigned", (int)num_usable_sectors_pri, + "but slot1 has %d assigned", (int)(num_sectors_pri - 1), (int)num_sectors_pri, (int)num_sectors_sec); } @@ -340,7 +314,6 @@ swap_status_source(struct boot_loader_state *state) struct boot_swap_state state_primary_slot; struct boot_swap_state state_secondary_slot; int rc; - uint8_t source; uint8_t image_index; #if (BOOT_IMAGE_NUMBER == 1) @@ -365,10 +338,8 @@ swap_status_source(struct boot_loader_state *state) state_primary_slot.copy_done == BOOT_FLAG_UNSET && state_secondary_slot.magic != BOOT_MAGIC_GOOD) { - source = BOOT_STATUS_SOURCE_PRIMARY_SLOT; - BOOT_LOG_INF("Boot source: primary slot"); - return source; + return BOOT_STATUS_SOURCE_PRIMARY_SLOT; } BOOT_LOG_INF("Boot source: none"); @@ -590,11 +561,23 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs, int app_max_size(struct boot_loader_state *state) { - uint32_t sector_sz_primary; + uint32_t available_pri_sz; + uint32_t available_sec_sz; + + size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); + size_t sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); + size_t padding_sz = sector_sz; - sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); + /* The trailer size needs to be sector-aligned */ + trailer_sz = ALIGN_UP(trailer_sz, sector_sz); + + /* The slot whose size is used to compute the maximum image size must be the one containing the + * padding required for the swap. + */ + available_pri_sz = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) * sector_sz - trailer_sz - padding_sz; + available_sec_sz = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz - trailer_sz; - return app_max_sectors(state) * sector_sz_primary; + return (available_pri_sz < available_sec_sz ? available_pri_sz : available_sec_sz); } #endif diff --git a/boot/bootutil/src/swap_offset.c b/boot/bootutil/src/swap_offset.c index 8bc6e760a..d8bfac318 100644 --- a/boot/bootutil/src/swap_offset.c +++ b/boot/bootutil/src/swap_offset.c @@ -302,33 +302,6 @@ uint32_t boot_status_internal_off(const struct boot_status *bs, int elem_sz) return off; } -static int app_max_sectors(struct boot_loader_state *state) -{ - uint32_t sz = 0; - uint32_t sector_sz; - uint32_t trailer_sz; - uint32_t available_sectors_pri; - uint32_t available_sectors_sec; - uint32_t trailer_sectors = 0; - - sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); - trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); - - while (1) { - sz += sector_sz; - ++trailer_sectors; - - if (sz >= trailer_sz) { - break; - } - } - - available_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - trailer_sectors; - available_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) - 1; - - return (available_sectors_pri < available_sectors_sec ? available_sectors_pri : available_sectors_sec); -} - int boot_slots_compatible(struct boot_loader_state *state) { size_t num_sectors_pri; @@ -336,32 +309,30 @@ int boot_slots_compatible(struct boot_loader_state *state) size_t sector_sz_pri = 0; size_t sector_sz_sec = 0; size_t i; - size_t num_usable_sectors; num_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT); num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT); - num_usable_sectors = app_max_sectors(state); if (num_sectors_pri != num_sectors_sec && - (num_sectors_pri + 1) != num_sectors_sec && - num_usable_sectors != (num_sectors_sec - 1)) { + (num_sectors_pri + 1) != num_sectors_sec) { BOOT_LOG_WRN("Cannot upgrade: not a compatible amount of sectors"); BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable sectors: %d", (int)num_sectors_pri, (int)num_sectors_sec, - (int)(num_usable_sectors)); + (int)(num_sectors_sec - 1)); return 0; } else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) { BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed"); return 0; } - if ((num_usable_sectors + 1) != num_sectors_sec) { + /* Optimal says secondary has one more than primary. Always. Both have trailers. */ + if ((num_sectors_pri + 1) != num_sectors_sec) { BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors " - "but slot1 has %d usable sectors", (int)(num_usable_sectors), + "but slot1 has %d usable sectors", (int)(num_sectors_pri), ((int)num_sectors_sec - 1)); } - for (i = 0; i < num_usable_sectors; i++) { + for (i = 0; i < (num_sectors_sec - 1); i++) { sector_sz_pri = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, i); sector_sz_sec = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, i); @@ -417,7 +388,6 @@ int swap_status_source(struct boot_loader_state *state) struct boot_swap_state state_primary_slot; struct boot_swap_state state_secondary_slot; int rc; - uint8_t source; uint8_t image_index; #if (BOOT_IMAGE_NUMBER == 1) @@ -439,10 +409,8 @@ int swap_status_source(struct boot_loader_state *state) state_primary_slot.copy_done == BOOT_FLAG_UNSET && state_secondary_slot.magic != BOOT_MAGIC_GOOD) { - source = BOOT_STATUS_SOURCE_PRIMARY_SLOT; - BOOT_LOG_INF("Boot source: primary slot"); - return source; + return BOOT_STATUS_SOURCE_PRIMARY_SLOT; } BOOT_LOG_INF("Boot source: none"); @@ -729,11 +697,23 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs, int app_max_size(struct boot_loader_state *state) { - uint32_t sector_sz_primary; + uint32_t available_pri_sz; + uint32_t available_sec_sz; + + size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); + size_t sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); + size_t padding_sz = sector_sz; + + /* The trailer size needs to be sector-aligned */ + trailer_sz = ALIGN_UP(trailer_sz, sector_sz); - sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0); + /* The slot whose size is used to compute the maximum image size must be the one containing the + * padding required for the swap. + */ + available_pri_sz = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) * sector_sz - trailer_sz; + available_sec_sz = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz - trailer_sz - padding_sz; - return app_max_sectors(state) * sector_sz_primary; + return (available_pri_sz < available_sec_sz ? available_pri_sz : available_sec_sz); } /* Compute the total size of the given image. Includes the size of the TLVs. */ diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c index f9dbb7103..e1d49de49 100644 --- a/boot/bootutil/src/swap_scratch.c +++ b/boot/bootutil/src/swap_scratch.c @@ -47,6 +47,136 @@ int boot_status_fails = 0; #define BOOT_STATUS_ASSERT(x) ASSERT(x) #endif +#if MCUBOOT_SWAP_USING_SCRATCH +/** + * Finds the first sector of a given slot that holds image trailer data. + * + * @param state Current bootloader's state. + * @param slot The index of the slot to consider. + * @param trailer_sz The size of the trailer, in bytes. + * + * @return The index of the first sector of the slot that holds image trailer data. + */ +static size_t +boot_get_first_trailer_sector(struct boot_loader_state *state, size_t slot, size_t trailer_sz) +{ + size_t first_trailer_sector = boot_img_num_sectors(state, slot) - 1; + size_t sector_sz = boot_img_sector_size(state, slot, first_trailer_sector); + size_t trailer_sector_sz = sector_sz; + + while (trailer_sector_sz < trailer_sz) { + /* Consider that the image trailer may span across sectors of different sizes */ + --first_trailer_sector; + sector_sz = boot_img_sector_size(state, slot, first_trailer_sector); + + trailer_sector_sz += sector_sz; + } + + return first_trailer_sector; +} + +/** + * Returns the offset to the end of the first sector of a given slot that holds image trailer data. + * + * @param state Current bootloader's state. + * @param slot The index of the slot to consider. + * @param trailer_sz The size of the trailer, in bytes. + * + * @return The offset to the end of the first sector of the slot that holds image trailer data. + */ +static uint32_t +get_first_trailer_sector_end_off(struct boot_loader_state *state, size_t slot, size_t trailer_sz) +{ + size_t first_trailer_sector = boot_get_first_trailer_sector(state, slot, trailer_sz); + + return boot_img_sector_off(state, slot, first_trailer_sector) + + boot_img_sector_size(state, slot, first_trailer_sector); +} + +/** + * Returns the size of the part of the slot that can be used for storing image data. + * + * @param state Current bootloader's state. + * @param slot_size The size of the slot partition. + * + * @return The offset to the end of the first sector of the slot that holds image trailer data. + */ +static size_t app_max_size_adjust_to_trailer(struct boot_loader_state *state, size_t slot_size) +{ + size_t slot_trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state)); + size_t slot_trailer_off = slot_size - slot_trailer_sz; + size_t trailer_sz_in_first_sector; + size_t trailer_sector_end_off; + + + size_t trailer_sector_primary_end_off = + get_first_trailer_sector_end_off(state, BOOT_PRIMARY_SLOT, slot_trailer_sz); + size_t trailer_sector_secondary_end_off = + get_first_trailer_sector_end_off(state, BOOT_SECONDARY_SLOT, slot_trailer_sz); + + /* If slots have sectors of different sizes, we need to find the "common" sector + * boundary (slot compatibility checks ensure that the larger sector contains a multiple + * of the smaller sector size). This will be the larger of the + * trailer_sector_primary_end_off/trailer_sector_secondary_end_off. + * + * <-------copy size-------> <--------copy size------> <----copy size---> + * v v v v + * +------------+------------+-------------------------+------------------+ + * | sector | sector | sector | sector | + * +------------+------------+------------+------------+------------------+ + * | sector | sector | sector | sector | + * +-------------------------+------------+------------+------------------+ + * + * The swap logic always uses the common boundary when performing the copy. + * Hence, the first trailer sector used for calculation is the larger + * sector from the two slots. + * + * <-----------copy size---------------> + * | sector | sector | + * +-----------------------------------+ + * | sector | + * +-----------------------------------+ + * |Image->| |<-trailer------------| + * +-----------------------------------+ + * | |<-scratch trailer>| + * +-----------------------------------+ + */ + if (trailer_sector_primary_end_off > trailer_sector_secondary_end_off) { + trailer_sector_end_off = trailer_sector_primary_end_off; + } else { + trailer_sector_end_off = trailer_sector_secondary_end_off; + } + + trailer_sz_in_first_sector = trailer_sector_end_off - slot_trailer_off; + + size_t trailer_padding = 0; + size_t scratch_trailer_sz = boot_scratch_trailer_sz(BOOT_WRITE_SZ(state)); + + /* Some padding might have to be inserted between the end of the firmware image and the + * beginning of the trailer to ensure there is enough space for the trailer in the scratch area + * when the last sector of the secondary will be copied to the scratch area. + * + * +-----------------------------------+-----------------------------------+ + * | sector | sector | + * +-----------------------------------+-----------------------------------+ + * |Image->| |<--trailer---|-----------trailer (cont.)-------->| + * +-----------------------------------+-----------------------------------+ + * | |<----scratch trailer---->| + * +-----------------------------------+ + * <-padding-> + * <--------scratch area size--------> + * + * The value of the padding depends on the amount of trailer data that is contained in the first + * sector containing part of the trailer in the primary and secondary slot. + */ + if (scratch_trailer_sz > trailer_sz_in_first_sector) { + trailer_padding = scratch_trailer_sz - trailer_sz_in_first_sector; + } + + return slot_trailer_off - trailer_padding; +} +#endif /* MCUBOOT_SWAP_USING_SCRATCH */ + #if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD) /** * Reads the status of a partially-completed swap, if any. This is necessary @@ -821,8 +951,8 @@ int app_max_size(struct boot_loader_state *state) size_t num_sectors_primary; size_t num_sectors_secondary; size_t sz0, sz1; - size_t primary_slot_sz, secondary_slot_sz; #ifndef MCUBOOT_OVERWRITE_ONLY + size_t slot_sz; size_t scratch_sz; #endif size_t i, j; @@ -842,8 +972,11 @@ int app_max_size(struct boot_loader_state *state) * number of a slot's sectors are able to fit into another, which only * excludes cases where sector sizes are not a multiple of each other. */ - i = sz0 = primary_slot_sz = 0; - j = sz1 = secondary_slot_sz = 0; +#ifndef MCUBOOT_OVERWRITE_ONLY + slot_sz = 0; +#endif + i = sz0 = 0; + j = sz1 = 0; smaller = 0; while (i < num_sectors_primary || j < num_sectors_secondary) { if (sz0 == sz1) { @@ -876,8 +1009,7 @@ int app_max_size(struct boot_loader_state *state) } #ifndef MCUBOOT_OVERWRITE_ONLY if (sz0 == sz1) { - primary_slot_sz += sz0; - secondary_slot_sz += sz1; + slot_sz += sz0; /* Scratch has to fit each swap operation to the size of the larger * sector among the primary slot and the secondary slot. */ @@ -892,8 +1024,10 @@ int app_max_size(struct boot_loader_state *state) #ifdef MCUBOOT_OVERWRITE_ONLY return (sz1 < sz0 ? sz1 : sz0); +#elif MCUBOOT_SWAP_USING_SCRATCH + return app_max_size_adjust_to_trailer(state, slot_sz); #else - return (secondary_slot_sz < primary_slot_sz ? secondary_slot_sz : primary_slot_sz); + return slot_sz; #endif } #else