bootutil: keep image areas open while bootloading
Keep both image areas and the scratch area open while we are
bootloading. This fixes up a hack and will make it easier to use
flash_area_get_sectors() later.
Signed-off-by: Marti Bolivar <marti.bolivar@linaro.org>
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 18db4af..5990b80 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -335,11 +335,6 @@
return BOOT_EFLASH;
}
- rc = boot_initialize_area(&boot_data, FLASH_AREA_IMAGE_SCRATCH);
- if (rc != 0) {
- return BOOT_EFLASH;
- }
-
boot_data.write_sz = boot_write_sz();
return 0;
@@ -1203,6 +1198,7 @@
int swap_type;
int slot;
int rc;
+ int fa_id;
/* The array of slot sectors are defined here (as opposed to file scope) so
* that they don't get allocated for non-boot-loader apps. This is
@@ -1214,16 +1210,26 @@
boot_data.imgs[0].sectors = slot0_sectors;
boot_data.imgs[1].sectors = slot1_sectors;
+ /* Open boot_data image areas for the duration of this call. */
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ fa_id = flash_area_id_from_image_slot(slot);
+ rc = flash_area_open(fa_id, &BOOT_IMG_AREA(&boot_data, slot));
+ assert(rc == 0);
+ }
+ rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH,
+ &BOOT_SCRATCH_AREA(&boot_data));
+ assert(rc == 0);
+
/* Determine the sector layout of the image slots and scratch area. */
rc = boot_read_sectors();
if (rc != 0) {
- return rc;
+ goto out;
}
/* Attempt to read an image header from each slot. */
rc = boot_read_image_headers();
if (rc != 0) {
- return rc;
+ goto out;
}
/* If the image slots aren't compatible, no swap is possible. Just boot
@@ -1233,7 +1239,7 @@
rc = boot_swap_if_needed(&swap_type);
assert(rc == 0);
if (rc != 0) {
- return rc;
+ goto out;
}
} else {
swap_type = BOOT_SWAP_TYPE_NONE;
@@ -1245,7 +1251,8 @@
rc = boot_validate_slot(0);
assert(rc == 0);
if (rc != 0) {
- return BOOT_EBADIMAGE;
+ rc = BOOT_EBADIMAGE;
+ goto out;
}
#endif
slot = 0;
@@ -1282,30 +1289,38 @@
rsp->br_image_addr = boot_img_slot_off(&boot_data, 0);
rsp->br_hdr = boot_img_hdr(&boot_data, slot);
- return 0;
+ out:
+ flash_area_close(BOOT_SCRATCH_AREA(&boot_data));
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ flash_area_close(BOOT_IMG_AREA(&boot_data, BOOT_NUM_SLOTS - 1 - slot));
+ }
+ return rc;
}
int
split_go(int loader_slot, int split_slot, void **entry)
{
- const struct flash_area *loader_fap;
- const struct flash_area *app_fap;
struct flash_area *sectors;
uintptr_t entry_val;
int loader_flash_id;
- int app_flash_id;
+ int split_flash_id;
int rc;
- app_fap = NULL;
- loader_fap = NULL;
-
sectors = malloc(BOOT_MAX_IMG_SECTORS * 2 * sizeof *sectors);
if (sectors == NULL) {
- rc = SPLIT_GO_ERR;
- goto done;
+ return SPLIT_GO_ERR;
}
- boot_data.imgs[0].sectors = sectors + 0;
- boot_data.imgs[1].sectors = sectors + BOOT_MAX_IMG_SECTORS;
+ boot_data.imgs[loader_slot].sectors = sectors + 0;
+ boot_data.imgs[split_slot].sectors = sectors + BOOT_MAX_IMG_SECTORS;
+
+ loader_flash_id = flash_area_id_from_image_slot(loader_slot);
+ rc = flash_area_open(loader_flash_id,
+ &BOOT_IMG_AREA(&boot_data, split_slot));
+ assert(rc == 0);
+ split_flash_id = flash_area_id_from_image_slot(split_slot);
+ rc = flash_area_open(split_flash_id,
+ &BOOT_IMG_AREA(&boot_data, split_slot));
+ assert(rc == 0);
/* Determine the sector layout of the image slots and scratch area. */
rc = boot_read_sectors();
@@ -1319,28 +1334,14 @@
goto done;
}
- app_flash_id = flash_area_id_from_image_slot(split_slot);
- rc = flash_area_open(app_flash_id, &app_fap);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- goto done;
- }
-
- loader_flash_id = flash_area_id_from_image_slot(loader_slot);
- rc = flash_area_open(loader_flash_id, &loader_fap);
- if (rc != 0) {
- rc = BOOT_EFLASH;
- goto done;
- }
-
/* Don't check the bootable image flag because we could really call a
* bootable or non-bootable image. Just validate that the image check
* passes which is distinct from the normal check.
*/
rc = split_image_check(boot_img_hdr(&boot_data, split_slot),
- app_fap,
+ BOOT_IMG_AREA(&boot_data, split_slot),
boot_img_hdr(&boot_data, loader_slot),
- loader_fap);
+ BOOT_IMG_AREA(&boot_data, loader_slot));
if (rc != 0) {
rc = SPLIT_GO_NON_MATCHING;
goto done;
@@ -1352,8 +1353,8 @@
rc = SPLIT_GO_OK;
done:
+ flash_area_close(BOOT_IMG_AREA(&boot_data, split_slot));
+ flash_area_close(BOOT_IMG_AREA(&boot_data, loader_slot));
free(sectors);
- flash_area_close(app_fap);
- flash_area_close(loader_fap);
return rc;
}