You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/08/24 00:53:43 UTC

[29/50] [abbrv] incubator-mynewt-core git commit: boot; don't use NFFS or FCB for keeping status. Interim commit.

boot; don't use NFFS or FCB for keeping status. Interim commit.


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/b2009c9f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/b2009c9f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/b2009c9f

Branch: refs/heads/master
Commit: b2009c9fbce7d7ac8f6f039cda6866e81868b622
Parents: 5de9a72
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Aug 16 18:07:30 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Aug 19 15:11:49 2016 -0700

----------------------------------------------------------------------
 apps/boot/pkg.yml                              |   3 +-
 apps/boot/src/boot.c                           |  91 +----
 apps/slinky/src/main.c                         |   1 -
 libs/bootutil/include/bootutil/bootutil_misc.h |   4 +-
 libs/bootutil/include/bootutil/loader.h        |   3 +
 libs/bootutil/src/bootutil_misc.c              | 264 ++-----------
 libs/bootutil/src/bootutil_priv.h              |  44 +--
 libs/bootutil/src/loader.c                     | 399 +++++++++++---------
 libs/imgmgr/src/imgmgr_boot.c                  |   6 +-
 9 files changed, 291 insertions(+), 524 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/apps/boot/pkg.yml
----------------------------------------------------------------------
diff --git a/apps/boot/pkg.yml b/apps/boot/pkg.yml
index 10ec482..b877557 100644
--- a/apps/boot/pkg.yml
+++ b/apps/boot/pkg.yml
@@ -29,12 +29,11 @@ pkg.features: bootloader
 
 pkg.deps:
     - sys/config
-    - fs/nffs
     - libs/bootutil
     - libs/mbedtls
     - libs/os
     - libs/util
-    - libs/console/stub
+    - libs/console/full
 
 pkg.cflags: -DLOG_LEVEL=255
 pkg.cflags.NFFS:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/apps/boot/src/boot.c
----------------------------------------------------------------------
diff --git a/apps/boot/src/boot.c b/apps/boot/src/boot.c
index 97a9b32..37172ba 100755
--- a/apps/boot/src/boot.c
+++ b/apps/boot/src/boot.c
@@ -27,19 +27,11 @@
 #include <hal/hal_flash.h>
 #include <config/config.h>
 #include <config/config_file.h>
-#ifdef NFFS_PRESENT
-#include <fs/fs.h>
-#include <nffs/nffs.h>
-#elif FCB_PRESENT
-#include <fcb/fcb.h>
-#include <config/config_fcb.h>
-#else
-#error "Need NFFS or FCB for config storage"
-#endif
 #ifdef BOOT_SERIAL
 #include <hal/hal_gpio.h>
 #include <boot_serial/boot_serial.h>
 #endif
+#include <console/console.h>
 #include "bootutil/image.h"
 #include "bootutil/loader.h"
 #include "bootutil/bootutil_misc.h"
@@ -58,76 +50,11 @@ static struct os_task boot_ser_task;
 static os_stack_t boot_ser_stack[BOOT_SER_STACK_SZ];
 #endif
 
