Boot: Save image sequence number to image trailer
Overload the swap_type field in image trailer to store as an addition
the image sequence number. It indicates which image's swap was
interrupted. It is required by multi image boot to determine which
image the trailer belongs to if boot status is found on scratch area
when the swap operation is resumed.
Change-Id: I1a695fa7b51ccf7fb7969496517617d76bc44c02
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
Co-authored-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 5ad8bcf..c076c31 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_misc.c
@@ -17,6 +17,13 @@
* under the License.
*/
+/*
+ * Original code taken from mcuboot project at:
+ * https://github.com/JuulLabs-OSS/mcuboot
+ * Git SHA of the original version: 3c469bc698a9767859ed73cd0201c44161204d5c
+ * Modifications are Copyright (c) 2019 Arm Limited.
+ */
+
#include <assert.h>
#include <string.h>
#include <inttypes.h>
@@ -183,7 +190,7 @@
}
uint32_t
-boot_swap_type_off(const struct flash_area *fap)
+boot_swap_info_off(const struct flash_area *fap)
{
return fap->fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 3;
}
@@ -212,6 +219,7 @@
{
uint32_t magic[BOOT_MAGIC_ARR_SZ];
uint32_t off;
+ uint8_t swap_info;
int rc;
off = boot_magic_off(fap);
@@ -225,14 +233,19 @@
state->magic = boot_magic_decode(magic);
}
- off = boot_swap_type_off(fap);
- rc = flash_area_read_is_empty(fap, off, &state->swap_type,
- sizeof state->swap_type);
+ off = boot_swap_info_off(fap);
+ rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
if (rc < 0) {
return BOOT_EFLASH;
}
+
+ /* Extract the swap type and image number */
+ state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
+ state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
+
if (rc == 1 || state->swap_type > BOOT_SWAP_TYPE_REVERT) {
state->swap_type = BOOT_SWAP_TYPE_NONE;
+ state->image_num = 0;
}
off = boot_copy_done_off(fap);
@@ -420,14 +433,20 @@
* resume in case of an unexpected reset.
*/
int
-boot_write_swap_type(const struct flash_area *fap, uint8_t swap_type)
+boot_write_swap_info(const struct flash_area *fap, uint8_t swap_type,
+ uint8_t image_num)
{
uint32_t off;
+ uint8_t swap_info;
- off = boot_swap_type_off(fap);
- BOOT_LOG_DBG("writing swap_type; fa_id=%d off=0x%x (0x%x), swap_type=0x%x",
- fap->fa_id, off, fap->fa_off + off, swap_type);
- return boot_write_trailer_byte(fap, off, swap_type);
+ BOOT_SET_SWAP_INFO(swap_info, image_num, swap_type);
+ off = boot_swap_info_off(fap);
+ BOOT_LOG_DBG("writing swap_info; fa_id=%d off=0x%x (0x%x), swap_type=0x%x"
+ " image_num=0x%x",
+ fap->fa_id, off, fap->fa_off + off,
+ BOOT_GET_SWAP_TYPE(swap_info),
+ BOOT_GET_IMAGE_NUM(swap_info));
+ return boot_write_trailer_byte(fap, off, swap_info);
}
int
@@ -557,7 +576,7 @@
} else {
swap_type = BOOT_SWAP_TYPE_TEST;
}
- rc = boot_write_swap_type(fap, swap_type);
+ rc = boot_write_swap_info(fap, swap_type, 0);
}
flash_area_close(fap);
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
index 5d70e0c..5a38dac 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
@@ -98,7 +98,7 @@
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Swap size (4 octets) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Swap type | 0xff padding (7 octets) |
+ * | Swap info | 0xff padding (7 octets) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Copy done | 0xff padding (7 octets) |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -116,9 +116,31 @@
uint8_t swap_type; /* One of the BOOT_SWAP_TYPE_[...] values. */
uint8_t copy_done; /* One of the BOOT_FLAG_[...] values. */
uint8_t image_ok; /* One of the BOOT_FLAG_[...] values. */
+ uint8_t image_num; /* Boot status belongs to this image */
};
/*
+ * Extract the swap type and image number from image trailers's swap_info
+ * field.
+ */
+#define SWAP_INFO_SWAP_TYPE_MASK (0x0Fu)
+#define SWAP_INFO_SWAP_TYPE_POS (0)
+#define SWAP_INFO_IMAGE_NUM_MASK (0xF0u)
+#define SWAP_INFO_IMAGE_NUM_POS (4)
+
+#define BOOT_GET_SWAP_TYPE(swap_info) ((swap_info) & SWAP_INFO_SWAP_TYPE_MASK)
+#define BOOT_GET_IMAGE_NUM(swap_info) ((swap_info) >> SWAP_INFO_IMAGE_NUM_POS)
+
+/* Construct the swap_info field from swap type and image number */
+#define BOOT_SET_SWAP_INFO(swap_info, image, type) { \
+ assert(((image) & (SWAP_INFO_IMAGE_NUM_MASK >> \
+ SWAP_INFO_IMAGE_NUM_POS)) == (image)); \
+ assert(((type) & SWAP_INFO_SWAP_TYPE_MASK) == (type)); \
+ (swap_info) = (image) << SWAP_INFO_IMAGE_NUM_POS \
+ | (type); \
+ }
+
+/*
* The current flashmap API does not check the amount of space allocated when
* loading sector data from the flash device, allowing for smaller counts here
* would most surely incur in overruns.
@@ -180,7 +202,7 @@
uint32_t boot_trailer_sz(uint8_t min_write_sz);
int boot_status_entries(const struct flash_area *fap);
uint32_t boot_status_off(const struct flash_area *fap);
-uint32_t boot_swap_type_off(const struct flash_area *fap);
+uint32_t boot_swap_info_off(const struct flash_area *fap);
int boot_read_swap_state(const struct flash_area *fap,
struct boot_swap_state *state);
int boot_read_swap_state_by_id(int flash_area_id,
@@ -190,7 +212,8 @@
int boot_schedule_test_swap(void);
int boot_write_copy_done(const struct flash_area *fap);
int boot_write_image_ok(const struct flash_area *fap);
-int boot_write_swap_type(const struct flash_area *fap, uint8_t swap_type);
+int boot_write_swap_info(const struct flash_area *fap, uint8_t swap_type,
+ uint8_t image_num);
int boot_write_swap_size(const struct flash_area *fap, uint32_t swap_size);
int boot_read_swap_size(uint32_t *swap_size);
diff --git a/bl2/ext/mcuboot/bootutil/src/loader.c b/bl2/ext/mcuboot/bootutil/src/loader.c
index 3631018..80789e5 100644
--- a/bl2/ext/mcuboot/bootutil/src/loader.c
+++ b/bl2/ext/mcuboot/bootutil/src/loader.c
@@ -678,6 +678,7 @@
{
const struct flash_area *fap;
uint32_t off;
+ uint8_t swap_info;
int status_loc;
int area_id;
int rc;
@@ -717,13 +718,15 @@
rc = boot_read_status_bytes(fap, bs);
if (rc == 0) {
- off = boot_swap_type_off(fap);
- rc = flash_area_read_is_empty(fap, off, &bs->swap_type,
- sizeof bs->swap_type);
+ off = boot_swap_info_off(fap);
+ rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
if (rc == 1) {
- bs->swap_type = BOOT_SWAP_TYPE_NONE;
+ BOOT_SET_SWAP_INFO(swap_info, 0, BOOT_SWAP_TYPE_NONE);
rc = 0;
}
+
+ /* Extract the swap type info */
+ bs->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
}
flash_area_close(fap);
@@ -945,7 +948,9 @@
assert(rc == 0);
if (bs->swap_type != BOOT_SWAP_TYPE_NONE) {
- rc = boot_write_swap_type(fap, bs->swap_type);
+ rc = boot_write_swap_info(fap,
+ bs->swap_type,
+ 0);
assert(rc == 0);
}
@@ -1154,8 +1159,9 @@
}
if (swap_state.swap_type != BOOT_SWAP_TYPE_NONE) {
- rc = boot_write_swap_type(fap_primary_slot,
- swap_state.swap_type);
+ rc = boot_write_swap_info(fap_primary_slot,
+ swap_state.swap_type,
+ 0);
assert(rc == 0);
}