Skip to content

Commit e74e382

Browse files
committed
[nrf fromlist] 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. Upstream PR #: 2318 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 1525b16 commit e74e382

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
@@ -484,25 +484,28 @@ uint32_t bootutil_max_image_size(struct boot_loader_state *state, const struct f
484484
#elif defined(MCUBOOT_SWAP_USING_MOVE) || defined(MCUBOOT_SWAP_USING_OFFSET)
485485
(void) fap;
486486

487-
/* The slot whose size is used to compute the maximum image size must be the one containing the
488-
* padding required for the swap. */
489-
#ifdef MCUBOOT_SWAP_USING_MOVE
490-
size_t slot = BOOT_PRIMARY_SLOT;
491-
#else
492-
size_t slot = BOOT_SECONDARY_SLOT;
493-
#endif
494-
495-
const struct flash_area *fap_padded_slot = BOOT_IMG_AREA(state, slot);
496-
assert(fap_padded_slot != NULL);
487+
uint32_t available_pri_sz;
488+
uint32_t available_sec_sz;
497489

498490
size_t trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
499-
size_t sector_sz = boot_img_sector_size(state, slot, 0);
491+
size_t sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
500492
size_t padding_sz = sector_sz;
501493

502494
/* The trailer size needs to be sector-aligned */
503495
trailer_sz = ALIGN_UP(trailer_sz, sector_sz);
504496

505-
return flash_area_get_size(fap_padded_slot) - trailer_sz - padding_sz;
497+
available_pri_sz = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) * sector_sz - trailer_sz;
498+
available_sec_sz = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) * sector_sz - trailer_sz;
499+
500+
/* The slot whose size is used to compute the maximum image size must be the one containing the
501+
* padding required for the swap. */
502+
#ifdef MCUBOOT_SWAP_USING_MOVE
503+
available_pri_sz -= padding_sz;
504+
#else
505+
available_sec_sz -= padding_sz;
506+
#endif
507+
508+
return (available_pri_sz < available_sec_sz ? available_pri_sz : available_sec_sz);
506509
#elif defined(MCUBOOT_OVERWRITE_ONLY)
507510
(void) state;
508511
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
{
@@ -270,19 +247,16 @@ boot_slots_compatible(struct boot_loader_state *state)
270247
size_t sector_sz_pri = 0;
271248
size_t sector_sz_sec = 0;
272249
size_t i;
273-
size_t num_usable_sectors_pri;
274250

275251
num_sectors_pri = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT);
276252
num_sectors_sec = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT);
277-
num_usable_sectors_pri = app_max_sectors(state);
278253

279254
if ((num_sectors_pri != num_sectors_sec) &&
280-
(num_sectors_pri != (num_sectors_sec + 1)) &&
281-
(num_usable_sectors_pri != (num_sectors_sec + 1))) {
255+
(num_sectors_pri != (num_sectors_sec + 1))) {
282256
BOOT_LOG_WRN("Cannot upgrade: not a compatible amount of sectors");
283257
BOOT_LOG_DBG("slot0 sectors: %d, slot1 sectors: %d, usable slot0 sectors: %d",
284258
(int)num_sectors_pri, (int)num_sectors_sec,
285-
(int)(num_usable_sectors_pri - 1));
259+
(int)(num_sectors_pri - 1));
286260
return 0;
287261
} else if (num_sectors_pri > BOOT_MAX_IMG_SECTORS) {
288262
BOOT_LOG_WRN("Cannot upgrade: more sectors than allowed");
@@ -292,7 +266,7 @@ boot_slots_compatible(struct boot_loader_state *state)
292266
/* Optimal says primary has one more than secondary. Always. Both have trailers. */
293267
if (num_sectors_pri != (num_sectors_sec + 1)) {
294268
BOOT_LOG_DBG("Non-optimal sector distribution, slot0 has %d usable sectors (%d assigned) "
295-
"but slot1 has %d assigned", (int)num_usable_sectors_pri,
269+
"but slot1 has %d assigned", (int)(num_sectors_pri - 1),
296270
(int)num_sectors_pri, (int)num_sectors_sec);
297271
}
298272

@@ -353,7 +327,6 @@ swap_status_source(struct boot_loader_state *state)
353327
struct boot_swap_state state_primary_slot;
354328
struct boot_swap_state state_secondary_slot;
355329
int rc;
356-
uint8_t source;
357330
uint8_t image_index;
358331

359332
#if (BOOT_IMAGE_NUMBER == 1)
@@ -378,10 +351,8 @@ swap_status_source(struct boot_loader_state *state)
378351
state_primary_slot.copy_done == BOOT_FLAG_UNSET &&
379352
state_secondary_slot.magic != BOOT_MAGIC_GOOD) {
380353

381-
source = BOOT_STATUS_SOURCE_PRIMARY_SLOT;
382-
383354
BOOT_LOG_INF("Boot source: primary slot");
384-
return source;
355+
return BOOT_STATUS_SOURCE_PRIMARY_SLOT;
385356
}
386357

387358
BOOT_LOG_INF("Boot source: none");
@@ -603,11 +574,7 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs,
603574

604575
int app_max_size(struct boot_loader_state *state)
605576
{
606-
uint32_t sector_sz_primary;
607-
608-
sector_sz_primary = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
609-
610-
return app_max_sectors(state) * sector_sz_primary;
577+
return bootutil_max_image_size(state, NULL);
611578
}
612579

613580
#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
@@ -920,7 +920,7 @@ int app_max_size(struct boot_loader_state *state)
920920

921921
fap = BOOT_IMG_AREA(state, active_slot);
922922
assert(fap != NULL);
923-
primary_sz = flash_area_get_size(fap);
923+
primary_sz = bootutil_max_image_size(state, fap);
924924

925925
if (active_slot == BOOT_PRIMARY_SLOT) {
926926
active_slot = BOOT_SECONDARY_SLOT;
@@ -930,7 +930,7 @@ int app_max_size(struct boot_loader_state *state)
930930

931931
fap = BOOT_IMG_AREA(state, active_slot);
932932
assert(fap != NULL);
933-
secondary_sz = flash_area_get_size(fap);
933+
secondary_sz = bootutil_max_image_size(state, fap);
934934

935935
return (secondary_sz < primary_sz ? secondary_sz : primary_sz);
936936
}

0 commit comments

Comments
 (0)