-#ifdef NFFS_PRESENT
-#define MY_CONFIG_FILE "/cfg/run"
-
-static struct conf_file my_conf = {
-    .cf_name = MY_CONFIG_FILE
-};
-
-static void
-setup_for_nffs(void)
-{
-    struct nffs_area_desc nffs_descs[NFFS_AREA_MAX + 1];
-    int cnt;
-    int rc;
-
-    /*
-     * Make sure we have enough left to initialize the NFFS with the
-     * right number of maximum areas otherwise the file-system will not
-     * be readable.
-     */
-    cnt = NFFS_AREA_MAX;
-    rc = flash_area_to_nffs_desc(FLASH_AREA_NFFS, &cnt, nffs_descs);
-    assert(rc == 0);
-
-    /*
-     * Initializes the flash driver and file system for use by the boot loader.
-     */
-    rc = nffs_init();
-    if (rc == 0) {
-        /* Look for an nffs file system in internal flash.  If no file
-         * system gets detected, all subsequent file operations will fail,
-         * but the boot loader should proceed anyway.
-         */
-        nffs_detect(nffs_descs);
-    }
-
-    rc = conf_file_src(&my_conf);
-    assert(rc == 0);
-    rc = conf_file_dst(&my_conf);
-    assert(rc == 0);
-}
-#else
-struct flash_area conf_fcb_area[NFFS_AREA_MAX + 1];
-
-static struct conf_fcb my_conf = {
-    .cf_fcb.f_magic = 0xc09f6e5e,
-    .cf_fcb.f_sectors = conf_fcb_area
-};
-
-static void
-setup_for_fcb(void)
-{
-    int cnt;
-    int rc;
-
-    rc = flash_area_to_sectors(FLASH_AREA_NFFS, &cnt, NULL);
-    assert(rc == 0);
-    assert(cnt <= sizeof(conf_fcb_area) / sizeof(conf_fcb_area[0]));
-    flash_area_to_sectors(FLASH_AREA_NFFS, &cnt, conf_fcb_area);
-
-    my_conf.cf_fcb.f_sector_cnt = cnt;
-
-    conf_fcb_src(&my_conf);
-    conf_fcb_dst(&my_conf);
-}
-#endif
-
 int
 main(void)
 {
     struct flash_area descs[AREA_DESC_MAX];
+    const struct flash_area *fap;
     /** Areas representing the beginning of image slots. */
     uint8_t img_starts[2];
     int cnt;
@@ -149,6 +76,9 @@ main(void)
     img_starts[0] = 0;
     total = cnt;
 
+    flash_area_open(FLASH_AREA_IMAGE_0, &fap);
+    req.br_img_sz = fap->fa_size;
+
     cnt = BOOT_AREA_DESC_MAX - total;
     assert(cnt >= 0);
     rc = flash_area_to_sectors(FLASH_AREA_IMAGE_1, &cnt, &descs[total]);
@@ -167,13 +97,8 @@ main(void)
 
     conf_init();
 
-#ifdef NFFS_PRESENT
-    setup_for_nffs();
-#elif FCB_PRESENT
-    setup_for_fcb();
-#endif
-    bootutil_cfg_register();
-
+    console_init(NULL);
+    console_printf("\nboot_loader\n");
 #ifdef BOOT_SERIAL
     /*
      * Configure a GPIO as input, and compare it against expected value.
@@ -189,6 +114,8 @@ main(void)
 #endif
     rc = boot_go(&req, &rsp);
     assert(rc == 0);
+    console_blocking_mode();
+    console_printf("\nboot_go = %d\n", rc);
 
     system_start((void *)(rsp.br_image_addr + rsp.br_hdr->ih_hdr_size));
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/apps/slinky/src/main.c
----------------------------------------------------------------------
diff --git a/apps/slinky/src/main.c b/apps/slinky/src/main.c
index 7f724e6..fd68aa4 100755
--- a/apps/slinky/src/main.c
+++ b/apps/slinky/src/main.c
@@ -397,7 +397,6 @@ main(int argc, char **argv)
 
     nmgr_task_init(NEWTMGR_TASK_PRIO, newtmgr_stack, NEWTMGR_TASK_STACK_SIZE);
     imgmgr_module_init();
-    bootutil_cfg_register();
 
     stats_module_init();
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/libs/bootutil/include/bootutil/bootutil_misc.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/include/bootutil/bootutil_misc.h b/libs/bootutil/include/bootutil/bootutil_misc.h
index ff42ac8..e8834db 100644
--- a/libs/bootutil/include/bootutil/bootutil_misc.h
+++ b/libs/bootutil/include/bootutil/bootutil_misc.h
@@ -23,9 +23,7 @@
 struct image_version;
 int boot_vect_read_test(struct image_version *out_ver);
 int boot_vect_read_main(struct image_version *out_ver);
-int boot_vect_write_test(struct image_version *ver);
+int boot_vect_write_test(int slot);
 int boot_vect_write_main(struct image_version *ver);
 
-void bootutil_cfg_register(void);
-
 #endif /*  __BOOTUTIL_MISC_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/libs/bootutil/include/bootutil/loader.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/include/bootutil/loader.h b/libs/bootutil/include/bootutil/loader.h
index 86f06ba..57a9eef 100644
--- a/libs/bootutil/include/bootutil/loader.h
+++ b/libs/bootutil/include/bootutil/loader.h
@@ -46,6 +46,9 @@ struct boot_req {
     /** 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;
+
+    /** Size of the image slot */
+    uint32_t br_img_sz;
 };
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/libs/bootutil/src/bootutil_misc.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/bootutil_misc.c b/libs/bootutil/src/bootutil_misc.c
index 94536ef..8ae5599 100644
--- a/libs/bootutil/src/bootutil_misc.c
+++ b/libs/bootutil/src/bootutil_misc.c
@@ -20,89 +20,11 @@
 #include <string.h>
 #include <inttypes.h>
 #include <hal/hal_flash.h>
-#include <config/config.h>
+#include <hal/flash_map.h>
 #include <os/os.h>
 #include "bootutil/image.h"
 #include "bootutil_priv.h"
 
