/* * Read version from image header from flash area 'area_id'. * Returns -1 if area is not readable. * Returns 0 if image in slot is ok, and version string is valid. * Returns 1 if there is not a full image. * Returns 2 if slot is empty. */ int imgr_read_ver(int area_id, struct image_version *ver) { struct image_header hdr; int rc; const struct flash_area *fa; rc = flash_area_open(area_id, &fa); if (rc) { return -1; } rc = flash_area_read(fa, 0, &hdr, sizeof(hdr)); if (rc) { return -1; } memset(ver, 0xff, sizeof(*ver)); if (hdr.ih_magic == 0x96f3b83c) { memcpy(ver, &hdr.ih_ver, sizeof(*ver)); rc = 0; } else { rc = 1; } flash_area_close(fa); return rc; }
/* * Read the image trailer from a given slot. */ static int boot_vect_read_img_trailer(int slot, struct boot_img_trailer *bit) { int rc; const struct flash_area *fap; uint32_t off; rc = flash_area_open(slot, &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; }
/** * Write the test image version number from the boot vector. * * @return 0 on success; nonzero on failure. */ int boot_vect_write_test(int slot) { 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; rc = flash_area_write(fap, off, &magic, sizeof(magic)); flash_area_close(fap); return rc; }
/* * Read version and build hash from image located slot "image_slot". Note: * this is a slot index, not a flash area ID. * * @param image_slot * @param ver (optional) * @param hash (optional) * @param flags * * Returns -1 if area is not readable. * Returns 0 if image in slot is ok, and version string is valid. * Returns 1 if there is not a full image. * Returns 2 if slot is empty. XXXX not there yet */ int imgr_read_info(int image_slot, struct image_version *ver, uint8_t *hash, uint32_t *flags) { struct image_header *hdr; struct image_tlv *tlv; int rc = -1; int rc2; const struct flash_area *fa; uint8_t data[sizeof(struct image_header)]; uint32_t data_off, data_end; int area_id; area_id = flash_area_id_from_image_slot(image_slot); hdr = (struct image_header *)data; rc2 = flash_area_open(area_id, &fa); if (rc2) { return -1; } rc2 = flash_area_read(fa, 0, hdr, sizeof(*hdr)); if (rc2) { goto end; } if (ver != NULL) { memset(ver, 0xff, sizeof(*ver)); if (hdr->ih_magic == IMAGE_MAGIC) { memcpy(ver, &hdr->ih_ver, sizeof(*ver)); } else if (hdr->ih_magic == 0xffffffff) { rc = 2; goto end; } else { rc = 1; goto end; } } if(flags) { *flags = hdr->ih_flags; } /* * Build ID is in a TLV after the image. */ data_off = hdr->ih_hdr_size + hdr->ih_img_size; data_end = data_off + hdr->ih_tlv_size; if (data_end > fa->fa_size) { rc = 1; goto end; } tlv = (struct image_tlv *)data; while (data_off + sizeof(*tlv) <= data_end) { rc2 = flash_area_read(fa, data_off, tlv, sizeof(*tlv)); if (rc2) { goto end; } if (tlv->it_type == 0xff && tlv->it_len == 0xffff) { break; } if (tlv->it_type != IMAGE_TLV_SHA256 || tlv->it_len != IMGMGR_HASH_LEN) { data_off += sizeof(*tlv) + tlv->it_len; continue; } data_off += sizeof(*tlv); if (hash) { if (data_off + IMGMGR_HASH_LEN > data_end) { goto end; } rc2 = flash_area_read(fa, data_off, hash, IMGMGR_HASH_LEN); if (rc2) { goto end; } } rc = 0; goto end; } rc = 1; end: flash_area_close(fa); return rc; }