diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 8bbabbbac..9a771a07a 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -470,6 +470,10 @@ boot_write_status(const struct boot_loader_state *state, struct boot_status *bs) memset(buf, erased_val, BOOT_MAX_ALIGN); buf[0] = bs->state; + BOOT_LOG_DBG("writing swap status; fa_id=%d off=0x%lx (0x%lx)", + flash_area_get_id(fap), (unsigned long)off, + (unsigned long)flash_area_get_off(fap) + off); + rc = flash_area_write(fap, off, buf, align); if (rc != 0) { rc = BOOT_EFLASH; diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c index 61246b9e5..111e82f05 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,20 +264,31 @@ 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; - } - - if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) { + } else 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++) { sector_sz_pri = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, i); sector_sz_sec = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, 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 diff --git a/docs/release-notes.d/bootutil-sector.md b/docs/release-notes.d/bootutil-sector.md new file mode 100644 index 000000000..be1186de0 --- /dev/null +++ b/docs/release-notes.d/bootutil-sector.md @@ -0,0 +1,7 @@ +- bootutil: Fixed issue with comparing sector sizes for + compatibility, this now also checks against the number of usable + sectors (which is the slot size minus the swap status and moved + up by one sector). +- bootutil: Added debug logging to show write location of swap status + and details on sectors including if slot sizes are not optimal for + a given board.