-#ifdef USE_STATUS_FILE
-#include <fs/fs.h>
-#include <fs/fsutil.h>
-#endif
-
-static int boot_conf_set(int argc, char **argv, char *val);
-
-static struct image_version boot_main;
-static struct image_version boot_test;
-#ifndef USE_STATUS_FILE
-static struct boot_status boot_saved;
-#endif
-
-static struct conf_handler boot_conf_handler = {
-    .ch_name = "boot",
-    .ch_get = NULL,
-    .ch_set = boot_conf_set,
-    .ch_commit = NULL,
-    .ch_export = NULL,
-};
-
-static int
-boot_conf_set(int argc, char **argv, char *val)
-{
-    int rc;
-    int len;
-
-    if (argc == 1) {
-        if (!strcmp(argv[0], "main")) {
-            len = sizeof(boot_main);
-            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);
-            if (val) {
-                rc = conf_bytes_from_str(val, &boot_test, &len);
-            } else {
-                memset(&boot_test, 0, len);
-                rc = 0;
-            }
-#ifndef USE_STATUS_FILE
-        } else if (!strcmp(argv[0], "status")) {
-            if (!val) {
-                boot_saved.state = 0;
-                rc = 0;
-            } else {
-                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;
-#endif
-        } else {
-            rc = OS_ENOENT;
-        }
-    } else {
-        rc = OS_ENOENT;
-    }
-    return rc;
-}
-
-static int
-boot_vect_read_one(struct image_version *dst, struct image_version *src)
-{
-    if (src->iv_major == 0 && src->iv_minor == 0 &&
-      src->iv_revision == 0 && src->iv_build_num == 0) {
-        return BOOT_EBADVECT;
-    }
-    memcpy(dst, src, sizeof(*dst));
-    return 0;
-}
-
 /**
  * Retrieves from the boot vector the version number of the test image (i.e.,
  * the image that has not been proven stable, and which will only run once).
@@ -114,7 +36,7 @@ boot_vect_read_one(struct image_version *dst, struct image_version *src)
 int
 boot_vect_read_test(struct image_version *out_ver)
 {
-    return boot_vect_read_one(out_ver, &boot_test);
+    return 0;
 }
 
 /**
@@ -127,24 +49,7 @@ boot_vect_read_test(struct image_version *out_ver)
 int
 boot_vect_read_main(struct image_version *out_ver)
 {
-    return boot_vect_read_one(out_ver, &boot_main);
-}
-
-static int
-boot_vect_write_one(const char *name, struct image_version *ver)
-{
-    char str[CONF_STR_FROM_BYTES_LEN(sizeof(struct image_version))];
-    char *to_store;
-
-    if (!ver) {
-        to_store = NULL;
-    } else {
-        if (!conf_str_from_bytes(ver, sizeof(*ver), str, sizeof(str))) {
-            return -1;
-        }
-        to_store = str;
-    }
-    return conf_save_one(name, to_store);
+    return 0;
 }
 
 /**
@@ -153,15 +58,22 @@ boot_vect_write_one(const char *name, struct image_version *ver)
  * @return                  0 on success; nonzero on failure.
  */
 int
