Skip to content

Commit 9446404

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 9cae1ca commit 9446404

File tree

2 files changed

+167
-2
lines changed

2 files changed

+167
-2
lines changed

boot/bootutil/src/bootutil_priv.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,18 @@ struct boot_loader_state {
235235
struct {
236236
struct image_header hdr;
237237
const struct flash_area *area;
238+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
238239
boot_sector_t *sectors;
240+
#endif
239241
uint32_t num_sectors;
240242
} imgs[BOOT_IMAGE_NUMBER][BOOT_NUM_SLOTS];
241243

242244
#if MCUBOOT_SWAP_USING_SCRATCH
243245
struct {
244246
const struct flash_area *area;
247+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
245248
boot_sector_t *sectors;
249+
#endif
246250
uint32_t num_sectors;
247251
} scratch;
248252
#endif
@@ -508,6 +512,7 @@ boot_img_slot_off(struct boot_loader_state *state, size_t slot)
508512
return flash_area_get_off(BOOT_IMG_AREA(state, slot));
509513
}
510514

515+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
511516
#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
512517

513518
static inline size_t
@@ -547,6 +552,25 @@ boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
547552
}
548553

549554
#endif /* !defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
555+
#else
556+
static inline size_t
557+
boot_img_sector_size(const struct boot_loader_state *state,
558+
size_t slot, size_t sector)
559+
{
560+
return MCUBOOT_LOGICAL_SECTOR_SIZE;
561+
}
562+
563+
/*
564+
* Offset of the sector from the beginning of the image, NOT the flash
565+
* device.
566+
*/
567+
static inline uint32_t
568+
boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
569+
size_t sector)
570+
{
571+
return MCUBOOT_LOGICAL_SECTOR_SIZE * sector;
572+
}
573+
#endif
550574

551575
#ifdef MCUBOOT_RAM_LOAD
552576
# ifdef __BOOTSIM__

boot/bootutil/src/loader.c

Lines changed: 143 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,15 @@ static struct boot_loader_state boot_data;
6868
static struct image_max_size image_max_sizes[BOOT_IMAGE_NUMBER] = {0};
6969
#endif
7070

71+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
7172
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
7273
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
7374
/* Used for holding static buffers in multiple functions to work around issues
7475
* in older versions of gcc (e.g. 4.8.4)
7576
*/
7677
static struct boot_sector_buffer sector_buffers;
7778
#endif
79+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
7880

7981
#if (BOOT_IMAGE_NUMBER > 1)
8082
#define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x))
@@ -296,6 +298,7 @@ boot_version_cmp(const struct image_version *ver1,
296298
}
297299
#endif
298300

301+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
299302
#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || \
300303
defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
301304
static int
@@ -336,6 +339,111 @@ boot_initialize_area(struct boot_loader_state *state, int flash_area)
336339
return 0;
337340
}
338341
#endif
342+
#else /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
343+
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
344+
/* Validation can only run once all flash areaa area open and pointers to
345+
* flash area objects area stored in state.
346+
*/
347+
static int
348+
boot_validate_logical_sectors(const struct boot_loader_state *state, int faid, const struct flash_area *fa)
349+
{
350+
uint32_t num_sectors = BOOT_MAX_IMG_SECTORS;
351+
size_t slot_size;
352+
size_t slot_off;
353+
size_t sect_off = 0;
354+
int rc;
355+
int final_rc = 0;
356+
357+
assert(fa != NULL);
358+
assert(faid != 0);
359+
360+
slot_off = flash_area_get_off(fa);
361+
slot_size = flash_area_get_size(fa);
362+
363+
364+
/* Go till all validations are complete or we face issue that does not allow
365+
* to proceede with further tests.
366+
*/
367+
BOOT_LOG_INF("boot_validate_logical_sectors: validating flash area %p", fa);
368+
BOOT_LOG_INF("boot_validate_logical_sectors: MCUBOOT_LOGICAL_SECTOR_SIZE == 0x%x",
369+
MCUBOOT_LOGICAL_SECTOR_SIZE);
370+
BOOT_LOG_INF("boot_validate_logical_sectors: slot offset == 0x%x", slot_off);
371+
if (slot_size != 0) {
372+
BOOT_LOG_INF("boot_validate_logical_sectors: slot size == 0x%x", slot_size);
373+
} else {
374+
BOOT_LOG_ERR("boot_validate_logical_sectors: 0 size slot");
375+
return BOOT_EFLASH;
376+
}
377+
378+
BOOT_LOG_INF("boot_validate_logical_sectors: max %d logical sectors",
379+
slot_size / MCUBOOT_LOGICAL_SECTOR_SIZE);
380+
381+
if (slot_off % MCUBOOT_LOGICAL_SECTOR_SIZE) {
382+
BOOT_LOG_ERR("boot_validate_logical_sectors: area offset not aligned");
383+
final_rc = BOOT_EFLASH;
384+
}
385+
386+
if (slot_size % MCUBOOT_LOGICAL_SECTOR_SIZE) {
387+
BOOT_LOG_ERR("boot_validate_logical_sectors: area size not aligned");
388+
final_rc = BOOT_EFLASH;
389+
}
390+
391+
/* Check all hardware specific pages against erase pages of a device */
392+
for (size_t i = 0; i < num_sectors; i++) {
393+
struct flash_sector fas;
394+
395+
MCUBOOT_WATCHDOG_FEED();
396+
397+
BOOT_LOG_INF("boot_validate_logical_sectors: page 0x%x:0x%x ", slot_off, sect_off);
398+
rc = flash_area_get_sector(fa, sect_off, &fas);
399+
if (rc < 0) {
400+
BOOT_LOG_ERR("boot_validate_logical_sectors: query err %d", rc);
401+
final_rc = BOOT_EFLASH;
402+
continue;
403+
}
404+
405+
406+
if (flash_sector_get_off(&fas) % MCUBOOT_LOGICAL_SECTOR_SIZE) {
407+
BOOT_LOG_ERR("boot_validate_logical_sectors: misaligned offset");
408+
final_rc = BOOT_EFLASH;
409+
}
410+
411+
sect_off += flash_sector_get_size(&fas);
412+
}
413+
414+
BOOT_LOG_INF("boot_validate_logical_sectors: done %d", final_rc);
415+
416+
return final_rc;
417+
}
418+
#endif /* MCUBOOT_LOGICAL_SECTOR_VALIDATION */
419+
420+
static int
421+
boot_initialize_area(struct boot_loader_state *state, int flash_area)
422+
{
423+
size_t area_size;
424+
uint32_t *out_num_sectors;
425+
426+
if (flash_area == FLASH_AREA_IMAGE_PRIMARY(BOOT_CURR_IMG(state))) {
427+
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT));
428+
out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors;
429+
} else if (flash_area == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
430+
area_size = flash_area_get_size(BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT));
431+
out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
432+
#if MCUBOOT_SWAP_USING_SCRATCH
433+
} else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
434+
area_size = flash_area_get_size(state->scratch.area);
435+
out_num_sectors = &state->scratch.num_sectors;
436+
#endif
437+
} else {
438+
return BOOT_EFLASH;
439+
}
440+
441+
*out_num_sectors = area_size / MCUBOOT_LOGICAL_SECTOR_SIZE;
442+
443+
return 0;
444+
}
445+
446+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
339447

