예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
0
/*
 * 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;
}
예제 #4
0
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;
}
예제 #5
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));
}
예제 #6
0
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;
}
예제 #7
0
int
imgr_my_version(struct image_version *ver)
{
    return imgr_read_info(boot_current_slot, ver, NULL, NULL);
}