-boot_vect_write_test(struct image_version *ver)
+boot_vect_write_test(int slot)
 {
-    if (!ver) {
-        memset(&boot_test, 0, sizeof(boot_test));
-        return boot_vect_write_one("boot/test", NULL);
-    } else {
-        memcpy(&boot_test, ver, sizeof(boot_test));
-        return boot_vect_write_one("boot/test", &boot_test);
+    const struct flash_area *fap;
+    uint32_t off;
+    uint32_t magic;
+    int rc;
+
+    rc = flash_area_open(slot, &fap);
+    if (rc) {
+        return rc;
     }
+
+    off = fap->fa_size - sizeof(struct boot_img_trailer);
+    magic = BOOT_IMG_MAGIC;
+
+    return flash_area_write(fap, off, &magic, sizeof(magic));
 }
 
 /**
@@ -172,37 +84,12 @@ boot_vect_write_test(struct image_version *ver)
 int
 boot_vect_write_main(struct image_version *ver)
 {
-    if (!ver) {
-        memset(&boot_main, 0, sizeof(boot_main));
-        return boot_vect_write_one("boot/main", NULL);
-    } else {
-        memcpy(&boot_main, ver, sizeof(boot_main));
-        return boot_vect_write_one("boot/main", &boot_main);
-    }
-}
-
-static int
-boot_read_image_header(struct image_header *out_hdr,
-                       const struct boot_image_location *loc)
-{
-    int rc;
-
-    rc = hal_flash_read(loc->bil_flash_id, loc->bil_address, out_hdr,
-                        sizeof *out_hdr);
-    if (rc != 0) {
-        return BOOT_EFLASH;
-    }
-
-    if (out_hdr->ih_magic != IMAGE_MAGIC) {
-        return BOOT_EBADIMAGE;
-    }
-
     return 0;
 }
 
 /**
- * Reads the header of each image present in flash.  Headers corresponding to
- * empty image slots are filled with 0xff bytes.
+ * Reads the header of image present in flash.  Header corresponding to
+ * empty image slot is filled with 0xff bytes.
  *
  * @param out_headers           Points to an array of image headers.  Each
  *                                  element is filled with the header of the
@@ -213,118 +100,23 @@ boot_read_image_header(struct image_header *out_hdr,
  *                                  also be equal to the lengths of the
  *                                  out_headers and addresses arrays.
  */
-void
-boot_read_image_headers(struct image_header *out_headers,
-                        const struct boot_image_location *addresses,
-                        int num_addresses)
-{
-    struct image_header *hdr;
-    int rc;
-    int i;
-
-    for (i = 0; i < num_addresses; i++) {
-        hdr = out_headers + i;
-        rc = boot_read_image_header(hdr, &addresses[i]);
-        if (rc != 0 || hdr->ih_magic != IMAGE_MAGIC) {
-            memset(hdr, 0xff, sizeof *hdr);
-        }
-    }
-}
-
-void
-bootutil_cfg_register(void)
-{
-    conf_register(&boot_conf_handler);
-}
-
-#ifndef USE_STATUS_FILE
-int
-boot_read_status(struct boot_status *bs)
-{
-    conf_load();
-
-    *bs = boot_saved;
-    return (boot_saved.state != 0);
-}
-
-/**
- * Writes the supplied boot status to the flash file system.  The boot status
- * contains the current state of an in-progress image copy operation.
- *
- * @param status                The boot status base to write.
- *
- * @return                      0 on success; nonzero on failure.
- */
-int
-boot_write_status(struct boot_status *bs)
-{
-    char str[12];
-    int rc;
-
-    rc = conf_save_one("boot/len",
-      conf_str_from_value(CONF_INT32, &bs->length, str, sizeof(str)));
-    if (rc) {
-        return rc;
-    }
-    return conf_save_one("boot/status",
-      conf_str_from_value(CONF_INT32, &bs->state, str, sizeof(str)));
-}
-
-/**
- * Erases the boot status from the flash file system.  The boot status
- * contains the current state of an in-progress image copy operation.  By
- * erasing the boot status, it is implied that there is no copy operation in
- * progress.
- */
-void
-boot_clear_status(void)
-{
-    conf_save_one("boot/status", NULL);
-}
-
-#else
-
-/**
- * Reads the boot status from the flash file system.  The boot status contains
- * the current state of an interrupted image copy operation.  If the boot
- * status is not present in the file system, the implication is that there is
- * no copy operation in progress.
- */
 int
-boot_read_status(struct boot_status *bs)
+boot_read_image_header(struct boot_image_location *loc,
+                       struct image_header *out_hdr)
 {
     int rc;
-    uint32_t bytes_read;
 
-    conf_load();
-
-    rc = fsutil_read_file(BOOT_PATH_STATUS, 0, sizeof(*bs),
-      bs, &bytes_read);
-    if (rc || bytes_read != sizeof(*bs)) {
-        memset(bs, 0, sizeof(*bs));
-        return 0;
+    rc = hal_flash_read(loc->bil_flash_id, loc->bil_address, out_hdr,
+                        sizeof *out_hdr);
+    if (rc != 0) {
+        rc = BOOT_EFLASH;
+    } else if (out_hdr->ih_magic != IMAGE_MAGIC) {
+        rc = BOOT_EBADIMAGE;
     }
-    return 1;
-}
 
-int
-boot_write_status(struct boot_status *bs)
-{
-    int rc;
-
-    /*
-     * XXX point of failure.
-     */
-    rc = fsutil_write_file(BOOT_PATH_STATUS, bs, sizeof(*bs));
     if (rc) {
-        rc = BOOT_EFILE;
+        memset(out_hdr, 0xff, sizeof(*out_hdr));
     }
     return rc;
 }
 
-void
-boot_clear_status(void)
-{
-    fs_unlink(BOOT_PATH_STATUS);
-}
-#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/libs/bootutil/src/bootutil_priv.h
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/bootutil_priv.h b/libs/bootutil/src/bootutil_priv.h
index 98aa29f..3de5dd9 100644
--- a/libs/bootutil/src/bootutil_priv.h
+++ b/libs/bootutil/src/bootutil_priv.h
@@ -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,
@@ -21,7 +21,6 @@
 #define H_BOOTUTIL_PRIV_
 
 #include "bootutil/image.h"
-struct image_header;
 
 #define BOOT_EFLASH     1
 #define BOOT_EFILE      2
@@ -30,37 +29,38 @@ struct image_header;
 #define BOOT_EBADSTATUS 5
 #define BOOT_ENOMEM     6
 
-#define BOOT_IMAGE_NUM_NONE     0xff
-
-#define BOOT_PATH_STATUS    "/cfg/bst"
-
 #define BOOT_TMPBUF_SZ  256
 
+struct boot_image_location {
+    uint8_t bil_flash_id;
+    uint32_t bil_address;
+};
+
+/*
+ * Maintain state of copy progress.
+ */
 struct boot_status {
-    uint32_t length;
+    uint32_t idx;
     uint32_t state;
 };
 
-/**
- * The boot status header read from the file system, or generated if not
- * 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.
+/*
+ * End-of-image data structure.
  */
-
-struct boot_image_location {
-    uint8_t bil_flash_id;
-    uint32_t bil_address;
+#define BOOT_IMG_MAGIC  0x12344321
+struct boot_img_trailer {
+    uint32_t bit_start;
+    uint32_t bit_done;
 };
 
-void boot_read_image_headers(struct image_header *out_headers,
-                             const struct boot_image_location *addresses,
-                             int num_addresses);
-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,
     uint8_t key_id);
 
+int boot_read_image_header(struct boot_image_location *loc,
+  struct image_header *out_hdr);
+int boot_write_status(struct boot_status *bs);
+int boot_read_status(struct boot_status *bs);
+void boot_clear_status(void);
+
 #endif
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/libs/bootutil/src/loader.c
----------------------------------------------------------------------
diff --git a/libs/bootutil/src/loader.c b/libs/bootutil/src/loader.c
index bd7fbd8..f8a0003 100644
--- a/libs/bootutil/src/loader.c
+++ b/libs/bootutil/src/loader.c
@@ -24,6 +24,7 @@
 #include <hal/flash_map.h>
 #include <hal/hal_flash.h>
 #include <os/os_malloc.h>
+#include <console/console.h>
 #include "bootutil/loader.h"
 #include "bootutil/image.h"
 #include "bootutil/bootutil_misc.h"
@@ -36,13 +37,16 @@
 static const struct boot_req *boot_req;
 
 /** Image headers read from flash. */
-struct image_header boot_img_hdrs[2];
+static struct boot_img {
+    struct image_header hdr;
+    struct boot_image_location loc;
+    uint32_t area;
+} boot_img[BOOT_NUM_SLOTS];
 
 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)
+static int boot_erase_area(int area_idx, uint32_t sz);
+static uint32_t boot_copy_sz(int max_idx, int *cnt);
 
 /**
  * Calculates the flash offset of the specified image slot.
@@ -52,77 +56,73 @@ static struct boot_status boot_state;
  * @return                      The flash offset of the image slot.
  */
 static void
-boot_slot_addr(int slot_num, uint8_t *flash_id, uint32_t *address)
+boot_slot_addr(int slot_num, struct boot_image_location *loc)
 {
     const struct flash_area *area_desc;
     uint8_t area_idx;
 
-    assert(slot_num >= 0 && slot_num < BOOT_NUM_SLOTS);
-
     area_idx = boot_req->br_slot_areas[slot_num];
     area_desc = boot_req->br_area_descs + area_idx;
-    *flash_id = area_desc->fa_flash_id;
-    *address = area_desc->fa_off;
+    loc->bil_flash_id = area_desc->fa_flash_id;
+    loc->bil_address = area_desc->fa_off;
 }
 
-/**
- * Searches flash for an image with the specified version number.
- *
- * @param ver                   The version number to search for.
- *
- * @return                      The image slot containing the specified image
- *                              on success; -1 on failure.
- */
-static int
-boot_find_image_slot(const struct image_version *ver)
+static uint32_t
+boot_magic_off(int slot_num)
 {
-    int i;
+    return boot_img[slot_num].area + boot_img[slot_num].loc.bil_address -
+      sizeof(struct boot_img_trailer);
+}
 
-    for (i = 0; i < 2; i++) {
-        if (memcmp(&boot_img_hdrs[i].ih_ver, ver, sizeof *ver) == 0) {
-            return i;
-        }
-    }
+static uint32_t
+boot_scratch_off(void)
+{
+    struct flash_area *scratch;
+    uint32_t off;
+    int cnt;
 
-    return -1;
+    scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx];
+    off = boot_copy_sz(boot_req->br_slot_areas[1], &cnt);
+    off += (scratch->fa_off - sizeof(struct boot_img_trailer));
+    return off;
 }
 
