Commit 82a4b1a7 authored by Ederson de Souza's avatar Ederson de Souza Committed by Andrzej Puzdrowski
Browse files

sim: Test for boot_load_image_from_flash_to_sram API



Directly load an image to RAM and see if that works.

Signed-off-by: default avatarEderson de Souza <ederson.desouza@intel.com>
parent c4a7b250
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -289,6 +289,63 @@ int invoke_boot_go(struct sim_context *ctx, struct area_desc *adesc,
    }
}

int invoke_boot_load_image_from_flash_to_sram(struct sim_context *ctx, struct area_desc *adesc)
{
#ifdef MCUBOOT_RAM_LOAD
    int res;
    struct boot_loader_state *state;
    const struct flash_area *fa_p;
    struct image_header hdr;

#if defined(MCUBOOT_SIGN_RSA) || \
    (defined(MCUBOOT_SIGN_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
    (defined(MCUBOOT_ENCRYPT_EC256) && defined(MCUBOOT_USE_MBED_TLS)) ||\
    (defined(MCUBOOT_ENCRYPT_X25519) && defined(MCUBOOT_USE_MBED_TLS))
    mbedtls_platform_set_calloc_free(calloc, free);
#endif

    state = malloc(sizeof(struct boot_loader_state));

    sim_set_flash_areas(adesc);
    sim_set_context(ctx);
    boot_state_clear(state);

    res = flash_area_open(FLASH_AREA_IMAGE_PRIMARY(0), &fa_p);
    if (res != 0) {
        printf("Failed to open primary image area: %d\n", res);
        sim_reset_flash_areas();
        sim_reset_context();
        free(state);
        return res;
    }

    res = boot_image_load_header(fa_p, &hdr);
    if (res != 0) {
        printf("Failed to load image header: %d\n", res);
        flash_area_close(fa_p);
        sim_reset_flash_areas();
        sim_reset_context();
        free(state);
        return res;
    }

    res = boot_load_image_from_flash_to_sram(state, &hdr, fa_p);
    if (res != 0) {
        printf("Failed to load image from flash to SRAM: %d\n", res);
    }

    flash_area_close(fa_p);
    sim_reset_flash_areas();
    sim_reset_context();
    free(state);
    return res;
#else
    (void)ctx;
    (void)adesc;
    return 0;
#endif /* MCUBOOT_RAM_LOAD */
}

void *os_malloc(size_t size)
{
    // printf("os_malloc 0x%x bytes\n", size);
+25 −0
Original line number Diff line number Diff line
@@ -115,6 +115,28 @@ pub fn boot_go(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc,
    }
}

pub fn boot_load_image_from_flash_to_sram(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc) -> bool {
    init_crypto();

    for (&dev_id, flash) in multiflash.iter_mut() {
        api::set_flash(dev_id, flash);
    }
    let mut sim_ctx = api::CSimContext {
        flash_counter: 0,
        c_catch_asserts: 0,
        .. Default::default()
    };
    let result: i32 = unsafe {
        let adesc = areadesc.get_c();
        raw::invoke_boot_load_image_from_flash_to_sram(&mut sim_ctx as *mut _,
                            adesc.borrow() as *const _) as i32
    };
    for &dev_id in multiflash.keys() {
        api::clear_flash(dev_id);
    }
    result == 0
}

pub fn boot_trailer_sz(align: u32) -> u32 {
    unsafe { raw::boot_trailer_sz(align) }
}
@@ -181,6 +203,9 @@ mod raw {
        pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc,
            rsp: *mut BootRsp, image_index: libc::c_int) -> libc::c_int;

        pub fn invoke_boot_load_image_from_flash_to_sram(sim_ctx: *mut CSimContext,
            areadesc: *const CAreaDesc) -> libc::c_int;

        pub fn boot_trailer_sz(min_write_sz: u32) -> u32;
        pub fn boot_status_sz(min_write_sz: u32) -> u32;

+34 −0
Original line number Diff line number Diff line
@@ -1413,6 +1413,40 @@ impl Images {
        false
    }

    pub fn run_ram_load_from_flash(&self) -> bool {
        if !Caps::RamLoad.present() {
            return false;
        }

        // Clone the flash so we can tell if unchanged.
        let mut flash = self.flash.clone();

        // Create RAM config.
        let ram = RamBlock::new(self.ram.total - RAM_LOAD_ADDR, RAM_LOAD_ADDR);

        // Run boot_load_image_from_flash_to_sram directly
        let result = ram.invoke(|| c::boot_load_image_from_flash_to_sram(&mut flash, &self.areadesc));

        if !result {
            error!("RAM load from flash failed!");
            return true;
        }

        // Compare loaded image with the first image in the flash.
        let image = &self.images[0].primaries;
        let ram_image = ram.borrow();
        let src_sz = image.plain.len();
        let src_image = &image.plain[0..src_sz];
        let ram_image = &ram_image[0..src_sz];

        if ram_image != src_image {
            error!("Image not loaded correctly");
            return true;
        }

        false
    }

    /// Adds a new flash area that fails statistically
    fn mark_bad_status_with_rate(&self, flash: &mut SimMultiFlash, slot: usize,
                                 rate: f32) {
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ sim_test!(downgrade_prevention, make_image(&REV_DEPS, true), run_nodowngrade());
sim_test!(direct_xip_first, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_direct_xip());
sim_test!(ram_load_first, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_ram_load());
sim_test!(ram_load_split, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_split_ram_load());
sim_test!(ram_load_from_flash, make_no_upgrade_image(&NO_DEPS, ImageManipulation::None), run_ram_load_from_flash());
sim_test!(hw_prot_failed_security_cnt_check, make_image_with_security_counter(Some(0)), run_hw_rollback_prot());
sim_test!(hw_prot_missing_security_cnt, make_image_with_security_counter(None), run_hw_rollback_prot());
sim_test!(ram_load_out_of_bounds, make_no_upgrade_image(&NO_DEPS, ImageManipulation::WrongOffset), run_ram_load_boot_with_result(false));