Skip to content

Commit f01bf12

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 <[email protected]>
1 parent 07222c1 commit f01bf12

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

boot/bootutil/src/bootutil_priv.h

Lines changed: 43 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
@@ -283,12 +287,14 @@ struct boot_loader_state {
283287
#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
284288
};
285289

290+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
286291
struct boot_sector_buffer {
287292
boot_sector_t primary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
288293
boot_sector_t secondary[BOOT_IMAGE_NUMBER][BOOT_MAX_IMG_SECTORS];
289294
#if MCUBOOT_SWAP_USING_SCRATCH
290295
boot_sector_t scratch[BOOT_MAX_IMG_SECTORS];
291296
#endif
297+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
292298
};
293299

294300
/* The function is intended for verification of image hash against
@@ -508,6 +514,7 @@ boot_img_slot_off(struct boot_loader_state *state, size_t slot)
508514
return flash_area_get_off(BOOT_IMG_AREA(state, slot));
509515
}
510516

517+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
511518
#ifndef MCUBOOT_USE_FLASH_AREA_GET_SECTORS
512519

513520
static inline size_t
@@ -546,7 +553,43 @@ boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
546553
flash_sector_get_off(&BOOT_IMG(state, slot).sectors[0]);
547554
}
548555

556+
static inline int
557+
boot_img_sector_size_fa(const struct flash_area *fa, size_t off, size_t *size)
558+
{
559+
struct flash_sector sector;
560+
int ret;
561+
562+
assert(size != NULL);
563+
assert(fa != NULL);
564+
565+
ret = flash_area_get_sector(fa, off, &sector);
566+
567+
if (ret >= 0) {
568+
*size = flash_sector_get_size(&sector);
569+
}
570+
571+
return ret;
572+
}
549573
#endif /* !defined(MCUBOOT_USE_FLASH_AREA_GET_SECTORS) */
574+
#else
575+
static inline size_t
576+
boot_img_sector_size(const struct boot_loader_state *state,
577+
size_t slot, size_t sector)
578+
{
579+
return MCUBOOT_LOGICAL_SECTOR_SIZE;
580+
}
581+
582+
/*
583+
* Offset of the sector from the beginning of the image, NOT the flash
584+
* device.
585+
*/
586+
static inline uint32_t
587+
boot_img_sector_off(const struct boot_loader_state *state, size_t slot,
588+
size_t sector)
589+
{
590+
return MCUBOOT_LOGICAL_SECTOR_SIZE * sector;
591+
}
592+
#endif
550593

551594
#ifdef MCUBOOT_RAM_LOAD
552595
# ifdef __BOOTSIM__

boot/bootutil/src/loader.c

Lines changed: 137 additions & 0 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
@@ -652,6 +760,29 @@ boot_read_sectors(struct boot_loader_state *state, struct boot_sector_buffer *se
652760

653761
BOOT_WRITE_SZ(state) = boot_write_sz(state);
654762

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

@@ -789,6 +920,7 @@ boot_image_check(struct boot_loader_state *state, struct image_header *hdr,
789920
}
790921

791922
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
923+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
792924
static fih_ret
793925
split_image_check(struct image_header *app_hdr,
794926
const struct flash_area *app_fap,
@@ -819,6 +951,7 @@ split_image_check(struct image_header *app_hdr,
819951
out:
820952
FIH_RET(fih_rc);
821953
}
954+
#endif /* defined(MCUBOOT_LOGICAL_SECTOR_SIZE) && MCUBOOT_LOGICAL_SECTOR_SIZE != 0 */
822955
#endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */
823956

824957
/*
@@ -2297,10 +2430,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
22972430

22982431
BOOT_LOG_DBG("context_boot_go");
22992432

2433+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
23002434
#if defined(__BOOTSIM__)
23012435
struct boot_sector_buffer sector_buf;
23022436
sectors = &sector_buf;
23032437
#endif
2438+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
23042439

23052440
has_upgrade = false;
23062441

@@ -2560,6 +2695,7 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
25602695
FIH_RET(fih_rc);
25612696
}
25622697

2698+
#if !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0
25632699
fih_ret
25642700
split_go(int loader_slot, int split_slot, void **entry)
25652701
{
@@ -2625,6 +2761,7 @@ split_go(int loader_slot, int split_slot, void **entry)
26252761

26262762
FIH_RET(fih_rc);
26272763
}
2764+
#endif /* !defined(MCUBOOT_LOGICAL_SECTOR_SIZE) || MCUBOOT_LOGICAL_SECTOR_SIZE == 0 */
26282765

26292766
#else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
26302767

0 commit comments

Comments
 (0)