-/**
- * Selects a slot number to boot from, based on the contents of the boot
- * vector.
- *
- * @return                      The slot number to boot from on success;
- *                              -1 if an appropriate slot could not be
- *                              determined.
- */
-static int
-boot_select_image_slot(void)
+static void
+boot_slot_magic(int slot_num, struct boot_img_trailer *bit)
 {
-    struct image_version ver;
-    int slot;
-    int rc;
+    uint32_t off;
+    struct boot_img *b;
 
-    rc = boot_vect_read_test(&ver);
-    if (rc == 0) {
-        slot = boot_find_image_slot(&ver);
-        if (slot == -1) {
-            boot_vect_write_test(NULL);
-        } else {
-            return slot;
-        }
-    }
+    b = &boot_img[slot_num];
+    off = boot_magic_off(slot_num);
+    memset(bit, 0xff, sizeof(*bit));
+    hal_flash_read(b->loc.bil_flash_id, off, bit, sizeof(*bit));
+}
 
-    rc = boot_vect_read_main(&ver);
-    if (rc == 0) {
-        slot = boot_find_image_slot(&ver);
-        if (slot == -1) {
-            boot_vect_write_main(NULL);
-        } else {
-            return slot;
-        }
-    }
+static void
+boot_scratch_magic(struct boot_img_trailer *bit)
+{
+    uint32_t off;
+    struct flash_area *scratch;
+
+    scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx];
+
+    off = boot_scratch_off();
+    hal_flash_read(scratch->fa_flash_id, off, bit, sizeof(*bit));
+}
 
