Refactor routines that read swap status data
When doing a swap some of the information required by the process
is temporarily written to the status area; previously each data
writing routines tried to find the correct area by looking for the
magic and assuming that data is located there (because everything
fits a single sector). This moves the code to find the magic into
a separate routine that is now used by others.
Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index 35b9f15..e15579e 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -310,118 +310,92 @@
return rc;
}
+/**
+ * This functions tries to locate the status area after an aborted swap,
+ * by looking for the magic in the possible locations.
+ *
+ * If the magic is sucessfully found, a flash_area * is returned and it
+ * is the responsibility of the called to close it.
+ *
+ * @returns 0 on success, -1 on errors
+ */
+static int
+boot_find_status(int image_index, const struct flash_area **fap)
+{
+ uint32_t magic[BOOT_MAGIC_ARR_SZ];
+ uint32_t off;
+ uint8_t areas[2] = {
+ FLASH_AREA_IMAGE_PRIMARY(image_index),
+ FLASH_AREA_IMAGE_SCRATCH,
+ };
+ unsigned int i;
+ int rc;
+
+ /*
+ * In the middle a swap, tries to locate the area that is currently
+ * storing a valid magic, first on the primary slot, then on scratch.
+ * Both "slots" can end up being temporary storage for a swap and it
+ * is assumed that if magic is valid then other metadata is too,
+ * because magic is always written in the last step.
+ */
+
+ for (i = 0; i < sizeof(areas) / sizeof(areas[0]); i++) {
+ rc = flash_area_open(areas[i], fap);
+ if (rc != 0) {
+ return rc;
+ }
+
+ off = boot_magic_off(*fap);
+ rc = flash_area_read(*fap, off, magic, BOOT_MAGIC_SZ);
+ if (rc != 0) {
+ flash_area_close(*fap);
+ return rc;
+ }
+
+ if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0) {
+ return 0;
+ }
+
+ flash_area_close(*fap);
+ }
+
+ /* If we got here, no magic was found */
+ return -1;
+}
+
int
boot_read_swap_size(int image_index, uint32_t *swap_size)
{
- uint32_t magic[BOOT_MAGIC_ARR_SZ];
uint32_t off;
const struct flash_area *fap;
int rc;
- /*
- * In the middle a swap, tries to locate the saved swap size. Looks
- * for a valid magic, first on the primary slot, then on scratch.
- * Both "slots" can end up being temporary storage for a swap and it
- * is assumed that if magic is valid then swap size is too, because
- * magic is always written in the last step.
- */
-
- rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
-
- off = boot_magic_off(fap);
- rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- goto out;
- }
-
- if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) != 0) {
- /*
- * If the primary slot's magic is not valid, try scratch...
- */
-
+ rc = boot_find_status(image_index, &fap);
+ if (rc == 0) {
+ off = boot_swap_size_off(fap);
+ rc = flash_area_read(fap, off, swap_size, sizeof *swap_size);
flash_area_close(fap);
-
- rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
-
- off = boot_magic_off(fap);
- rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- goto out;
- }
-
- assert(memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0);
}
- off = boot_swap_size_off(fap);
- rc = flash_area_read(fap, off, swap_size, sizeof *swap_size);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- }
-
-out:
- flash_area_close(fap);
return rc;
}
+
#ifdef MCUBOOT_ENC_IMAGES
int
boot_read_enc_key(int image_index, uint8_t slot, uint8_t *enckey)
{
- uint32_t magic[BOOT_MAGIC_SZ];
uint32_t off;
const struct flash_area *fap;
int rc;
- rc = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(image_index), &fap);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
-
- off = boot_magic_off(fap);
- rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- goto out;
- }
-
- if (memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) != 0) {
- /*
- * If the primary slot's magic is not valid, try scratch...
- */
-
+ rc = boot_find_status(image_index, &fap);
+ if (rc == 0) {
+ off = boot_enc_key_off(fap, slot);
+ rc = flash_area_read(fap, off, enckey, BOOT_ENC_KEY_SIZE);
flash_area_close(fap);
-
- rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
-
- off = boot_magic_off(fap);
- rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- goto out;
- }
-
- assert(memcmp(magic, boot_img_magic, BOOT_MAGIC_SZ) == 0);
}
- off = boot_enc_key_off(fap, slot);
- rc = flash_area_read(fap, off, enckey, BOOT_ENC_KEY_SIZE);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- }
-
-out:
- flash_area_close(fap);
return rc;
}
#endif