Skip to content

Commit 0a7e9a6

Browse files
committed
bootutil: Unify app_max_size() implementations
Remove redundant application size calculations in favour of a common function, implemented inside bootutil_misc.c. In this way, slot sizes use the same restrictions as image validation. Signed-off-by: Tomasz Chyrowicz <tomasz.chyrowicz@nordicsemi.no>
1 parent 15b8991 commit 0a7e9a6

File tree

7 files changed

+37
-98
lines changed

7 files changed

+37
-98
lines changed

boot/bootutil/include/bootutil/bootutil.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct boot_loader_state *boot_get_loader_state(void);
9292
const struct image_max_size *boot_get_max_app_size(void);
9393
uint32_t boot_get_state_secondary_offset(struct boot_loader_state *state,
9494
const struct flash_area *fap);
95+
uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct flash_area *fap);
9596

9697
#define SPLIT_GO_OK (0)
9798
#define SPLIT_GO_NON_MATCHING (-1)

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: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -479,25 +479,28 @@ uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct f
479479
#elif defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET)
480480
(void) fap;
481481

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);
482+
uint32_t available_pri_sz;
483+
uint32_t available_sec_sz;
492484

493485
size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
494-
size_t sector_sz = boot_img_sector_size(state, slot, 0);
486+
size_t sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
495487
size_t padding_sz = sector_sz;
496488

497489
/* The trailer size needs to be sector-aligned */
498490
trailer_sz = ALIGN_UP(trailer_sz, sector_sz);
499491

500-
return flash_area_get_size(fap_padded_slot) - trailer_sz - padding_sz;
492+
available_pri_sz = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) * sector_sz - trailer_sz;
493+
available_sec_sz = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz - trailer_sz;
494+
495+
/* The slot whose size is used to compute the maximum image size must be the one containing the
496+
* padding required for the swap. */
497+
#ifdef MCUBOOT_SWAP_USING_MOVE
498+
available_pri_sz -= padding_sz;
499+
#else
500+
available_sec_sz -= padding_sz;
501+
#endif
502+
503+
return (available_pri_sz < available_sec_sz ? available_pri_sz : available_sec_sz);
501504
#elif defined(MCUBOOT_OVERWRITE_ONLY)
502505
(void) state;
503506
return boot_swap_info_off(fap);

boot/bootutil/src/bootutil_priv.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,6 @@ int boot_load_image_to_sram(struct boot_loader_state *state);
544544

545545
#endif /* MCUBOOT_RAM_LOAD */
546546

547-
uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct flash_area *fap);
548-
549547
int boot_read_image_size(struct boot_loader_state *state, int slot,
550548
uint32_t *size);
551549

boot/bootutil/src/swap_move.c

Lines changed: 5 additions & 38 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,7 @@ 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;
594-
595-
sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
596-
597-
return app_max_sectors(state) * sector_sz_primary;
564+
return bootutil_max_image_size(state, NULL);
598565
}
599566

600567
#endif

boot/bootutil/src/swap_offset.c

Lines changed: 8 additions & 44 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,7 @@ 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;
733-
734-
sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
735-
736-
return app_max_sectors(state) * sector_sz_primary;
700+
return bootutil_max_image_size(state, NULL);
737701
}
738702

739703
/* 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)