Skip to content

Logical sectors #2352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 138 additions & 2 deletions boot/bootutil/src/bootutil_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
/* Currently only used by imgmgr */
int boot_current_slot;

#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
/* Used for holding static buffers in multiple functions to work around issues
* in older versions of gcc (e.g. 4.8.4)
*/
static struct boot_sector_buffer sector_buffers;
#endif
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */

/**
* @brief Determine if the data at two memory addresses is equal
Expand Down Expand Up @@ -625,6 +627,7 @@ boot_erase_region(const struct flash_area *fa, uint32_t off, uint32_t size, bool

#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
int
boot_initialize_area(struct boot_loader_state *state, int flash_area)
{
Expand Down Expand Up @@ -665,6 +668,112 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area)
return 0;
}

#else /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
/* Validation can only run once all flash areas are open and pointers to
* flash area objects are stored in state.
*/
static int
boot_validate_logical_sectors(const struct boot_loader_state *state, int faid, const struct flash_area *fa)
{
uint32_t num_sectors = BOOT_MAX_IMG_SECTORS;
size_t slot_size;
size_t slot_off;
size_t sect_off = 0;
int rc;
int final_rc = 0;

assert(fa != NULL);
assert(faid != 0);

slot_off = flash_area_get_off(fa);
slot_size = flash_area_get_size(fa);


/* Go till all validations are complete or we face issue that does not allow
* to proceede with further tests.
*/
BOOT_LOG_INF("boot_validate_logical_sectors: validating flash area %p", fa);
BOOT_LOG_INF("boot_validate_logical_sectors: MCUBOOT_LOGICAL_SECTOR_SIZE == 0x%x",
MCUBOOT_LOGICAL_SECTOR_SIZE);
BOOT_LOG_INF("boot_validate_logical_sectors: slot offset == 0x%x", slot_off);
if (slot_size != 0) {
BOOT_LOG_INF("boot_validate_logical_sectors: slot size == 0x%x", slot_size);
} else {
BOOT_LOG_ERR("boot_validate_logical_sectors: 0 size slot");
return BOOT_EFLASH;
}

BOOT_LOG_INF("boot_validate_logical_sectors: max %d logical sectors",
slot_size / MCUBOOT_LOGICAL_SECTOR_SIZE);

if (slot_off % MCUBOOT_LOGICAL_SECTOR_SIZE) {
BOOT_LOG_ERR("boot_validate_logical_sectors: area offset not aligned");
final_rc = BOOT_EFLASH;
}

if (slot_size % MCUBOOT_LOGICAL_SECTOR_SIZE) {
BOOT_LOG_ERR("boot_validate_logical_sectors: area size not aligned");
final_rc = BOOT_EFLASH;
}

/* Check all hardware specific pages against erase pages of a device */
for (size_t i = 0; i < num_sectors; i++) {
struct flash_sector fas;

MCUBOOT_WATCHDOG_FEED();

BOOT_LOG_INF("boot_validate_logical_sectors: page 0x%x:0x%x ", slot_off, sect_off);
rc = flash_area_get_sector(fa, sect_off, &fas);
if (rc < 0) {
BOOT_LOG_ERR("boot_validate_logical_sectors: query err %d", rc);
final_rc = BOOT_EFLASH;
continue;
}


if (flash_sector_get_off(&fas) % MCUBOOT_LOGICAL_SECTOR_SIZE) {
BOOT_LOG_ERR("boot_validate_logical_sectors: misaligned offset");
final_rc = BOOT_EFLASH;
}

sect_off += flash_sector_get_size(&fas);
}

BOOT_LOG_INF("boot_validate_logical_sectors: done %d", final_rc);

return final_rc;
}
#endif /* MCUBOOT_LOGICAL_SECTOR_VALIDATION */

static int
boot_initialize_area(struct boot_loader_state *state, int flash_area)
{
size_t area_size;
uint32_t *out_num_sectors;

if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors;
} else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT));
out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
#if MCUBOOT_SWAP_USING_SCRATCH
} else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
area_size = flash_area_get_size(state->scratch.area);
out_num_sectors = &state->scratch.num_sectors;
#endif
} else {
return BOOT_EFLASH;
}

*out_num_sectors = area_size / MCUBOOT_LOGICAL_SECTOR_SIZE;

return 0;
}

#endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */

static uint32_t
boot_write_sz(struct boot_loader_state *state)
{
Expand Down Expand Up @@ -694,12 +803,13 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
uint8_t image_index;
int rc;

image_index = BOOT_CURR_IMG(state);

#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
if (sectors == NULL) {
sectors = &sector_buffers;
}

image_index = BOOT_CURR_IMG(state);

BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
sectors->primary[image_index];
#if BOOT_NUM_SLOTS > 1
Expand All @@ -709,6 +819,9 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
state->scratch.sectors = sectors->scratch;
#endif
#endif
#else
(void)sectors;
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */

rc = boot_initialize_area(state, FLASH_AREA_IMAGE_PRIMARY(image_index));
if (rc != 0) {
Expand All @@ -732,6 +845,29 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se

BOOT_WRITE_SZ(state) = boot_write_sz(state);

#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
BOOT_LOG_INF("boot_read_sectors: validate image %d slots", image_index);
BOOT_LOG_INF("boot_read_sectors: BOOT_PRIMARY_SLOT");
if (boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_PRIMARY(image_index),
BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)) != 0) {
rc = BOOT_EFLASH;
}

