Skip to content

Commit f1efd48

Browse files
taltenbachnordicjm
authored andcommitted
bootutil: loader: Expose routine to determine sector layout
For most upgrade strategies, it is currently needed to determine the sector layout of each flash area to initialize a bootloader state. This is made in loader.c by the internal boot_read_sectors routine. Since doing so will also be needed in boot_serial, this commit exposes this routine in bootutil_priv.h. Previously boot_read_sectors was assuming the provided bootloader state already contained buffers where to store the sectors. To avoid code duplication, the routine is now also responsible for initializing the state with the buffers that are provided as argument. By default, the global static buffers defined in loader.c are used. This will avoid allocating dedicated buffers in boot_serial. Signed-off-by: Thomas Altenbach <[email protected]>
1 parent 7216686 commit f1efd48

File tree

2 files changed

+59
-72
lines changed

2 files changed

+59
-72
lines changed

boot/bootutil/src/bootutil_priv.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@ struct boot_loader_state {
283283
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
284284
};
285285

286+
struct boot_sector_buffer {
287+
boot_sector_t primary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
288+
boot_sector_t secondary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
289+
#if MCUBOOT_SWAP_USING_SCRATCH
290+
boot_sector_t scratch[BOOT_MAX_IMG_SECTORS];
291+
#endif
292+
};
293+
286294
/* The function is intended for verification of image hash against
287295
* provided signature.
288296
*/
@@ -403,6 +411,21 @@ int boot_open_all_flash_areas(struct boot_loader_state *state);
403411
*/
404412
void boot_close_all_flash_areas(struct boot_loader_state *state);
405413

414+
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
415+
/**
416+
* Determines the sector layout of both image slots and the scratch area.
417+
*
418+
* This information is necessary for calculating the number of bytes to erase
419+
* and copy during an image swap. The information collected during this
420+
* function is used to populate the state.
421+
*
422+
* @param state Bootloader state.
423+
* @param sectors Buffers where to store the sector layout. If NULL, the statically-allocated
424+
* buffers in loader.c will be used.
425+
*/
426+
int boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *sectors);
427+
#endif
428+
406429
/**
407430
* Safe (non-overflowing) uint32_t addition. Returns true, and stores
408431
* the result in *dest if it can be done without overflow. Otherwise,

boot/bootutil/src/loader.c

Lines changed: 36 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,10 @@ static struct image_max_size image_max_sizes[BOOT_IMAGE_NUMBER] = {0};
7070

7171
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
7272
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
73-
#if !defined(__BOOTSIM__)
7473
/* Used for holding static buffers in multiple functions to work around issues
7574
* in older versions of gcc (e.g. 4.8.4)
7675
*/
77-
struct sector_buffer_t {
78-
boot_sector_t primary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
79-
boot_sector_t secondary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
80-
#if MCUBOOT_SWAP_USING_SCRATCH
81-
boot_sector_t scratch[BOOT_MAX_IMG_SECTORS];
82-
#endif
83-
};
84-
85-
static struct sector_buffer_t sector_buffers;
86-
#endif
76+
static struct boot_sector_buffer sector_buffers;
8777
#endif
8878

8979
#if (BOOT_IMAGE_NUMBER > 1)
@@ -622,20 +612,26 @@ boot_write_sz(struct boot_loader_state *state)
622612
return elem_sz;
623613
}
624614