-    return -1;
+void
+boot_image_info(void)
+{
+    int i;
+    struct boot_img *b;
+
+    for (i = 0; i < BOOT_NUM_SLOTS; i++) {
+        b = &boot_img[i];
+        boot_slot_addr(i, &b->loc);
+        boot_read_image_header(&b->loc, &b->hdr);
+        b->area = boot_req->br_img_sz;
+    }
 }
 
 /*
@@ -146,12 +146,54 @@ boot_image_check(struct image_header *hdr, struct boot_image_location *loc)
     return 0;
 }
 
+/**
+ * Selects a slot number to boot from.
+ *
+ * @return                      The slot number to boot from on success;
+ *                              -1 if an appropriate slot could not be
+ *                              determined.
+ */
+static int
+boot_select_image_slot(void)
+{
+    /*
+     * Check for swap magic. Check the integrity of the suggested image.
+     */
+    int rc;
+    int i;
+    struct boot_img *b;
+    struct boot_img_trailer bit;
+
+    for (i = 1; i < BOOT_NUM_SLOTS; i++) {
+        b = &boot_img[i];
+        boot_slot_magic(i, &bit);
+        if (bit.bit_start == BOOT_IMG_MAGIC) {
+            rc = boot_image_check(&b->hdr, &b->loc);
+            if (rc) {
+                /*
+                 * Image fails integrity check. Erase it.
+                 */
+                boot_erase_area(boot_req->br_slot_areas[i], b->area);
+            } else {
+                return i;
+            }
+        }
+    }
+    return 0;
+}
+
+static int
+boot_status_sz(void)
+{
+    return sizeof(struct boot_img_trailer) + 32 * sizeof(uint32_t);
+}
+
 /*
  * How many sectors starting from sector[idx] can fit inside scratch.
  *
  */
 static uint32_t
-boot_copy_sz(int idx, int max_idx, int *cnt)
+boot_copy_sz(int max_idx, int *cnt)
 {
     int i;
     uint32_t sz;
@@ -166,7 +208,7 @@ boot_copy_sz(int idx, int max_idx, int *cnt)
     }
     sz = 0;
     *cnt = 0;
