Skip to content

Commit 4772da1

Browse files
committed
bootutil: Support for logical sectors
The commit adds support for logical/software sectors. User can select size of sector by which image will be moved using configuration identifier MCUBOOT_LOGICAL_SECTOR_SIZE. Non-0 value set to MCUBOOT_LOGICAL_SECTOR_SIZE will be used as sector size for image swap algorithms. Note that the value provided here should be aligned to hardware erase page of device(s) used and may not be smaller than of such a device. There is also additional option provided, MCUBOOT_LOGICAL_SECTOR_VALIDATE, that allows to enable validation of selected logical sector against true layout of a device. Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
1 parent c136f4a commit 4772da1

File tree

3 files changed

+168
-2
lines changed

3 files changed

+168
-2
lines changed

boot/bootutil/src/bootutil_misc.c

Lines changed: 138 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,15 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
5656
/* Currently only used by imgmgr */
5757
int boot_current_slot;
5858

59+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
5960
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
6061
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
6162
/* Used for holding static buffers in multiple functions to work around issues
6263
* in older versions of gcc (e.g. 4.8.4)
6364
*/
6465
static struct boot_sector_buffer sector_buffers;
6566
#endif
67+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
6668

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

626628
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
627629
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
630+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
628631
int
629632
boot_initialize_area(struct boot_loader_state *state, int flash_area)
630633
{
@@ -665,6 +668,112 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area)
665668
return 0;
666669
}
667670

671+
#else /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
672+
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
673+
/* Validation can only run once all flash areas are open and pointers to
674+
* flash area objects are stored in state.
675+
*/
676+
static int
677+
boot_validate_logical_sectors(const struct boot_loader_state *state, int faid, const struct flash_area *fa)
678+
{
679+
uint32_t num_sectors = BOOT_MAX_IMG_SECTORS;
680+
size_t slot_size;
681+
size_t slot_off;
682+
size_t sect_off = 0;
683+
int rc;
684+
int final_rc = 0;
685+
686+
assert(fa != NULL);
687+
assert(faid != 0);
688+
689+
slot_off = flash_area_get_off(fa);
690+
slot_size = flash_area_get_size(fa);
691+
692+
693+
/* Go till all validations are complete or we face issue that does not allow
694+
* to proceede with further tests.
695+
*/
696+
BOOT_LOG_INF("boot_validate_logical_sectors: validating flash area %p", fa);
697+
BOOT_LOG_INF("boot_validate_logical_sectors: MCUBOOT_LOGICAL_SECTOR_SIZE == 0x%x",
698+
MCUBOOT_LOGICAL_SECTOR_SIZE);
699+
BOOT_LOG_INF("boot_validate_logical_sectors: slot offset == 0x%x", slot_off);
700+
if (slot_size != 0) {
701+
BOOT_LOG_INF("boot_validate_logical_sectors: slot size == 0x%x", slot_size);
702+
} else {
703+
BOOT_LOG_ERR("boot_validate_logical_sectors: 0 size slot");
704+
return BOOT_EFLASH;
705+
}
706+
707+
BOOT_LOG_INF("boot_validate_logical_sectors: max %d logical sectors",
708+
slot_size / MCUBOOT_LOGICAL_SECTOR_SIZE);
709+
710+
if (slot_off % MCUBOOT_LOGICAL_SECTOR_SIZE) {
711+
BOOT_LOG_ERR("boot_validate_logical_sectors: area offset not aligned");
712+
final_rc = BOOT_EFLASH;
713+
}
714+
715+
if (slot_size % MCUBOOT_LOGICAL_SECTOR_SIZE) {
716+
BOOT_LOG_ERR("boot_validate_logical_sectors: area size not aligned");
717+
final_rc = BOOT_EFLASH;
718+
}
719+
720+
/* Check all hardware specific pages against erase pages of a device */
721+
for (size_t i = 0; i < num_sectors; i++) {
722+
struct flash_sector fas;
723+
724+
MCUBOOT_WATCHDOG_FEED();
725+
726+
BOOT_LOG_INF("boot_validate_logical_sectors: page 0x%x:0x%x ", slot_off, sect_off);
727+
rc = flash_area_get_sector(fa, sect_off, &fas);
728+
if (rc < 0) {
729+
BOOT_LOG_ERR("boot_validate_logical_sectors: query err %d", rc);
730+
final_rc = BOOT_EFLASH;
731+
continue;
732+
}
733+
734+
735+
if (flash_sector_get_off(&fas) % MCUBOOT_LOGICAL_SECTOR_SIZE) {
736+
BOOT_LOG_ERR("boot_validate_logical_sectors: misaligned offset");
737+
final_rc = BOOT_EFLASH;
738+
}
739+
740+
sect_off += flash_sector_get_size(&fas);
741+
}
742+
743+
BOOT_LOG_INF("boot_validate_logical_sectors: done %d", final_rc);
744+
745+
return final_rc;
746+
}
747+
#endif /* MCUBOOT_LOGICAL_SECTOR_VALIDATION */
748+
749+
static int
750+
boot_initialize_area(struct boot_loader_state *state, int flash_area)
751+
{
752+
size_t area_size;
753+
uint32_t *out_num_sectors;
754+
755+
if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
756+
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
757+
out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors;
758+
} else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
759+
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT));
760+
out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
761+
#if MCUBOOT_SWAP_USING_SCRATCH
762+
} else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
763+
area_size = flash_area_get_size(state->scratch.area);
764+
out_num_sectors = &state->scratch.num_sectors;
765+
#endif
766+
} else {
767+
return BOOT_EFLASH;
768+
}
769+
770+
*out_num_sectors = area_size / MCUBOOT_LOGICAL_SECTOR_SIZE;
771+
772+
return 0;
773+
}
774+
775+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
776+
668777
static uint32_t
669778
boot_write_sz(struct boot_loader_state *state)
670779
{
@@ -694,12 +803,13 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
694803
uint8_t image_index;
695804
int rc;
696805

806+
image_index = BOOT_CURR_IMG(state);
807+
808+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
697809
if (sectors == NULL) {
698810
sectors = &sector_buffers;
699811
}
700812

701-
image_index = BOOT_CURR_IMG(state);
702-
703813
BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
704814
sectors->primary[image_index];
705815
#if BOOT_NUM_SLOTS > 1
@@ -709,6 +819,9 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
709819
state->scratch.sectors = sectors->scratch;
710820
#endif
711821
#endif
822+
#else
823+
(void)sectors;
824+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
712825

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

733846
BOOT_WRITE_SZ(state) = boot_write_sz(state);
734847

848+
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
849+
BOOT_LOG_INF("boot_read_sectors: validate image %d slots", image_index);
850+
BOOT_LOG_INF("boot_read_sectors: BOOT_PRIMARY_SLOT");
851+
if (boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_PRIMARY(image_index),
852+
BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)) != 0) {
853+
rc = BOOT_EFLASH;
854+
}
855+
856+
BOOT_LOG_INF("boot_read_sectors: BOOT_SECONDARY_SLOT");
857+
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SECONDARY(image_index),
858+
BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) != 0) {
859+
rc = BOOT_EFLASH_SEC;
860+
}
861+
862+
#if MCUBOOT_SWAP_USING_SCRATCH
863+
BOOT_LOG_INF("boot_read_sectors: SCRATCH");
864+
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SCRATCH,
865+
state->scratch.area) != 0) {
866+
rc = BOOT_EFLASH;
867+
}
868+
#endif /* MCUBOOT_SWAP_USING_SCRATCH */
869+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION) */
870+
735871
return 0;
736872
}
737873
#endif

