Skip to content

Commit f8ae71b

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 2e4e144 commit f8ae71b

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
@@ -52,13 +52,15 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
5252
/* Currently only used by imgmgr */
5353
int boot_current_slot;
5454

55+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
5556
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
5657
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
5758
/* Used for holding static buffers in multiple functions to work around issues
5859
* in older versions of gcc (e.g. 4.8.4)
5960
*/
6061
static struct boot_sector_buffer sector_buffers;
6162
#endif
63+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
6264

6365
/**
6466
* @brief Determine if the data at two memory addresses is equal
@@ -711,6 +713,7 @@ boot_erase_region(const struct flash_area *fa, uint32_t off, uint32_t size, bool
711713

712714
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
713715
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
716+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
714717
int
715718
boot_initialize_area(struct boot_loader_state *state, int flash_area)
716719
{
@@ -751,6 +754,112 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area)
751754
return 0;
752755
}
753756

757+
#else /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
758+
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
759+
/* Validation can only run once all flash areas are open and pointers to
760+
* flash area objects are stored in state.
761+
*/
762+
static int
763+
boot_validate_logical_sectors(const struct boot_loader_state *state, int faid, const struct flash_area *fa)
764+
{
765+
uint32_t num_sectors = BOOT_MAX_IMG_SECTORS;
766+
size_t slot_size;
767+
size_t slot_off;
768+
size_t sect_off = 0;
769+
int rc;
770+
int final_rc = 0;
771+
772+
assert(fa != NULL);
773+
assert(faid != 0);
774+
775+
slot_off = flash_area_get_off(fa);
776+
slot_size = flash_area_get_size(fa);
777+
778+
779+
/* Go till all validations are complete or we face issue that does not allow
780+
* to proceede with further tests.
781+
*/
782+
BOOT_LOG_INF("boot_validate_logical_sectors: validating flash area %p", fa);
783+
BOOT_LOG_INF("boot_validate_logical_sectors: MCUBOOT_LOGICAL_SECTOR_SIZE == 0x%x",
784+
MCUBOOT_LOGICAL_SECTOR_SIZE);
785+
BOOT_LOG_INF("boot_validate_logical_sectors: slot offset == 0x%x", slot_off);
786+
if (slot_size != 0) {
787+
BOOT_LOG_INF("boot_validate_logical_sectors: slot size == 0x%x", slot_size);
788+
} else {
789+
BOOT_LOG_ERR("boot_validate_logical_sectors: 0 size slot");
790+
return BOOT_EFLASH;
791+
}
792+
793+
BOOT_LOG_INF("boot_validate_logical_sectors: max %d logical sectors",
794+
slot_size / MCUBOOT_LOGICAL_SECTOR_SIZE);
795+
796+
if (slot_off % MCUBOOT_LOGICAL_SECTOR_SIZE) {
797+
BOOT_LOG_ERR("boot_validate_logical_sectors: area offset not aligned");
798+
final_rc = BOOT_EFLASH;
799+
}
800+
801+
if (slot_size % MCUBOOT_LOGICAL_SECTOR_SIZE) {
802+
BOOT_LOG_ERR("boot_validate_logical_sectors: area size not aligned");
803+
final_rc = BOOT_EFLASH;
804+
}
805+
806+
/* Check all hardware specific pages against erase pages of a device */
807+
for (size_t i = 0; i < num_sectors; i++) {
808+
struct flash_sector fas;
809+
810+
MCUBOOT_WATCHDOG_FEED();
811+
812+
BOOT_LOG_INF("boot_validate_logical_sectors: page 0x%x:0x%x ", slot_off, sect_off);
813+
rc = flash_area_get_sector(fa, sect_off, &fas);
814+
if (rc < 0) {
815+
BOOT_LOG_ERR("boot_validate_logical_sectors: query err %d", rc);
816+
final_rc = BOOT_EFLASH;
817+
continue;
818+
}
819+
820+
821+
if (flash_sector_get_off(&fas) % MCUBOOT_LOGICAL_SECTOR_SIZE) {
822+
BOOT_LOG_ERR("boot_validate_logical_sectors: misaligned offset");
823+
final_rc = BOOT_EFLASH;
824+
}
825+
826+
sect_off += flash_sector_get_size(&fas);
827+
}
828+
829+
BOOT_LOG_INF("boot_validate_logical_sectors: done %d", final_rc);
830+
831+
return final_rc;
832+
}
833+
#endif /* MCUBOOT_LOGICAL_SECTOR_VALIDATION */
834+
835+
static int
836+
boot_initialize_area(struct boot_loader_state *state, int flash_area)
837+
{
838+
size_t area_size;
839+
uint32_t *out_num_sectors;
840+
841+
if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
842+
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
843+
out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors;
844+
} else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
845+
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT));
846+
out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
847+
#if MCUBOOT_SWAP_USING_SCRATCH
848+
} else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
849+
area_size = flash_area_get_size(state->scratch.area);
850+
out_num_sectors = &state->scratch.num_sectors;
851+
#endif
852+
} else {
853+
return BOOT_EFLASH;
854+
}
855+
856+
*out_num_sectors = area_size / MCUBOOT_LOGICAL_SECTOR_SIZE;
857+
858+
return 0;
859+
}
860+
861+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
862+
754863
static uint32_t
755864
boot_write_sz(struct boot_loader_state *state)
756865
{
@@ -780,12 +889,13 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
780889
uint8_t image_index;
781890
int rc;
782891

892+
image_index = BOOT_CURR_IMG(state);
893+
894+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
783895
if (sectors == NULL) {
784896
sectors = &sector_buffers;
785897
}
786898

787-
image_index = BOOT_CURR_IMG(state);
788-
789899
BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
790900
sectors->primary[image_index];
791901
#if BOOT_NUM_SLOTS > 1
@@ -795,6 +905,9 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
795905
state->scratch.sectors = sectors->scratch;
796906
#endif
797907
#endif
908+
#else
909+
(void)sectors;
910+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
798911

799912
rc = boot_initialize_area(state, FLASH_AREA_IMAGE_PRIMARY(image_index));
800913
if (rc != 0) {
@@ -818,6 +931,29 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
818931

819932
BOOT_WRITE_SZ(state) = boot_write_sz(state);
820933

934+
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
935+
BOOT_LOG_INF("boot_read_sectors: validate image %d slots", image_index);
936+
BOOT_LOG_INF("boot_read_sectors: BOOT_PRIMARY_SLOT");
937+
if (boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_PRIMARY(image_index),
938+
BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)) != 0) {
939+
rc = BOOT_EFLASH;
940+
}
941+
942+
BOOT_LOG_INF("boot_read_sectors: BOOT_SECONDARY_SLOT");
943+
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SECONDARY(image_index),
944+
BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) != 0) {
945+
rc = BOOT_EFLASH_SEC;
946+
}
947+
948+
#if MCUBOOT_SWAP_USING_SCRATCH
949+
BOOT_LOG_INF("boot_read_sectors: SCRATCH");
950+
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SCRATCH,
951+
state->scratch.area) != 0) {
952+
rc = BOOT_EFLASH;
953+
}
954+
#endif /* MCUBOOT_SWAP_USING_SCRATCH */
955+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION) */
956+
821957
return 0;
822958
}
823959
#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
@@ -518,6 +522,7 @@ boot_img_slot_off(struct boot_loader_state *state, size_t slot)
518522
return flash_area_get_off(BOOT_IMG_AREA(state, slot));
519523
}
520524

525+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
521526
#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
522527

523528
static inline size_t
@@ -557,6 +562,25 @@ boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
557562
}
558563

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

561585
#ifdef MCUBOOT_RAM_LOAD
562586
# 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)