BOOT_LOG_INF("boot_read_sectors: BOOT_SECONDARY_SLOT");
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SECONDARY(image_index),
BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) != 0) {
rc = BOOT_EFLASH_SEC;
}

#if MCUBOOT_SWAP_USING_SCRATCH
BOOT_LOG_INF("boot_read_sectors: SCRATCH");
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SCRATCH,
state->scratch.area) != 0) {
rc = BOOT_EFLASH;
}
#endif /* MCUBOOT_SWAP_USING_SCRATCH */
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION) */

return 0;
}
#endif
Expand Down
24 changes: 24 additions & 0 deletions boot/bootutil/src/bootutil_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,14 +245,18 @@ struct boot_loader_state {
struct {
struct image_header hdr;
const struct flash_area *area;
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
boot_sector_t *sectors;
#endif
uint32_t num_sectors;
} imgs[BOOT_IMAGE_NUMBER][BOOT_NUM_SLOTS];

#if MCUBOOT_SWAP_USING_SCRATCH
struct {
const struct flash_area *area;
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
boot_sector_t *sectors;
#endif
uint32_t num_sectors;
} scratch;
#endif
Expand Down Expand Up @@ -515,6 +519,7 @@ boot_img_slot_off(struct boot_loader_state *state, size_t slot)
return flash_area_get_off(BOOT_IMG_AREA(state, slot));
}

#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS

static inline size_t
Expand Down Expand Up @@ -554,6 +559,25 @@ boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
}

#endif /* !defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
#else
static inline size_t
boot_img_sector_size(const struct boot_loader_state *state,
size_t slot, size_t sector)
{
return MCUBOOT_LOGICAL_SECTOR_SIZE;
}

/*
* Offset of the sector from the beginning of the image, NOT the flash
* device.
*/
static inline uint32_t
boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
size_t sector)
{
return MCUBOOT_LOGICAL_SECTOR_SIZE * sector;
}
#endif

#ifdef MCUBOOT_RAM_LOAD
# ifdef __BOOTSIM__
Expand Down
6 changes: 6 additions & 0 deletions boot/bootutil/src/loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr,
}

#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
static fih_ret
split_image_check(struct image_header *app_hdr,
const struct flash_area *app_fap,
Expand Down Expand Up @@ -681,6 +682,7 @@ split_image_check(struct image_header *app_hdr,
out:
FIH_RET(fih_rc);
}
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
#endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */

/*
Expand Down Expand Up @@ -2159,10 +2161,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)

BOOT_LOG_DBG("context_boot_go");

#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
#if defined(__BOOTSIM__)
struct boot_sector_buffer sector_buf;
sectors = &sector_buf;
#endif
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */

has_upgrade = false;

Expand Down Expand Up @@ -2422,6 +2426,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
FIH_RET(fih_rc);
}

#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
fih_ret
split_go(int loader_slot, int split_slot, void **entry)
{
Expand Down Expand Up @@ -2487,6 +2492,7 @@ split_go(int loader_slot, int split_slot, void **entry)

FIH_RET(fih_rc);
}
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */

#else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */

Expand Down
23 changes: 22 additions & 1 deletion boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1112,14 +1112,35 @@ config BOOT_FIH_PROFILE_DEFAULT_HIGH

endmenu

config MCUBOOT_LOGICAL_SECTOR_SIZE
int "Size of a logical sector"
default 0
help
Set to 0 to use hardware sectors. Any other value here should be
aligned to hardware sectors in size and alignment.

config MCUBOOT_LOGICAL_SECTOR_SIZE_SET
bool
default y if MCUBOOT_LOGICAL_SECTOR_SIZE != 0

config MCUBOOT_LOGICAL_SECTOR_VALIDATION
bool "Validate logical sector layout"
default true if MCUBOOT_LOGICAL_SECTOR_SIZE != 0
depends on MCUBOOT_LOGICAL_SECTOR_SIZE_SET
help
Validation of logical sector size against hardware constrains.
Should be used to validate compile-time configuration against run-time
system.

config MCUBOOT_DEVICE_SETTINGS
# Hidden selector for device-specific settings
bool
default y
# CPU options
select MCUBOOT_DEVICE_CPU_CORTEX_M0 if CPU_CORTEX_M0
# Enable flash page layout if available
select FLASH_PAGE_LAYOUT if FLASH_HAS_PAGE_LAYOUT
select FLASH_PAGE_LAYOUT if FLASH_HAS_PAGE_LAYOUT && !MCUBOOT_LOGICAL_SECTOR_SIZE_SET
select FLASH_PAGE_LAYOUT if FLASH_HAS_PAGE_LAYOUT && MCUBOOT_LOGICAL_SECTOR_VALIDATION
# Enable flash_map module as flash I/O back-end
select FLASH_MAP

Expand Down
Loading
Loading