Skip to content

Commit 84cf14a

Browse files
committed
bootutil: Unify app_max_size() implementations
Remove redundant application size calculations in favour of a swap-specific function, implemented inside swap_<type>.c. In this way, slot sizes use the same restrictions as image validation. Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 15b8991 commit 84cf14a

File tree

5 files changed

+53
-100
lines changed

5 files changed

+53
-100
lines changed

boot/bootutil/include/bootutil/bootutil_public.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,12 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm);
302302
/**
303303
* Attempts to load image header from flash; verifies flash header fields.
304304
*
305+
* The selected update method (i.e. swap move) may impose additional restrictions
306+
* on the image size (i.e. due to the presence of the image trailer).
307+
* Such restrictions are not verified by this function.
308+
* These checks are implemented as part of the boot_image_validate(..) that uses
309+
* sizes from the bootutil_max_image_size(..).
310+
*
305311
* @param[in] fa_p flash area pointer
306312
* @param[out] hdr buffer for image header
307313
*

boot/bootutil/src/bootutil_misc.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
#ifdef MCUBOOT_ENC_IMAGES
4343
#include "bootutil/enc_key.h"
4444
#endif
45+
#if defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET)
46+
#include "swap_priv.h"
47+
#endif
4548

4649
BOOT_LOG_MODULE_DECLARE(mcuboot);
4750

@@ -478,26 +481,7 @@ uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct f
478481
return slot_trailer_off - trailer_padding;
479482
#elif defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET)
480483
(void) fap;
481-
482-
/* The slot whose size is used to compute the maximum image size must be the one containing the
483-
* padding required for the swap. */
484-
#ifdef MCUBOOT_SWAP_USING_MOVE
485-
size_t slot = BOOT_PRIMARY_SLOT;
486-
#else
487-
size_t slot = BOOT_SECONDARY_SLOT;
488-
#endif
489-
490-
const struct flash_area *fap_padded_slot = BOOT_IMG_AREA(state, slot);
491-
assert(fap_padded_slot != NULL);
492-
493-
size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
494-
size_t sector_sz = boot_img_sector_size(state, slot, 0);
495-
size_t padding_sz = sector_sz;
496-
497-
/* The trailer size needs to be sector-aligned */
498-
trailer_sz = ALIGN_UP(trailer_sz, sector_sz);
499-
500-
return flash_area_get_size(fap_padded_slot) - trailer_sz - padding_sz;
484+
return app_max_size(state);
501485
#elif defined(MCUBOOT_OVERWRITE_ONLY)
502486
(void) state;
503487
return boot_swap_info_off(fap);

boot/bootutil/src/swap_move.c

Lines changed: 19 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -227,29 +227,6 @@ boot_status_internal_off(const struct boot_status *bs, int elem_sz)
227227
return off;
228228
}
229229

230-
static int app_max_sectors(struct boot_loader_state *state)
231-
{
232-
uint32_t sz = 0;
233-
uint32_t sector_sz;
234-
uint32_t trailer_sz;
235-
uint32_t first_trailer_idx;
236-
237-
sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
238-
trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
239-
/* subtract 1 for swap and at least 1 for trailer */
240-
first_trailer_idx = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 2;
241-
242-
while (1) {
243-
sz += sector_sz;
244-
if (sz >= trailer_sz) {
245-
break;
246-
}
247-
first_trailer_idx--;
248-
}
249-
250-
return first_trailer_idx;
251-
}
252-
253230
int
254231
boot_slots_compatible(struct boot_loader_state *state)
255232
{
@@ -258,19 +235,16 @@ boot_slots_compatible(struct boot_loader_state *state)
258235
size_t sector_sz_pri = 0;
259236
size_t sector_sz_sec = 0;
260237
size_t i;
261-
size_t num_usable_sectors_pri;
262238

263239
num_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT);
264240
num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT);
265-
num_usable_sectors_pri = app_max_sectors(state);
266241