-    for (i = idx; i < max_idx; i++) {
+    for (i = max_idx - 1; i >= 0; i--) {
         if (sz + boot_req->br_area_descs[i].fa_size > scratch_sz) {
             break;
         }
@@ -176,7 +218,6 @@ boot_copy_sz(int idx, int max_idx, int *cnt)
     return sz;
 }
 
-
 static int
 boot_erase_area(int area_idx, uint32_t sz)
 {
@@ -258,12 +299,11 @@ boot_copy_area(int from_area_idx, int to_area_idx, uint32_t sz)
  * @return                      0 on success; nonzero on failure.
  */
 static int
-boot_swap_areas(int idx, uint32_t sz)
+boot_swap_areas(int idx, uint32_t sz, int end_area)
 {
     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;
@@ -271,8 +311,7 @@ boot_swap_areas(int idx, uint32_t sz)
     assert(area_idx_1 != boot_req->br_scratch_area_idx);
     assert(area_idx_2 != boot_req->br_scratch_area_idx);
 
-    state = BOOT_PERSIST_ST(boot_state.state);
-    if (state == 0) {
+    if (boot_state.state == 0) {
         rc = boot_erase_area(boot_req->br_scratch_area_idx, sz);
         if (rc != 0) {
             return rc;
@@ -283,26 +322,25 @@ boot_swap_areas(int idx, uint32_t sz)
             return rc;
         }
 
-        boot_state.state = BOOT_PERSIST(idx, 1);
+        boot_state.state = 1;
         (void)boot_write_status(&boot_state);
-        state = 1;
     }
-    if (state == 1) {
+    if (boot_state.state == 1) {
         rc = boot_erase_area(area_idx_2, sz);
         if (rc != 0) {
             return rc;
         }
 
-        rc = boot_copy_area(area_idx_1, area_idx_2, sz);
+        rc = boot_copy_area(area_idx_1, area_idx_2,
+          end_area ? (sz - boot_status_sz()) : sz);
         if (rc != 0) {
             return rc;
         }
 
-        boot_state.state = BOOT_PERSIST(idx, 2);
+        boot_state.state = 2;
         (void)boot_write_status(&boot_state);
-        state = 2;
     }
-    if (state == 2) {
+    if (boot_state.state == 2) {
         rc = boot_erase_area(area_idx_1, sz);
         if (rc != 0) {
             return rc;
@@ -313,9 +351,9 @@ boot_swap_areas(int idx, uint32_t sz)
             return rc;
         }
 
-        boot_state.state = BOOT_PERSIST(idx + 1, 0);
+        boot_state.idx++;
+        boot_state.state = 0;
         (void)boot_write_status(&boot_state);
-        state = 3;
     }
     return 0;
 }
@@ -324,63 +362,129 @@ boot_swap_areas(int idx, uint32_t sz)
  * Swaps the two images in flash.  If a prior copy operation was interrupted
  * by a system reset, this function completes that operation.
  *
- * @param img1_length           The length, in bytes, of the slot 1 image.
- * @param img2_length           The length, in bytes, of the slot 2 image.
- *
  * @return                      0 on success; nonzero on failure.
  */
 static int
 boot_copy_image(void)
 {
-    uint32_t off;
     uint32_t sz;
     int i;
+    int end_area = 1;
     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);
+    int cur_idx;
+
+    for (i = boot_req->br_slot_areas[1], cur_idx = 0; i > 0; cur_idx++) {
+        sz = boot_copy_sz(i, &cnt);
+        i -= cnt;
+        if (cur_idx >= boot_state.idx) {
+            boot_swap_areas(i, sz, end_area);
         }
+        end_area = 0;
     }
+    boot_clear_status();
 
     return 0;
 }
 
-/**
- * Builds a default boot status corresponding to all images being fully present
- * in their slots.  This function is used when a boot status is not present in
- * flash (i.e., in the usual case when the previous boot operation ran to
- * completion).
+
+/*
+ * Is copy in progress?
  */
 static void
-boot_build_status(void)
+boot_read_status_bytes(struct boot_status *bs, uint8_t flash_id, uint32_t off)
 {
-    uint32_t len1;
-    uint32_t len2;
+    uint8_t status;
 
-    if (boot_img_hdrs[0].ih_magic == IMAGE_MAGIC) {
-        len1 = boot_img_hdrs[0].ih_hdr_size + boot_img_hdrs[0].ih_img_size +
-          boot_img_hdrs[0].ih_tlv_size;
-    } else {
-        len1 = 0;
+    off -= sizeof(status) * 2;
+    while (1) {
+        hal_flash_read(flash_id, off, &status, sizeof(status));
+        if (status == 0xff) {
+            break;
+        }
+        off--;
+        if (bs->state == 2) {
+            bs->idx++;
+            bs->state = 0;
+        } else {
+            bs->state++;
+        }
     }
+}
 
-    if (boot_img_hdrs[1].ih_magic == IMAGE_MAGIC) {
-        len2 = boot_img_hdrs[1].ih_hdr_size + boot_img_hdrs[1].ih_img_size +
-          boot_img_hdrs[0].ih_tlv_size;
-    } else {
-        len2 = 0;
+int
+boot_read_status(struct boot_status *bs)
+{
+    struct boot_img_trailer bit;
+    struct flash_area *scratch;
+
+    /*
+     * Check if boot_img_trailer is in scratch, or at the end of slot0.
+     */
+    boot_slot_magic(0, &bit);
+    if (bit.bit_start == BOOT_IMG_MAGIC && bit.bit_done == 0xffffffff) {
+        boot_read_status_bytes(bs, boot_img[0].loc.bil_flash_id,
+          boot_magic_off(0));
+        console_printf("status in slot0, %lu/%lu\n", bs->idx, bs->state);
+        return 1;
     }
-    boot_state.length = len1;
-    if (len1 < len2) {
-        boot_state.length = len2;
+    boot_scratch_magic(&bit);
+    if (bit.bit_start == BOOT_IMG_MAGIC && bit.bit_done == 0xffffffff) {
+        scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx];
+        boot_read_status_bytes(bs, scratch->fa_flash_id, boot_scratch_off());
+        console_printf("status in scratch, %lu/%lu\n", bs->idx, bs->state);
+        return 1;
     }
-    boot_state.state = 0;
+    return 0;
+}
+
+#include <hal/hal_system.h>
+
+int
+boot_write_status(struct boot_status *bs)
+{
+    uint32_t off;
+    uint8_t flash_id;
+    uint8_t val;
+
+    if (bs->idx == 0) {
+        /*
+         * Write to scratch
+         */
+        off = boot_scratch_off();
+        flash_id =
+          boot_req->br_area_descs[boot_req->br_scratch_area_idx].fa_flash_id;
+    } else {
+        /*
+         * Write to slot 0;
+         */
+        off = boot_magic_off(0);
+        flash_id = boot_img[0].loc.bil_flash_id;
+    }
+    off -= ((3 * sizeof(uint8_t)) * bs->idx +
+      sizeof(uint8_t) * (bs->state + 1));
+
+    console_printf("status write, %lu/%lu -> %lx\n", bs->idx, bs->state, off);
+
+    val = bs->state;
+    hal_flash_write(flash_id, off, &val, sizeof(val));
+
+    return 0;
+}
+
+void
+boot_clear_status(void)
+{
+    uint32_t off;
+    uint32_t val = BOOT_IMG_MAGIC;
+    uint8_t flash_id;
+
+    /*
+     * Write to slot 0;
+     */
+    off = boot_magic_off(0);
+    flash_id = boot_img[0].loc.bil_flash_id;
+    off += sizeof(uint32_t);
+    hal_flash_write(flash_id, off, &val, sizeof(val));
 }
 
 /**
@@ -396,23 +500,23 @@ boot_build_status(void)
 int
 boot_go(const struct boot_req *req, struct boot_rsp *rsp)
 {
-    struct boot_image_location image_addrs[BOOT_NUM_SLOTS];
     int slot;
     int rc;
-    int i;
 
     /* Set the global boot request object.  The remainder of the boot process
      * will reference the global.
      */
     boot_req = req;
 
+    /* Attempt to read an image header from each slot. */
+    boot_image_info();
+
     /* Read the boot status to determine if an image copy operation was
      * interrupted (i.e., the system was reset before the boot loader could
      * finish its task last time).
      */
     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();
         if (rc != 0) {
             /* We failed to put the images back together; there is really no
@@ -422,80 +526,25 @@ boot_go(const struct boot_req *req, struct boot_rsp *rsp)
         }
     }
 
-    /* Cache the flash address of each image slot. */
-    for (i = 0; i < BOOT_NUM_SLOTS; i++) {
-        boot_slot_addr(i, &image_addrs[i].bil_flash_id,
-                       &image_addrs[i].bil_address);
-    }
-
-    /* Attempt to read an image header from each slot. */
-    boot_read_image_headers(boot_img_hdrs, image_addrs, BOOT_NUM_SLOTS);
-
-    /* Build a boot status structure indicating the flash location of each
-     * image part.  This structure will need to be used if an image copy
-     * operation is required.
+    /*
+     * Check if we should initiate copy.
      */
-    boot_build_status();
-
-    /* Determine which image the user wants to run, and where it is located. */
     slot = boot_select_image_slot();
     if (slot == -1) {
-        /* Either there is no image vector, or none of the requested images are
-         * present.  Just try booting from the first image slot.
-         */
-        if (boot_img_hdrs[0].ih_magic != IMAGE_MAGIC_NONE) {
-            slot = 0;
-        } else if (boot_img_hdrs[1].ih_magic != IMAGE_MAGIC_NONE) {
-            slot = 1;
-        } else {
-            /* No images present. */
-            return BOOT_EBADIMAGE;
-        }
+        return BOOT_EBADIMAGE;
     }
 
-    /*
-     * If the selected image fails integrity check, try the other one.
-     */
-    if (boot_image_check(&boot_img_hdrs[slot], &image_addrs[slot])) {
-        slot ^= 1;
-        if (boot_image_check(&boot_img_hdrs[slot], &image_addrs[slot])) {
-            return BOOT_EBADIMAGE;
-        }
-    }
-    switch (slot) {
-    case 0:
-        rsp->br_hdr = &boot_img_hdrs[0];
-        break;
-
-    case 1:
-        /* The user wants to run the image in the secondary slot.  The contents
-         * of this slot need to moved to the primary slot.
-         */
+    if (slot) {
         rc = boot_copy_image();
-        if (rc != 0) {
-            /* We failed to put the images back together; there is really no
-             * solution here.
-             */
+        if (rc) {
             return rc;
         }
-
-        rsp->br_hdr = &boot_img_hdrs[1];
-        break;
-
-    default:
-        assert(0);
-        break;
     }
 
     /* Always boot from the primary slot. */
-    rsp->br_flash_id = image_addrs[0].bil_flash_id;
-    rsp->br_image_addr = image_addrs[0].bil_address;
-
-    /* After successful boot, there should not be a status file. */
-    boot_clear_status();
-
-    /* If an image is being tested, it should only be booted into once. */
-    boot_vect_write_test(NULL);
+    rsp->br_flash_id = boot_img[0].loc.bil_flash_id;
+    rsp->br_image_addr = boot_img[0].loc.bil_address;
+    rsp->br_hdr = &boot_img[0].hdr;
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/b2009c9f/libs/imgmgr/src/imgmgr_boot.c
----------------------------------------------------------------------
diff --git a/libs/imgmgr/src/imgmgr_boot.c b/libs/imgmgr/src/imgmgr_boot.c
index e678b74..c0277b1 100644
--- a/libs/imgmgr/src/imgmgr_boot.c
+++ b/libs/imgmgr/src/imgmgr_boot.c
@@ -132,12 +132,11 @@ imgr_boot_write(struct nmgr_jbuf *njb)
         rc = NMGR_ERR_EINVAL;
         goto err;
     }
-    rc = boot_vect_write_test(&ver);
+    rc = boot_vect_write_test(rc);
     if (rc) {
         rc = NMGR_ERR_EINVAL;
         goto err;
     }
-
     enc = &njb->njb_enc;
 
     json_encode_object_start(enc);
@@ -226,11 +225,12 @@ imgr_boot2_write(struct nmgr_jbuf *njb)
     base64_decode(hash_str, hash);
     rc = imgr_find_by_hash(hash, &ver);
     if (rc >= 0) {
-        rc = boot_vect_write_test(&ver);
+        rc = boot_vect_write_test(rc);
         if (rc) {
             rc = NMGR_ERR_EUNKNOWN;
             goto err;
         }
+        rc = 0;
     } else {
         rc = NMGR_ERR_EINVAL;
         goto err;