625-
/**
626-
* Determines the sector layout of both image slots and the scratch area.
627-
* This information is necessary for calculating the number of bytes to erase
628-
* and copy during an image swap. The information collected during this
629-
* function is used to populate the state.
630-
*/
631-
static int
632-
boot_read_sectors(struct boot_loader_state *state)
615+
int
616+
boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *sectors)
633617
{
634618
uint8_t image_index;
635619
int rc;
636620

621+
if (sectors == NULL) {
622+
sectors = &sector_buffers;
623+
}
624+
637625
image_index = BOOT_CURR_IMG(state);
638626

627+
BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
628+
sectors->primary[image_index];
629+
BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors =
630+
sectors->secondary[image_index];
631+
#if MCUBOOT_SWAP_USING_SCRATCH
632+
state->scratch.sectors = sectors->scratch;
633+
#endif
634+
639635
rc = boot_initialize_area(state, FLASH_AREA_IMAGE_PRIMARY(image_index));
640636
if (rc != 0) {
641637
return BOOT_EFLASH;
@@ -2067,22 +2063,6 @@ boot_prepare_image_for_update(struct boot_loader_state *state,
20672063
int max_size;
20682064
#endif
20692065

2070-
/* Determine the sector layout of the image slots and scratch area. */
2071-
rc = boot_read_sectors(state);
2072-
if (rc != 0) {
2073-
BOOT_LOG_WRN("Failed reading sectors; BOOT_MAX_IMG_SECTORS=%d"
2074-
" - too small?", BOOT_MAX_IMG_SECTORS);
2075-
/* Unable to determine sector layout, continue with next image
2076-
* if there is one.
2077-
*/
2078-
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
2079-
if (rc == BOOT_EFLASH)
2080-
{
2081-
/* Only return on error from the primary image flash */
2082-
return;
2083-
}
2084-
}
2085-
20862066
/* Attempt to read an image header from each slot. */
20872067
rc = boot_read_image_headers(state, false, NULL);
20882068
if (rc != 0) {
@@ -2341,25 +2321,17 @@ fih_ret
23412321
context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
23422322
{
23432323
struct boot_status bs;
2324+
struct boot_sector_buffer *sectors = NULL;
23442325
int rc = -1;
23452326
FIH_DECLARE(fih_rc, FIH_FAILURE);
2346-
int image_index;
23472327
bool has_upgrade;
23482328
volatile int fih_cnt;
23492329

23502330
BOOT_LOG_DBG("context_boot_go");
23512331

23522332
#if defined(__BOOTSIM__)
2353-
/* The array of slot sectors are defined here (as opposed to file scope) so
2354-
* that they don't get allocated for non-boot-loader apps. This is
2355-
* necessary because the gcc option "-fdata-sections" doesn't seem to have
2356-
* any effect in older gcc versions (e.g., 4.8.4).
2357-
*/
2358-
TARGET_STATIC boot_sector_t primary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
2359-
TARGET_STATIC boot_sector_t secondary_slot_sectors[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
2360-
#if MCUBOOT_SWAP_USING_SCRATCH
2361-
TARGET_STATIC boot_sector_t scratch_sectors[BOOT_MAX_IMG_SECTORS];
2362-
#endif
2333+
struct boot_sector_buffer sector_buf;
2334+
sectors = &sector_buf;
23632335
#endif
23642336

23652337
has_upgrade = false;
@@ -2394,28 +2366,22 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
23942366
*/
23952367
boot_enc_zeroize(BOOT_CURR_ENC(state));
23962368
#endif
2369+
/* Determine the sector layout of the image slots and scratch area. */
2370+
rc = boot_read_sectors(state, sectors);
2371+
if (rc != 0) {
2372+
BOOT_LOG_WRN("Failed reading sectors; BOOT_MAX_IMG_SECTORS=%d"
2373+
" - too small?", BOOT_MAX_IMG_SECTORS);
2374+
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_NONE;
2375+
}
23972376

2398-
image_index = BOOT_CURR_IMG(state);
2399-
2400-
#if !defined(__BOOTSIM__)
2401-
BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
2402-
sector_buffers.primary[image_index];
2403-
BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors =
2404-
sector_buffers.secondary[image_index];
2405-
#if MCUBOOT_SWAP_USING_SCRATCH
2406-
state->scratch.sectors = sector_buffers.scratch;
2407-
#endif
2408-
#else
2409-
BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
2410-
primary_slot_sectors[image_index];
2411-
BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors =
2412-
secondary_slot_sectors[image_index];
2413-
#if MCUBOOT_SWAP_USING_SCRATCH
2414-
state->scratch.sectors = scratch_sectors;
2415-
#endif
2416-
#endif
2417-
/* Determine swap type and complete swap if it has been aborted. */
2418-
boot_prepare_image_for_update(state, &bs);
2377+
/* Unless there was an error when determining the sector layout of the primary slot,
2378+
* determine swap type and complete swap if it has been aborted.
2379+
*
2380+
* Note boot_read_sectors returns BOOT_EFLASH_SEC for errors regarding the secondary slot.
2381+
*/
2382+
if (rc != BOOT_EFLASH) {
2383+
boot_prepare_image_for_update(state, &bs);
2384+
}
24192385

24202386
if (BOOT_IS_UPGRADE(BOOT_SWAP_TYPE(state))) {
24212387
has_upgrade = true;
@@ -2629,19 +2595,17 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
26292595
fih_ret
26302596
split_go(int loader_slot, int split_slot, void **entry)
26312597
{
2632-
boot_sector_t *sectors;
2598+
struct boot_sector_buffer *sectors;
26332599
uintptr_t entry_val;
26342600
int loader_flash_id;
26352601
int split_flash_id;
26362602
int rc;
26372603
FIH_DECLARE(fih_rc, FIH_FAILURE);
26382604

2639-
sectors = malloc(BOOT_MAX_IMG_SECTORS * 2 * sizeof *sectors);
2605+
sectors = malloc(sizeof(struct boot_sector_buffer));
26402606
if (sectors == NULL) {
26412607
FIH_RET(FIH_FAILURE);
26422608
}
2643-
BOOT_IMG(&boot_data, loader_slot).sectors = sectors + 0;
2644-
BOOT_IMG(&boot_data, split_slot).sectors = sectors + BOOT_MAX_IMG_SECTORS;
26452609

26462610
loader_flash_id = flash_area_id_from_image_slot(loader_slot);
26472611
rc = flash_area_open(loader_flash_id,
@@ -2653,7 +2617,7 @@ split_go(int loader_slot, int split_slot, void **entry)
26532617
assert(rc == 0);
26542618

26552619
/* Determine the sector layout of the image slots and scratch area. */
2656-
rc = boot_read_sectors(&boot_data);
2620+
rc = boot_read_sectors(&boot_data, sectors);
26572621
if (rc != 0) {
26582622
rc = SPLIT_GO_ERR;
26592623
goto done;

0 commit comments

Comments
 (0)