267242
if ((num_sectors_pri != num_sectors_sec) &&
268-
(num_sectors_pri != (num_sectors_sec + 1)) &&
269-
(num_usable_sectors_pri != (num_sectors_sec + 1))) {
243+
(num_sectors_pri != (num_sectors_sec + 1))) {
270244
BOOT_LOG_WRN("Cannot upgrade: not a compatible amount of sectors");
271245
BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable slot0 sectors: %d",
272246
(int)num_sectors_pri, (int)num_sectors_sec,
273-
(int)(num_usable_sectors_pri - 1));
247+
(int)(num_sectors_pri - 1));
274248
return 0;
275249
} else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) {
276250
BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed");
@@ -280,7 +254,7 @@ boot_slots_compatible(struct boot_loader_state *state)
280254
/* Optimal says primary has one more than secondary. Always. Both have trailers. */
281255
if (num_sectors_pri != (num_sectors_sec + 1)) {
282256
BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors (%d assigned) "
283-
"but slot1 has %d assigned", (int)num_usable_sectors_pri,
257+
"but slot1 has %d assigned", (int)(num_sectors_pri - 1),
284258
(int)num_sectors_pri, (int)num_sectors_sec);
285259
}
286260

@@ -340,7 +314,6 @@ swap_status_source(struct boot_loader_state *state)
340314
struct boot_swap_state state_primary_slot;
341315
struct boot_swap_state state_secondary_slot;
342316
int rc;
343-
uint8_t source;
344317
uint8_t image_index;
345318

346319
#if (BOOT_IMAGE_NUMBER == 1)
@@ -365,10 +338,8 @@ swap_status_source(struct boot_loader_state *state)
365338
state_primary_slot.copy_done == BOOT_FLAG_UNSET &&
366339
state_secondary_slot.magic != BOOT_MAGIC_GOOD) {
367340

368-
source = BOOT_STATUS_SOURCE_PRIMARY_SLOT;
369-
370341
BOOT_LOG_INF("Boot source: primary slot");
371-
return source;
342+
return BOOT_STATUS_SOURCE_PRIMARY_SLOT;
372343
}
373344

374345
BOOT_LOG_INF("Boot source: none");
@@ -590,11 +561,23 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs,
590561

591562
int app_max_size(struct boot_loader_state *state)
592563
{
593-
uint32_t sector_sz_primary;
564+
uint32_t available_pri_sz;
565+
uint32_t available_sec_sz;
566+
567+
size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
568+
size_t sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
569+
size_t padding_sz = sector_sz;
594570

595-
sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
571+
/* The trailer size needs to be sector-aligned */
572+
trailer_sz = ALIGN_UP(trailer_sz, sector_sz);
573+
574+
/* The slot whose size is used to compute the maximum image size must be the one containing the
575+
* padding required for the swap.
576+
*/
577+
available_pri_sz = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) * sector_sz - trailer_sz - padding_sz;
578+
available_sec_sz = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz - trailer_sz;
596579

597-
return app_max_sectors(state) * sector_sz_primary;
580+
return (available_pri_sz < available_sec_sz ? available_pri_sz : available_sec_sz);
598581
}
599582

600583
#endif

boot/bootutil/src/swap_offset.c

Lines changed: 22 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -302,66 +302,37 @@ uint32_t boot_status_internal_off(const struct boot_status *bs, int elem_sz)
302302
return off;
303303
}
304304

305-
static int app_max_sectors(struct boot_loader_state *state)
306-
{
307-
uint32_t sz = 0;
308-
uint32_t sector_sz;
309-
uint32_t trailer_sz;
310-
uint32_t available_sectors_pri;
311-
uint32_t available_sectors_sec;
312-
uint32_t trailer_sectors = 0;
313-
314-
sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
315-
trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
316-
317-
while (1) {
318-
sz += sector_sz;
319-
++trailer_sectors;
320-
321-
if (sz >= trailer_sz) {
322-
break;
323-
}
324-
}
325-
326-
available_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - trailer_sectors;
327-
available_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) - 1;
328-
329-
return (available_sectors_pri < available_sectors_sec ? available_sectors_pri : available_sectors_sec);
330-
}
331-
332305
int boot_slots_compatible(struct boot_loader_state *state)
333306
{
334307
size_t num_sectors_pri;
335308
size_t num_sectors_sec;
336309
size_t sector_sz_pri = 0;
337310
size_t sector_sz_sec = 0;
338311
size_t i;
339-
size_t num_usable_sectors;
340312

341313
num_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT);
342314
num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT);
343-
num_usable_sectors = app_max_sectors(state);
344315

