diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 61246b9e..111e82f0 100644 --- a/boot/bootutil/src/swap_move.c +++ b/boot/bootutil/src/swap_move.c @@ -234,6 +234,28 @@ 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)); + first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 1; + + 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) { @@ -242,18 +264,29 @@ 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_sectors_pri != (num_sectors_sec + 1)) && + (num_usable_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)); + return 0; + } else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) { + BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed"); return 0; } - if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) { - BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed"); - return 0; + if (num_usable_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 - 1), + (int)num_sectors_pri, (int)num_sectors_sec); } for (i = 0; i < num_sectors_sec; i++) { @@ -544,24 +577,11 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs, int app_max_size(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)); - first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 1; - while (1) { - sz += sector_sz; - if (sz >= trailer_sz) { - break; - } - first_trailer_idx--; - } - - return (first_trailer_idx * sector_sz); + return (app_max_sectors(state) * sector_sz); } #endif