You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/18 20:04:29 UTC

[11/14] incubator-mynewt-core git commit: bootutil; change the amount of status data we persist during upgrade. Try to use the full scratch area when moving data between areas, instead of copying it one sector at a time.

bootutil; change the amount of status data we persist during upgrade.
Try to use the full scratch area when moving data between areas,
instead of copying it one sector at a time.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/705d3346
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/705d3346
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/705d3346

Branch: refs/heads/develop
Commit: 705d334699c3d057a59503be76932b9bde944439
Parents: d27f80e
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Apr 15 16:30:12 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Mon Apr 18 10:49:42 2016 -0700

----------------------------------------------------------------------
 apps/boot/src/boot.c                    |   8 -
 libs/bootutil/include/bootutil/loader.h |  13 +-
 libs/bootutil/pkg.yml                   |   1 +
 libs/bootutil/src/bootutil_misc.c       |  66 ++--
 libs/bootutil/src/bootutil_priv.h       |  24 +-
 libs/bootutil/src/loader.c              | 441 +++++++--------------------
 libs/bootutil/src/test/boot_test.c      | 321 +++++++++----------
 7 files changed, 319 insertions(+), 555 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/apps/boot/src/boot.c
----------------------------------------------------------------------
diff --git a/apps/boot/src/boot.c b/apps/boot/src/boot.c
index 9cee56d..d0bdb1c 100755
--- a/apps/boot/src/boot.c
+++ b/apps/boot/src/boot.c
@@ -50,8 +50,6 @@ main(void)
 {
     struct nffs_area_desc nffs_descs[NFFS_AREA_MAX + 1];
     struct flash_area descs[AREA_DESC_MAX];
-    /** Contains indices of the areas which can contain image data. */
-    uint8_t img_areas[AREA_DESC_MAX];
     /** Areas representing the beginning of image slots. */
     uint8_t img_starts[2];
     int cnt;
@@ -60,7 +58,6 @@ main(void)
     int rc;
     struct boot_req req = {
         .br_area_descs = descs,
-        .br_image_areas = img_areas,
         .br_slot_areas = img_starts,
     };
 
@@ -90,10 +87,6 @@ main(void)
 
     req.br_num_image_areas = total;
 
-    for (cnt = 0; cnt < total; cnt++) {
-        img_areas[cnt] = cnt;
-    }
-
     /*
      * Make sure we have enough left to initialize the NFFS with the
      * right number of maximum areas otherwise the file-system will not
@@ -115,7 +108,6 @@ main(void)
         nffs_detect(nffs_descs);
     }
 
-    log_init();
     conf_init();
 
     rc = conf_file_src(&my_conf);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/libs/bootutil/include/bootutil/loader.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/include/bootutil/loader.h b/libs/bootutil/include/bootutil/loader.h
index 1f82519..86f06ba 100644
--- a/libs/bootutil/include/bootutil/loader.h
+++ b/libs/bootutil/include/bootutil/loader.h
@@ -33,14 +33,8 @@ struct boot_req {
 
     /**
      * Array of indices of elements in the br_area_descs array; indicates which
-     * areas hold image data.
-     */
-    uint8_t *br_image_areas;
-
-    /**
-     * Array of indices of elements in the br_area_descs array; indicates which
-     * areas represent the beginning of an image slot.  This should be a subset
-     * of the br_image_areas array.
+     * areas represent the beginning of an image slot.  These are indices
+     * to br_area_descs array.
      */
     uint8_t *br_slot_areas;
 
@@ -49,7 +43,8 @@ struct boot_req {
      */
     uint8_t br_num_image_areas;
 
-    /** The index of the area to use as the image scratch area. */
+    /** The area to use as the image scratch area, index is
+	index to br_area_descs array, of the  */
     uint8_t br_scratch_area_idx;
 };
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/libs/bootutil/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/bootutil/pkg.yml b/libs/bootutil/pkg.yml
index c1bd59a..01b8c43 100644
--- a/libs/bootutil/pkg.yml
+++ b/libs/bootutil/pkg.yml
@@ -31,6 +31,7 @@ pkg.deps:
     - libs/testutil
     - libs/mbedtls
     - hw/hal
+    - sys/config
 
 pkg.cflags.IMAGE_KEYS_RSA: -DIMAGE_SIGNATURES_RSA
 pkg.cflags.IMAGE_KEYS_EC: -DIMAGE_SIGNATURES_EC

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/libs/bootutil/src/bootutil_misc.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/bootutil_misc.c b/libs/bootutil/src/bootutil_misc.c
index d81dafe..eaaeaf7 100644
--- a/libs/bootutil/src/bootutil_misc.c
+++ b/libs/bootutil/src/bootutil_misc.c
@@ -29,7 +29,7 @@ static int boot_conf_set(int argc, char **argv, char *val);
 
 static struct image_version boot_main;
 static struct image_version boot_test;
-static uint8_t boot_st_loaded;
+static struct boot_status boot_saved;
 
 static struct conf_handler boot_conf_handler = {
     .ch_name = "boot",
@@ -48,18 +48,32 @@ boot_conf_set(int argc, char **argv, char *val)
     if (argc == 1) {
         if (!strcmp(argv[0], "main")) {
             len = sizeof(boot_main);
-            rc = conf_bytes_from_str(val, &boot_main, &len);
+            if (val) {
+                rc = conf_bytes_from_str(val, &boot_main, &len);
+            } else {
+                memset(&boot_main, 0, len);
+                rc = 0;
+            }
         } else if (!strcmp(argv[0], "test")) {
             len = sizeof(boot_test);
-            rc = conf_bytes_from_str(val, &boot_test, &len);
+            if (val) {
+                rc = conf_bytes_from_str(val, &boot_test, &len);
+            } else {
+                memset(&boot_test, 0, len);
+                rc = 0;
+            }
         } else if (!strcmp(argv[0], "status")) {
-            len = boot_st_sz;
-            rc = conf_bytes_from_str(val, boot_st, &len);
-            if (rc == 0 && len > 0) {
-                boot_st_loaded = 1;
+            if (!val) {
+                boot_saved.state = 0;
+                rc = 0;
             } else {
-                boot_st_loaded = 0;
+                rc = conf_value_from_str(val, CONF_INT32,
+                  &boot_saved.state, sizeof(boot_saved.state));
             }
+        } else if (!strcmp(argv[0], "len")) {
+            conf_value_from_str(val, CONF_INT32, &boot_saved.length,
+              sizeof(boot_saved.length));
+            rc = 0;
         } else {
             rc = OS_ENOENT;
         }
@@ -107,7 +121,7 @@ boot_vect_read_main(struct image_version *out_ver)
     return boot_vect_read_one(out_ver, &boot_main);
 }
 
-int
+static int
 boot_vect_write_one(const char *name, struct image_version *ver)
 {
     char str[CONF_STR_FROM_BYTES_LEN(sizeof(struct image_version))];
@@ -215,11 +229,12 @@ bootutil_cfg_register(void)
 }
 
 int
-boot_read_status(void)
+boot_read_status(struct boot_status *bs)
 {
     conf_load();
 
-    return boot_st_loaded == 1;
+    *bs = boot_saved;
+    return (boot_saved.state != 0);
 }
 
 /**
@@ -235,29 +250,18 @@ boot_read_status(void)
  * @return                      0 on success; nonzero on failure.
  */
 int
-boot_write_status(void)
+boot_write_status(struct boot_status *bs)
 {
-    char *val_str;
-    char *rstr;
-    int rc = 0;
-    int len;
+    char str[12];
+    int rc;
 
-    len = CONF_STR_FROM_BYTES_LEN(boot_st_sz);
-    val_str = malloc(len);
-    if (!val_str) {
-        return BOOT_ENOMEM;
-    }
-    rstr = conf_str_from_bytes(boot_st, boot_st_sz, val_str, len);
-    if (!rstr) {
-        rc = BOOT_EFILE;
-    } else {
-        if (conf_save_one(&boot_conf_handler, "status", val_str)) {
-            rc = BOOT_EFLASH;
-        }
+    rc = conf_save_one(&boot_conf_handler, "status",
+      conf_str_from_value(CONF_INT32, &bs->state, str, sizeof(str)));
+    if (rc) {
+        return rc;
     }
-    free(val_str);
-
-    return rc;
+    return conf_save_one(&boot_conf_handler, "len",
+      conf_str_from_value(CONF_INT32, &bs->length, str, sizeof(str)));
 }
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/libs/bootutil/src/bootutil_priv.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/bootutil_priv.h b/libs/bootutil/src/bootutil_priv.h
index c4b2d81..ddbbd5c 100644
--- a/libs/bootutil/src/bootutil_priv.h
+++ b/libs/bootutil/src/bootutil_priv.h
@@ -39,16 +39,8 @@ struct image_header;
 #define BOOT_TMPBUF_SZ  256
 
 struct boot_status {
-    uint32_t bs_img1_length;
-    uint32_t bs_img2_length;
-    /* Followed by sequence of boot status entries; file size indicates number
-     * of entries.
-     */
-};
-
-struct boot_status_entry {
-    uint8_t bse_image_num;
-    uint8_t bse_part_num;
+    uint32_t length;
+    uint32_t state;
 };
 
 /**
@@ -56,25 +48,17 @@ struct boot_status_entry {
  * present on disk.  The boot status indicates the state of the image slots in
  * case the system was restarted while images were being moved in flash.
  */
-struct boot_state {
-	struct boot_status status;
-	/** The entries associated with the boot status header. */
-	struct boot_status_entry entries[0];
-};
 
 struct boot_image_location {
     uint8_t bil_flash_id;
     uint32_t bil_address;
 };
 
-extern struct boot_state *boot_st;
-extern int boot_st_sz;
-
 void boot_read_image_headers(struct image_header *out_headers,
                              const struct boot_image_location *addresses,
                              int num_addresses);
-int boot_read_status(void);
-int boot_write_status(void);
+int boot_read_status(struct boot_status *);
+int boot_write_status(struct boot_status *);
 void boot_clear_status(void);
 
 int bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/libs/bootutil/src/loader.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/loader.c b/libs/bootutil/src/loader.c
index 906bc64..b3704ee 100644
--- a/libs/bootutil/src/loader.c
+++ b/libs/bootutil/src/loader.c
@@ -21,8 +21,8 @@
 #include <stddef.h>
 #include <inttypes.h>
 #include <string.h>
-#include <hal/hal_flash.h>
 #include <hal/flash_map.h>
+#include <hal/hal_flash.h>
 #include <os/os_malloc.h>
 #include "bootutil/loader.h"
 #include "bootutil/image.h"
@@ -38,8 +38,11 @@ static const struct boot_req *boot_req;
 /** Image headers read from flash. */
 struct image_header boot_img_hdrs[2];
 
-struct boot_state *boot_st;
-int boot_st_sz;
+static struct boot_status boot_state;
+
+#define BOOT_PERSIST(idx, st) (((idx) << 8) | (0xff & (st)))
+#define BOOT_PERSIST_IDX(st) (((st) >> 8) & 0xffffff)
+#define BOOT_PERSIST_ST(st) ((st) & 0xff)
 
 /**
  * Calculates the flash offset of the specified image slot.
@@ -122,90 +125,48 @@ boot_select_image_slot(void)
     return -1;
 }
 
-/**
- * Searches the current boot status for the specified image-num,part-num pair.
- *
- * @param image_num             The image number to search for.
- * @param part_num              The part number of the specified image to
- *                                  search for.
+/*
+ * How many sectors starting from sector[idx] can fit inside scratch.
  *
- * @return                      The area index containing the specified image
- *                              part number;
- *                              -1 if the part number is not present in flash.
  */
-static int
-boot_find_image_part(int image_num, int part_num)
+static uint32_t
+boot_copy_sz(int idx, int max_idx, int *cnt)
 {
     int i;
-
-    for (i = 0; i < boot_req->br_num_image_areas; i++) {
-        if (boot_st->entries[i].bse_image_num == image_num &&
-            boot_st->entries[i].bse_part_num == part_num) {
-
-            return boot_req->br_image_areas[i];
+    uint32_t sz;
+    static uint32_t scratch_sz = 0;
+
+    if (!scratch_sz) {
+        for (i = boot_req->br_scratch_area_idx;
+             i < boot_req->br_num_image_areas;
+             i++) {
+            scratch_sz += boot_req->br_area_descs[i].fa_size;
         }
     }
-
-    return -1;
-}
-
-static int
-boot_slot_to_area_idx(int slot_num)
-{
-    int i;
-    uint8_t flash_id;
-    uint32_t address;
-
-    assert(slot_num >= 0 && slot_num < BOOT_NUM_SLOTS);
-
-    for (i = 0; boot_req->br_area_descs[i].fa_size != 0; i++) {
-        boot_slot_addr(slot_num, &flash_id, &address);
-        if (boot_req->br_area_descs[i].fa_off == address &&
-          boot_req->br_area_descs[i].fa_flash_id == flash_id) {
-
-            return i;
+    sz = 0;
+    *cnt = 0;
+    for (i = idx; i < max_idx; i++) {
+        if (sz + boot_req->br_area_descs[i].fa_size > scratch_sz) {
+            break;
         }
+        sz += boot_req->br_area_descs[i].fa_size;
+        *cnt = *cnt + 1;
     }
-
-    return -1;
+    return sz;
 }
 
-/**
- * Locates the specified area index within the array of image areas.
- *
- * @param area_idx              The area index to search for.
- *
- * @return                      The index of the element in the image area
- *                              array.  that contains the sought after area
- *                              index; -1 if the area index is not present.
- */
-static int
-boot_find_image_area_idx(int area_idx)
-{
-    int i;
-
-    for (i = 0; i < boot_req->br_num_image_areas; i++) {
-        if (boot_req->br_image_areas[i] == area_idx) {
-            return i;
-        }
-    }
-
-    return -1;
-}
 
 static int
-boot_erase_area(int area_idx)
+boot_erase_area(int area_idx, uint32_t sz)
 {
     const struct flash_area *area_desc;
     int rc;
 
     area_desc = boot_req->br_area_descs + area_idx;
-    rc = hal_flash_erase(area_desc->fa_flash_id, area_desc->fa_off,
-                         area_desc->fa_size);
+    rc = hal_flash_erase(area_desc->fa_flash_id, area_desc->fa_off, sz);
     if (rc != 0) {
         return BOOT_EFLASH;
     }
-
     return 0;
 }
 
@@ -215,11 +176,12 @@ boot_erase_area(int area_idx)
  *
  * @param from_area_idx       The index of the source area.
  * @param to_area_idx         The index of the destination area.
+ * @param sz                  The number of bytes to move.
  *
  * @return                      0 on success; nonzero on failure.
  */
 static int
-boot_copy_area(int from_area_idx, int to_area_idx)
+boot_copy_area(int from_area_idx, int to_area_idx, uint32_t sz)
 {
     const struct flash_area *from_area_desc;
     const struct flash_area *to_area_desc;
@@ -237,11 +199,11 @@ boot_copy_area(int from_area_idx, int to_area_idx)
     assert(to_area_desc->fa_size >= from_area_desc->fa_size);
 
     off = 0;
-    while (off < from_area_desc->fa_size) {
-        if (from_area_desc->fa_size - off > sizeof buf) {
+    while (off < sz) {
+        if (sz - off > sizeof buf) {
             chunk_sz = sizeof buf;
         } else {
-            chunk_sz = from_area_desc->fa_size - off;
+            chunk_sz = sz - off;
         }
 
         from_addr = from_area_desc->fa_off + off;
@@ -267,212 +229,82 @@ boot_copy_area(int from_area_idx, int to_area_idx)
 /**
  * Swaps the contents of two flash areas.
  *
- * @param area_idx_1            The index of one area to swap.  This area
- *                                  must be part of the first image slot.
- * @param part_num_1            The image part number stored in the first
- *                                  area.
- * @param area_idx_2            The index of the other area to swap.  This
- *                                  area must be part of the second image
- *                                  slot.
- * @param part_num_2            The image part number stored in the second
- *                                  area.
- *
- * @return                      0 on success; nonzero on failure.
- */
-static int
-boot_move_area(int from_area_idx, int to_area_idx,
-                 int img_num, uint8_t part_num)
-{
-    int src_image_idx;
-    int dst_image_idx;
-    int rc;
-
-    src_image_idx = boot_find_image_area_idx(from_area_idx);
-    assert(src_image_idx != -1);
-
-    dst_image_idx = boot_find_image_area_idx(to_area_idx);
-    assert(dst_image_idx != -1);
-
-    rc = boot_erase_area(to_area_idx);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = boot_copy_area(from_area_idx, to_area_idx);
-    if (rc != 0) {
-        return rc;
-    }
-
-    boot_st->entries[src_image_idx].bse_image_num = BOOT_IMAGE_NUM_NONE;
-    boot_st->entries[src_image_idx].bse_part_num = BOOT_IMAGE_NUM_NONE;
-    boot_st->entries[dst_image_idx].bse_image_num = img_num;
-    boot_st->entries[dst_image_idx].bse_part_num = part_num;
-    rc = boot_write_status();
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = boot_erase_area(from_area_idx);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/**
- * Swaps the contents of two flash areas.
- *
  * @param area_idx_1          The index of one area to swap.  This area
  *                                  must be part of the first image slot.
- * @param part_num_1            The image part number stored in the first
- *                                  area.
  * @param area_idx_2          The index of the other area to swap.  This
  *                                  area must be part of the second image
  *                                  slot.
- * @param part_num_2            The image part number stored in the second
- *                                  area.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
-boot_swap_areas(int area_idx_1, int img_num_1, uint8_t part_num_1,
-                  int area_idx_2, int img_num_2, uint8_t part_num_2)
+boot_swap_areas(int idx, uint32_t sz)
 {
-    int scratch_image_idx;
-    int image_idx_1;
-    int image_idx_2;
+    int area_idx_1;
+    int area_idx_2;
     int rc;
+    int state;
 
+    area_idx_1 = boot_req->br_slot_areas[0] + idx;
+    area_idx_2 = boot_req->br_slot_areas[1] + idx;
     assert(area_idx_1 != area_idx_2);
     assert(area_idx_1 != boot_req->br_scratch_area_idx);
     assert(area_idx_2 != boot_req->br_scratch_area_idx);
 
-    image_idx_1 = boot_find_image_area_idx(area_idx_1);
-    assert(image_idx_1 != -1);
-
-    image_idx_2 = boot_find_image_area_idx(area_idx_2);
-    assert(image_idx_2 != -1);
-
-    scratch_image_idx =
-        boot_find_image_area_idx(boot_req->br_scratch_area_idx);
-    assert(scratch_image_idx != -1);
-
-    rc = boot_erase_area(boot_req->br_scratch_area_idx);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = boot_copy_area(area_idx_2, boot_req->br_scratch_area_idx);
-    if (rc != 0) {
-        return rc;
-    }
-
-    boot_st->entries[scratch_image_idx] = boot_st->entries[image_idx_2];
-    boot_st->entries[image_idx_2].bse_image_num = BOOT_IMAGE_NUM_NONE;
-    boot_st->entries[image_idx_2].bse_part_num = BOOT_IMAGE_NUM_NONE;
-
-    rc = boot_write_status();
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = boot_erase_area(area_idx_2);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = boot_copy_area(area_idx_1, area_idx_2);
-    if (rc != 0) {
-        return rc;
-    }
+    state = BOOT_PERSIST_ST(boot_state.state);
+    if (state == 0) {
+        rc = boot_erase_area(boot_req->br_scratch_area_idx, sz);
+        if (rc != 0) {
+            return rc;
+        }
 
-    boot_st->entries[image_idx_2] = boot_st->entries[image_idx_1];
-    boot_st->entries[image_idx_1].bse_image_num = BOOT_IMAGE_NUM_NONE;
-    boot_st->entries[image_idx_1].bse_part_num = BOOT_IMAGE_NUM_NONE;
-    rc = boot_write_status();
-    if (rc != 0) {
-        return rc;
-    }
+        rc = boot_copy_area(area_idx_2, boot_req->br_scratch_area_idx, sz);
+        if (rc != 0) {
+            return rc;
+        }
 
-    rc = boot_erase_area(area_idx_1);
-    if (rc != 0) {
-        return rc;
+        boot_state.state = BOOT_PERSIST(idx, 1);
+        rc = boot_write_status(&boot_state);
+        if (rc != 0) {
+            return rc;
+        }
+        state = 1;
     }
+    if (state == 1) {
+        rc = boot_erase_area(area_idx_2, sz);
+        if (rc != 0) {
+            return rc;
+        }
 
-    rc = boot_copy_area(boot_req->br_scratch_area_idx, area_idx_1);
-    if (rc != 0) {
-        return rc;
-    }
+        rc = boot_copy_area(area_idx_1, area_idx_2, sz);
+        if (rc != 0) {
+            return rc;
+        }
 
-    boot_st->entries[image_idx_1] = boot_st->entries[scratch_image_idx];
-    boot_st->entries[scratch_image_idx].bse_image_num = BOOT_IMAGE_NUM_NONE;
-    boot_st->entries[scratch_image_idx].bse_part_num = BOOT_IMAGE_NUM_NONE;
-    rc = boot_write_status();
-    if (rc != 0) {
-        return rc;
+        boot_state.state = BOOT_PERSIST(idx, 2);
+        rc = boot_write_status(&boot_state);
+        if (rc != 0) {
+            return rc;
+        }
+        state = 2;
     }
-
-    return 0;
-}
-
-static int
-boot_fill_slot(int img_num, uint32_t img_length, int start_area_idx)
-{
-    const struct flash_area *area_desc;
-    uint32_t off;
-    int dst_image_area_idx;
-    int src_area_idx;
-    int dst_area_idx;
-    int src_img_num;
-    int dst_img_num;
-    int part_num;
-    int rc;
-
-    part_num = 0;
-    off = 0;
-    while (off < img_length) {
-        /* Determine which area contains the current part of the image that
-         * we want to boot.
-         */
-        src_area_idx = boot_find_image_part(img_num, part_num);
-        if (src_area_idx == -1) {
-            return BOOT_EBADIMAGE;
+    if (state == 2) {
+        rc = boot_erase_area(area_idx_1, sz);
+        if (rc != 0) {
+            return rc;
         }
 
-        /* Determine which area we want to copy the source to. */
-        dst_area_idx = start_area_idx + part_num;
-
-        if (src_area_idx != dst_area_idx) {
-            /* Determine what is currently in the destination area. */
-            dst_image_area_idx = boot_find_image_area_idx(dst_area_idx);
-
-            if (boot_st->entries[dst_image_area_idx].bse_image_num ==
-                BOOT_IMAGE_NUM_NONE) {
-
-                /* The destination doesn't contain anything useful; we don't
-                 * need to back up its contents.
-                 */
-                rc = boot_move_area(src_area_idx, dst_area_idx,
-                                    img_num, part_num);
-            } else {
-                /* Swap the two areas. */
-                src_img_num = img_num ^ 1;
-                dst_img_num = img_num;
-                rc = boot_swap_areas(src_area_idx, src_img_num, part_num,
-                                     dst_area_idx, dst_img_num, part_num);
-            }
-            if (rc != 0) {
-                return rc;
-            }
+        rc = boot_copy_area(boot_req->br_scratch_area_idx, area_idx_1, sz);
+        if (rc != 0) {
+            return rc;
         }
 
-        area_desc = boot_req->br_area_descs + dst_area_idx;
-        off += area_desc->fa_size;
-
-        part_num++;
+        boot_state.state = BOOT_PERSIST(idx + 1, 0);
+        rc = boot_write_status(&boot_state);
+        if (rc != 0) {
+            return rc;
+        }
+        state = 3;
     }
-
     return 0;
 }
 
@@ -486,59 +318,25 @@ boot_fill_slot(int img_num, uint32_t img_length, int start_area_idx)
  * @return                      0 on success; nonzero on failure.
  */
 static int
-boot_copy_image(uint32_t img1_length, uint32_t img2_length)
-{
-    int rc;
-
-    rc = boot_fill_slot(1, img2_length, boot_slot_to_area_idx(0));
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = boot_fill_slot(0, img1_length, boot_slot_to_area_idx(1));
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/**
- * Builds a single default boot status for the specified image slot.
- */
-static void
-boot_build_status_one(int image_num, uint8_t flash_id, uint32_t addr,
-                      uint32_t length)
+boot_copy_image(void)
 {
-    uint32_t offset;
-    int area_idx = 0;
-    int part_num;
+    uint32_t off;
+    uint32_t sz;
     int i;
-
-    for (i = 0; i < boot_req->br_num_image_areas; i++) {
-        area_idx = boot_req->br_image_areas[i];
-        if (boot_req->br_area_descs[area_idx].fa_off == addr &&
-            boot_req->br_area_descs[area_idx].fa_flash_id == flash_id) {
-            break;
+    int cnt;
+    int rc;
+    int state_idx;
+
+    state_idx = BOOT_PERSIST_IDX(boot_state.state);
+    for (off = 0, i = 0; off < boot_state.length; off += sz, i += cnt) {
+        sz = boot_copy_sz(i, boot_req->br_slot_areas[1], &cnt);
+        if (i >= state_idx) {
+            rc = boot_swap_areas(i, sz);
+            assert(rc == 0);
         }
     }
 
-    assert(i < boot_req->br_num_image_areas);
-
-    offset = 0;
-    part_num = 0;
-    while (offset < length) {
-        assert(boot_st->entries[i].bse_image_num == 0xff);
-        boot_st->entries[i].bse_image_num = image_num;
-        boot_st->entries[i].bse_part_num = part_num;
-
-        offset += boot_req->br_area_descs[area_idx].fa_size;
-        part_num++;
-        i++;
-        area_idx++;
-    }
-
-    assert(i <= boot_req->br_num_image_areas);
+    return 0;
 }
 
 /**
@@ -550,30 +348,27 @@ boot_build_status_one(int image_num, uint8_t flash_id, uint32_t addr,
 static void
 boot_build_status(void)
 {
-    uint8_t flash_id;
-    uint32_t address;
-    uint32_t len;
-
-    memset(boot_st->entries, 0xff,
-           boot_req->br_num_image_areas * sizeof boot_st->entries[0]);
+    uint32_t len1;
+    uint32_t len2;
 
     if (boot_img_hdrs[0].ih_magic == IMAGE_MAGIC) {
-        boot_st->status.bs_img1_length =
-	    boot_img_hdrs[0].ih_img_size + boot_img_hdrs[0].ih_tlv_size;
-        boot_slot_addr(0, &flash_id, &address);
-        boot_build_status_one(0, flash_id, address, len);
+        len1 = boot_img_hdrs[0].ih_hdr_size + boot_img_hdrs[0].ih_img_size +
+          boot_img_hdrs[0].ih_tlv_size;
     } else {
-        boot_st->status.bs_img1_length = 0;
+        len1 = 0;
     }
 
     if (boot_img_hdrs[1].ih_magic == IMAGE_MAGIC) {
-        boot_st->status.bs_img2_length =
-	    boot_img_hdrs[1].ih_img_size + boot_img_hdrs[1].ih_tlv_size;
-        boot_slot_addr(1, &flash_id, &address);
-        boot_build_status_one(1, flash_id, address, len);
+        len2 = boot_img_hdrs[1].ih_hdr_size + boot_img_hdrs[1].ih_img_size +
+          boot_img_hdrs[0].ih_tlv_size;
     } else {
-        boot_st->status.bs_img2_length = 0;
+        len2 = 0;
     }
+    boot_state.length = len1;
+    if (len1 < len2) {
+        boot_state.length = len2;
+    }
+    boot_state.state = 0;
 }
 
 /**
@@ -604,18 +399,10 @@ boot_go(const struct boot_req *req, struct boot_rsp *rsp)
      * interrupted (i.e., the system was reset before the boot loader could
      * finish its task last time).
      */
-    boot_st_sz = sizeof(struct boot_state) +
-	req->br_num_image_areas * sizeof boot_st->entries[0];
-    boot_st = malloc(boot_st_sz);
-    if (boot_st == NULL) {
-        return BOOT_ENOMEM;
-    }
-
-    if (boot_read_status()) {
+    if (boot_read_status(&boot_state)) {
         /* We are resuming an interrupted image copy. */
         /* XXX if copy has not actually started yet, validate image */
-        rc = boot_copy_image(boot_st->status.bs_img1_length,
-                             boot_st->status.bs_img2_length);
+        rc = boot_copy_image();
         if (rc != 0) {
             /* We failed to put the images back together; there is really no
              * solution here.
@@ -673,9 +460,7 @@ boot_go(const struct boot_req *req, struct boot_rsp *rsp)
         /* The user wants to run the image in the secondary slot.  The contents
          * of this slot need to moved to the primary slot.
          */
-        rc = boot_copy_image(boot_st->status.bs_img1_length,
-                             boot_st->status.bs_img2_length);
-
+        rc = boot_copy_image();
         if (rc != 0) {
             /* We failed to put the images back together; there is really no
              * solution here.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/705d3346/libs/bootutil/src/test/boot_test.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/test/boot_test.c b/libs/bootutil/src/test/boot_test.c
index 9a3513c..2ea9c9d 100644
--- a/libs/bootutil/src/test/boot_test.c
+++ b/libs/bootutil/src/test/boot_test.c
@@ -6,7 +6,7 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  *  http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing,
@@ -25,11 +25,13 @@
 #include <inttypes.h>
 #include "testutil/testutil.h"
 #include "hal/hal_flash.h"
+#include "hal/flash_map.h"
 #include "fs/fs.h"
-#include "fs/fsutil.h"
 #include "nffs/nffs.h"
+#include <config/config_file.h>
 #include "bootutil/image.h"
 #include "bootutil/loader.h"
+#include "bootutil/bootutil_misc.h"
 #include "../src/bootutil_priv.h"
 
 #include "mbedtls/sha256.h"
@@ -37,37 +39,26 @@
 #define BOOT_TEST_HEADER_SIZE       0x200
 
 /** Internal flash layout. */
-static struct nffs_area_desc boot_test_area_descs[] = {
-    [0] =  { 0x00000000, 16 * 1024 },
-    [1] =  { 0x00004000, 16 * 1024 },
-    [2] =  { 0x00008000, 16 * 1024 },
-    [3] =  { 0x0000c000, 16 * 1024 },
-    [4] =  { 0x00010000, 64 * 1024 },
-    [5] =  { 0x00020000, 128 * 1024 },
-    [6] =  { 0x00040000, 128 * 1024 },
-    [7] =  { 0x00060000, 128 * 1024 },
-    [8] =  { 0x00080000, 128 * 1024 },
-    [9] =  { 0x000a0000, 128 * 1024 },
-    [10] = { 0x000c0000, 128 * 1024 },
-    [11] = { 0x000e0000, 128 * 1024 },
-    { 0, 0 },
-};
-
-static const struct nffs_area_desc boot_test_format_descs[] = {
-    [0] =  { 0x00004000, 16 * 1024 },
-    [1] =  { 0x00008000, 16 * 1024 },
-    [2] =  { 0x0000c000, 16 * 1024 },
-    { 0, 0 },
+static struct flash_area boot_test_area_descs[] = {
+    [0] = { .fa_off = 0x00020000, .fa_size = 128 * 1024 },
+    [1] = { .fa_off = 0x00040000, .fa_size = 128 * 1024 },
+    [2] = { .fa_off = 0x00060000, .fa_size = 128 * 1024 },
+    [3] = { .fa_off = 0x00080000, .fa_size = 128 * 1024 },
+    [4] = { .fa_off = 0x000a0000, .fa_size = 128 * 1024 },
+    [5] = { .fa_off = 0x000c0000, .fa_size = 128 * 1024 },
+    [6] = { .fa_off = 0x000e0000, .fa_size = 128 * 1024 },
 };
 
-/** Contains indices of the areas which can contain image data. */
-static uint8_t boot_test_img_areas[] = {
-    5, 6, 7, 8, 9, 10, 11
+static const struct flash_area boot_test_format_descs[] = {
+    [0] = { .fa_off = 0x00004000, .fa_size = 16 * 1024 },
+    [1] = { .fa_off = 0x00008000, .fa_size = 16 * 1024 },
+    [2] = { .fa_off = 0x0000c000, .fa_size = 16 * 1024 },
+    [3] = { .fa_off = 0, .fa_size = 0 },
 };
 
 /** Areas representing the beginning of image slots. */
 static uint8_t boot_test_slot_areas[] = {
-    5, 8,
+    0, 3,
 };
 
 /** Flash offsets of the two image slots. */
@@ -79,11 +70,13 @@ static struct {
     { 0, 0x80000 },
 };
 
-#define BOOT_TEST_NUM_IMG_AREAS \
-    ((int)(sizeof boot_test_img_areas / sizeof boot_test_img_areas[0]))
+#define BOOT_TEST_AREA_IDX_SCRATCH 6
+
+#define MY_CONF_PATH "/cfg/run"
 
-#define BOOT_TEST_AREA_IDX_SCRATCH 11
-#define BOOT_TEST_IMG_AREA_IDX_SCRATCH 6
+static struct conf_file my_conf = {
+    .cf_name = MY_CONF_PATH
+};
 
 static uint8_t
 boot_test_util_byte_at(int img_msb, uint32_t image_offset)
@@ -100,60 +93,61 @@ boot_test_util_byte_at(int img_msb, uint32_t image_offset)
 static void
 boot_test_util_init_flash(void)
 {
-    const struct nffs_area_desc *area_desc;
+    const struct flash_area *area_desc;
     int rc;
+    struct nffs_area_desc nffs_descs[32];
+    int cnt;
 
     rc = hal_flash_init();
     TEST_ASSERT(rc == 0);
 
     for (area_desc = boot_test_area_descs;
-         area_desc->nad_length != 0;
+         area_desc->fa_size != 0;
          area_desc++) {
 
-        rc = hal_flash_erase(area_desc->nad_flash_id, area_desc->nad_offset,
-                             area_desc->nad_length);
+        rc = flash_area_erase(area_desc, 0, area_desc->fa_size);
         TEST_ASSERT(rc == 0);
     }
+    cnt = 32;
 
-    rc = nffs_init();
+    rc = flash_area_to_nffs_desc(FLASH_AREA_NFFS, &cnt, nffs_descs);
     TEST_ASSERT(rc == 0);
 
-    rc = nffs_format(boot_test_format_descs);
+    rc = nffs_init();
     TEST_ASSERT(rc == 0);
-
-    rc = fs_mkdir("/boot");
+    rc = nffs_format(nffs_descs);
     TEST_ASSERT(rc == 0);
+
+    fs_mkdir("/cfg");
 }
 
 static void
 boot_test_util_copy_area(int from_area_idx, int to_area_idx)
 {
-    const struct nffs_area_desc *from_area_desc;
-    const struct nffs_area_desc *to_area_desc;
+    const struct flash_area *from_area_desc;
+    const struct flash_area *to_area_desc;
     void *buf;
     int rc;
 
     from_area_desc = boot_test_area_descs + from_area_idx;
     to_area_desc = boot_test_area_descs + to_area_idx;
 
-    TEST_ASSERT(from_area_desc->nad_length == to_area_desc->nad_length);
+    TEST_ASSERT(from_area_desc->fa_size == to_area_desc->fa_size);
 
-    buf = malloc(from_area_desc->nad_length);
+    buf = malloc(from_area_desc->fa_size);
     TEST_ASSERT(buf != NULL);
 
-    rc = hal_flash_read(from_area_desc->nad_flash_id,
-                        from_area_desc->nad_offset, buf,
-                        from_area_desc->nad_length);
+    rc = flash_area_read(from_area_desc, 0, buf,
+                         from_area_desc->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_erase(to_area_desc->nad_flash_id,
-                         to_area_desc->nad_offset,
-                         to_area_desc->nad_length);
+    rc = flash_area_erase(to_area_desc,
+                          0,
+                          to_area_desc->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_write(to_area_desc->nad_flash_id,
-                         to_area_desc->nad_offset, buf,
-                         to_area_desc->nad_length);
+    rc = flash_area_write(to_area_desc, 0, buf,
+                          to_area_desc->fa_size);
     TEST_ASSERT(rc == 0);
 
     free(buf);
@@ -162,8 +156,8 @@ boot_test_util_copy_area(int from_area_idx, int to_area_idx)
 static void
 boot_test_util_swap_areas(int area_idx1, int area_idx2)
 {
-    const struct nffs_area_desc *area_desc1;
-    const struct nffs_area_desc *area_desc2;
+    const struct flash_area *area_desc1;
+    const struct flash_area *area_desc2;
     void *buf1;
     void *buf2;
     int rc;
@@ -171,36 +165,30 @@ boot_test_util_swap_areas(int area_idx1, int area_idx2)
     area_desc1 = boot_test_area_descs + area_idx1;
     area_desc2 = boot_test_area_descs + area_idx2;
 
-    TEST_ASSERT(area_desc1->nad_length == area_desc2->nad_length);
+    TEST_ASSERT(area_desc1->fa_size == area_desc2->fa_size);
 
-    buf1 = malloc(area_desc1->nad_length);
+    buf1 = malloc(area_desc1->fa_size);
     TEST_ASSERT(buf1 != NULL);
 
-    buf2 = malloc(area_desc2->nad_length);
+    buf2 = malloc(area_desc2->fa_size);
     TEST_ASSERT(buf2 != NULL);
 
-    rc = hal_flash_read(area_desc1->nad_flash_id, area_desc1->nad_offset,
-                        buf1, area_desc1->nad_length);
+    rc = flash_area_read(area_desc1, 0, buf1, area_desc1->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_read(area_desc2->nad_flash_id, area_desc2->nad_offset,
-                        buf2, area_desc2->nad_length);
+    rc = flash_area_read(area_desc2, 0, buf2, area_desc2->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_erase(area_desc1->nad_flash_id, area_desc1->nad_offset,
-                         area_desc1->nad_length);
+    rc = flash_area_erase(area_desc1, 0, area_desc1->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_erase(area_desc2->nad_flash_id, area_desc2->nad_offset,
-                         area_desc2->nad_length);
+    rc = flash_area_erase(area_desc2, 0, area_desc2->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_write(area_desc1->nad_flash_id, area_desc1->nad_offset,
-                         buf2, area_desc1->nad_length);
+    rc = flash_area_write(area_desc1, 0, buf2, area_desc1->fa_size);
     TEST_ASSERT(rc == 0);
 
-    rc = hal_flash_write(area_desc2->nad_flash_id, area_desc2->nad_offset,
-                         buf1, area_desc2->nad_length);
+    rc = flash_area_write(area_desc2, 0, buf1, area_desc2->fa_size);
     TEST_ASSERT(rc == 0);
 
     free(buf1);
@@ -291,7 +279,7 @@ boot_test_util_write_hash(const struct image_header *hdr, int slot)
 }
 
 static void
-boot_test_util_verify_area(const struct nffs_area_desc *area_desc,
+boot_test_util_verify_area(const struct flash_area *area_desc,
                            const struct image_header *hdr,
                            uint32_t image_addr, int img_msb)
 {
@@ -309,13 +297,13 @@ boot_test_util_verify_area(const struct nffs_area_desc *area_desc,
     int rc;
     int i;
 
-    addr = area_desc->nad_offset;
+    addr = area_desc->fa_off;
 
     if (hdr != NULL) {
         img_size = hdr->ih_img_size;
 
         if (addr == image_addr) {
-            rc = hal_flash_read(area_desc->nad_flash_id, image_addr,
+            rc = hal_flash_read(area_desc->fa_flash_id, image_addr,
                                 &temp_hdr, sizeof temp_hdr);
             TEST_ASSERT(rc == 0);
             TEST_ASSERT(memcmp(&temp_hdr, hdr, sizeof *hdr) == 0);
@@ -326,7 +314,7 @@ boot_test_util_verify_area(const struct nffs_area_desc *area_desc,
         img_size = 0;
     }
 
-    area_end = area_desc->nad_offset + area_desc->nad_length;
+    area_end = area_desc->fa_off + area_desc->fa_size;
     img_end = image_addr + img_size;
     past_image = addr >= img_end;
 
@@ -346,7 +334,7 @@ boot_test_util_verify_area(const struct nffs_area_desc *area_desc,
             chunk_sz = rem_area;
         }
 
-        rc = hal_flash_read(area_desc->nad_flash_id, addr, buf, chunk_sz);
+        rc = hal_flash_read(area_desc->fa_flash_id, addr, buf, chunk_sz);
         TEST_ASSERT(rc == 0);
 
         for (i = 0; i < chunk_sz; i++) {
@@ -367,24 +355,55 @@ boot_test_util_verify_status_clear(void)
 {
     struct fs_file *file;
     int rc;
+    int empty = 1;
+    char *needle = "boot/status=";
+    int nlen = strlen(needle);
+    uint32_t len, hlen;
+    char *haystack, *ptr;
+
+    rc = fs_open(MY_CONF_PATH, FS_ACCESS_READ, &file);
+    if (rc != 0) {
+        return;
+    }
+    rc = fs_filelen(file, &len);
+    TEST_ASSERT(rc == 0);
+
+    haystack = malloc(len + 1);
+    TEST_ASSERT(haystack);
 
-    rc = fs_open(BOOT_PATH_STATUS, FS_ACCESS_READ, &file);
-    TEST_ASSERT(rc == FS_ENOENT);
+    rc = fs_read(file, len, haystack, &hlen);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(hlen == len);
+    haystack[len] = '\0';
+
+    fs_close(file);
+
+    ptr = haystack;
+    while ((ptr = strstr(ptr, needle))) {
+        if (ptr[nlen] == '\n') {
+            empty = 1;
+        } else {
+            empty = 0;
+        }
+        ptr += nlen;
+    }
+    TEST_ASSERT(empty == 1);
+    free(haystack);
 }
 
 static void
 boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0,
                             const struct image_header *hdr1, int orig_slot_1)
 {
-    const struct nffs_area_desc *area_desc;
+    const struct flash_area *area_desc;
     int area_idx;
 
-    area_idx = boot_test_img_areas[0];
+    area_idx = 0;
 
     while (1) {
         area_desc = boot_test_area_descs + area_idx;
-        if (area_desc->nad_offset == boot_test_img_addrs[1].address &&
-            area_desc->nad_flash_id == boot_test_img_addrs[1].flash_id) {
+        if (area_desc->fa_off == boot_test_img_addrs[1].address &&
+            area_desc->fa_flash_id == boot_test_img_addrs[1].flash_id) {
             break;
         }
 
@@ -405,6 +424,18 @@ boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0,
     }
 }
 
+TEST_CASE(boot_test_setup)
+{
+    int rc;
+
+    rc = conf_file_src(&my_conf);
+    assert(rc == 0);
+    rc = conf_file_dst(&my_conf);
+    assert(rc == 0);
+
+    bootutil_cfg_register();
+}
+
 TEST_CASE(boot_test_nv_ns_10)
 {
     struct boot_rsp rsp;
@@ -421,9 +452,8 @@ TEST_CASE(boot_test_nv_ns_10)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
     };
 
@@ -459,10 +489,9 @@ TEST_CASE(boot_test_nv_ns_01)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -505,10 +534,9 @@ TEST_CASE(boot_test_nv_ns_11)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -545,17 +573,16 @@ TEST_CASE(boot_test_vm_ns_10)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
     boot_test_util_write_image(&hdr, 0);
     boot_test_util_write_hash(&hdr, 0);
 
-    rc = fsutil_write_file(BOOT_PATH_MAIN, &hdr.ih_ver, sizeof hdr.ih_ver);
+    rc = boot_vect_write_main(&hdr.ih_ver);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -574,7 +601,6 @@ TEST_CASE(boot_test_vm_ns_01)
     struct boot_rsp rsp;
     int rc;
 
-
     struct image_header hdr = {
         .ih_magic = IMAGE_MAGIC,
         .ih_tlv_size = 4 + 32,
@@ -586,17 +612,16 @@ TEST_CASE(boot_test_vm_ns_01)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
     boot_test_util_write_image(&hdr, 1);
     boot_test_util_write_hash(&hdr, 1);
 
-    rc = fsutil_write_file(BOOT_PATH_MAIN, &hdr.ih_ver, sizeof hdr.ih_ver);
+    rc = boot_vect_write_main(&hdr.ih_ver);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -635,10 +660,9 @@ TEST_CASE(boot_test_vm_ns_11_a)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -647,7 +671,7 @@ TEST_CASE(boot_test_vm_ns_11_a)
     boot_test_util_write_image(&hdr1, 1);
     boot_test_util_write_hash(&hdr1, 1);
 
-    rc = fsutil_write_file(BOOT_PATH_MAIN, &hdr0.ih_ver, sizeof hdr0.ih_ver);
+    rc = boot_vect_write_main(&hdr0.ih_ver);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -686,10 +710,9 @@ TEST_CASE(boot_test_vm_ns_11_b)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -698,7 +721,7 @@ TEST_CASE(boot_test_vm_ns_11_b)
     boot_test_util_write_image(&hdr1, 1);
     boot_test_util_write_hash(&hdr1, 1);
 
-    rc = fsutil_write_file(BOOT_PATH_MAIN, &hdr1.ih_ver, sizeof hdr1.ih_ver);
+    rc = boot_vect_write_main(&hdr1.ih_ver);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -737,10 +760,9 @@ TEST_CASE(boot_test_vm_ns_11_2areas)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -749,7 +771,7 @@ TEST_CASE(boot_test_vm_ns_11_2areas)
     boot_test_util_write_image(&hdr1, 1);
     boot_test_util_write_hash(&hdr1, 1);
 
-    rc = fsutil_write_file(BOOT_PATH_MAIN, &hdr1.ih_ver, sizeof hdr1.ih_ver);
+    rc = boot_vect_write_main(&hdr1.ih_ver);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -765,7 +787,6 @@ TEST_CASE(boot_test_vm_ns_11_2areas)
 
 TEST_CASE(boot_test_nv_bs_10)
 {
-    struct boot_status_entry entries[BOOT_TEST_NUM_IMG_AREAS];
     struct boot_status status;
     struct boot_rsp rsp;
     int rc;
@@ -781,27 +802,23 @@ TEST_CASE(boot_test_nv_bs_10)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
     boot_test_util_write_image(&hdr, 0);
     boot_test_util_write_hash(&hdr, 0);
-    boot_test_util_swap_areas(boot_test_img_areas[0],
-                                BOOT_TEST_AREA_IDX_SCRATCH);
-
-    memset(&status, 0xff, sizeof status);
-    status.bs_img2_length = hdr.ih_img_size;
+    boot_test_util_swap_areas(boot_test_slot_areas[1],
+      BOOT_TEST_AREA_IDX_SCRATCH);
 
-    memset(entries, 0xff, sizeof entries);
-    entries[BOOT_TEST_IMG_AREA_IDX_SCRATCH].bse_image_num = 1;
-    entries[BOOT_TEST_IMG_AREA_IDX_SCRATCH].bse_part_num = 0;
+    status.length = hdr.ih_hdr_size + hdr.ih_img_size + hdr.ih_tlv_size;
+    status.state = 1;
 
-    rc = boot_write_status(&status, entries, BOOT_TEST_NUM_IMG_AREAS);
+    rc = boot_write_status(&status);
     TEST_ASSERT(rc == 0);
+    conf_load();
 
     rc = boot_go(&req, &rsp);
     TEST_ASSERT(rc == 0);
@@ -816,9 +833,9 @@ TEST_CASE(boot_test_nv_bs_10)
 
 TEST_CASE(boot_test_nv_bs_11)
 {
-    struct boot_status_entry entries[BOOT_TEST_NUM_IMG_AREAS];
     struct boot_status status;
     struct boot_rsp rsp;
+    int len;
     int rc;
 
     struct image_header hdr0 = {
@@ -841,10 +858,9 @@ TEST_CASE(boot_test_nv_bs_11)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -852,20 +868,17 @@ TEST_CASE(boot_test_nv_bs_11)
     boot_test_util_write_hash(&hdr0, 0);
     boot_test_util_write_image(&hdr1, 1);
     boot_test_util_write_hash(&hdr1, 1);
-    boot_test_util_copy_area(boot_test_img_areas[0],
-                             BOOT_TEST_AREA_IDX_SCRATCH);
+    boot_test_util_copy_area(boot_test_slot_areas[1],
+      BOOT_TEST_AREA_IDX_SCRATCH);
 
-    memset(&status, 0xff, sizeof status);
-    status.bs_img1_length = hdr0.ih_img_size;
-    status.bs_img2_length = hdr1.ih_img_size;
-
-    memset(entries, 0xff, sizeof entries);
-    entries[3].bse_image_num = 1;
-    entries[3].bse_part_num = 0;
-    entries[BOOT_TEST_IMG_AREA_IDX_SCRATCH].bse_image_num = 0;
-    entries[BOOT_TEST_IMG_AREA_IDX_SCRATCH].bse_part_num = 0;
+    status.length = hdr0.ih_hdr_size + hdr0.ih_img_size + hdr0.ih_tlv_size;
+    len = hdr1.ih_hdr_size + hdr1.ih_img_size + hdr1.ih_tlv_size;
+    if (len > status.length) {
+        status.length = len;
+    }
+    status.state = 1;
 
-    rc = boot_write_status(&status, entries, BOOT_TEST_NUM_IMG_AREAS);
+    rc = boot_write_status(&status);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -881,10 +894,10 @@ TEST_CASE(boot_test_nv_bs_11)
 
 TEST_CASE(boot_test_nv_bs_11_2areas)
 {
-    struct boot_status_entry entries[BOOT_TEST_NUM_IMG_AREAS];
     struct boot_status status;
     struct boot_rsp rsp;
     int rc;
+    int len;
 
     struct image_header hdr0 = {
         .ih_magic = IMAGE_MAGIC,
@@ -906,10 +919,9 @@ TEST_CASE(boot_test_nv_bs_11_2areas)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -917,23 +929,17 @@ TEST_CASE(boot_test_nv_bs_11_2areas)
     boot_test_util_write_hash(&hdr0, 0);
     boot_test_util_write_image(&hdr1, 1);
     boot_test_util_write_hash(&hdr1, 1);
-    boot_test_util_swap_areas(boot_test_img_areas[0], boot_test_img_areas[3]);
-
-    memset(&status, 0xff, sizeof status);
-    status.bs_img1_length = hdr0.ih_img_size;
-    status.bs_img2_length = hdr1.ih_img_size;
-
-    memset(entries, 0xff, sizeof entries);
-    entries[0].bse_image_num = 1;
-    entries[0].bse_part_num = 0;
-    entries[1].bse_image_num = 0;
-    entries[1].bse_part_num = 1;
-    entries[3].bse_image_num = 0;
-    entries[3].bse_part_num = 0;
-    entries[4].bse_image_num = 1;
-    entries[4].bse_part_num = 1;
-
-    rc = boot_write_status(&status, entries, BOOT_TEST_NUM_IMG_AREAS);
+    boot_test_util_swap_areas(boot_test_slot_areas[0],
+      boot_test_slot_areas[1]);
+
+    status.length = hdr0.ih_hdr_size + hdr0.ih_img_size + hdr0.ih_tlv_size;
+    len = hdr1.ih_hdr_size + hdr1.ih_img_size + hdr1.ih_tlv_size;
+    if (len > status.length) {
+        status.length = len;
+    }
+    status.state = 1 << 8;
+
+    rc = boot_write_status(&status);
     TEST_ASSERT(rc == 0);
 
     rc = boot_go(&req, &rsp);
@@ -973,10 +979,9 @@ TEST_CASE(boot_test_vb_ns_11)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
     };
 
     boot_test_util_init_flash();
@@ -985,10 +990,10 @@ TEST_CASE(boot_test_vb_ns_11)
     boot_test_util_write_hash(&hdr0, 0);
     boot_test_util_write_hash(&hdr1, 1);
 
-    rc = fsutil_write_file(BOOT_PATH_MAIN, &hdr0.ih_ver, sizeof hdr0.ih_ver);
+    rc = boot_vect_write_main(&hdr0.ih_ver);
     TEST_ASSERT(rc == 0);
 
-    rc = fsutil_write_file(BOOT_PATH_TEST, &hdr1.ih_ver, sizeof hdr1.ih_ver);
+    rc = boot_vect_write_test(&hdr1.ih_ver);
     TEST_ASSERT(rc == 0);
 
     /* First boot should use the test image. */
@@ -1032,9 +1037,8 @@ TEST_CASE(boot_test_no_hash)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
     };
 
@@ -1064,9 +1068,8 @@ TEST_CASE(boot_test_no_flag_has_hash)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
     };
 
@@ -1097,9 +1100,8 @@ TEST_CASE(boot_test_invalid_hash)
 
     struct boot_req req = {
         .br_area_descs = boot_test_area_descs,
-        .br_image_areas = boot_test_img_areas,
         .br_slot_areas = boot_test_slot_areas,
-        .br_num_image_areas = BOOT_TEST_NUM_IMG_AREAS,
+        .br_num_image_areas = BOOT_TEST_AREA_IDX_SCRATCH + 1,
         .br_scratch_area_idx = BOOT_TEST_AREA_IDX_SCRATCH,
     };
 
@@ -1123,6 +1125,7 @@ TEST_CASE(boot_test_invalid_hash)
 
 TEST_SUITE(boot_test_main)
 {
+    boot_test_setup();
     boot_test_nv_ns_10();
     boot_test_nv_ns_01();
     boot_test_nv_ns_11();