345316
if (num_sectors_pri != num_sectors_sec &&
346-
(num_sectors_pri + 1) != num_sectors_sec &&
347-
num_usable_sectors != (num_sectors_sec - 1)) {
317+
(num_sectors_pri + 1) != num_sectors_sec) {
348318
BOOT_LOG_WRN("Cannot upgrade: not a compatible amount of sectors");
349319
BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable sectors: %d",
350320
(int)num_sectors_pri, (int)num_sectors_sec,
351-
(int)(num_usable_sectors));
321+
(int)(num_sectors_sec - 1));
352322
return 0;
353323
} else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) {
354324
BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed");
355325
return 0;
356326
}
357327

358-
if ((num_usable_sectors + 1) != num_sectors_sec) {
328+
/* Optimal says secondary has one more than primary. Always. Both have trailers. */
329+
if ((num_sectors_pri + 1) != num_sectors_sec) {
359330
BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors "
360-
"but slot1 has %d usable sectors", (int)(num_usable_sectors),
331+
"but slot1 has %d usable sectors", (int)(num_sectors_pri),
361332
((int)num_sectors_sec - 1));
362333
}
363334

364-
for (i = 0; i < num_usable_sectors; i++) {
335+
for (i = 0; i < (num_sectors_sec - 1); i++) {
365336
sector_sz_pri = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, i);
366337
sector_sz_sec = boot_img_sector_size(state, BOOT_SECONDARY_SLOT, i);
367338

@@ -417,7 +388,6 @@ int swap_status_source(struct boot_loader_state *state)
417388
struct boot_swap_state state_primary_slot;
418389
struct boot_swap_state state_secondary_slot;
419390
int rc;
420-
uint8_t source;
421391
uint8_t image_index;
422392

423393
#if (BOOT_IMAGE_NUMBER == 1)
@@ -439,10 +409,8 @@ int swap_status_source(struct boot_loader_state *state)
439409
state_primary_slot.copy_done == BOOT_FLAG_UNSET &&
440410
state_secondary_slot.magic != BOOT_MAGIC_GOOD) {
441411

442-
source = BOOT_STATUS_SOURCE_PRIMARY_SLOT;
443-
444412
BOOT_LOG_INF("Boot source: primary slot");
445-
return source;
413+
return BOOT_STATUS_SOURCE_PRIMARY_SLOT;
446414
}
447415

448416
BOOT_LOG_INF("Boot source: none");
@@ -729,11 +697,23 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs,
729697

730698
int app_max_size(struct boot_loader_state *state)
731699
{
732-
uint32_t sector_sz_primary;
700+
uint32_t available_pri_sz;
701+
uint32_t available_sec_sz;
702+
703+
size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
704+
size_t sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
705+
size_t padding_sz = sector_sz;
706+
707+
/* The trailer size needs to be sector-aligned */
708+
trailer_sz = ALIGN_UP(trailer_sz, sector_sz);
733709

734-
sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
710+
/* The slot whose size is used to compute the maximum image size must be the one containing the
711+
* padding required for the swap.
712+
*/
713+
available_pri_sz = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) * sector_sz - trailer_sz;
714+
available_sec_sz = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz - trailer_sz - padding_sz;
735715

736-
return app_max_sectors(state) * sector_sz_primary;
716+
return (available_pri_sz < available_sec_sz ? available_pri_sz : available_sec_sz);
737717
}
738718

739719
/* Compute the total size of the given image. Includes the size of the TLVs. */

boot/bootutil/src/swap_scratch.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,7 +907,7 @@ int app_max_size(struct boot_loader_state *state)
907907

908908
fap = BOOT_IMG_AREA(state, active_slot);
909909
assert(fap != NULL);
910-
primary_sz = flash_area_get_size(fap);
910+
primary_sz = bootutil_max_image_size(state, fap);
911911

912912
if (active_slot == BOOT_PRIMARY_SLOT) {
913913
active_slot = BOOT_SECONDARY_SLOT;
@@ -917,7 +917,7 @@ int app_max_size(struct boot_loader_state *state)
917917

918918
fap = BOOT_IMG_AREA(state, active_slot);
919919
assert(fap != NULL);
920-
secondary_sz = flash_area_get_size(fap);
920+
secondary_sz = bootutil_max_image_size(state, fap);
921921

922922
return (secondary_sz < primary_sz ? secondary_sz : primary_sz);
923923
}

0 commit comments

Comments
 (0)