Boot: Extend flash layout for multiple images
This patch extends the flash layout of supported platforms, and also
introduces the BOOT_IMAGE_NUMBER macro and the current_image variable
in MCUBoot to support multiple updatable images.
The FLASH_AREA_IMAGE_PRIMARY/SECONDARY object-like macros are replaced
with function-like ones and therefore some functions have been updated,
because the labels of a switch statement and the initialization
values of objects with static storage duration have to be constant
expressions.
Change-Id: Ic4425c9034f877fe2b83d80a3df211232f14a09f
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
index c076c31..94fdc30 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
@@ -164,13 +164,12 @@
int
boot_status_entries(const struct flash_area *fap)
{
- switch (fap->fa_id) {
- case FLASH_AREA_IMAGE_PRIMARY:
- case FLASH_AREA_IMAGE_SECONDARY:
- return BOOT_STATUS_STATE_COUNT * BOOT_STATUS_MAX_ENTRIES;
- case FLASH_AREA_IMAGE_SCRATCH:
+ if (fap->fa_id == FLASH_AREA_IMAGE_SCRATCH) {
return BOOT_STATUS_STATE_COUNT;
- default:
+ } else if ((fap->fa_id == FLASH_AREA_IMAGE_PRIMARY) ||
+ (fap->fa_id == FLASH_AREA_IMAGE_SECONDARY)) {
+ return BOOT_STATUS_STATE_COUNT * BOOT_STATUS_MAX_ENTRIES;
+ } else {
return BOOT_EBADARGS;
}
}
@@ -284,16 +283,14 @@
const struct flash_area *fap;
int rc;
- switch (flash_area_id) {
- case FLASH_AREA_IMAGE_SCRATCH:
- case FLASH_AREA_IMAGE_PRIMARY:
- case FLASH_AREA_IMAGE_SECONDARY:
+ if (flash_area_id == FLASH_AREA_IMAGE_SCRATCH ||
+ flash_area_id == FLASH_AREA_IMAGE_PRIMARY ||
+ flash_area_id == FLASH_AREA_IMAGE_SECONDARY) {
rc = flash_area_open(flash_area_id, &fap);
if (rc != 0) {
return BOOT_EFLASH;
}
- break;
- default:
+ } else {
return BOOT_EBADARGS;
}
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
index 5a38dac..9ea1a24 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
@@ -119,6 +119,12 @@
uint8_t image_num; /* Boot status belongs to this image */
};
+#ifdef MCUBOOT_IMAGE_NUMBER
+#define BOOT_IMAGE_NUMBER MCUBOOT_IMAGE_NUMBER
+#else
+#define BOOT_IMAGE_NUMBER 1
+#endif
+
/*
* Extract the swap type and image number from image trailers's swap_info
* field.
@@ -285,23 +291,19 @@
int num_sectors = BOOT_MAX_IMG_SECTORS;
int rc;
- switch (flash_area) {
- case FLASH_AREA_IMAGE_PRIMARY:
+ if (flash_area == FLASH_AREA_IMAGE_PRIMARY) {
rc = flash_area_to_sectors(flash_area, &num_sectors,
state->imgs[BOOT_PRIMARY_SLOT].sectors);
state->imgs[BOOT_PRIMARY_SLOT].num_sectors = (size_t)num_sectors;
- break;
- case FLASH_AREA_IMAGE_SECONDARY:
+ } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY) {
rc = flash_area_to_sectors(flash_area, &num_sectors,
state->imgs[BOOT_SECONDARY_SLOT].sectors);
state->imgs[BOOT_SECONDARY_SLOT].num_sectors = (size_t)num_sectors;
- break;
- case FLASH_AREA_IMAGE_SCRATCH:
+ } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
rc = flash_area_to_sectors(flash_area, &num_sectors,
state->scratch.sectors);
state->scratch.num_sectors = (size_t)num_sectors;
- break;
- default:
+ } else {
return BOOT_EFLASH;
}
@@ -333,24 +335,19 @@
size_t *out_num_sectors;
int rc;
- switch (flash_area) {
- case FLASH_AREA_IMAGE_PRIMARY:
- num_sectors = BOOT_MAX_IMG_SECTORS;
+ num_sectors = BOOT_MAX_IMG_SECTORS;
+
+ if (flash_area == FLASH_AREA_IMAGE_PRIMARY) {
out_sectors = state->imgs[BOOT_PRIMARY_SLOT].sectors;
out_num_sectors = &state->imgs[BOOT_PRIMARY_SLOT].num_sectors;
- break;
- case FLASH_AREA_IMAGE_SECONDARY:
- num_sectors = BOOT_MAX_IMG_SECTORS;
+ } else if (flash_area == FLASH_AREA_IMAGE_SECONDARY) {
out_sectors = state->imgs[BOOT_SECONDARY_SLOT].sectors;
out_num_sectors = &state->imgs[BOOT_SECONDARY_SLOT].num_sectors;
- break;
- case FLASH_AREA_IMAGE_SCRATCH:
- num_sectors = BOOT_MAX_IMG_SECTORS;
+ } else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
out_sectors = state->scratch.sectors;
out_num_sectors = &state->scratch.num_sectors;
- break;
- default:
- return -1;
+ } else {
+ return BOOT_EFLASH;
}
rc = flash_area_get_sectors(flash_area, &num_sectors, out_sectors);
diff --git a/bl2/ext/mcuboot/bootutil/src/loader.c b/bl2/ext/mcuboot/bootutil/src/loader.c
index 80789e5..c7c7173 100644
--- a/bl2/ext/mcuboot/bootutil/src/loader.c
+++ b/bl2/ext/mcuboot/bootutil/src/loader.c
@@ -47,6 +47,7 @@
#include "bootutil/bootutil_log.h"
static struct boot_loader_state boot_data;
+uint8_t current_image = 0;
#if !defined(MCUBOOT_NO_SWAP) && !defined(MCUBOOT_RAM_LOADING)
@@ -977,18 +978,20 @@
uint32_t total_sz;
uint32_t off;
uint32_t sz;
+ int fa_id_primary;
+ int fa_id_secondary;
int rc;
BOOT_LOG_DBG("erasing trailer; fa_id=%d", fap->fa_id);
- switch (fap->fa_id) {
- case FLASH_AREA_IMAGE_PRIMARY:
+ fa_id_primary = flash_area_id_from_image_slot(BOOT_PRIMARY_SLOT);
+ fa_id_secondary = flash_area_id_from_image_slot(BOOT_SECONDARY_SLOT);
+
+ if (fap->fa_id == fa_id_primary) {
slot = BOOT_PRIMARY_SLOT;
- break;
- case FLASH_AREA_IMAGE_SECONDARY:
+ } else if (fap->fa_id == fa_id_secondary) {
slot = BOOT_SECONDARY_SLOT;
- break;
- default:
+ } else {
return BOOT_EFLASH;
}
diff --git a/bl2/ext/mcuboot/flash_map.c b/bl2/ext/mcuboot/flash_map.c
index 31a9d74..5cbb824 100644
--- a/bl2/ext/mcuboot/flash_map.c
+++ b/bl2/ext/mcuboot/flash_map.c
@@ -64,28 +64,48 @@
{
.magic = FLASH_MAP_ENTRY_MAGIC,
.area = {
- .fa_id = FLASH_AREA_IMAGE_PRIMARY,
+ .fa_id = FLASH_AREA_0_ID,
.fa_device_id = FLASH_DEVICE_ID,
- .fa_off = FLASH_AREA_IMAGE_PRIMARY_OFFSET,
- .fa_size = FLASH_AREA_IMAGE_PRIMARY_SIZE,
+ .fa_off = FLASH_AREA_0_OFFSET,
+ .fa_size = FLASH_AREA_0_SIZE,
},
},
{
.magic = FLASH_MAP_ENTRY_MAGIC,
.area = {
- .fa_id = FLASH_AREA_IMAGE_SECONDARY,
+ .fa_id = FLASH_AREA_2_ID,
.fa_device_id = FLASH_DEVICE_ID,
- .fa_off = FLASH_AREA_IMAGE_SECONDARY_OFFSET,
- .fa_size = FLASH_AREA_IMAGE_SECONDARY_SIZE,
+ .fa_off = FLASH_AREA_2_OFFSET,
+ .fa_size = FLASH_AREA_2_SIZE,
+ },
+ },
+#if (MCUBOOT_IMAGE_NUMBER == 2)
+ {
+ .magic = FLASH_MAP_ENTRY_MAGIC,
+ .area = {
+ .fa_id = FLASH_AREA_1_ID,
+ .fa_device_id = FLASH_DEVICE_ID,
+ .fa_off = FLASH_AREA_1_OFFSET,
+ .fa_size = FLASH_AREA_1_SIZE,
},
},
{
.magic = FLASH_MAP_ENTRY_MAGIC,
.area = {
- .fa_id = FLASH_AREA_IMAGE_SCRATCH,
+ .fa_id = FLASH_AREA_3_ID,
.fa_device_id = FLASH_DEVICE_ID,
- .fa_off = FLASH_AREA_IMAGE_SCRATCH_OFFSET,
- .fa_size = FLASH_AREA_IMAGE_SCRATCH_SIZE,
+ .fa_off = FLASH_AREA_3_OFFSET,
+ .fa_size = FLASH_AREA_3_SIZE,
+ },
+ },
+#endif
+ {
+ .magic = FLASH_MAP_ENTRY_MAGIC,
+ .area = {
+ .fa_id = FLASH_AREA_SCRATCH_ID,
+ .fa_device_id = FLASH_DEVICE_ID,
+ .fa_off = FLASH_AREA_SCRATCH_OFFSET,
+ .fa_size = FLASH_AREA_SCRATCH_SIZE,
},
}
};
@@ -251,9 +271,12 @@
*/
int flash_area_id_from_image_slot(int slot)
{
- static const int area_id_tab[] = {FLASH_AREA_IMAGE_PRIMARY,
- FLASH_AREA_IMAGE_SECONDARY,
- FLASH_AREA_IMAGE_SCRATCH};
+#if (MCUBOOT_IMAGE_NUMBER == 1)
+ static
+#endif
+ const int area_id_tab[] = {FLASH_AREA_IMAGE_PRIMARY,
+ FLASH_AREA_IMAGE_SECONDARY,
+ FLASH_AREA_IMAGE_SCRATCH};
if (slot >= 0 && slot < ARRAY_SIZE(area_id_tab)) {
return area_id_tab[slot];
@@ -264,15 +287,15 @@
int flash_area_id_to_image_slot(int area_id)
{
- switch (area_id) {
- case FLASH_AREA_IMAGE_PRIMARY:
+ if (area_id == FLASH_AREA_IMAGE_PRIMARY) {
return 0;
- case FLASH_AREA_IMAGE_SECONDARY:
- return 1;
- default:
- BOOT_LOG_ERR("invalid flash area ID");
- return -1;
}
+ if (area_id == FLASH_AREA_IMAGE_SECONDARY) {
+ return 1;
+ }
+
+ BOOT_LOG_ERR("invalid flash area ID");
+ return -1;
}
static int validate_idx(int idx, uint32_t *off, uint32_t *len)
@@ -283,17 +306,27 @@
*/
switch (idx) {
- case FLASH_AREA_IMAGE_PRIMARY:
- *off = FLASH_AREA_IMAGE_PRIMARY_OFFSET;
- *len = FLASH_AREA_IMAGE_PRIMARY_SIZE;
+ case FLASH_AREA_0_ID:
+ *off = FLASH_AREA_0_OFFSET;
+ *len = FLASH_AREA_0_SIZE;
break;
- case FLASH_AREA_IMAGE_SECONDARY:
- *off = FLASH_AREA_IMAGE_SECONDARY_OFFSET;
- *len = FLASH_AREA_IMAGE_SECONDARY_SIZE;
+ case FLASH_AREA_2_ID:
+ *off = FLASH_AREA_2_OFFSET;
+ *len = FLASH_AREA_2_SIZE;
break;
- case FLASH_AREA_IMAGE_SCRATCH:
- *off = FLASH_AREA_IMAGE_SCRATCH_OFFSET;
- *len = FLASH_AREA_IMAGE_SCRATCH_SIZE;
+#if (MCUBOOT_IMAGE_NUMBER == 2)
+ case FLASH_AREA_1_ID:
+ *off = FLASH_AREA_1_OFFSET;
+ *len = FLASH_AREA_1_SIZE;
+ break;
+ case FLASH_AREA_3_ID:
+ *off = FLASH_AREA_3_OFFSET;
+ *len = FLASH_AREA_3_SIZE;
+ break;
+#endif
+ case FLASH_AREA_SCRATCH_ID:
+ *off = FLASH_AREA_SCRATCH_OFFSET;
+ *len = FLASH_AREA_SCRATCH_SIZE;
break;
default:
BOOT_LOG_ERR("unknown flash area %d", idx);
diff --git a/bl2/ext/mcuboot/include/flash_map/flash_map.h b/bl2/ext/mcuboot/include/flash_map/flash_map.h
index 1c40c3d..3f00a5d 100644
--- a/bl2/ext/mcuboot/include/flash_map/flash_map.h
+++ b/bl2/ext/mcuboot/include/flash_map/flash_map.h
@@ -50,9 +50,27 @@
*/
#include <inttypes.h>
-#define FLASH_AREA_IMAGE_PRIMARY 1
-#define FLASH_AREA_IMAGE_SECONDARY 2
-#define FLASH_AREA_IMAGE_SCRATCH 3
+extern uint8_t current_image;
+
+#if (MCUBOOT_IMAGE_NUMBER == 1)
+#define FLASH_AREA_IMAGE_PRIMARY FLASH_AREA_0_ID
+#define FLASH_AREA_IMAGE_SECONDARY FLASH_AREA_2_ID
+#elif (MCUBOOT_IMAGE_NUMBER == 2)
+/* MCUBoot currently supports only up to 2 updatable firmware images.
+ * If the number of the current image is greater than MCUBOOT_IMAGE_NUMBER - 1
+ * then a dummy value will be assigned to the flash area macros.
+ */
+#define FLASH_AREA_IMAGE_PRIMARY ((current_image == 0) ? FLASH_AREA_0_ID : \
+ (current_image == 1) ? FLASH_AREA_1_ID : \
+ 255 )
+#define FLASH_AREA_IMAGE_SECONDARY ((current_image == 0) ? FLASH_AREA_2_ID : \
+ (current_image == 1) ? FLASH_AREA_3_ID : \
+ 255 )
+#else
+#error "Image slot and flash area mapping is not defined"
+#endif
+
+#define FLASH_AREA_IMAGE_SCRATCH FLASH_AREA_SCRATCH_ID
/**
* @brief Structure describing an area on a flash device.
diff --git a/bl2/ext/mcuboot/include/target.h b/bl2/ext/mcuboot/include/target.h
index 97930d7..728541c 100644
--- a/bl2/ext/mcuboot/include/target.h
+++ b/bl2/ext/mcuboot/include/target.h
@@ -21,28 +21,46 @@
#error "FLASH_AREA_IMAGE_SECTOR_SIZE must be defined by the target"
#endif
-#ifndef FLASH_AREA_IMAGE_PRIMARY_OFFSET
-#error "FLASH_AREA_IMAGE_PRIMARY_OFFSET must be defined by the target"
+#ifndef FLASH_AREA_0_OFFSET
+#error "FLASH_AREA_0_OFFSET must be defined by the target"
#endif
-#ifndef FLASH_AREA_IMAGE_PRIMARY_SIZE
-#error "FLASH_AREA_IMAGE_PRIMARY_SIZE must be defined by the target"
+#ifndef FLASH_AREA_0_SIZE
+#error "FLASH_AREA_0_SIZE must be defined by the target"
#endif
-#ifndef FLASH_AREA_IMAGE_SECONDARY_OFFSET
-#error "FLASH_AREA_IMAGE_SECONDARY_OFFSET must be defined by the target"
+#ifndef FLASH_AREA_2_OFFSET
+#error "FLASH_AREA_2_OFFSET must be defined by the target"
#endif
-#ifndef FLASH_AREA_IMAGE_SECONDARY_SIZE
-#error "FLASH_AREA_IMAGE_SECONDARY_SIZE must be defined by the target"
+#ifndef FLASH_AREA_2_SIZE
+#error "FLASH_AREA_2_SIZE must be defined by the target"
#endif
-#ifndef FLASH_AREA_IMAGE_SCRATCH_OFFSET
-#error "FLASH_AREA_IMAGE_SCRATCH_OFFSET must be defined by the target"
+#if (MCUBOOT_IMAGE_NUMBER == 2)
+#ifndef FLASH_AREA_1_OFFSET
+#error "FLASH_AREA_1_OFFSET must be defined by the target"
#endif
-#ifndef FLASH_AREA_IMAGE_SCRATCH_SIZE
-#error "FLASH_AREA_IMAGE_SCRATCH_SIZE must be defined by the target"
+#ifndef FLASH_AREA_1_SIZE
+#error "FLASH_AREA_1_SIZE must be defined by the target"
+#endif
+
+#ifndef FLASH_AREA_3_OFFSET
+#error "FLASH_AREA_3_OFFSET must be defined by the target"
+#endif
+
+#ifndef FLASH_AREA_3_SIZE
+#error "FLASH_AREA_3_SIZE must be defined by the target"
+#endif
+#endif /* (MCUBOOT_IMAGE_NUMBER == 2) */
+
+#ifndef FLASH_AREA_SCRATCH_OFFSET
+#error "FLASH_AREA_SCRATCH_OFFSET must be defined by the target"
+#endif
+
+#ifndef FLASH_AREA_SCRATCH_SIZE
+#error "FLASH_AREA_SCRATCH_SIZE must be defined by the target"
#endif
#ifndef FLASH_DEV_NAME
@@ -57,4 +75,4 @@
#error "BOOT_MAX_IMG_SECTORS must be defined by the target"
#endif
-#endif
+#endif /* H_TARGETS_TARGET_ */