340448
#if defined(MCUBOOT_SERIAL_IMG_GRP_SLOT_INFO)
341449
static int
@@ -618,19 +726,23 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
618726
uint8_t image_index;
619727
int rc;
620728

729+
image_index = BOOT_CURR_IMG(state);
730+
731+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
621732
if (sectors == NULL) {
622733
sectors = &sector_buffers;
623734
}
624735

625-
image_index = BOOT_CURR_IMG(state);
626-
627736
BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors =
628737
sectors->primary[image_index];
629738
BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors =
630739
sectors->secondary[image_index];
631740
#if MCUBOOT_SWAP_USING_SCRATCH
632741
state->scratch.sectors = sectors->scratch;
633742
#endif
743+
#else
744+
(void)sectors;
745+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
634746

635747
rc = boot_initialize_area(state, FLASH_AREA_IMAGE_PRIMARY(image_index));
636748
if (rc != 0) {
@@ -652,6 +764,29 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
652764

653765
BOOT_WRITE_SZ(state) = boot_write_sz(state);
654766

767+
#if defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION)
768+
BOOT_LOG_INF("boot_read_sectors: validate image %d slots", image_index);
769+
BOOT_LOG_INF("boot_read_sectors: BOOT_PRIMARY_SLOT");
770+
if (boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_PRIMARY(image_index),
771+
BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT)) != 0) {
772+
rc = BOOT_EFLASH;
773+
}
774+
775+
BOOT_LOG_INF("boot_read_sectors: BOOT_SECONDARY_SLOT");
776+
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SECONDARY(image_index),
777+
BOOT_IMG_AREA(state, BOOT_SECONDARY_SLOT)) != 0) {
778+
rc = BOOT_EFLASH_SEC;
779+
}
780+
781+
#if MCUBOOT_SWAP_USING_SCRATCH
782+
BOOT_LOG_INF("boot_read_sectors: SCRATCH");
783+
if(boot_validate_logical_sectors(state, FLASH_AREA_IMAGE_SCRATCH,
784+
state->scratch.area) != 0) {
785+
rc = BOOT_EFLASH;
786+
}
787+
#endif /* MCUBOOT_SWAP_USING_SCRATCH */
788+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_VALIDATION) */
789+
655790
return 0;
656791
}
657792

@@ -789,6 +924,7 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr,
789924
}
790925

791926
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
927+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
792928
static fih_ret
793929
split_image_check(struct image_header *app_hdr,
794930
const struct flash_area *app_fap,
@@ -819,6 +955,7 @@ split_image_check(struct image_header *app_hdr,
819955
out:
820956
FIH_RET(fih_rc);
821957
}
958+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
822959
#endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */
823960

824961
/*
@@ -2297,10 +2434,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
22972434

22982435
BOOT_LOG_DBG("context_boot_go");
22992436

2437+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
23002438
#if defined(__BOOTSIM__)
23012439
struct boot_sector_buffer sector_buf;
23022440
sectors = &sector_buf;
23032441
#endif
2442+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
23042443

23052444
has_upgrade = false;
23062445

@@ -2560,6 +2699,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
25602699
FIH_RET(fih_rc);
25612700
}
25622701

2702+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
25632703
fih_ret
25642704
split_go(int loader_slot, int split_slot, void **entry)
25652705
{
@@ -2625,6 +2765,7 @@ split_go(int loader_slot, int split_slot, void **entry)
26252765

26262766
FIH_RET(fih_rc);
26272767
}
2768+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
26282769

26292770
#else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
26302771

0 commit comments

Comments
 (0)