int imgr_boot_read(struct nmgr_jbuf *njb) { int rc; struct json_encoder *enc; struct image_version ver; struct json_value jv; uint8_t hash[IMGMGR_HASH_LEN]; enc = &njb->njb_enc; json_encode_object_start(enc); rc = boot_vect_read_test(&ver); if (!rc) { imgr_ver_jsonstr(enc, "test", &ver); } rc = boot_vect_read_main(&ver); if (!rc) { imgr_ver_jsonstr(enc, "main", &ver); } rc = imgr_read_info(bsp_imgr_current_slot(), &ver, hash); if (!rc) { imgr_ver_jsonstr(enc, "active", &ver); } JSON_VALUE_INT(&jv, NMGR_ERR_EOK); json_encode_object_entry(enc, "rc", &jv); json_encode_object_finish(enc); return 0; }
/* * Finds image given hash of the image. Returns the slot number image is in, * or -1 if not found. */ int imgr_find_by_hash(uint8_t *find, struct image_version *ver) { int i; uint8_t hash[IMGMGR_HASH_LEN]; for (i = 0; i < 2; i++) { if (imgr_read_info(i, ver, hash, NULL) != 0) { continue; } if (!memcmp(hash, find, IMGMGR_HASH_LEN)) { return i; } } return -1; }
/* * Finds image given version number. Returns the slot number image is in, * or -1 if not found. */ int imgr_find_by_ver(struct image_version *find, uint8_t *hash) { int i; struct image_version ver; for (i = 0; i < 2; i++) { if (imgr_read_info(i, &ver, hash, NULL) != 0) { continue; } if (!memcmp(find, &ver, sizeof(ver))) { return i; } } return -1; }
int imgmgr_state_test_slot(int slot) { uint32_t image_flags; uint8_t state_flags; int split_app_active; int rc; state_flags = imgmgr_state_flags(slot); split_app_active = split_app_active_get(); /* Unconfirmed slots are always testable. A confirmed slot can only be * tested if it is a loader in a split image setup. */ if (state_flags & IMGMGR_STATE_F_CONFIRMED && (slot != 0 || !split_app_active)) { return MGMT_ERR_EBADSTATE; } rc = imgr_read_info(slot, NULL, NULL, &image_flags); if (rc != 0) { return MGMT_ERR_EUNKNOWN; } if (!(image_flags & IMAGE_F_NON_BOOTABLE)) { /* Unified image or loader. */ if (!split_app_active) { /* No change in split status. */ rc = boot_set_pending(); if (rc != 0) { return MGMT_ERR_EUNKNOWN; } } else { /* Currently loader + app; testing loader-only. */ rc = split_write_split(SPLIT_MODE_TEST_LOADER); } } else { /* Testing split app. */ rc = split_write_split(SPLIT_MODE_TEST_APP); if (rc != 0) { return MGMT_ERR_EUNKNOWN; } } return 0; }
void coredump_dump(void *regs, int regs_sz) { struct coredump_header hdr; struct coredump_tlv tlv; const struct flash_area *fa; struct image_version ver; const struct bsp_mem_dump *mem, *cur; int area_cnt, i; uint8_t hash[IMGMGR_HASH_LEN]; uint32_t off; uint32_t area_off, area_end; if (coredump_disabled) { return; } if (flash_area_open(FLASH_AREA_CORE, &fa)) { return; } if (flash_area_read(fa, 0, &hdr, sizeof(hdr))) { return; } if (hdr.ch_magic == COREDUMP_MAGIC) { /* * Don't override corefile. */ return; } if (flash_area_erase(fa, 0, fa->fa_size)) { return; } /* * First put in data, followed by the header. */ tlv.ct_type = COREDUMP_TLV_REGS; tlv._pad = 0; tlv.ct_len = regs_sz; tlv.ct_off = 0; off = sizeof(hdr); dump_core_tlv(fa, &off, &tlv, regs); if (imgr_read_info(bsp_imgr_current_slot(), &ver, hash) == 0) { tlv.ct_type = COREDUMP_TLV_IMAGE; tlv.ct_len = IMGMGR_HASH_LEN; dump_core_tlv(fa, &off, &tlv, hash); } mem = bsp_core_dump(&area_cnt); for (i = 0; i < area_cnt; i++) { cur = &mem[i]; area_off = (uint32_t)cur->bmd_start; area_end = area_off + cur->bmd_size; while (area_off < area_end) { tlv.ct_type = COREDUMP_TLV_MEM; if (cur->bmd_size > USHRT_MAX) { tlv.ct_len = SHRT_MAX + 1; } else { tlv.ct_len = cur->bmd_size; } tlv.ct_off = area_off; dump_core_tlv(fa, &off, &tlv, (void *)area_off); area_off += tlv.ct_len; } } hdr.ch_magic = COREDUMP_MAGIC; hdr.ch_size = off; flash_area_write(fa, 0, &hdr, sizeof(hdr)); }
int imgmgr_state_read(struct mgmt_cbuf *cb) { int i; int rc; uint32_t flags; struct image_version ver; uint8_t hash[IMGMGR_HASH_LEN]; /* SHA256 hash */ char vers_str[IMGMGR_NMGR_MAX_VER]; int any_non_bootable; int split_status; uint8_t state_flags; CborError g_err = CborNoError; CborEncoder *penc = &cb->encoder; CborEncoder rsp, images, image; any_non_bootable = 0; g_err |= cbor_encoder_create_map(penc, &rsp, CborIndefiniteLength); g_err |= cbor_encode_text_stringz(&rsp, "images"); g_err |= cbor_encoder_create_array(&rsp, &images, CborIndefiniteLength); for (i = 0; i < 2; i++) { rc = imgr_read_info(i, &ver, hash, &flags); if (rc != 0) { continue; } if (flags & IMAGE_F_NON_BOOTABLE) { any_non_bootable = 1; } state_flags = imgmgr_state_flags(i); g_err |= cbor_encoder_create_map(&images, &image, CborIndefiniteLength); g_err |= cbor_encode_text_stringz(&image, "slot"); g_err |= cbor_encode_int(&image, i); g_err |= cbor_encode_text_stringz(&image, "version"); imgr_ver_str(&ver, vers_str); g_err |= cbor_encode_text_stringz(&image, vers_str); g_err |= cbor_encode_text_stringz(&image, "hash"); g_err |= cbor_encode_byte_string(&image, hash, IMGMGR_HASH_LEN); g_err |= cbor_encode_text_stringz(&image, "bootable"); g_err |= cbor_encode_boolean(&image, !(flags & IMAGE_F_NON_BOOTABLE)); g_err |= cbor_encode_text_stringz(&image, "pending"); g_err |= cbor_encode_boolean(&image, state_flags & IMGMGR_STATE_F_PENDING); g_err |= cbor_encode_text_stringz(&image, "confirmed"); g_err |= cbor_encode_boolean(&image, state_flags & IMGMGR_STATE_F_CONFIRMED); g_err |= cbor_encode_text_stringz(&image, "active"); g_err |= cbor_encode_boolean(&image, state_flags & IMGMGR_STATE_F_ACTIVE); g_err |= cbor_encoder_close_container(&images, &image); } g_err |= cbor_encoder_close_container(&rsp, &images); if (any_non_bootable) { split_status = split_check_status(); } else { split_status = SPLIT_STATUS_INVALID; } g_err |= cbor_encode_text_stringz(&rsp, "splitStatus"); g_err |= cbor_encode_int(&rsp, split_status); g_err |= cbor_encoder_close_container(penc, &rsp); if (g_err) { return MGMT_ERR_ENOMEM; } return 0; }
int imgr_my_version(struct image_version *ver) { return imgr_read_info(boot_current_slot, ver, NULL, NULL); }