Repository: incubator-mynewt-core Updated Branches: refs/heads/develop d0df2fbd4 -> 94944515c
Boot loader - code cleanup. 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/94944515 Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/94944515 Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/94944515 Branch: refs/heads/develop Commit: 94944515c601c3fbc557ab747c69d38435cd5965 Parents: d0df2fb Author: Christopher Collins <ccoll...@apache.org> Authored: Mon Oct 17 16:03:14 2016 -0700 Committer: Christopher Collins <ccoll...@apache.org> Committed: Tue Oct 18 14:37:21 2016 -0700 ---------------------------------------------------------------------- boot/bootutil/include/bootutil/bootutil.h | 25 +- boot/bootutil/src/bootutil_misc.c | 454 +--------------- boot/bootutil/src/bootutil_priv.h | 12 +- boot/bootutil/src/loader.c | 520 +++++++++++++++---- .../test/src/testcases/boot_test_invalid_hash.c | 2 +- .../src/testcases/boot_test_no_flag_has_hash.c | 2 +- .../test/src/testcases/boot_test_no_hash.c | 2 +- .../test/src/testcases/boot_test_nv_bs_11.c | 3 +- .../src/testcases/boot_test_nv_bs_11_2areas.c | 2 +- .../test/src/testcases/boot_test_nv_ns_01.c | 2 +- .../test/src/testcases/boot_test_vb_ns_11.c | 2 +- .../test/src/testcases/boot_test_vm_ns_01.c | 2 +- .../src/testcases/boot_test_vm_ns_11_2areas.c | 2 +- .../test/src/testcases/boot_test_vm_ns_11_b.c | 2 +- mgmt/imgmgr/include/imgmgr/imgmgr.h | 1 + mgmt/imgmgr/src/imgmgr_cli.c | 11 +- mgmt/imgmgr/src/imgmgr_state.c | 4 +- 17 files changed, 481 insertions(+), 567 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/include/bootutil/bootutil.h ---------------------------------------------------------------------- diff --git a/boot/bootutil/include/bootutil/bootutil.h b/boot/bootutil/include/bootutil/bootutil.h index af84b8c..ebc3441 100644 --- a/boot/bootutil/include/bootutil/bootutil.h +++ b/boot/bootutil/include/bootutil/bootutil.h @@ -34,18 +34,8 @@ extern "C" { #define BOOT_SWAP_TYPE_TEST 1 #define BOOT_SWAP_TYPE_REVERT 2 -int boot_status_source(void); -int boot_swap_type(void); -int boot_partial_swap_type(void); - -int boot_vect_read_test(int *slot); -int boot_vect_read_main(int *slot); -int boot_set_pending(int slot); -int boot_set_confirmed(void); - -void boot_set_image_slot_split(void); - struct image_header; +struct boot_img_trailer; /** A request object instructing the boot loader how to proceed. */ struct boot_req { @@ -92,12 +82,17 @@ struct boot_rsp { }; /* you must have pre-allocated all the entries within this structure */ -int -boot_build_request(struct boot_req *preq, int area_descriptor_max); +int boot_build_request(struct boot_req *preq, int area_descriptor_max); -int -boot_go(const struct boot_req *req, struct boot_rsp *rsp); +int boot_go(const struct boot_req *req, struct boot_rsp *rsp); + +int boot_swap_type(void); + +int boot_set_pending(void); +int boot_set_confirmed(void); +int boot_read_img_trailer(int slot, struct boot_img_trailer *bit); +int boot_read_scratch_trailer(struct boot_img_trailer *bit); #define SPLIT_GO_OK (0) #define SPLIT_GO_NON_MATCHING (-1) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/src/bootutil_misc.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 675308f..37bfaa2 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -33,88 +33,6 @@ int boot_current_slot; -struct boot_status_table { - /** * For each field, a value of 0 means "any". */ - uint32_t bst_magic_slot0; - uint32_t bst_magic_scratch; - uint8_t bst_copy_done_slot0; - - uint8_t bst_status_source; -}; - -/** - * This set of tables maps image trailer contents to swap status location. - * When searching for a match, these tables must be iterated sequentially. - */ -static const struct boot_status_table boot_status_tables[] = { - { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | 0x12344321 | 0x******** | - * copy-done | 0x01 | N/A | - * ----------+------------+------------' - * status: none | - * ------------------------------------' - */ - .bst_magic_slot0 = BOOT_IMG_MAGIC, - .bst_magic_scratch = 0, - .bst_copy_done_slot0 = 0x01, - .bst_status_source = BOOT_STATUS_SOURCE_NONE, - }, - - { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | 0x12344321 | 0x******** | - * copy-done | 0xff | N/A | - * ----------+------------+------------' - * status: slot 0 | - * ------------------------------------' - */ - .bst_magic_slot0 = BOOT_IMG_MAGIC, - .bst_magic_scratch = 0, - .bst_copy_done_slot0 = 0xff, - .bst_status_source = BOOT_STATUS_SOURCE_SLOT0, - }, - - { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | 0x******** | 0x12344321 | - * copy-done | 0x** | N/A | - * ----------+------------+------------' - * status: scratch | - * ------------------------------------' - */ - .bst_magic_slot0 = 0, - .bst_magic_scratch = BOOT_IMG_MAGIC, - .bst_copy_done_slot0 = 0, - .bst_status_source = BOOT_STATUS_SOURCE_SCRATCH, - }, - - { - /* | slot-0 | scratch | - * ----------+------------+------------| - * magic | 0xffffffff | 0xffffffff | - * copy-done | 0xff | N/A | - * ----------+------------+------------| - * status: slot0 | - * ------------------------------------+-------------------------------+ - * This represents one of two cases: | - * o No swaps ever (no status to read anyway, so no harm in checking). | - * o Mid-revert; status in slot 0. | - * --------------------------------------------------------------------' - */ - .bst_magic_slot0 = 0xffffffff, - .bst_magic_scratch = 0, - .bst_copy_done_slot0 = 0xff, - .bst_status_source = BOOT_STATUS_SOURCE_SLOT0, - }, -}; - -#define BOOT_STATUS_TABLES_COUNT \ - (sizeof boot_status_tables / sizeof boot_status_tables[0]) - struct boot_swap_table { /** * For each field, a value of 0 means "any". */ uint32_t bsw_magic_slot0; @@ -194,18 +112,16 @@ static const struct boot_swap_table boot_swap_tables[] = { (sizeof boot_swap_tables / sizeof boot_swap_tables[0]) /** - * Reads the image trailer from a given image slot. + * Reads the image trailer from the scratch area. */ -static int -boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) +int +boot_read_scratch_trailer(struct boot_img_trailer *bit) { int rc; const struct flash_area *fap; uint32_t off; - int area_id; - area_id = flash_area_id_from_image_slot(slot); - rc = flash_area_open(area_id, &fap); + rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap); if (rc) { return rc; } @@ -217,16 +133,18 @@ boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) } /** - * Reads the image trailer from the scratch area. + * Reads the image trailer from a given image slot. */ -static int -boot_vect_read_scratch_trailer(struct boot_img_trailer *bit) +int +boot_read_img_trailer(int slot, struct boot_img_trailer *bit) { int rc; const struct flash_area *fap; uint32_t off; + int area_id; - rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &fap); + area_id = flash_area_id_from_image_slot(slot); + rc = flash_area_open(area_id, &fap); if (rc) { return rc; } @@ -238,42 +156,6 @@ boot_vect_read_scratch_trailer(struct boot_img_trailer *bit) } int -boot_status_source(void) -{ - const struct boot_status_table *table; - struct boot_img_trailer bit_scratch; - struct boot_img_trailer bit_slot0; - struct boot_img_trailer bit_slot1; - int rc; - int i; - - rc = boot_vect_read_img_trailer(0, &bit_slot0); - assert(rc == 0); - - rc = boot_vect_read_img_trailer(1, &bit_slot1); - assert(rc == 0); - - rc = boot_vect_read_scratch_trailer(&bit_scratch); - assert(rc == 0); - - for (i = 0; i < BOOT_STATUS_TABLES_COUNT; i++) { - table = boot_status_tables + i; - - if ((table->bst_magic_slot0 == 0 || - table->bst_magic_slot0 == bit_slot0.bit_copy_start) && - (table->bst_magic_scratch == 0 || - table->bst_magic_scratch == bit_scratch.bit_copy_start) && - (table->bst_copy_done_slot0 == 0 || - table->bst_copy_done_slot0 == bit_slot0.bit_copy_done)) { - - return table->bst_status_source; - } - } - - return BOOT_STATUS_SOURCE_NONE; -} - -int boot_swap_type(void) { const struct boot_swap_table *table; @@ -282,10 +164,10 @@ boot_swap_type(void) int rc; int i; - rc = boot_vect_read_img_trailer(0, &bit_slot0); + rc = boot_read_img_trailer(0, &bit_slot0); assert(rc == 0); - rc = boot_vect_read_img_trailer(1, &bit_slot1); + rc = boot_read_img_trailer(1, &bit_slot1); assert(rc == 0); for (i = 0; i < BOOT_SWAP_TABLES_COUNT; i++) { @@ -306,27 +188,13 @@ boot_swap_type(void) return BOOT_SWAP_TYPE_NONE; } +/** + * Write the test image version number from the boot vector. + * + * @return 0 on success; nonzero on failure. + */ int -boot_partial_swap_type(void) -{ - int swap_type; - - swap_type = boot_swap_type(); - switch (swap_type) { - case BOOT_SWAP_TYPE_NONE: - return BOOT_SWAP_TYPE_REVERT; - - case BOOT_SWAP_TYPE_REVERT: - return BOOT_SWAP_TYPE_TEST; - - default: - assert(0); - return BOOT_SWAP_TYPE_REVERT; - } -} - -int -boot_schedule_test_swap(void) +boot_set_pending(void) { const struct flash_area *fap; struct boot_img_trailer bit_slot1; @@ -334,7 +202,7 @@ boot_schedule_test_swap(void) int area_id; int rc; - rc = boot_vect_read_img_trailer(1, &bit_slot1); + rc = boot_read_img_trailer(1, &bit_slot1); assert(rc == 0); switch (bit_slot1.bit_copy_start) { @@ -365,82 +233,6 @@ boot_schedule_test_swap(void) } /** - * Retrieves from the slot number of the test image (i.e., - * the image that has not been proven stable, and which will only run once). - * - * @param slot On success, the slot number of image to boot. - * - * @return 0 on success; nonzero on failure. - */ -int -boot_vect_read_test(int *slot) -{ - struct boot_img_trailer bit; - int i; - int rc; - - for (i = 0; i < 2; i++) { - if (i == boot_current_slot) { - continue; - } - rc = boot_vect_read_img_trailer(i, &bit); - if (rc) { - continue; - } - if (bit.bit_copy_start == BOOT_IMG_MAGIC) { - *slot = i; - return 0; - } - } - return -1; -} - -/** - * Retrieves from the slot number of the main image. If this is - * different from test image slot, next restart will revert to main. - * - * @param out_ver On success, the main version gets written here. - * - * @return 0 on success; nonzero on failure. - */ -int -boot_vect_read_main(int *slot) -{ - int rc; - struct boot_img_trailer bit; - - rc = boot_vect_read_img_trailer(0, &bit); - assert(rc == 0); - - if (bit.bit_copy_start != BOOT_IMG_MAGIC || bit.bit_img_ok != 0xff) { - /* - * If there never was copy that took place, or if the current - * image has been marked good, we'll keep booting it. - */ - *slot = 0; - } else { - *slot = 1; - } - return 0; -} - -/** - * Write the test image version number from the boot vector. - * - * @return 0 on success; nonzero on failure. - */ -int -boot_set_pending(int slot) -{ - int rc; - - assert(slot == 1); - - rc = boot_schedule_test_swap(); - return rc; -} - -/** * Deletes the main image version number from the boot vector. * This must be called by the app to confirm that it is ok to keep booting * to this image. @@ -456,7 +248,7 @@ boot_set_confirmed(void) uint8_t img_ok; int rc; - rc = boot_vect_read_img_trailer(0, &bit_slot0); + rc = boot_read_img_trailer(0, &bit_slot0); assert(rc == 0); if (bit_slot0.bit_copy_start != BOOT_IMG_MAGIC) { @@ -487,209 +279,3 @@ boot_set_confirmed(void) rc = flash_area_write(fap, off, &img_ok, 1); return rc; } - -/** - * 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 - * corresponding image in flash. - * @param addresses An array containing the flash addresses of each - * image slot. - * @param num_addresses The number of headers to read. This should - * also be equal to the lengths of the - * out_headers and addresses arrays. - */ -int -boot_read_image_header(struct boot_image_location *loc, - struct image_header *out_hdr) -{ - int rc; - - 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; - } - - if (rc) { - memset(out_hdr, 0xff, sizeof(*out_hdr)); - } - return rc; -} - -uint32_t -boot_status_sz(int elem_sz) -{ - return BOOT_STATUS_MAX_ENTRIES * BOOT_STATUS_STATE_COUNT * elem_sz; -} - -static uint32_t -boot_status_off(uint32_t trailer_off, int status_idx, int status_state, - int elem_sz) -{ - uint32_t status_start; - int idx_sz; - - status_start = trailer_off - boot_status_sz(elem_sz); - - idx_sz = BOOT_STATUS_STATE_COUNT * elem_sz; - return status_start + - status_idx * idx_sz + - status_state * elem_sz; -} - -/* - * How far has the copy progressed? - */ -static void -boot_read_status_bytes(struct boot_status *bs, uint8_t flash_id, - uint32_t trailer_off) -{ - uint32_t status_sz; - uint32_t off; - uint8_t status; - int found; - int i; - - status_sz = boot_status_sz(bs->elem_sz); - off = trailer_off - status_sz; - - found = 0; - for (i = 0; i < status_sz; i++) { - hal_flash_read(flash_id, off + i * bs->elem_sz, - &status, sizeof status); - if (status == 0xff) { - if (found) { - break; - } - } else if (!found) { - found = 1; - } - } - - if (found) { - i--; - bs->idx = i / BOOT_STATUS_STATE_COUNT; - bs->state = i % BOOT_STATUS_STATE_COUNT; - } -} - -/** - * Reads the boot status from the flash. The boot status contains - * the current state of an interrupted image copy operation. If the boot - * status is not present, or it indicates that previous copy finished, - * there is no operation in progress. - */ -int -boot_read_status(struct boot_status *bs) -{ - uint32_t off; - uint8_t flash_id; - int status_loc; - - status_loc = boot_status_source(); - - switch (status_loc) { - case BOOT_STATUS_SOURCE_NONE: - break; - - case BOOT_STATUS_SOURCE_SCRATCH: - boot_scratch_loc(&flash_id, &off); - boot_read_status_bytes(bs, flash_id, off); - break; - - case BOOT_STATUS_SOURCE_SLOT0: - boot_magic_loc(0, &flash_id, &off); - boot_read_status_bytes(bs, flash_id, off); - break; - - default: - assert(0); - break; - } - - return bs->idx != 0 || bs->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 bs The boot status to write. - * - * @return 0 on success; nonzero on failure. - */ -int -boot_write_status(struct boot_status *bs) -{ - uint32_t trailer_off; - uint32_t status_off; - uint8_t flash_id; - - if (bs->idx == 0) { - /* Write to scratch. */ - boot_scratch_loc(&flash_id, &trailer_off); - } else { - /* Write to slot 0. */ - boot_magic_loc(0, &flash_id, &trailer_off); - } - - status_off = boot_status_off(trailer_off, bs->idx, bs->state, bs->elem_sz); - hal_flash_write(flash_id, status_off, &bs->state, 1); - - return 0; -} - -/** - * Marks a test image in slot 0 as fully copied. - */ -int -boot_finalize_test_swap(void) -{ - struct boot_img_trailer bit; - uint32_t off; - uint8_t flash_id; - int rc; - - boot_magic_loc(0, &flash_id, &off); - off += offsetof(struct boot_img_trailer, bit_copy_done); - - bit.bit_copy_done = 1; - rc = hal_flash_write(flash_id, off, &bit.bit_copy_done, 1); - - return rc; -} - -/** - * Marks a reverted image in slot 0 as confirmed. This is necessary to ensure - * the status bytes from the image revert operation don't get processed on a - * subsequent boot. - */ -int -boot_finalize_revert_swap(void) -{ - struct boot_img_trailer bit; - uint32_t off; - uint8_t flash_id; - int rc; - - boot_magic_loc(0, &flash_id, &off); - - bit.bit_copy_start = BOOT_IMG_MAGIC; - bit.bit_copy_done = 1; - bit.bit_img_ok = 1; - rc = hal_flash_write(flash_id, off, &bit, sizeof bit); - - return rc; -} - -void -boot_set_image_slot_split(void) -{ - boot_current_slot = 1; -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/src/bootutil_priv.h ---------------------------------------------------------------------- diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index 1279e41..5ed1414 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -20,6 +20,7 @@ #ifndef H_BOOTUTIL_PRIV_ #define H_BOOTUTIL_PRIV_ +#include "syscfg/syscfg.h" #include "bootutil/image.h" #ifdef __cplusplus @@ -63,22 +64,15 @@ struct boot_status { 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); int boot_schedule_test_swap(void); -int boot_finalize_test_swap(void); -int boot_finalize_revert_swap(void); -void boot_magic_loc(int slot_num, uint8_t *flash_id, uint32_t *off); -void boot_scratch_loc(uint8_t *flash_id, uint32_t *off); -void boot_slot_magic(int slot_num, struct boot_img_trailer *bit); -void boot_scratch_magic(struct boot_img_trailer *bit); uint32_t boot_status_sz(int elem_sz); +#if MYNEWT_VAL(TEST) struct boot_req; void boot_req_set(struct boot_req *req); +#endif #ifdef __cplusplus } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/src/loader.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index db8b73a..c1a4281 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -17,6 +17,11 @@ * under the License. */ +/** + * This file provides an interface to the boot loader. Functions defined in + * this file should only be called while the boot loader is running. + */ + #include <assert.h> #include <stddef.h> #include <inttypes.h> @@ -43,11 +48,212 @@ static struct boot_img { uint32_t area; } boot_img[BOOT_NUM_SLOTS]; -static struct boot_status boot_state; - static int boot_erase_area(int area_idx, uint32_t sz); static uint32_t boot_copy_sz(int max_idx, int *cnt); +struct boot_status_table { + /** * For each field, a value of 0 means "any". */ + uint32_t bst_magic_slot0; + uint32_t bst_magic_scratch; + uint8_t bst_copy_done_slot0; + + uint8_t bst_status_source; +}; + +/** + * This set of tables maps image trailer contents to swap status location. + * When searching for a match, these tables must be iterated sequentially. + */ +static const struct boot_status_table boot_status_tables[] = { + { + /* | slot-0 | scratch | + * ----------+------------+------------| + * magic | 0x12344321 | 0x******** | + * copy-done | 0x01 | N/A | + * ----------+------------+------------' + * status: none | + * ------------------------------------' + */ + .bst_magic_slot0 = BOOT_IMG_MAGIC, + .bst_magic_scratch = 0, + .bst_copy_done_slot0 = 0x01, + .bst_status_source = BOOT_STATUS_SOURCE_NONE, + }, + + { + /* | slot-0 | scratch | + * ----------+------------+------------| + * magic | 0x12344321 | 0x******** | + * copy-done | 0xff | N/A | + * ----------+------------+------------' + * status: slot 0 | + * ------------------------------------' + */ + .bst_magic_slot0 = BOOT_IMG_MAGIC, + .bst_magic_scratch = 0, + .bst_copy_done_slot0 = 0xff, + .bst_status_source = BOOT_STATUS_SOURCE_SLOT0, + }, + + { + /* | slot-0 | scratch | + * ----------+------------+------------| + * magic | 0x******** | 0x12344321 | + * copy-done | 0x** | N/A | + * ----------+------------+------------' + * status: scratch | + * ------------------------------------' + */ + .bst_magic_slot0 = 0, + .bst_magic_scratch = BOOT_IMG_MAGIC, + .bst_copy_done_slot0 = 0, + .bst_status_source = BOOT_STATUS_SOURCE_SCRATCH, + }, + + { + /* | slot-0 | scratch | + * ----------+------------+------------| + * magic | 0xffffffff | 0xffffffff | + * copy-done | 0xff | N/A | + * ----------+------------+------------| + * status: slot 0 | + * ------------------------------------+-------------------------------+ + * This represents one of two cases: | + * o No swaps ever (no status to read anyway, so no harm in checking). | + * o Mid-revert; status in slot 0. | + * --------------------------------------------------------------------' + */ + .bst_magic_slot0 = 0xffffffff, + .bst_magic_scratch = 0, + .bst_copy_done_slot0 = 0xff, + .bst_status_source = BOOT_STATUS_SOURCE_SLOT0, + }, +}; + +#define BOOT_STATUS_TABLES_COUNT \ + (sizeof boot_status_tables / sizeof boot_status_tables[0]) + +static int +boot_status_source(void) +{ + const struct boot_status_table *table; + struct boot_img_trailer bit_scratch; + struct boot_img_trailer bit_slot0; + struct boot_img_trailer bit_slot1; + int rc; + int i; + + rc = boot_read_img_trailer(0, &bit_slot0); + assert(rc == 0); + + rc = boot_read_img_trailer(1, &bit_slot1); + assert(rc == 0); + + rc = boot_read_scratch_trailer(&bit_scratch); + assert(rc == 0); + + for (i = 0; i < BOOT_STATUS_TABLES_COUNT; i++) { + table = boot_status_tables + i; + + if ((table->bst_magic_slot0 == 0 || + table->bst_magic_slot0 == bit_slot0.bit_copy_start) && + (table->bst_magic_scratch == 0 || + table->bst_magic_scratch == bit_scratch.bit_copy_start) && + (table->bst_copy_done_slot0 == 0 || + table->bst_copy_done_slot0 == bit_slot0.bit_copy_done)) { + + return table->bst_status_source; + } + } + + return BOOT_STATUS_SOURCE_NONE; +} + +static int +boot_partial_swap_type(void) +{ + int swap_type; + + swap_type = boot_swap_type(); + switch (swap_type) { + case BOOT_SWAP_TYPE_NONE: + return BOOT_SWAP_TYPE_REVERT; + + case BOOT_SWAP_TYPE_REVERT: + return BOOT_SWAP_TYPE_TEST; + + default: + assert(0); + return BOOT_SWAP_TYPE_REVERT; + } +} + +/** + * Calculates the flash offset of the specified image slot. + * + * @param slot_num The number of the slot to calculate. + * @param loc The flash location of the slot. + * + */ +static void +boot_slot_addr(int slot_num, struct boot_image_location *loc) +{ + const struct flash_area *area_desc; + uint8_t area_idx; + + area_idx = boot_req->br_slot_areas[slot_num]; + area_desc = boot_req->br_area_descs + area_idx; + loc->bil_flash_id = area_desc->fa_device_id; + loc->bil_address = area_desc->fa_off; +} + +/** + * 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 + * corresponding image in flash. + * @param addresses An array containing the flash addresses of each + * image slot. + * @param num_addresses The number of headers to read. This should + * also be equal to the lengths of the + * out_headers and addresses arrays. + */ +static int +boot_read_image_header(struct boot_image_location *loc, + struct image_header *out_hdr) +{ + int rc; + + 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; + } + + if (rc) { + memset(out_hdr, 0xff, sizeof(*out_hdr)); + } + return rc; +} + +static void +boot_read_image_headers(void) +{ + struct boot_img *b; + int i; + + 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; + } +} + int boot_build_request(struct boot_req *preq, int area_descriptor_max) { @@ -67,20 +273,20 @@ boot_build_request(struct boot_req *preq, int area_descriptor_max) preq->br_img_sz = fap->fa_size; cnt = area_descriptor_max - total; - if( cnt < 0) { + if (cnt < 0) { return -1; } rc = flash_area_to_sectors(FLASH_AREA_IMAGE_1, &cnt, &descs[total]); - if(rc != 0) { + if (rc != 0) { return -2; } img_starts[1] = total; total += cnt; cnt = area_descriptor_max - total; - if( cnt < 0) { + if (cnt < 0) { return -3; } @@ -96,31 +302,6 @@ boot_build_request(struct boot_req *preq, int area_descriptor_max) return 0; } -void -boot_req_set(struct boot_req *req) -{ - boot_req = req; -} - -/** - * Calculates the flash offset of the specified image slot. - * - * @param slot_num The number of the slot to calculate. - * @param loc The flash location of the slot. - * - */ -static void -boot_slot_addr(int slot_num, struct boot_image_location *loc) -{ - const struct flash_area *area_desc; - uint8_t area_idx; - - area_idx = boot_req->br_slot_areas[slot_num]; - area_desc = boot_req->br_area_descs + area_idx; - loc->bil_flash_id = area_desc->fa_device_id; - loc->bil_address = area_desc->fa_off; -} - /* * Status about copy-in-progress is either in slot0 (target slot) or * in scratch area. It is in scratch area if the process is currently @@ -136,7 +317,7 @@ boot_slot_addr(int slot_num, struct boot_image_location *loc) * scratch when the first area is being moved. Otherwise it will be * in slot 0. */ -void +static void boot_magic_loc(int slot_num, uint8_t *flash_id, uint32_t *off) { struct boot_img *b; @@ -146,7 +327,7 @@ boot_magic_loc(int slot_num, uint8_t *flash_id, uint32_t *off) *off = b->area + b->loc.bil_address - sizeof(struct boot_img_trailer); } -void +static void boot_scratch_loc(uint8_t *flash_id, uint32_t *off) { struct flash_area *scratch; @@ -160,60 +341,148 @@ boot_scratch_loc(uint8_t *flash_id, uint32_t *off) *off += (scratch->fa_off - sizeof(struct boot_img_trailer)); } -void -boot_slot_magic(int slot_num, struct boot_img_trailer *bit) +static uint32_t +boot_status_off(uint32_t trailer_off, int status_idx, int status_state, + int elem_sz) { - uint32_t off; - uint8_t flash_id; + uint32_t status_start; + int idx_sz; + + status_start = trailer_off - boot_status_sz(elem_sz); - boot_magic_loc(slot_num, &flash_id, &off); - memset(bit, 0xff, sizeof(*bit)); - hal_flash_read(flash_id, off, bit, sizeof(*bit)); + idx_sz = BOOT_STATUS_STATE_COUNT * elem_sz; + return status_start + + status_idx * idx_sz + + status_state * elem_sz; } -void -boot_scratch_magic(struct boot_img_trailer *bit) +/** + * Reads the status of a partially-completed swap, if any. This is necessary + * to recover in case the boot lodaer was reset in the middle of a swap + * operation. + */ +static void +boot_read_status_bytes(struct boot_status *bs, uint8_t flash_id, + uint32_t trailer_off) { + uint32_t status_sz; uint32_t off; - uint8_t flash_id; + uint8_t status; + int found; + int i; + + status_sz = boot_status_sz(bs->elem_sz); + off = trailer_off - status_sz; + + found = 0; + for (i = 0; i < status_sz; i++) { + hal_flash_read(flash_id, off + i * bs->elem_sz, + &status, sizeof status); + if (status == 0xff) { + if (found) { + break; + } + } else if (!found) { + found = 1; + } + } - boot_scratch_loc(&flash_id, &off); - memset(bit, 0xff, sizeof(*bit)); - hal_flash_read(flash_id, off, bit, sizeof(*bit)); + if (found) { + i--; + bs->idx = i / BOOT_STATUS_STATE_COUNT; + bs->state = i % BOOT_STATUS_STATE_COUNT; + } } -/* - * Gather info about image in a given slot. +static uint8_t +boot_status_elem_sz(void) +{ + const struct flash_area *scratch; + uint8_t elem_sz; + uint8_t align; + + /* Figure out what size to write update status update as. The size depends + * on what the minimum write size is for scratch area, active image slot. + * We need to use the bigger of those 2 values. + */ + elem_sz = hal_flash_align(boot_img[0].loc.bil_flash_id); + + scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx]; + align = hal_flash_align(scratch->fa_device_id); + if (align > elem_sz) { + elem_sz = align; + } + + return elem_sz; +} + +/** + * Reads the boot status from the flash. The boot status contains + * the current state of an interrupted image copy operation. If the boot + * status is not present, or it indicates that previous copy finished, + * there is no operation in progress. */ -void -boot_image_info(void) +static int +boot_read_status(struct boot_status *boot_state) { - int i; - struct boot_img *b; - struct flash_area *scratch; + uint32_t off; + uint8_t flash_id; + int status_loc; - memset(&boot_state, 0, sizeof boot_state); + memset(boot_state, 0, sizeof *boot_state); - 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; + boot_state->elem_sz = boot_status_elem_sz(); + + status_loc = boot_status_source(); + switch (status_loc) { + case BOOT_STATUS_SOURCE_NONE: + break; + + case BOOT_STATUS_SOURCE_SCRATCH: + boot_scratch_loc(&flash_id, &off); + boot_read_status_bytes(boot_state, flash_id, off); + break; + + case BOOT_STATUS_SOURCE_SLOT0: + boot_magic_loc(0, &flash_id, &off); + boot_read_status_bytes(boot_state, flash_id, off); + break; + + default: + assert(0); + break; } - /* - * Figure out what size to write update status update as. - * The size depends on what the minimum write size is for scratch - * area, active image slot. We need to use the bigger of those 2 - * values. - */ - boot_state.elem_sz = hal_flash_align(boot_img[0].loc.bil_flash_id); + return boot_state->idx != 0 || boot_state->state != 0; +} - scratch = &boot_req->br_area_descs[boot_req->br_scratch_area_idx]; - i = hal_flash_align(scratch->fa_device_id); - if (i > boot_state.elem_sz) { - boot_state.elem_sz = i; +/** + * 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 bs The boot status to write. + * + * @return 0 on success; nonzero on failure. + */ +int +boot_write_status(struct boot_status *bs) +{ + uint32_t trailer_off; + uint32_t status_off; + uint8_t flash_id; + + if (bs->idx == 0) { + /* Write to scratch. */ + boot_scratch_loc(&flash_id, &trailer_off); + } else { + /* Write to slot 0. */ + boot_magic_loc(0, &flash_id, &trailer_off); } + + status_off = boot_status_off(trailer_off, bs->idx, bs->state, bs->elem_sz); + hal_flash_write(flash_id, status_off, &bs->state, 1); + + return 0; } /* @@ -441,17 +710,18 @@ boot_copy_area(int from_area_idx, int to_area_idx, uint32_t sz) /** * Swaps the contents of two flash areas belonging to images. * - * @param area_idx The index of first slot to exchange. This area + * @param idx The index of first slot to exchange. This area * must be part of the first image slot. - * @param sz The number of bytes swap. + * @param sz The number of bytes swap. * - * @param end_area Boolean telling whether this includes this - * area has last slots. + * @param end_area Whether this is the last sector in the source + * and destination slots (0/1). * * @return 0 on success; nonzero on failure. */ static int -boot_swap_areas(int idx, uint32_t sz, int end_area) +boot_swap_areas(int idx, uint32_t sz, int end_area, + struct boot_status *boot_state) { int area_idx_0; int area_idx_1; @@ -463,7 +733,7 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) assert(area_idx_0 != boot_req->br_scratch_area_idx); assert(area_idx_1 != boot_req->br_scratch_area_idx); - if (boot_state.state == 0) { + if (boot_state->state == 0) { rc = boot_erase_area(boot_req->br_scratch_area_idx, sz); if (rc != 0) { return rc; @@ -474,25 +744,25 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) return rc; } - boot_state.state = 1; - (void)boot_write_status(&boot_state); + boot_state->state = 1; + (void)boot_write_status(boot_state); } - if (boot_state.state == 1) { + if (boot_state->state == 1) { rc = boot_erase_area(area_idx_1, sz); if (rc != 0) { return rc; } rc = boot_copy_area(area_idx_0, area_idx_1, - end_area ? (sz - boot_meta_sz(boot_state.elem_sz)) : sz); + end_area ? (sz - boot_meta_sz(boot_state->elem_sz)) : sz); if (rc != 0) { return rc; } - boot_state.state = 2; - (void)boot_write_status(&boot_state); + boot_state->state = 2; + (void)boot_write_status(boot_state); } - if (boot_state.state == 2) { + if (boot_state->state == 2) { rc = boot_erase_area(area_idx_0, sz); if (rc != 0) { return rc; @@ -503,9 +773,9 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) return rc; } - boot_state.idx++; - boot_state.state = 0; - (void)boot_write_status(&boot_state); + boot_state->idx++; + boot_state->state = 0; + (void)boot_write_status(boot_state); } return 0; } @@ -517,7 +787,7 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) * @return 0 on success; nonzero on failure. */ static int -boot_copy_image(void) +boot_copy_image(struct boot_status *boot_state) { uint32_t sz; int i; @@ -528,8 +798,8 @@ boot_copy_image(void) 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); + if (cur_idx >= boot_state->idx) { + boot_swap_areas(i, sz, end_area, boot_state); } end_area = 0; } @@ -538,6 +808,55 @@ boot_copy_image(void) } /** + * Marks a test image in slot 0 as fully copied. + */ +static int +boot_finalize_test_swap(void) +{ + struct boot_img_trailer bit; + uint32_t off; + uint8_t flash_id; + int rc; + + boot_magic_loc(0, &flash_id, &off); + off += offsetof(struct boot_img_trailer, bit_copy_done); + + bit.bit_copy_done = 1; + rc = hal_flash_write(flash_id, off, &bit.bit_copy_done, 1); + + return rc; +} + +/** + * Marks a reverted image in slot 0 as confirmed. This is necessary to ensure + * the status bytes from the image revert operation don't get processed on a + * subsequent boot. + */ +static int +boot_finalize_revert_swap(void) +{ + struct boot_img_trailer bit; + uint32_t off; + uint8_t flash_id; + int rc; + + boot_magic_loc(0, &flash_id, &off); + + bit.bit_copy_start = BOOT_IMG_MAGIC; + bit.bit_copy_done = 1; + bit.bit_img_ok = 1; + rc = hal_flash_write(flash_id, off, &bit, sizeof bit); + + return rc; +} + +uint32_t +boot_status_sz(int elem_sz) +{ + return BOOT_STATUS_MAX_ENTRIES * BOOT_STATUS_STATE_COUNT * elem_sz; +} + +/** * Prepares the booting process. Based on the information provided in the * request object, this function moves images around in flash as appropriate, * and tells you what address to boot from. @@ -550,6 +869,7 @@ boot_copy_image(void) int boot_go(const struct boot_req *req, struct boot_rsp *rsp) { + struct boot_status boot_state; int partial_swap; int swap_type; int slot; @@ -561,20 +881,20 @@ boot_go(const struct boot_req *req, struct boot_rsp *rsp) boot_req = req; /* Attempt to read an image header from each slot. */ - boot_image_info(); + boot_read_image_headers(); - /* Determine if we rebootded in the middle of an image swap operation. */ + /* Determine if we rebooted in the middle of an image swap operation. */ partial_swap = boot_read_status(&boot_state); if (partial_swap) { /* Complete the partial swap. */ - rc = boot_copy_image(); + rc = boot_copy_image(&boot_state); assert(rc == 0); swap_type = boot_partial_swap_type(); } else { swap_type = boot_validated_swap_type(); if (swap_type != BOOT_SWAP_TYPE_NONE) { - rc = boot_copy_image(); + rc = boot_copy_image(&boot_state); assert(rc == 0); } } @@ -637,7 +957,7 @@ split_go(int loader_slot, int split_slot, void **entry) boot_req = &req; - boot_image_info(); + boot_read_image_headers(); /* Don't check the bootable image flag because we could really * call a bootable or non-bootable image. Just validate that @@ -660,3 +980,17 @@ split_app_go_end: free(descs); return rc; } + +#if MYNEWT_VAL(TEST) + +/** + * Used by unit tests. This allows a test to call boot loader functions + * without starting the boot loader. + */ +void +boot_req_set(struct boot_req *req) +{ + boot_req = req; +} + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c b/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c index af3e558..c26abfb 100644 --- a/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c +++ b/boot/bootutil/test/src/testcases/boot_test_invalid_hash.c @@ -60,7 +60,7 @@ TEST_CASE(boot_test_invalid_hash) &tlv, sizeof(tlv)); TEST_ASSERT(rc == 0); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr0, NULL); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c b/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c index c3d1636..6bfa845 100644 --- a/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c +++ b/boot/bootutil/test/src/testcases/boot_test_no_flag_has_hash.c @@ -53,7 +53,7 @@ TEST_CASE(boot_test_no_flag_has_hash) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr0, NULL); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_no_hash.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_no_hash.c b/boot/bootutil/test/src/testcases/boot_test_no_hash.c index 0ce1a54..6f05d16 100644 --- a/boot/bootutil/test/src/testcases/boot_test_no_hash.c +++ b/boot/bootutil/test/src/testcases/boot_test_no_hash.c @@ -52,7 +52,7 @@ TEST_CASE(boot_test_no_hash) boot_test_util_write_hash(&hdr0, 0); boot_test_util_write_image(&hdr1, 1); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr0, NULL); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c index 86146b1..c3376b4 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11.c @@ -54,9 +54,10 @@ 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); - rc = boot_set_pending(1); + rc = boot_set_pending(); boot_test_util_copy_area(5, BOOT_TEST_AREA_IDX_SCRATCH); + // XXX boot_req_set(&req); status.idx = 0; status.elem_sz = 1; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c index e427f36..1cb808d 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_bs_11_2areas.c @@ -54,7 +54,7 @@ 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); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT_FATAL(rc == 0); boot_test_util_swap_areas(2, 5); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c b/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c index 00a1967..b4cb4ea 100644 --- a/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c +++ b/boot/bootutil/test/src/testcases/boot_test_nv_ns_01.c @@ -41,7 +41,7 @@ TEST_CASE(boot_test_nv_ns_01) boot_test_util_write_image(&hdr, 1); boot_test_util_write_hash(&hdr, 1); - boot_set_pending(1); + boot_set_pending(); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_REVERT, NULL, &hdr); } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c b/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c index 0ac7480..3596e22 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c +++ b/boot/bootutil/test/src/testcases/boot_test_vb_ns_11.c @@ -54,7 +54,7 @@ TEST_CASE(boot_test_vb_ns_11) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_TEST, &hdr0, &hdr1); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c index b749f87..807f548 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_01.c @@ -43,7 +43,7 @@ TEST_CASE(boot_test_vm_ns_01) boot_test_util_write_image(&hdr, 1); boot_test_util_write_hash(&hdr, 1); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_REVERT, NULL, &hdr); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c index 6f75c31..19cc2b3 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_2areas.c @@ -54,7 +54,7 @@ TEST_CASE(boot_test_vm_ns_11_2areas) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_TEST, &hdr0, &hdr1); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c index 88d9e74..5c79981 100644 --- a/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c +++ b/boot/bootutil/test/src/testcases/boot_test_vm_ns_11_b.c @@ -54,7 +54,7 @@ TEST_CASE(boot_test_vm_ns_11_b) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = boot_set_pending(1); + rc = boot_set_pending(); TEST_ASSERT(rc == 0); boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_TEST, &hdr0, &hdr1); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/mgmt/imgmgr/include/imgmgr/imgmgr.h ---------------------------------------------------------------------- diff --git a/mgmt/imgmgr/include/imgmgr/imgmgr.h b/mgmt/imgmgr/include/imgmgr/imgmgr.h index d06da61..9d2dd1d 100644 --- a/mgmt/imgmgr/include/imgmgr/imgmgr.h +++ b/mgmt/imgmgr/include/imgmgr/imgmgr.h @@ -66,6 +66,7 @@ int imgr_my_version(struct image_version *ver); uint8_t imgmgr_state_flags(int query_slot); int imgmgr_state_slot_in_use(int slot); +int imgmgr_state_test_slot(int slot); #ifdef __cplusplus } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/mgmt/imgmgr/src/imgmgr_cli.c ---------------------------------------------------------------------- diff --git a/mgmt/imgmgr/src/imgmgr_cli.c b/mgmt/imgmgr/src/imgmgr_cli.c index 22fac00..62d6751 100644 --- a/mgmt/imgmgr/src/imgmgr_cli.c +++ b/mgmt/imgmgr/src/imgmgr_cli.c @@ -87,6 +87,7 @@ imgr_cli_boot_set(char *hash_str) { uint8_t hash[IMGMGR_HASH_LEN]; struct image_version ver; + int slot; int rc; if (hex_parse(hash_str, strlen(hash_str), hash, sizeof(hash)) != @@ -94,14 +95,16 @@ imgr_cli_boot_set(char *hash_str) console_printf("Invalid hash %s\n", hash_str); return; } - rc = imgr_find_by_hash(hash, &ver); - if (rc < 0) { + + slot = imgr_find_by_hash(hash, &ver); + if (slot == -1) { console_printf("Unknown img\n"); return; } - rc = boot_set_pending(rc); + + rc = imgmgr_state_test_slot(slot); if (rc) { - console_printf("Can't make img active\n"); + console_printf("Error setting image to pending; rc=%d\n", rc); return; } } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/94944515/mgmt/imgmgr/src/imgmgr_state.c ---------------------------------------------------------------------- diff --git a/mgmt/imgmgr/src/imgmgr_state.c b/mgmt/imgmgr/src/imgmgr_state.c index b8662b2..bae2332 100644 --- a/mgmt/imgmgr/src/imgmgr_state.c +++ b/mgmt/imgmgr/src/imgmgr_state.c @@ -132,7 +132,7 @@ imgmgr_state_slot_in_use(int slot) state_flags & IMGMGR_STATE_F_PENDING; } -static int +int imgmgr_state_test_slot(int slot) { uint32_t image_flags; @@ -161,7 +161,7 @@ imgmgr_state_test_slot(int slot) /* Unified image or loader. */ if (!split_app_active) { /* No change in split status. */ - rc = boot_set_pending(slot); + rc = boot_set_pending(); if (rc != 0) { return MGMT_ERR_EUNKNOWN; }