boot/bootutil/src/bootutil_priv.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,14 +245,18 @@ struct boot_loader_state {
245245
struct {
246246
struct image_header hdr;
247247
const struct flash_area *area;
248+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
248249
boot_sector_t *sectors;
250+
#endif
249251
uint32_t num_sectors;
250252
} imgs[BOOT_IMAGE_NUMBER][BOOT_NUM_SLOTS];
251253

252254
#if MCUBOOT_SWAP_USING_SCRATCH
253255
struct {
254256
const struct flash_area *area;
257+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
255258
boot_sector_t *sectors;
259+
#endif
256260
uint32_t num_sectors;
257261
} scratch;
258262
#endif
@@ -515,6 +519,7 @@ boot_img_slot_off(struct boot_loader_state *state, size_t slot)
515519
return flash_area_get_off(BOOT_IMG_AREA(state, slot));
516520
}
517521

522+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
518523
#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
519524

520525
static inline size_t
@@ -554,6 +559,25 @@ boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
554559
}
555560

556561
#endif /* !defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
562+
#else
563+
static inline size_t
564+
boot_img_sector_size(const struct boot_loader_state *state,
565+
size_t slot, size_t sector)
566+
{
567+
return MCUBOOT_LOGICAL_SECTOR_SIZE;
568+
}
569+
570+
/*
571+
* Offset of the sector from the beginning of the image, NOT the flash
572+
* device.
573+
*/
574+
static inline uint32_t
575+
boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
576+
size_t sector)
577+
{
578+
return MCUBOOT_LOGICAL_SECTOR_SIZE * sector;
579+
}
580+
#endif
557581

558582
#ifdef MCUBOOT_RAM_LOAD
559583
# ifdef __BOOTSIM__

boot/bootutil/src/loader.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr,
651651
}
652652

653653
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
654+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
654655
static fih_ret
655656
split_image_check(struct image_header *app_hdr,
656657
const struct flash_area *app_fap,
@@ -681,6 +682,7 @@ split_image_check(struct image_header *app_hdr,
681682
out:
682683
FIH_RET(fih_rc);
683684
}
685+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
684686
#endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */
685687

686688
/*
@@ -2159,10 +2161,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
21592161

21602162
BOOT_LOG_DBG("context_boot_go");
21612163

2164+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
21622165
#if defined(__BOOTSIM__)
21632166
struct boot_sector_buffer sector_buf;
21642167
sectors = &sector_buf;
21652168
#endif
2169+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
21662170

21672171
has_upgrade = false;
21682172

@@ -2422,6 +2426,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
24222426
FIH_RET(fih_rc);
24232427
}
24242428

2429+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
24252430
fih_ret
24262431
split_go(int loader_slot, int split_slot, void **entry)
24272432
{
@@ -2487,6 +2492,7 @@ split_go(int loader_slot, int split_slot, void **entry)
24872492

24882493
FIH_RET(fih_rc);
24892494
}
2495+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
24902496

24912497
#else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
24922498

0 commit comments

Comments
 (0)