Repository: incubator-mynewt-core Updated Branches: refs/heads/develop e7abb3c74 -> 3758239db
Two-stage boot (test / confirm). Code cleanup to follow. 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/4b1a5c1d Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/4b1a5c1d Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/4b1a5c1d Branch: refs/heads/develop Commit: 4b1a5c1dacb83ca13df68460a752b3d6d94041ce Parents: e7abb3c Author: Christopher Collins <ccoll...@apache.org> Authored: Fri Oct 14 13:27:14 2016 -0700 Committer: Christopher Collins <ccoll...@apache.org> Committed: Fri Oct 14 16:39:43 2016 -0700 ---------------------------------------------------------------------- boot/bootutil/src/bootutil_misc.c | 65 ++++++++-- boot/bootutil/src/bootutil_priv.h | 67 ++++++++++- boot/bootutil/src/loader.c | 175 ++++++++++++++++----------- boot/bootutil/test/src/boot_test.c | 207 ++++++++++++++++++-------------- mgmt/imgmgr/src/imgmgr_state.c | 28 +++-- 5 files changed, 352 insertions(+), 190 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4b1a5c1d/boot/bootutil/src/bootutil_misc.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c index 0ee7ea9..bb7b2a3 100644 --- a/boot/bootutil/src/bootutil_misc.c +++ b/boot/bootutil/src/bootutil_misc.c @@ -39,7 +39,7 @@ int8_t boot_split_app_active; /* * Read the image trailer from a given slot. */ -static int +int boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) { int rc; @@ -59,6 +59,39 @@ boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) return rc; } +int +boot_status_sz(void) +{ + return sizeof(struct boot_img_trailer) + 32 * sizeof(uint32_t); +} + +/* + * Read the image trailer from a given slot. + */ +static int +boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) +{ + struct boot_img_trailer bit0; + struct boot_img_trailer bit1; + + boot_vect_read_img_trailer(0, &bit0); + boot_vect_read_img_trailer(1, &bit1); + + if (bit0.bit_copy_start == BOOT_MAGIC_SWAP_NONE && + bit1.bit_copy_start == BOOT_MAGIC_SWAP_NONE) { + + area_id = flash_area_id_from_image_slot(slot); + rc = flash_area_open(area_id, &fap); + if (rc) { + return rc; + } + off = fap->fa_size - sizeof(struct boot_img_trailer); + rc = flash_area_read(fap, off, bit, sizeof(*bit)); + flash_area_close(fap); + + return rc; +} + /** * 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). @@ -83,7 +116,7 @@ boot_vect_read_test(int *slot) if (rc) { continue; } - if (bit.bit_copy_start == BOOT_IMG_MAGIC) { + if (bit.bit_copy_start == BOOT_MAGIC_SWAP_TEMP) { *slot = i; return 0; } @@ -108,7 +141,7 @@ boot_vect_read_main(int *slot) 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 (bit.bit_copy_start != BOOT_MAGIC_SWAP_TEMP || 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. @@ -144,7 +177,7 @@ boot_vect_write_test(int slot) } off = fap->fa_size - sizeof(struct boot_img_trailer); - magic = BOOT_IMG_MAGIC; + magic = BOOT_MAGIC_SWAP_TEMP; rc = flash_area_write(fap, off, &magic, sizeof(magic)); flash_area_close(fap); @@ -256,21 +289,26 @@ boot_read_status(struct boot_status *bs) uint8_t flash_id; uint32_t off; - /* - * Check if boot_img_trailer is in scratch, or at the end of slot0. - */ + /* Check if boot_img_trailer is in scratch, or at the end of slot0. */ boot_slot_magic(0, &bit); - if (bit.bit_copy_start == BOOT_IMG_MAGIC && bit.bit_copy_done == 0xff) { + if (bit.bit_copy_start != BOOT_MAGIC_SWAP_NONE && + bit.bit_copy_done == 0xff) { + boot_magic_loc(0, &flash_id, &off); boot_read_status_bytes(bs, flash_id, off); return 1; } + boot_scratch_magic(&bit); - if (bit.bit_copy_start == BOOT_IMG_MAGIC && bit.bit_copy_done == 0xff) { + if (bit.bit_copy_start != BOOT_MAGIC_SWAP_NONE && + bit.bit_copy_done == 0xff) { + boot_scratch_loc(&flash_id, &off); boot_read_status_bytes(bs, flash_id, off); return 1; } + + return 0; } @@ -316,10 +354,10 @@ boot_write_status(struct boot_status *bs) * progress. */ void -boot_clear_status(void) +boot_set_copy_done(void) { + struct boot_img_trailer bit; uint32_t off; - uint8_t val = 0; uint8_t flash_id; /* @@ -327,8 +365,9 @@ boot_clear_status(void) * Here we say that copy operation was finished. */ boot_magic_loc(0, &flash_id, &off); - off += sizeof(uint32_t); - hal_flash_write(flash_id, off, &val, sizeof(val)); + bit.bit_copy_start = BOOT_MAGIC_SWAP_PERM; + bit.bit_copy_done = 1; + hal_flash_write(flash_id, off, &bit, 5); } int http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4b1a5c1d/boot/bootutil/src/bootutil_priv.h ---------------------------------------------------------------------- diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index d24a671..7112c60 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -36,21 +36,32 @@ extern "C" { #define BOOT_TMPBUF_SZ 256 - - /* * Maintain state of copy progress. */ struct boot_status { uint32_t idx; /* Which area we're operating on */ uint8_t elem_sz; /* Size of the status element to write in bytes */ - uint8_t state; /* Which part of the swapping process are we at */ + + /** + * Which action in the swapping process comes next. + * 0: copy slot-1-area --> scratch + * 1: copy slot-0-area --> slot-1-area + * 2: copy scratch --> slot-0-area + */ + uint8_t state; }; +#define BOOT_SWAP_TYPE_NONE 0 +#define BOOT_SWAP_TYPE_TEMP 1 +#define BOOT_SWAP_TYPE_PERM 2 + /* * End-of-image slot data structure. */ -#define BOOT_IMG_MAGIC 0x12344321 +#define BOOT_MAGIC_SWAP_NONE 0xffffffff +#define BOOT_MAGIC_SWAP_TEMP 0x12344321 +#define BOOT_MAGIC_SWAP_PERM 0x56788765 struct boot_img_trailer { uint32_t bit_copy_start; uint8_t bit_copy_done; @@ -58,6 +69,52 @@ struct boot_img_trailer { uint16_t _pad; }; +/* + * | slot-0 | slot-1 | + * ---------------+------------+------------| + * bit-copy-start | 0xffffffff | 0xffffffff | + * bit-copy-done | 0x** | 0x** | + * bit-img-ok | 0x** | 0x** | + * ---------------+------------+------------' + * swap: none | + * -----------------------------------------' + * + * ~~~ + * + * | slot-0 | slot-1 | + * ---------------+------------+------------| + * bit-copy-start | 0x******** | 0x12344321 | + * bit-copy-done | 0x** | 0x** | + * bit-img-ok | 0x** | 0x** | + * ---------------+------------+------------' + * swap: temporary | + * -----------------------------------------' + * + * ~~~ + * + * | slot-0 | slot-1 | + * ---------------+------------+------------| + * bit-copy-start | 0x56788765 | 0xffffffff | + * bit-copy-done | 0x** | 0x** | + * bit-img-ok | 0xff | 0x** | + * ---------------+------------+------------' + * swap: permanent (revert) | + * -----------------------------------------' + * + * ~~~ + * + * | slot-0 | slot-1 | + * ---------------+------------+------------| + * bit-copy-start | 0x56788765 | 0x******** | + * bit-copy-done | 0x** | 0x** | + * bit-img-ok | 0x01 | 0x** | + * ---------------+------------+------------' + * swap: none (confirmed) | + * -----------------------------------------' + */ + +int boot_status_sz(void); + int bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, int slen, uint8_t key_id); @@ -65,7 +122,7 @@ 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); +void boot_set_copy_done(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); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4b1a5c1d/boot/bootutil/src/loader.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 54a1e0c..7c07a9c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -185,6 +185,39 @@ boot_scratch_magic(struct boot_img_trailer *bit) hal_flash_read(flash_id, off, bit, sizeof(*bit)); } +static int +boot_swap_type(void) +{ + struct boot_img_trailer bit0; + struct boot_img_trailer bit1; + + boot_slot_magic(0, &bit0); + boot_slot_magic(1, &bit1); + + if (bit0.bit_copy_start == BOOT_MAGIC_SWAP_NONE && + bit1.bit_copy_start == BOOT_MAGIC_SWAP_NONE) { + + return BOOT_SWAP_TYPE_NONE; + } + + if (bit1.bit_copy_start == BOOT_MAGIC_SWAP_TEMP) { + return BOOT_SWAP_TYPE_TEMP; + } + + if (bit0.bit_copy_start == BOOT_MAGIC_SWAP_PERM) { + if (bit0.bit_img_ok != 0xff) { + return BOOT_SWAP_TYPE_NONE; + } else { + return BOOT_SWAP_TYPE_PERM; + } + } + + /* This should never happen. */ + /* XXX: Remove this assert. */ + assert(0); + return BOOT_SWAP_TYPE_NONE; +} + /* * Gather info about image in a given slot. */ @@ -195,6 +228,8 @@ boot_image_info(void) struct boot_img *b; struct flash_area *scratch; + 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); @@ -282,53 +317,47 @@ split_image_check(struct image_header *app_hdr, * determined. */ static int -boot_select_image_slot(void) +boot_validate_state(int swap_type) { - /* - * Check for swap magic. Check the integrity of the suggested image. - */ - int rc; - int i; - struct boot_img *b; struct boot_img_trailer bit; + struct boot_img *b; + int img_ok; + int slot; + int rc; - boot_slot_magic(0, &bit); - if (bit.bit_copy_start == BOOT_IMG_MAGIC && bit.bit_copy_done != 0xff && - bit.bit_img_ok == 0xff) { - /* - * Copied the image successfully, but image was not confirmed as good. - * We need to go back to another image. - */ - boot_vect_write_test(1); + if (swap_type == BOOT_SWAP_TYPE_NONE) { + slot = 0; + } else { + slot = 1; } - for (i = 1; i < BOOT_NUM_SLOTS; i++) { - b = &boot_img[i]; - boot_slot_magic(i, &bit); - if (bit.bit_copy_start == BOOT_IMG_MAGIC) { - if (b->hdr.ih_magic == IMAGE_MAGIC_NONE) { - continue; - } - if (!boot_image_bootable(&b->hdr)) { - continue; - } - 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; - } + + /* Assume selected image is OK to boot into. */ + img_ok = 1; + + b = &boot_img[slot]; + boot_slot_magic(slot, &bit); + if (b->hdr.ih_magic == IMAGE_MAGIC_NONE) { + img_ok = 0; + } else if (!boot_image_bootable(&b->hdr)) { + img_ok = 0; + } else { + rc = boot_image_check(&b->hdr, &b->loc); + if (rc != 0) { + /* Image fails integrity check. Erase it. */ + boot_erase_area(boot_req->br_slot_areas[slot], b->area); + img_ok = 0; } } - return 0; -} -static int -boot_status_sz(void) -{ - return sizeof(struct boot_img_trailer) + 32 * sizeof(uint32_t); + if (!img_ok) { + if (swap_type == BOOT_SWAP_TYPE_NONE) { + swap_type = BOOT_SWAP_TYPE_PERM; + } else { + swap_type = BOOT_SWAP_TYPE_NONE; + } + } + + return swap_type; } /* @@ -445,7 +474,7 @@ boot_copy_area(int from_area_idx, int to_area_idx, uint32_t sz) * * @param area_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 to swap. * * @param end_area Boolean telling whether this includes this * area has last slots. @@ -471,7 +500,8 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) return rc; } - rc = boot_copy_area(area_idx_2, boot_req->br_scratch_area_idx, sz); + rc = boot_copy_area(area_idx_2, boot_req->br_scratch_area_idx, + end_area ? (sz - boot_status_sz()) : sz); if (rc != 0) { return rc; } @@ -500,7 +530,8 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) return rc; } - rc = boot_copy_area(boot_req->br_scratch_area_idx, area_idx_1, sz); + rc = boot_copy_area(boot_req->br_scratch_area_idx, area_idx_1, + end_area ? (sz - boot_status_sz()) : sz); if (rc != 0) { return rc; } @@ -518,8 +549,8 @@ boot_swap_areas(int idx, uint32_t sz, int end_area) * * @return 0 on success; nonzero on failure. */ -static int -boot_copy_image(void) +static void +boot_copy_image(int swap_type) { uint32_t sz; int i; @@ -535,9 +566,10 @@ boot_copy_image(void) } end_area = 0; } - boot_clear_status(); - return 0; + if (swap_type == BOOT_SWAP_TYPE_TEMP) { + boot_set_copy_done(); + } } /** @@ -553,8 +585,9 @@ boot_copy_image(void) int boot_go(const struct boot_req *req, struct boot_rsp *rsp) { + int swap_type; + int num_swaps; int slot; - int rc; /* Set the global boot request object. The remainder of the boot process * will reference the global. @@ -564,39 +597,35 @@ boot_go(const struct boot_req *req, struct boot_rsp *rsp) /* Attempt to read an image header from each slot. */ boot_image_info(); + num_swaps = 0; + swap_type = boot_swap_type(); + /* 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. */ - rc = boot_copy_image(); - if (rc != 0) { - /* We failed to put the images back together; there is really no - * solution here. - */ - return rc; - } - } - - /* - * Check if we should initiate copy, or revert back to earlier image. - * - */ - slot = boot_select_image_slot(); - if (slot == -1) { - return BOOT_EBADIMAGE; - } - - if (slot) { + boot_read_status(&boot_state); + //if (boot_read_status(&boot_state)) { + ///* We are resuming an interrupted image copy. */ + //boot_copy_image(swap_type); + //swap_type = BOOT_SWAP_TYPE_NONE; + //num_swaps++; + //} + + /* Check if we should initiate copy, or revert back to earlier image. */ + //swap_type = boot_validate_state(swap_type); + swap_type = boot_validate_state(swap_type); + + if (swap_type == BOOT_SWAP_TYPE_NONE) { boot_state.idx = 0; boot_state.state = 0; - rc = boot_copy_image(); - if (rc) { - return rc; - } + } else { + num_swaps++; + boot_copy_image(swap_type); } + slot = num_swaps % 2; + /* Always boot from the primary slot. */ rsp->br_flash_id = boot_img[0].loc.bil_flash_id; rsp->br_image_addr = boot_img[0].loc.bil_address; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4b1a5c1d/boot/bootutil/test/src/boot_test.c ---------------------------------------------------------------------- diff --git a/boot/bootutil/test/src/boot_test.c b/boot/bootutil/test/src/boot_test.c index 82ea15f..8bb0015 100644 --- a/boot/bootutil/test/src/boot_test.c +++ b/boot/bootutil/test/src/boot_test.c @@ -63,6 +63,9 @@ static struct { { 0, 0x80000 }, }; +/** Three areas per image slot */ +#define BOOT_TEST_IMAGE_NUM_AREAS 3 + #define BOOT_TEST_AREA_IDX_SCRATCH 6 static uint8_t @@ -127,11 +130,46 @@ boot_test_util_copy_area(int from_area_idx, int to_area_idx) free(buf); } +static uint32_t +boot_test_util_area_write_size(int dst_idx, uint32_t off, uint32_t size) +{ + const struct flash_area *desc; + int64_t diff; + uint32_t trailer_start; + int i; + + for (i = 0; + i < sizeof boot_test_slot_areas / sizeof boot_test_slot_areas[0]; + i++) { + + /* Don't include trailer in copy. */ + if (dst_idx == + boot_test_slot_areas[i] + BOOT_TEST_IMAGE_NUM_AREAS - 1) { + + desc = boot_test_area_descs + dst_idx; + trailer_start = desc->fa_size - boot_status_sz(); + diff = off + size - trailer_start; + if (diff > 0) { + if (diff > size) { + size = 0; + } else { + size -= diff; + } + } + + break; + } + } + + return size; +} + static void boot_test_util_swap_areas(int area_idx1, int area_idx2) { const struct flash_area *area_desc1; const struct flash_area *area_desc2; + uint32_t size; void *buf1; void *buf2; int rc; @@ -159,10 +197,12 @@ boot_test_util_swap_areas(int area_idx1, int area_idx2) rc = flash_area_erase(area_desc2, 0, area_desc2->fa_size); TEST_ASSERT(rc == 0); - rc = flash_area_write(area_desc1, 0, buf2, area_desc1->fa_size); + size = boot_test_util_area_write_size(area_idx1, 0, area_desc1->fa_size); + rc = flash_area_write(area_desc1, 0, buf2, size); TEST_ASSERT(rc == 0); - rc = flash_area_write(area_desc2, 0, buf1, area_desc2->fa_size); + size = boot_test_util_area_write_size(area_idx2, 0, area_desc2->fa_size); + rc = flash_area_write(area_desc2, 0, buf1, size); TEST_ASSERT(rc == 0); free(buf1); @@ -339,7 +379,7 @@ boot_test_util_verify_status_clear(void) rc = flash_area_read(fap, fap->fa_size - sizeof(bit), &bit, sizeof(bit)); TEST_ASSERT(rc == 0); - TEST_ASSERT(bit.bit_copy_start != BOOT_IMG_MAGIC || + TEST_ASSERT(bit.bit_copy_start != BOOT_MAGIC_SWAP_TEMP || bit.bit_copy_done != 0xff); } @@ -376,11 +416,69 @@ boot_test_util_verify_flash(const struct image_header *hdr0, int orig_slot_0, } } -TEST_CASE(boot_test_nv_ns_10) +static void +boot_test_util_verify_all(const struct boot_req *req, int expected_swap_type, + const struct image_header *hdr0, + const struct image_header *hdr1) { + const struct image_header *slot0hdr; + const struct image_header *slot1hdr; struct boot_rsp rsp; + int orig_slot_0; + int orig_slot_1; + int num_swaps; int rc; + int i; + + num_swaps = 0; + for (i = 0; i < 3; i++) { + rc = boot_go(req, &rsp); + TEST_ASSERT_FATAL(rc == 0); + + if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { + num_swaps++; + } + + if (num_swaps % 2 == 0) { + slot0hdr = hdr0; + slot1hdr = hdr1; + orig_slot_0 = 0; + orig_slot_1 = 1; + } else { + slot0hdr = hdr1; + slot1hdr = hdr0; + orig_slot_0 = 1; + orig_slot_1 = 0; + } + + TEST_ASSERT(memcmp(rsp.br_hdr, slot0hdr, sizeof *slot0hdr) == 0); + TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); + TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); + + boot_test_util_verify_flash(slot0hdr, orig_slot_0, + slot1hdr, orig_slot_1); + boot_test_util_verify_status_clear(); + + if (expected_swap_type != BOOT_SWAP_TYPE_NONE) { + switch (expected_swap_type) { + case BOOT_SWAP_TYPE_TEMP: + expected_swap_type = BOOT_SWAP_TYPE_PERM; + break; + + case BOOT_SWAP_TYPE_PERM: + expected_swap_type = BOOT_SWAP_TYPE_NONE; + break; + default: + TEST_ASSERT_FATAL(0); + break; + } + } + } +} + +TEST_CASE(boot_test_nv_ns_10) +{ struct image_header hdr = { .ih_magic = IMAGE_MAGIC, .ih_tlv_size = 4 + 32, @@ -402,15 +500,7 @@ TEST_CASE(boot_test_nv_ns_10) boot_test_util_write_image(&hdr, 0); boot_test_util_write_hash(&hdr, 0); - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); - - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr, sizeof hdr) == 0); - TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); - TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); - - boot_test_util_verify_flash(&hdr, 0, NULL, 0xff); - boot_test_util_verify_status_clear(); + boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr, NULL); } TEST_CASE(boot_test_nv_ns_01) @@ -815,8 +905,7 @@ TEST_CASE(boot_test_nv_bs_11) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); rc = boot_vect_write_test(1); - boot_test_util_copy_area(5, - BOOT_TEST_AREA_IDX_SCRATCH); + boot_test_util_copy_area(5, BOOT_TEST_AREA_IDX_SCRATCH); boot_req_set(&req); status.idx = 0; @@ -840,7 +929,6 @@ TEST_CASE(boot_test_nv_bs_11) TEST_CASE(boot_test_nv_bs_11_2areas) { struct boot_status status; - struct boot_rsp rsp; int rc; struct image_header hdr0 = { @@ -874,35 +962,25 @@ 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_vect_write_test(1); boot_test_util_swap_areas(2, 5); + rc = boot_vect_write_test(1); + TEST_ASSERT_FATAL(rc == 0); + status.idx = 1; status.elem_sz = 1; status.state = 0; rc = boot_write_status(&status); - TEST_ASSERT(rc == 0); - - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); + TEST_ASSERT_FATAL(rc == 0); - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr1, sizeof hdr1) == 0); - TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); - TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); - - boot_test_util_verify_flash(&hdr1, 1, &hdr0, 0); - boot_test_util_verify_status_clear(); + boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_TEMP, &hdr0, &hdr1); } TEST_CASE(boot_test_vb_ns_11) { - const struct flash_area *fap; - struct boot_img_trailer bit; - struct boot_rsp rsp; int rc; - int i; struct image_header hdr0 = { .ih_magic = IMAGE_MAGIC, @@ -936,49 +1014,14 @@ TEST_CASE(boot_test_vb_ns_11) boot_test_util_write_image(&hdr1, 1); boot_test_util_write_hash(&hdr1, 1); - rc = flash_area_open(FLASH_AREA_IMAGE_0, &fap); - TEST_ASSERT(rc == 0); - - memset(&bit, 0xff, sizeof(bit)); - bit.bit_copy_start = BOOT_IMG_MAGIC; - bit.bit_copy_done = 0; - bit.bit_img_ok = 1; - - rc = flash_area_write(fap, fap->fa_size - sizeof(bit), &bit, sizeof(bit)); - TEST_ASSERT(rc == 0); - rc = boot_vect_write_test(1); - TEST_ASSERT(rc == 0); - - /* First boot should use the test image. */ - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); - - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr1, sizeof hdr1) == 0); - TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); - TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); - - boot_test_util_verify_flash(&hdr1, 1, &hdr0, 0); - boot_test_util_verify_status_clear(); - - /* Ensure all subsequent boots use the main image. */ - for (i = 0; i < 10; i++) { - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); + TEST_ASSERT_FATAL(rc == 0); - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); - TEST_ASSERT(rsp.br_flash_id == boot_test_img_addrs[0].flash_id); - TEST_ASSERT(rsp.br_image_addr == boot_test_img_addrs[0].address); - - boot_test_util_verify_flash(&hdr0, 0, &hdr1, 1); - boot_test_util_verify_status_clear(); - boot_vect_write_main(); - } + boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_TEMP, &hdr0, &hdr1); } TEST_CASE(boot_test_no_hash) { - struct boot_rsp rsp; int rc; struct image_header hdr0 = { @@ -1012,20 +1055,13 @@ TEST_CASE(boot_test_no_hash) boot_test_util_write_image(&hdr1, 1); rc = boot_vect_write_test(1); - TEST_ASSERT(rc == 0); + TEST_ASSERT_FATAL(rc == 0); - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); - - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); - - boot_test_util_verify_flash(&hdr0, 0, NULL, 0xff); - boot_test_util_verify_status_clear(); + boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr0, NULL); } TEST_CASE(boot_test_no_flag_has_hash) { - struct boot_rsp rsp; int rc; struct image_header hdr0 = { @@ -1062,18 +1098,11 @@ TEST_CASE(boot_test_no_flag_has_hash) rc = boot_vect_write_test(1); TEST_ASSERT(rc == 0); - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); - - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); - - boot_test_util_verify_flash(&hdr0, 0, NULL, 0xff); - boot_test_util_verify_status_clear(); + boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr0, NULL); } TEST_CASE(boot_test_invalid_hash) { - struct boot_rsp rsp; int rc; struct image_header hdr0 = { @@ -1117,13 +1146,7 @@ TEST_CASE(boot_test_invalid_hash) rc = boot_vect_write_test(1); TEST_ASSERT(rc == 0); - rc = boot_go(&req, &rsp); - TEST_ASSERT(rc == 0); - - TEST_ASSERT(memcmp(rsp.br_hdr, &hdr0, sizeof hdr0) == 0); - - boot_test_util_verify_flash(&hdr0, 0, NULL, 0xff); - boot_test_util_verify_status_clear(); + boot_test_util_verify_all(&req, BOOT_SWAP_TYPE_NONE, &hdr0, NULL); } TEST_SUITE(boot_test_main) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/4b1a5c1d/mgmt/imgmgr/src/imgmgr_state.c ---------------------------------------------------------------------- diff --git a/mgmt/imgmgr/src/imgmgr_state.c b/mgmt/imgmgr/src/imgmgr_state.c index 3a6efdd..ce61e32 100644 --- a/mgmt/imgmgr/src/imgmgr_state.c +++ b/mgmt/imgmgr/src/imgmgr_state.c @@ -47,13 +47,27 @@ imgmgr_state_flags(int query_slot) /* Determine if this is is pending or confirmed (only applicable for * unified images and loaders. */ - rc = boot_vect_read_test(&slot); - if (rc == 0 && slot == query_slot) { - flags |= IMGMGR_STATE_F_PENDING; - } - rc = boot_vect_read_main(&slot); - if (rc == 0 && slot == query_slot) { - flags |= IMGMGR_STATE_F_CONFIRMED; + swap_type = boot_swap_type(); + switch (swap_type) { + case BOOT_SWAP_TYPE_NONE: + if (query_slot == 0) { + flags |= IMGMGR_STATE_F_CONFIRMED; + flags |= IMGMGR_STATE_F_ACTIVE; + } + break; + + case BOOT_SWAP_TYPE_TEMP: + if (query_slot == 1) { + flags |= IMGMGR_STATE_F_PENDING; + } + break; + case BOOT_SWAP_TYPE_PERM: + if (query_slot == 0) { + flags |= IMGMGR_STATE_F_ACTIVE; + } else if (query_slot == 1) { + flags |= IMGMGR_STATE_F_CONFIRMED; + } + break; } /* Slot 0 is always active. Slot 1 is also active if a split app is