mcuboot/sim/mcuboot-sys/csupport/run.c

272 lines
6.6 KiB
C

/* Run the boot image. */
#include <assert.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bootutil/bootutil.h>
#include <bootutil/image.h>
#include "flash_map/flash_map.h"
#include "../../../boot/bootutil/src/bootutil_priv.h"
#include "bootsim.h"
#ifdef MCUBOOT_SIGN_EC256
#include "../../../ext/tinycrypt/lib/include/tinycrypt/ecc_dsa.h"
#endif
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
#include <bootutil/bootutil_log.h>
extern int sim_flash_erase(uint32_t offset, uint32_t size);
extern int sim_flash_read(uint32_t offset, uint8_t *dest, uint32_t size);
extern int sim_flash_write(uint32_t offset, const uint8_t *src, uint32_t size);
static jmp_buf boot_jmpbuf;
int flash_counter;
int jumped = 0;
uint8_t c_asserts = 0;
uint8_t c_catch_asserts = 0;
int ecdsa256_sign_(const uint8_t *privkey, const uint8_t *hash,
unsigned hash_len, uint8_t *signature)
{
#ifdef MCUBOOT_SIGN_EC256
return uECC_sign(privkey, hash, hash_len, signature, uECC_secp256r1());
#else
(void)privkey;
(void)hash;
(void)hash_len;
(void)signature;
return 0;
#endif
}
uint8_t sim_flash_align = 1;
uint8_t flash_area_align(const struct flash_area *area)
{
(void)area;
return sim_flash_align;
}
struct area {
struct flash_area whole;
struct flash_area *areas;
uint32_t num_areas;
uint8_t id;
};
struct area_desc {
struct area slots[16];
uint32_t num_slots;
};
static struct area_desc *flash_areas;
void *(*mbedtls_calloc)(size_t n, size_t size);
void (*mbedtls_free)(void *ptr);
int invoke_boot_go(struct area_desc *adesc)
{
int res;
struct boot_rsp rsp;
mbedtls_calloc = calloc;
mbedtls_free = free;
flash_areas = adesc;
if (setjmp(boot_jmpbuf) == 0) {
res = boot_go(&rsp);
flash_areas = NULL;
/* printf("boot_go off: %d (0x%08x)\n", res, rsp.br_image_off); */
return res;
} else {
flash_areas = NULL;
return -0x13579;
}
}
int hal_flash_read(uint8_t flash_id, uint32_t address, void *dst,
uint32_t num_bytes)
{
(void)flash_id;
// printf("hal_flash_read: %d, 0x%08x (0x%x)\n",
// flash_id, address, num_bytes);
return sim_flash_read(address, dst, num_bytes);
}
int hal_flash_write(uint8_t flash_id, uint32_t address,
const void *src, int32_t num_bytes)
{
(void)flash_id;
// printf("hal_flash_write: 0x%08x (0x%x)\n", address, num_bytes);
// fflush(stdout);
if (--flash_counter == 0) {
jumped++;
longjmp(boot_jmpbuf, 1);
}
return sim_flash_write(address, src, num_bytes);
}
int hal_flash_erase(uint8_t flash_id, uint32_t address,
uint32_t num_bytes)
{
(void)flash_id;
// printf("hal_flash_erase: 0x%08x, (0x%x)\n", address, num_bytes);
// fflush(stdout);
if (--flash_counter == 0) {
jumped++;
longjmp(boot_jmpbuf, 1);
}
return sim_flash_erase(address, num_bytes);
}
uint8_t hal_flash_align(uint8_t flash_id)
{
(void)flash_id;
return sim_flash_align;
}
void *os_malloc(size_t size)
{
// printf("os_malloc 0x%x bytes\n", size);
return malloc(size);
}
int flash_area_id_from_image_slot(int slot)
{
return slot + 1;
}
int flash_area_open(uint8_t id, const struct flash_area **area)
{
uint32_t i;
for (i = 0; i < flash_areas->num_slots; i++) {
if (flash_areas->slots[i].id == id)
break;
}
if (i == flash_areas->num_slots) {
printf("Unsupported area\n");
abort();
}
/* Unsure if this is right, just returning the first area. */
*area = &flash_areas->slots[i].whole;
return 0;
}
void flash_area_close(const struct flash_area *area)
{
(void)area;
}
/*
* Read/write/erase. Offset is relative from beginning of flash area.
*/
int flash_area_read(const struct flash_area *area, uint32_t off, void *dst,
uint32_t len)
{
BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x",
__func__, area->fa_id, off, len);
return hal_flash_read(area->fa_id,
area->fa_off + off,
dst, len);
}
int flash_area_write(const struct flash_area *area, uint32_t off, const void *src,
uint32_t len)
{
BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
area->fa_id, off, len);
return hal_flash_write(area->fa_id,
area->fa_off + off,
src, len);
}
int flash_area_erase(const struct flash_area *area, uint32_t off, uint32_t len)
{
BOOT_LOG_DBG("%s: area=%d, off=%x, len=%x", __func__,
area->fa_id, off, len);
return hal_flash_erase(area->fa_id,
area->fa_off + off,
len);
}
int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret)
{
uint32_t i;
struct area *slot;
for (i = 0; i < flash_areas->num_slots; i++) {
if (flash_areas->slots[i].id == idx)
break;
}
if (i == flash_areas->num_slots) {
printf("Unsupported area\n");
abort();
}
slot = &flash_areas->slots[i];
if (slot->num_areas > (uint32_t)*cnt) {
printf("Too many areas in slot\n");
abort();
}
*cnt = slot->num_areas;
memcpy(ret, slot->areas, slot->num_areas * sizeof(struct flash_area));
return 0;
}
int flash_area_get_sectors(int fa_id, uint32_t *count,
struct flash_sector *sectors)
{
uint32_t i;
struct area *slot;
for (i = 0; i < flash_areas->num_slots; i++) {
if (flash_areas->slots[i].id == fa_id)
break;
}
if (i == flash_areas->num_slots) {
printf("Unsupported area\n");
abort();
}
slot = &flash_areas->slots[i];
if (slot->num_areas > *count) {
printf("Too many areas in slot\n");
abort();
}
for (i = 0; i < slot->num_areas; i++) {
sectors[i].fs_off = slot->areas[i].fa_off -
slot->whole.fa_off;
sectors[i].fs_size = slot->areas[i].fa_size;
}
*count = slot->num_areas;
return 0;
}
void sim_assert(int x, const char *assertion, const char *file, unsigned int line, const char *function)
{
if (!(x)) {
if (c_catch_asserts) {
c_asserts++;
} else {
BOOT_LOG_ERR("%s:%d: %s: Assertion `%s' failed.", file, line, function, assertion);
/* NOTE: if the assert below is triggered, the place where it was originally
* asserted is printed by the message above...
*/
assert(x);
}
}
}