Boot: Enable multi-image boot
This patch adds the capability to handle multiple firmware images,
to update them independently. Also update the design documentation.
It separates the completion of aborted image swap operations and the
update of images even more as these should be happening at different
stages of the boot process according to the design proposal of
the multiple image support:
https://github.com/JuulLabs-OSS/mcuboot/pull/317.
Change-Id: I7eb5f632298bb08c805bfaee0359703b2ae19e9d
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index 11d0a54..09d5fac 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -124,6 +124,7 @@
* (`MCUBOOT_ENC_IMAGES`).
*/
+extern uint8_t current_image;
extern const uint32_t boot_img_magic[4];
struct boot_swap_state {
@@ -202,7 +203,7 @@
const struct flash_area *area;
boot_sector_t *sectors;
size_t num_sectors;
- } imgs[BOOT_NUM_SLOTS];
+ } imgs[BOOT_IMAGE_NUMBER][BOOT_NUM_SLOTS];
struct {
const struct flash_area *area;
@@ -210,6 +211,7 @@
size_t num_sectors;
} scratch;
+ uint8_t swap_type[BOOT_IMAGE_NUMBER];
uint8_t write_sz;
};
@@ -245,20 +247,22 @@
*/
/* These are macros so they can be used as lvalues. */
-#define BOOT_IMG_AREA(state, slot) ((state)->imgs[(slot)].area)
+#define BOOT_IMG(state, slot) ((state)->imgs[current_image][(slot)])
+#define BOOT_IMG_AREA(state, slot) (BOOT_IMG(state, slot).area)
#define BOOT_SCRATCH_AREA(state) ((state)->scratch.area)
#define BOOT_WRITE_SZ(state) ((state)->write_sz)
+#define BOOT_SWAP_TYPE(state) ((state)->swap_type[current_image])
static inline struct image_header*
boot_img_hdr(struct boot_loader_state *state, size_t slot)
{
- return &state->imgs[slot].hdr;
+ return &BOOT_IMG(state, slot).hdr;
}
static inline size_t
boot_img_num_sectors(struct boot_loader_state *state, size_t slot)
{
- return state->imgs[slot].num_sectors;
+ return BOOT_IMG(state, slot).num_sectors;
}
static inline size_t
@@ -273,7 +277,7 @@
static inline uint32_t
boot_img_slot_off(struct boot_loader_state *state, size_t slot)
{
- return state->imgs[slot].area->fa_off;
+ return BOOT_IMG(state, slot).area->fa_off;
}
static inline size_t boot_scratch_area_size(struct boot_loader_state *state)
@@ -287,7 +291,7 @@
boot_img_sector_size(struct boot_loader_state *state,
size_t slot, size_t sector)
{
- return state->imgs[slot].sectors[sector].fa_size;
+ return BOOT_IMG(state, slot).sectors[sector].fa_size;
}
/*
@@ -298,8 +302,8 @@
boot_img_sector_off(struct boot_loader_state *state, size_t slot,
size_t sector)
{
- return state->imgs[slot].sectors[sector].fa_off -
- state->imgs[slot].sectors[0].fa_off;
+ return BOOT_IMG(state, slot).sectors[sector].fa_off -
+ BOOT_IMG(state, slot).sectors[0].fa_off;
}
static inline int
@@ -310,13 +314,13 @@
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;
+ BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors);
+ BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_sectors = (size_t)num_sectors;
} 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;
+ BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors);
+ BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors = (size_t)num_sectors;
} else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
rc = flash_area_to_sectors(flash_area, &num_sectors,
@@ -335,15 +339,15 @@
boot_img_sector_size(struct boot_loader_state *state,
size_t slot, size_t sector)
{
- return state->imgs[slot].sectors[sector].fs_size;
+ return BOOT_IMG(state, slot).sectors[sector].fs_size;
}
static inline uint32_t
boot_img_sector_off(struct boot_loader_state *state, size_t slot,
size_t sector)
{
- return state->imgs[slot].sectors[sector].fs_off -
- state->imgs[slot].sectors[0].fs_off;
+ return BOOT_IMG(state, slot).sectors[sector].fs_off -
+ BOOT_IMG(state, slot).sectors[0].fs_off;
}
static inline int
@@ -357,11 +361,11 @@
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;
+ out_sectors = BOOT_IMG(state, BOOT_PRIMARY_SLOT).sectors;
+ out_num_sectors = &BOOT_IMG(state, BOOT_PRIMARY_SLOT).num_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;
+ out_sectors = BOOT_IMG(state, BOOT_SECONDARY_SLOT).sectors;
+ out_num_sectors = &BOOT_IMG(state, BOOT_SECONDARY_SLOT).num_sectors;
} else if (flash_area == FLASH_AREA_IMAGE_SCRATCH) {
out_sectors = state->scratch.sectors;
out_num_sectors = &state->scratch.num_sectors;