bootutil: Add active slot number and max app size to shared data
This allows the currently executing slot number to be checked by the external function, which can be used by XIP images to know which slot is currently being executed from to allow for correct uploading/positioning of firmware files, and also provides the maximum size of an upgrade that can be loaded so that applications can reject images that are too large. Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
parent
0540d0fb3f
commit
3016d00cd7
|
@ -59,13 +59,17 @@ int boot_save_boot_status(uint8_t sw_module,
|
|||
* Add application specific data to the shared memory area between the
|
||||
* bootloader and runtime SW.
|
||||
*
|
||||
* @param[in] hdr Pointer to the image header stored in RAM.
|
||||
* @param[in] fap Pointer to the flash area where image is stored.
|
||||
* @param[in] hdr Pointer to the image header stored in RAM.
|
||||
* @param[in] fap Pointer to the flash area where image is stored.
|
||||
* @param[in] slot The currently active slot being booted.
|
||||
* @param[in] max_app_size The maximum size of an image that can be loaded.
|
||||
*
|
||||
* @return 0 on success; nonzero on failure.
|
||||
* @return 0 on success; nonzero on failure.
|
||||
*/
|
||||
int boot_save_shared_data(const struct image_header *hdr,
|
||||
const struct flash_area *fap);
|
||||
const struct flash_area *fap,
|
||||
const uint8_t active_slot,
|
||||
const int max_app_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -129,11 +129,15 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all,
|
|||
*/
|
||||
static int
|
||||
boot_add_shared_data(struct boot_loader_state *state,
|
||||
uint32_t active_slot)
|
||||
uint8_t active_slot)
|
||||
{
|
||||
#if defined(MCUBOOT_MEASURED_BOOT) || defined(MCUBOOT_DATA_SHARING)
|
||||
int rc;
|
||||
|
||||
#ifdef MCUBOOT_DATA_SHARING
|
||||
int max_app_size;
|
||||
#endif
|
||||
|
||||
#ifdef MCUBOOT_MEASURED_BOOT
|
||||
rc = boot_save_boot_status(BOOT_CURR_IMG(state),
|
||||
boot_img_hdr(state, active_slot),
|
||||
|
@ -145,8 +149,10 @@ boot_add_shared_data(struct boot_loader_state *state,
|
|||
#endif /* MCUBOOT_MEASURED_BOOT */
|
||||
|
||||
#ifdef MCUBOOT_DATA_SHARING
|
||||
max_app_size = app_max_size(state);
|
||||
rc = boot_save_shared_data(boot_img_hdr(state, active_slot),
|
||||
BOOT_IMG_AREA(state, active_slot));
|
||||
BOOT_IMG_AREA(state, active_slot),
|
||||
active_slot, max_app_size);
|
||||
if (rc != 0) {
|
||||
BOOT_LOG_ERR("Failed to add data to shared memory area.");
|
||||
return rc;
|
||||
|
@ -3278,7 +3284,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
|
|||
goto out;
|
||||
}
|
||||
|
||||
rc = boot_add_shared_data(state, state->slot_usage[BOOT_CURR_IMG(state)].active_slot);
|
||||
rc = boot_add_shared_data(state, (uint8_t)state->slot_usage[BOOT_CURR_IMG(state)].active_slot);
|
||||
if (rc != 0) {
|
||||
FIH_SET(fih_rc, FIH_FAILURE);
|
||||
goto out;
|
||||
|
|
|
@ -542,4 +542,26 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs,
|
|||
flash_area_close(fap_sec);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -101,4 +101,9 @@ static inline size_t boot_scratch_area_size(const struct boot_loader_state *stat
|
|||
|
||||
#endif /* defined(MCUBOOT_SWAP_USING_SCRATCH) || defined(MCUBOOT_SWAP_USING_MOVE) */
|
||||
|
||||
/**
|
||||
* Returns the maximum size of an application that can be loaded to a slot.
|
||||
*/
|
||||
int app_max_size(struct boot_loader_state *state);
|
||||
|
||||
#endif /* H_SWAP_PRIV_ */
|
||||
|
|
|
@ -743,6 +743,118 @@ swap_run(struct boot_loader_state *state, struct boot_status *bs,
|
|||
}
|
||||
#endif /* !MCUBOOT_OVERWRITE_ONLY */
|
||||
|
||||
int app_max_size(struct boot_loader_state *state)
|
||||
{
|
||||
size_t num_sectors_primary;
|
||||
size_t num_sectors_secondary;
|
||||
size_t sz0, sz1;
|
||||
size_t primary_slot_sz, secondary_slot_sz;
|
||||
#ifndef MCUBOOT_OVERWRITE_ONLY
|
||||
size_t scratch_sz;
|
||||
#endif
|
||||
size_t i, j;
|
||||
int8_t smaller;
|
||||
|
||||
num_sectors_primary = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT);
|
||||
num_sectors_secondary = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT);
|
||||
|
||||
#ifndef MCUBOOT_OVERWRITE_ONLY
|
||||
scratch_sz = boot_scratch_area_size(state);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following loop scans all sectors in a linear fashion, assuring that
|
||||
* for each possible sector in each slot, it is able to fit in the other
|
||||
* slot's sector or sectors. Slot's should be compatible as long as any
|
||||
* number of a slot's sectors are able to fit into another, which only
|
||||
* excludes cases where sector sizes are not a multiple of each other.
|
||||
*/
|
||||
i = sz0 = primary_slot_sz = 0;
|
||||
j = sz1 = secondary_slot_sz = 0;
|
||||
smaller = 0;
|
||||
while (i < num_sectors_primary || j < num_sectors_secondary) {
|
||||
if (sz0 == sz1) {
|
||||
sz0 += boot_img_sector_size(state, BOOT_PRIMARY_SLOT, i);
|
||||
sz1 += boot_img_sector_size(state, BOOT_SECONDARY_SLOT, j);
|
||||
i++;
|
||||
j++;
|
||||
} else if (sz0 < sz1) {
|
||||
sz0 += boot_img_sector_size(state, BOOT_PRIMARY_SLOT, i);
|
||||
/* Guarantee that multiple sectors of the secondary slot
|
||||
* fit into the primary slot.
|
||||
*/
|
||||
if (smaller == 2) {
|
||||
BOOT_LOG_WRN("Cannot upgrade: slots have non-compatible sectors");
|
||||
return 0;
|
||||
}
|
||||
smaller = 1;
|
||||
i++;
|
||||
} else {
|
||||
sz1 += boot_img_sector_size(state, BOOT_SECONDARY_SLOT, j);
|
||||
/* Guarantee that multiple sectors of the primary slot
|
||||
* fit into the secondary slot.
|
||||
*/
|
||||
if (smaller == 1) {
|
||||
BOOT_LOG_WRN("Cannot upgrade: slots have non-compatible sectors");
|
||||
return 0;
|
||||
}
|
||||
smaller = 2;
|
||||
j++;
|
||||
}
|
||||
#ifndef MCUBOOT_OVERWRITE_ONLY
|
||||
if (sz0 == sz1) {
|
||||
primary_slot_sz += sz0;
|
||||
secondary_slot_sz += sz1;
|
||||
/* Scratch has to fit each swap operation to the size of the larger
|
||||
* sector among the primary slot and the secondary slot.
|
||||
*/
|
||||
if (sz0 > scratch_sz || sz1 > scratch_sz) {
|
||||
BOOT_LOG_WRN("Cannot upgrade: not all sectors fit inside scratch");
|
||||
return 0;
|
||||
}
|
||||
smaller = sz0 = sz1 = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef MCUBOOT_OVERWRITE_ONLY
|
||||
return (sz1 < sz0 ? sz1 : sz0);
|
||||
#else
|
||||
return (secondary_slot_sz < primary_slot_sz ? secondary_slot_sz : primary_slot_sz);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
int app_max_size(struct boot_loader_state *state)
|
||||
{
|
||||
const struct flash_area *fap;
|
||||
int fa_id;
|
||||
int rc;
|
||||
uint32_t active_slot;
|
||||
int primary_sz, secondary_sz;
|
||||
|
||||
active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
|
||||
|
||||
fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), active_slot);
|
||||
rc = flash_area_open(fa_id, &fap);
|
||||
assert(rc == 0);
|
||||
primary_sz = flash_area_get_size(fap);
|
||||
flash_area_close(fap);
|
||||
|
||||
if (active_slot == BOOT_PRIMARY_SLOT) {
|
||||
active_slot = BOOT_SECONDARY_SLOT;
|
||||
} else {
|
||||
active_slot = BOOT_PRIMARY_SLOT;
|
||||
}
|
||||
|
||||
fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), active_slot);
|
||||
rc = flash_area_open(fa_id, &fap);
|
||||
assert(rc == 0);
|
||||
secondary_sz = flash_area_get_size(fap);
|
||||
flash_area_close(fap);
|
||||
|
||||
return (secondary_sz < primary_sz ? secondary_sz : primary_sz);
|
||||
}
|
||||
|
||||
#endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */
|
||||
|
||||
#endif /* !MCUBOOT_SWAP_USING_MOVE */
|
||||
|
|
Loading…
Reference in New Issue