Infineon: Switch to 1.9.0 code base, add xmc7000 family support, refactor memory layer
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 7794b5a..bb623e5 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <string.h>
#include "bootutil/bootutil.h"
+#include "bootutil/bootutil_public.h"
#include "bootutil/image.h"
#include "bootutil_priv.h"
#include "swap_priv.h"
@@ -50,7 +51,7 @@
#include "bootutil/enc_key.h"
#endif
-#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
+#if (!defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)) || defined(MCUBOOT_MULTI_MEMORY_LOAD)
#include <os/os_malloc.h>
#endif
@@ -63,25 +64,9 @@
#if (BOOT_IMAGE_NUMBER > 1)
#define IMAGES_ITER(x) for ((x) = 0; (x) < BOOT_IMAGE_NUMBER; ++(x))
#else
-#define IMAGES_ITER(x)
+#define IMAGES_ITER(x) for (int iter = 0; iter < 1; ++iter)
#endif
-#if defined(MCUBOOT_DIRECT_XIP) || defined(MCUBOOT_RAM_LOAD)
-struct slot_usage_t {
- /* Index of the slot chosen to be loaded */
- uint32_t active_slot;
- bool slot_available[BOOT_NUM_SLOTS];
-#if defined(MCUBOOT_RAM_LOAD)
- /* Image destination and size for the active slot */
- uint32_t img_dst;
- uint32_t img_sz;
-#elif defined(MCUBOOT_DIRECT_XIP_REVERT)
- /* Swap status for the active slot */
- struct boot_swap_state swap_state;
-#endif
-};
-#endif /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
-
/*
* This macro allows some control on the allocation of local variables.
* When running natively on a target, we don't want to allocated huge
@@ -95,6 +80,14 @@
#define TARGET_STATIC
#endif
+#if BOOT_MAX_ALIGN > 1024
+#define BUF_SZ BOOT_MAX_ALIGN
+#else
+#define BUF_SZ 1024U
+#endif
+
+static fih_int FIH_SWAP_TYPE_NONE = FIH_INT_INIT(0x3A5C742E);
+
static int
boot_read_image_headers(struct boot_loader_state *state, bool require_all,
struct boot_status *bs)
@@ -175,26 +168,36 @@
* Fills rsp to indicate how booting should occur.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
- * Only used in MCUBOOT_DIRECT_XIP and MCUBOOT_RAM_LOAD
* @param rsp boot_rsp struct to fill.
*/
static void
-fill_rsp(struct boot_loader_state *state, void *slot_usage,
- struct boot_rsp *rsp)
+fill_rsp(struct boot_loader_state *state, struct boot_rsp *rsp)
{
- uint32_t active_slot;
+ uint32_t active_slot = BOOT_PRIMARY_SLOT;
#if (BOOT_IMAGE_NUMBER > 1)
- /* Always boot from Image 0. */
+ /* Always boot from the first enabled image. */
BOOT_CURR_IMG(state) = 0;
+ IMAGES_ITER(BOOT_CURR_IMG(state)) {
+ if (!state->img_mask[BOOT_CURR_IMG(state)]) {
+ break;
+ }
+ }
+ /* At least one image must be active, otherwise skip the execution */
+ if(BOOT_CURR_IMG(state) >= BOOT_IMAGE_NUMBER)
+ {
+ return;
+ }
#endif
+#if defined(MCUBOOT_MULTI_MEMORY_LOAD)
+ if ((state->slot_usage[BOOT_CURR_IMG(state)].active_slot != BOOT_PRIMARY_SLOT) &&
+ (state->slot_usage[BOOT_CURR_IMG(state)].active_slot != NO_ACTIVE_SLOT))
+#endif
#if defined(MCUBOOT_DIRECT_XIP) || defined(MCUBOOT_RAM_LOAD)
- active_slot = ((struct slot_usage_t *)slot_usage)[BOOT_CURR_IMG(state)].active_slot;
-#else
- (void) (slot_usage);
- active_slot = BOOT_PRIMARY_SLOT;
+ {
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ }
#endif
rsp->br_flash_dev_id = flash_area_get_device_id(BOOT_IMG_AREA(state, active_slot));
@@ -213,6 +216,11 @@
uint32_t slot;
IMAGES_ITER(BOOT_CURR_IMG(state)) {
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
#if MCUBOOT_SWAP_USING_SCRATCH
flash_area_close(BOOT_SCRATCH_AREA(state));
#endif
@@ -227,7 +235,7 @@
* Compute the total size of the given image. Includes the size of
* the TLVs.
*/
-#if !defined(MCUBOOT_OVERWRITE_ONLY) || defined(MCUBOOT_OVERWRITE_ONLY_FAST)
+#if !defined(MCUBOOT_OVERWRITE_ONLY) || defined(MCUBOOT_OVERWRITE_ONLY_FAST) || defined(MCUBOOT_RAM_LOAD)
static int
boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size)
{
@@ -271,6 +279,10 @@
rc = BOOT_EBADIMAGE;
goto done;
}
+ else
+ {
+ /* acc. to MISRA R.15.7 */
+ }
if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
rc = BOOT_EBADIMAGE;
@@ -284,9 +296,8 @@
flash_area_close(fap);
return rc;
}
-#endif /* !MCUBOOT_OVERWRITE_ONLY */
-#if !defined(MCUBOOT_RAM_LOAD)
+#endif
static uint32_t
boot_write_sz(struct boot_loader_state *state)
@@ -407,8 +418,8 @@
{
#ifdef MCUBOOT_ENC_IMAGES
(void)memset(&bs->enckey, BOOT_UNINITIALIZED_KEY_FILL,
- BOOT_NUM_SLOTS * BOOT_ENC_KEY_SIZE);
-#if MCUBOOT_SWAP_SAVE_ENCTLV
+ BOOT_NUM_SLOTS * BOOT_ENC_KEY_ALIGN_SIZE);
+#ifdef MCUBOOT_SWAP_SAVE_ENCTLV
(void)memset(&bs->enctlv, BOOT_UNINITIALIZED_TLV_FILL,
BOOT_NUM_SLOTS * BOOT_ENC_TLV_ALIGN_SIZE);
#endif
@@ -447,9 +458,9 @@
const struct flash_area *fap = NULL;
uint32_t off;
int area_id;
- int rc;
+ int rc = 0;
uint8_t buf[BOOT_MAX_ALIGN];
- size_t align;
+ uint32_t align;
uint8_t erased_val;
/* NOTE: The first sector copied (that is the last sector on slot) contains
@@ -498,12 +509,12 @@
done:
flash_area_close(fap);
+
return rc;
}
-#endif /* !MCUBOOT_RAM_LOAD */
-
#endif /* MCUBOOT_SWAP_USING_STATUS */
+
#endif /* !MCUBOOT_DIRECT_XIP */
/*
@@ -515,7 +526,6 @@
{
TARGET_STATIC uint8_t tmpbuf[BOOT_TMPBUF_SZ];
uint8_t image_index;
- int rc;
fih_int fih_rc = FIH_FAILURE;
#if (BOOT_IMAGE_NUMBER == 1)
@@ -523,15 +533,14 @@
#endif
(void)bs;
- (void)rc;
image_index = BOOT_CURR_IMG(state);
/* In the case of ram loading the image has already been decrypted as it is
* decrypted when copied in ram */
-#if defined(MCUBOOT_ENC_IMAGES) && !defined(MCUBOOT_RAM_LOAD)
- if (MUST_DECRYPT(fap, image_index, hdr)) {
- rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
+#if defined(MCUBOOT_ENC_IMAGES)
+ if (MUST_DECRYPT(fap, image_index, hdr) && !IS_RAM_BOOTABLE(hdr)) {
+ int rc = flash_area_id_to_multi_image_slot(image_index, fap->fa_id);
if (rc < 0) {
FIH_RET(fih_rc);
}
@@ -555,7 +564,6 @@
FIH_RET(fih_rc);
}
-#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
static fih_int
split_image_check(struct image_header *app_hdr,
const struct flash_area *app_fap,
@@ -575,7 +583,7 @@
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, loader_hdr, loader_fap,
tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, loader_hash);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
FIH_RET(fih_rc);
}
@@ -585,7 +593,6 @@
out:
FIH_RET(fih_rc);
}
-#endif /* !MCUBOOT_DIRECT_XIP && !MCUBOOT_RAM_LOAD */
/*
* Check that this is a valid header. Valid means that the magic is
@@ -711,14 +718,13 @@
* does not match the slot address.
*/
static bool
-boot_rom_address_check(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_rom_address_check(struct boot_loader_state *state)
{
uint32_t active_slot;
const struct image_header *hdr;
uint32_t f_off;
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
hdr = boot_img_hdr(state, active_slot);
f_off = boot_img_slot_off(state, active_slot);
@@ -764,6 +770,7 @@
BOOT_LOG_DBG("> boot_validate_slot: fa_id = %u", (unsigned)fap->fa_id);
hdr = boot_img_hdr(state, slot);
+
if (boot_check_header_erased(state, slot) == 0 ||
(hdr->ih_flags & IMAGE_F_NON_BOOTABLE)) {
@@ -787,7 +794,7 @@
BOOT_LOG_DBG(" * No bootable image in slot(%d); continue booting from the primary slot.", slot);
/* No bootable image in slot; continue booting from the primary slot. */
- fih_rc = fih_int_encode(1);
+ fih_rc = FIH_SWAP_TYPE_NONE;
goto out;
}
@@ -803,18 +810,18 @@
/* Image in the secondary slot does not satisfy version requirement.
* Erase the image and continue booting from the primary slot.
*/
- fih_rc = fih_int_encode(1);
+ fih_rc = FIH_SWAP_TYPE_NONE;
goto out;
}
}
#endif
BOOT_HOOK_CALL_FIH(boot_image_check_hook, fih_int_encode(BOOT_HOOK_REGULAR),
fih_rc, BOOT_CURR_IMG(state), slot);
- if (fih_eq(fih_rc, fih_int_encode(BOOT_HOOK_REGULAR)))
+ if (FIH_TRUE == fih_eq(fih_rc, fih_int_encode(BOOT_HOOK_REGULAR)))
{
FIH_CALL(boot_image_check, fih_rc, state, hdr, fap, bs);
}
- if (!boot_is_header_valid(hdr, fap) || fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (!boot_is_header_valid(hdr, fap) || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
if ((slot != BOOT_PRIMARY_SLOT) || ARE_SLOTS_EQUIVALENT()) {
BOOT_LOG_DBG(" * Image in the secondary slot is invalid. Erase the image");
flash_area_erase(fap, 0, flash_area_get_size(fap));
@@ -826,15 +833,48 @@
BOOT_LOG_ERR("Image in the %s slot is not valid!",
(slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
#endif
- fih_rc = fih_int_encode(1);
+ fih_rc = FIH_SWAP_TYPE_NONE;
goto out;
}
- /* Image in the secondary slot is valid. */
+#if MCUBOOT_IMAGE_NUMBER > 1 && !defined(MCUBOOT_ENC_IMAGES) && defined(MCUBOOT_VERIFY_IMG_ADDRESS)
+ /* Verify that the image in the secondary slot has a reset address
+ * located in the primary slot. This is done to avoid users incorrectly
+ * overwriting an application written to the incorrect slot.
+ * This feature is only supported by ARM platforms.
+ */
+ if (area_id == FLASH_AREA_IMAGE_SECONDARY(BOOT_CURR_IMG(state))) {
+ const struct flash_area *pri_fa = BOOT_IMG_AREA(state, BOOT_PRIMARY_SLOT);
+ struct image_header *secondary_hdr = boot_img_hdr(state, slot);
+ uint32_t reset_value = 0;
+ uint32_t reset_addr = secondary_hdr->ih_hdr_size + sizeof(reset_value);
+
+ rc = flash_area_read(fap, reset_addr, &reset_value, sizeof(reset_value));
+ if (rc != 0) {
+ fih_rc = fih_int_encode(1);
+ goto out;
+ }
+
+ if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) {
+ BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot");
+ BOOT_LOG_ERR("Erasing image from secondary slot");
+
+ /* The vector table in the image located in the secondary
+ * slot does not target the primary slot. This might
+ * indicate that the image was loaded to the wrong slot.
+ *
+ * Erase the image and continue booting from the primary slot.
+ */
+ flash_area_erase(fap, 0, fap->fa_size);
+ fih_rc = fih_int_encode(1);
+ goto out;
+ }
+ }
+#endif
out:
flash_area_close(fap);
- BOOT_LOG_DBG("< boot_validate_slot = %d", fih_int_decode(fih_rc));
+ BOOT_LOG_DBG("< boot_validate_slot: fa_id = %u", (unsigned)fap->fa_id);
FIH_RET(fih_rc);
}
@@ -857,12 +897,13 @@
struct image_header *hdr)
{
const struct flash_area *fap = NULL;
- uint32_t img_security_cnt;
+ fih_int fih_rc = FIH_FAILURE;
+ fih_uint img_security_cnt = FIH_UINT_ZERO;
void * custom_data = NULL;
int rc;
-#ifdef CYW20829
+#if defined CYW20829
uint8_t buff[REPROV_PACK_SIZE];
-#endif /* CYW20829 */
+#endif /* defined CYW20829 */
rc = flash_area_open(flash_area_id_from_multi_image_slot(image_index, slot),
&fap);
@@ -871,26 +912,30 @@
goto done;
}
- rc = bootutil_get_img_security_cnt(hdr, fap, &img_security_cnt);
- if (rc != 0) {
+ rc = -1;
+ FIH_CALL(bootutil_get_img_security_cnt, fih_rc, hdr, fap, &img_security_cnt);
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
goto done;
}
+ else
+ {
+ fih_rc = FIH_FAILURE;
+ }
-#ifdef CYW20829
+#if defined CYW20829
rc = bootutil_get_img_reprov_packet(hdr, fap, buff);
if (rc == 0) {
custom_data = (void *)buff;
}
-#endif /* CYW20829 */
- rc = boot_nv_security_counter_update(image_index, img_security_cnt, custom_data);
+#endif /* defined CYW20829 */
+ rc = boot_nv_security_counter_update(image_index, img_security_cnt, custom_data);
done:
flash_area_close(fap);
return rc;
}
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
-#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
/**
* Determines which swap operation to perform, if any. If it is determined
* that a swap operation is required, the image in the secondary slot is checked
@@ -912,8 +957,8 @@
* Ensure image is valid.
*/
FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_SECONDARY_SLOT, bs);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
- if (fih_eq(fih_rc, fih_int_encode(1))) {
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
+ if (FIH_TRUE == fih_eq(fih_rc, FIH_SWAP_TYPE_NONE)) {
swap_type = BOOT_SWAP_TYPE_NONE;
} else {
swap_type = BOOT_SWAP_TYPE_FAIL;
@@ -923,7 +968,6 @@
return swap_type;
}
-#endif
/**
* Erases a region of flash.
@@ -941,7 +985,6 @@
return flash_area_erase(fap, off, sz);
}
-#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
/**
* Copies the contents of one flash region to another. You must erase the
* destination region prior to calling this function.
@@ -1031,35 +1074,41 @@
}
#endif
if (IS_ENCRYPTED(hdr)) {
- blk_sz = chunk_sz;
- idx = 0;
- if (off + bytes_copied < hdr->ih_hdr_size) {
+ uint32_t abs_off = off + bytes_copied;
+ if (abs_off < hdr->ih_hdr_size) {
/* do not decrypt header */
- blk_off = 0;
- if(chunk_sz > hdr->ih_hdr_size) {
- blk_sz = chunk_sz - hdr->ih_hdr_size;
- idx = hdr->ih_hdr_size - (off + bytes_copied);
+ if (abs_off + chunk_sz > hdr->ih_hdr_size) {
+ /* The lower part of the chunk contains header data */
+ blk_off = 0;
+ blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off);
+ idx = hdr->ih_hdr_size - abs_off;
} else {
- /* still in header-area, no need to decrypt */
- blk_sz = 0;
+ /* The chunk contains exclusively header data */
+ blk_sz = 0; /* nothing to decrypt */
}
} else {
- blk_off = ((off + bytes_copied) - hdr->ih_hdr_size) & 0xf;
+ idx = 0;
+ blk_sz = chunk_sz;
+ blk_off = (abs_off - hdr->ih_hdr_size) & 0xf;
}
- tlv_off = BOOT_TLV_OFF(hdr);
- if (off + bytes_copied + chunk_sz > tlv_off) {
- /* do not decrypt TLVs */
- if (off + bytes_copied >= tlv_off) {
- blk_sz = 0;
- } else {
- blk_sz = tlv_off - (off + bytes_copied);
+
+ if (blk_sz > 0)
+ {
+ tlv_off = BOOT_TLV_OFF(hdr);
+ if (abs_off + chunk_sz > tlv_off) {
+ /* do not decrypt TLVs */
+ if (abs_off >= tlv_off) {
+ blk_sz = 0;
+ } else {
+ blk_sz = tlv_off - abs_off;
+ }
}
- }
- rc = boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
- (off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
- blk_off, &buf[idx]);
- if (rc != 0) {
- return rc;
+ rc = boot_encrypt(BOOT_CURR_ENC(state), image_index, fap_src,
+ (abs_off + idx) - hdr->ih_hdr_size, blk_sz,
+ blk_off, &buf[idx]);
+ if (rc != 0) {
+ return rc;
+ }
}
}
}
@@ -1297,7 +1346,7 @@
}
} else {
(void)memset(bs->enckey[0], BOOT_UNINITIALIZED_KEY_FILL,
- BOOT_ENC_KEY_SIZE);
+ BOOT_ENC_KEY_ALIGN_SIZE);
}
#endif
@@ -1322,7 +1371,7 @@
}
} else {
(void)memset(bs->enckey[1], BOOT_UNINITIALIZED_KEY_FILL,
- BOOT_ENC_KEY_SIZE);
+ BOOT_ENC_KEY_ALIGN_SIZE);
}
#endif
@@ -1381,8 +1430,7 @@
* @return 0 on success; nonzero on failure.
*/
static int
-boot_verify_slot_dependency(struct boot_loader_state *state,
- struct image_dependency *dep)
+boot_verify_slot_dependency_flash(struct boot_loader_state *state, struct image_dependency *dep)
{
struct image_version *dep_version;
size_t dep_slot;
@@ -1432,9 +1480,9 @@
* @return 0 on success; nonzero on failure.
*/
static int
-boot_verify_slot_dependencies(struct boot_loader_state *state, uint32_t slot)
+boot_verify_slot_dependencies_flash(struct boot_loader_state *state, uint32_t slot)
{
- const struct flash_area *fap;
+ const struct flash_area *fap = NULL;
struct image_tlv_iter it;
struct image_dependency dep;
uint32_t off;
@@ -1463,6 +1511,10 @@
rc = 0;
break;
}
+ else
+ {
+ /* acc. to MISRA R.15.7 */
+ }
if (len != sizeof(dep)) {
rc = BOOT_EBADIMAGE;
@@ -1481,7 +1533,7 @@
}
/* Verify dependency and modify the swap type if not satisfied. */
- rc = boot_verify_slot_dependency(state, &dep);
+ rc = boot_verify_slot_dependency_flash(state, &dep);
if (rc != 0) {
/* Dependency not satisfied. */
goto done;
@@ -1498,13 +1550,17 @@
* TLV area are all satisfied and update the related swap type if necessary.
*/
static int
-boot_verify_dependencies(struct boot_loader_state *state)
+boot_verify_dependencies_flash(struct boot_loader_state *state)
{
int rc = -1;
uint8_t slot;
BOOT_CURR_IMG(state) = 0;
while (BOOT_CURR_IMG(state) < BOOT_IMAGE_NUMBER) {
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ BOOT_CURR_IMG(state)++;
+ continue;
+ }
if (BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_NONE &&
BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_FAIL) {
slot = BOOT_SECONDARY_SLOT;
@@ -1512,7 +1568,7 @@
slot = BOOT_PRIMARY_SLOT;
}
- rc = boot_verify_slot_dependencies(state, slot);
+ rc = boot_verify_slot_dependencies_flash(state, slot);
if (rc == 0) {
/* All dependencies've been satisfied, continue with next image. */
BOOT_CURR_IMG(state)++;
@@ -1565,7 +1621,7 @@
fih_int fih_rc = FIH_FAILURE;
rc = boot_check_header_erased(state, BOOT_PRIMARY_SLOT);
FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, bs);
- if (rc == 0 || fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (rc == 0 || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
/* Initialize swap status partition for primary slot, because
* in swap mode it is needed to properly complete copying the image
* to the primary slot.
@@ -1802,6 +1858,45 @@
boot_status_reset(bs);
#ifndef MCUBOOT_OVERWRITE_ONLY
+#ifdef MCUBOOT_SWAP_USING_STATUS
+
+ const struct flash_area *fap;
+ uint32_t img_size = 0;
+
+ /* Check here if image firmware + tlvs in slot do not
+ * overlap with last sector of slot. Last sector of slot
+ * contains trailer of the image which needs to be
+ * manupulated independently of other image parts.
+ * If firmware overlaps with trailer sector it does not
+ * make sense to move further since any attemps to perform
+ * swap upgrade would lead to failure or unexpected behaviour
+ */
+
+ for (uint32_t i = 0; i < BOOT_NUM_SLOTS; i++) {
+
+ rc = boot_read_image_size(state, i, &img_size);
+
+ if (rc == 0) {
+ fap = BOOT_IMG(state, i).area;
+ if (fap != NULL) {
+
+ uint32_t trailer_sector_off = (BOOT_WRITE_SZ(state)) * boot_img_num_sectors(state, i) - BOOT_WRITE_SZ(state);
+
+ BOOT_LOG_DBG("Slot %u firmware + tlvs size = %u, slot size = %u, write_size = %u, write_size * sect_num - write_size = %u",
+ i , img_size, fap->fa_size, BOOT_WRITE_SZ(state), trailer_sector_off);
+
+ if (img_size > trailer_sector_off) {
+ BOOT_LOG_ERR("Firmware + tlvs in slot %u overlaps with last sector, which contains trailer, erasing this image", i);
+ rc = flash_area_erase(fap, 0, flash_area_get_size(fap));
+ }
+ else {
+ /* image firmware + tlvs do not overlap with last sector of slot, continue */
+ }
+ }
+ }
+ }
+#endif /* MCUBOOT_SWAP_USING_STATUS */
+
rc = swap_read_status(state, bs);
if (rc != 0) {
BOOT_LOG_WRN("Failed reading boot status; Image=%u",
@@ -1873,7 +1968,7 @@
} else {
FIH_CALL(boot_validate_slot, fih_rc,
state, BOOT_SECONDARY_SLOT, bs);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
BOOT_SWAP_TYPE(state) = BOOT_SWAP_TYPE_FAIL;
} else {
BOOT_SWAP_TYPE(state) = bs->swap_type;
@@ -1896,13 +1991,13 @@
FIH_CALL(boot_validate_slot, fih_rc,
state, BOOT_PRIMARY_SLOT, bs);
- if (rc == 0 || fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (rc == 0 || fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
rc = (boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_magic == IMAGE_MAGIC) ? 1: 0;
FIH_CALL(boot_validate_slot, fih_rc,
state, BOOT_SECONDARY_SLOT, bs);
- if (rc == 1 && fih_eq(fih_rc, FIH_SUCCESS)) {
+ if (rc == 1 && FIH_TRUE == fih_eq(fih_rc, FIH_SUCCESS)) {
/* Set swap type to REVERT to overwrite the primary
* slot with the image contained in secondary slot
* and to trigger the explicit setting of the
@@ -1929,7 +2024,7 @@
* @return 0 on success; nonzero on failure.
*/
static int
-boot_update_hw_rollback_protection(struct boot_loader_state *state)
+boot_update_hw_rollback_protection_flash(struct boot_loader_state *state)
{
#ifdef MCUBOOT_HW_ROLLBACK_PROT
int rc;
@@ -1966,10 +2061,10 @@
}
fih_int
-context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
+context_boot_go_flash(struct boot_loader_state *state, struct boot_rsp *rsp)
{
size_t slot;
- struct boot_status bs;
+ struct boot_status bs = {0};
int rc = -1;
fih_int fih_rc = FIH_FAILURE;
int fa_id;
@@ -1990,8 +2085,6 @@
TARGET_STATIC boot_sector_t status_sectors[BOOT_MAX_SWAP_STATUS_SECTORS];
#endif
- (void)memset(&bs, 0, sizeof(bs));
- (void)memset(state, 0, sizeof(struct boot_loader_state));
has_upgrade = false;
#if (BOOT_IMAGE_NUMBER == 1)
@@ -2003,7 +2096,11 @@
* completed.
*/
IMAGES_ITER(BOOT_CURR_IMG(state)) {
-
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
#if defined(MCUBOOT_ENC_IMAGES) && (BOOT_IMAGE_NUMBER > 1)
/* The keys used for encryption may no longer be valid (could belong to
* another images). Therefore, mark them as invalid to force their reload
@@ -2053,7 +2150,7 @@
/* Iterate over all the images and verify whether the image dependencies
* are all satisfied and update swap type if necessary.
*/
- rc = boot_verify_dependencies(state);
+ rc = boot_verify_dependencies_flash(state);
if (rc != 0) {
/*
* It was impossible to upgrade because the expected dependency version
@@ -2071,8 +2168,11 @@
* all required update operations will have been finished.
*/
IMAGES_ITER(BOOT_CURR_IMG(state)) {
-
#if (BOOT_IMAGE_NUMBER > 1)
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+
#ifdef MCUBOOT_ENC_IMAGES
/* The keys used for encryption may no longer be valid (could belong to
* another images). Therefore, mark them as invalid to force their reload
@@ -2142,6 +2242,11 @@
* have been re-validated.
*/
IMAGES_ITER(BOOT_CURR_IMG(state)) {
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
if (BOOT_SWAP_TYPE(state) != BOOT_SWAP_TYPE_NONE) {
/* Attempt to read an image header from each slot. Ensure that image
* headers in slots are aligned with headers in boot_data.
@@ -2159,7 +2264,7 @@
#ifdef MCUBOOT_VALIDATE_PRIMARY_SLOT
FIH_CALL(boot_validate_slot, fih_rc, state, BOOT_PRIMARY_SLOT, &bs);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
goto out;
}
#else
@@ -2186,7 +2291,7 @@
}
#endif /* MCUBOOT_ENC_IMAGES_XIP */
- rc = boot_update_hw_rollback_protection(state);
+ rc = boot_update_hw_rollback_protection_flash(state);
if (rc != 0) {
goto out;
}
@@ -2212,7 +2317,7 @@
*/
(void)memset(&bs, 0, sizeof(struct boot_status));
- fill_rsp(state, NULL, rsp);
+ fill_rsp(state, rsp);
fih_rc = FIH_SUCCESS;
out:
@@ -2276,7 +2381,7 @@
BOOT_IMG_AREA(&boot_data, split_slot),
boot_img_hdr(&boot_data, loader_slot),
BOOT_IMG_AREA(&boot_data, loader_slot));
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
goto done;
}
@@ -2297,22 +2402,18 @@
FIH_RET(fih_rc);
}
-#else /* MCUBOOT_DIRECT_XIP || MCUBOOT_RAM_LOAD */
-#define NO_ACTIVE_SLOT UINT32_MAX
+#if defined(MCUBOOT_DIRECT_XIP) || defined(MCUBOOT_RAM_LOAD)
/**
* Opens all flash areas and checks which contain an image with a valid header.
*
* @param state Boot loader status information.
- * @param slot_usage Structure to fill with information about the available
- * slots.
*
* @return 0 on success; nonzero on failure.
*/
static int
-boot_get_slot_usage(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_get_slot_usage(struct boot_loader_state *state)
{
uint32_t slot;
int fa_id;
@@ -2320,6 +2421,11 @@
struct image_header *hdr = NULL;
IMAGES_ITER(BOOT_CURR_IMG(state)) {
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
/* Open all the slots */
for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
fa_id = flash_area_id_from_multi_image_slot(
@@ -2340,10 +2446,10 @@
hdr = boot_img_hdr(state, slot);
if (boot_is_header_valid(hdr, BOOT_IMG_AREA(state, slot))) {
- slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true;
BOOT_LOG_IMAGE_INFO(slot, hdr);
} else {
- slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = false;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = false;
BOOT_LOG_INF("Image %u %s slot: Image not found",
(unsigned)BOOT_CURR_IMG(state),
(slot == BOOT_PRIMARY_SLOT)
@@ -2351,7 +2457,7 @@
}
}
- slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
}
return 0;
@@ -2362,21 +2468,19 @@
* current image.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return NO_ACTIVE_SLOT if no available slot found, number of
* the found slot otherwise.
*/
static uint32_t
-find_slot_with_highest_version(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+find_slot_with_highest_version(struct boot_loader_state *state)
{
uint32_t slot;
uint32_t candidate_slot = NO_ACTIVE_SLOT;
int rc;
for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
- if (slot_usage[BOOT_CURR_IMG(state)].slot_available[slot]) {
+ if (state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot]) {
if (candidate_slot == NO_ACTIVE_SLOT) {
candidate_slot = slot;
} else {
@@ -2401,18 +2505,21 @@
* Prints the state of the loaded images.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*/
static void
-print_loaded_images(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+print_loaded_images(struct boot_loader_state *state)
{
uint32_t active_slot;
(void)state;
IMAGES_ITER(BOOT_CURR_IMG(state)) {
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
BOOT_LOG_INF("Image %u loaded from the %s slot",
(unsigned)BOOT_CURR_IMG(state),
@@ -2429,13 +2536,11 @@
* otherwise marks it as selected if it has not been before.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 on success; nonzero on failure.
*/
static int
-boot_select_or_erase(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_select_or_erase(struct boot_loader_state *state)
{
const struct flash_area *fap;
int fa_id;
@@ -2443,13 +2548,13 @@
uint32_t active_slot;
struct boot_swap_state* active_swap_state;
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
fa_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state), active_slot);
rc = flash_area_open(fa_id, &fap);
assert(rc == 0);
- active_swap_state = &(slot_usage[BOOT_CURR_IMG(state)].swap_state);
+ active_swap_state = &(state->slot_usage[BOOT_CURR_IMG(state)].swap_state);
(void)memset(active_swap_state, 0, sizeof(struct boot_swap_state));
rc = boot_read_swap_state(fap, active_swap_state);
@@ -2510,13 +2615,11 @@
* predefined bounds that are allowed to be used by executable images.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 on success; nonzero on failure.
*/
static int
-boot_verify_ram_load_address(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_verify_ram_load_address(struct boot_loader_state *state)
{
uint32_t img_dst;
uint32_t img_sz;
@@ -2539,8 +2642,8 @@
exec_ram_size = IMAGE_EXECUTABLE_RAM_SIZE;
#endif
- img_dst = slot_usage[BOOT_CURR_IMG(state)].img_dst;
- img_sz = slot_usage[BOOT_CURR_IMG(state)].img_sz;
+ img_dst = state->slot_usage[BOOT_CURR_IMG(state)].img_dst;
+ img_sz = state->slot_usage[BOOT_CURR_IMG(state)].img_sz;
if (img_dst < exec_ram_start) {
return BOOT_EBADIMAGE;
@@ -2732,14 +2835,12 @@
* Checks if the image we want to load to memory overlap with an already
* ramloaded image.
*
- * @param slot_usage Information about the active and available slots.
- * @param image_id_to_check The ID of the image we would like to load.
+ * @param state Boot loader status information.
*
* @return 0 if there is no overlap; nonzero otherwise.
*/
static int
-boot_check_ram_load_overlapping(struct slot_usage_t slot_usage[],
- uint32_t image_id_to_check)
+boot_check_ram_load_overlapping(struct boot_loader_state *state)
{
uint32_t i;
@@ -2747,22 +2848,23 @@
uint32_t end_a;
uint32_t start_b;
uint32_t end_b;
+ uint32_t image_id_to_check = BOOT_CURR_IMG(state);
- start_a = slot_usage[image_id_to_check].img_dst;
+ start_a = state->slot_usage[image_id_to_check].img_dst;
/* Safe to add here, values are already verified in
* boot_verify_ram_load_address() */
- end_a = start_a + slot_usage[image_id_to_check].img_sz;
+ end_a = start_a + state->slot_usage[image_id_to_check].img_sz;
for (i = 0; i < BOOT_IMAGE_NUMBER; i++) {
- if (slot_usage[i].active_slot == NO_ACTIVE_SLOT
+ if (state->slot_usage[i].active_slot == NO_ACTIVE_SLOT
|| i == image_id_to_check) {
continue;
}
- start_b = slot_usage[i].img_dst;
+ start_b = state->slot_usage[i].img_dst;
/* Safe to add here, values are already verified in
* boot_verify_ram_load_address() */
- end_b = start_b + slot_usage[i].img_sz;
+ end_b = start_b + state->slot_usage[i].img_sz;
if (do_regions_overlap(start_a, end_a, start_b, end_b)) {
return -1;
@@ -2778,24 +2880,22 @@
* image size is extracted from the image header.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 on success; nonzero on failure.
*/
static int
-boot_load_image_to_sram(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_load_image_to_sram(struct boot_loader_state *state)
{
uint32_t active_slot;
struct image_header *hdr = NULL;
uint32_t img_dst;
uint32_t img_sz;
- int rc;
+ int rc = 0;
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
hdr = boot_img_hdr(state, active_slot);
- if (hdr->ih_flags & IMAGE_F_RAM_LOAD) {
+ if (IS_RAM_BOOTABLE(hdr)) {
img_dst = hdr->ih_load_addr;
@@ -2804,17 +2904,17 @@
return rc;
}
- slot_usage[BOOT_CURR_IMG(state)].img_dst = img_dst;
- slot_usage[BOOT_CURR_IMG(state)].img_sz = img_sz;
+ state->slot_usage[BOOT_CURR_IMG(state)].img_dst = img_dst;
+ state->slot_usage[BOOT_CURR_IMG(state)].img_sz = img_sz;
- rc = boot_verify_ram_load_address(state, slot_usage);
+ rc = boot_verify_ram_load_address(state);
if (rc != 0) {
BOOT_LOG_INF("Image RAM load address 0x%" PRIx32 " is invalid.", img_dst);
return rc;
}
#if (BOOT_IMAGE_NUMBER > 1)
- rc = boot_check_ram_load_overlapping(slot_usage, BOOT_CURR_IMG(state));
+ rc = boot_check_ram_load_overlapping(state);
if (rc != 0) {
BOOT_LOG_INF("Image RAM loading to address 0x%" PRIx32
" would overlap with another image.", img_dst);
@@ -2839,7 +2939,8 @@
} else {
BOOT_LOG_INF("RAM loading to 0x%" PRIx32 " is succeeded.", img_dst);
}
- } else {
+ }
+ else {
/* Only images that support IMAGE_F_RAM_LOAD are allowed if
* MCUBOOT_RAM_LOAD is set.
*/
@@ -2847,8 +2948,8 @@
}
if (rc != 0) {
- slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
- slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
+ state->slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
+ state->slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
}
return rc;
@@ -2858,24 +2959,22 @@
* Removes an image from SRAM, by overwriting it with zeros.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 on success; nonzero on failure.
*/
static inline int
-boot_remove_image_from_sram(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_remove_image_from_sram(struct boot_loader_state *state)
{
(void)state;
- BOOT_LOG_INF("Removing image from SRAM at address 0x%" PRIx32,
- slot_usage[BOOT_CURR_IMG(state)].img_dst);
+ BOOT_LOG_INF("Removing image from SRAM at address 0x%x",
+ state->slot_usage[BOOT_CURR_IMG(state)].img_dst);
- memset((void*)(IMAGE_RAM_BASE + slot_usage[BOOT_CURR_IMG(state)].img_dst),
- 0, slot_usage[BOOT_CURR_IMG(state)].img_sz);
+ (void)memset((void*)(IMAGE_RAM_BASE + state->slot_usage[BOOT_CURR_IMG(state)].img_dst),
+ 0, state->slot_usage[BOOT_CURR_IMG(state)].img_sz);
- slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
- slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
+ state->slot_usage[BOOT_CURR_IMG(state)].img_dst = 0;
+ state->slot_usage[BOOT_CURR_IMG(state)].img_sz = 0;
return 0;
}
@@ -2914,14 +3013,12 @@
* Checks the image dependency whether it is satisfied.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
* @param dep Image dependency which has to be verified.
*
* @return 0 if dependencies are met; nonzero otherwise.
*/
static int
-boot_verify_slot_dependency(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[],
+boot_verify_slot_dependency_ram(struct boot_loader_state *state,
struct image_dependency *dep)
{
struct image_version *dep_version;
@@ -2931,7 +3028,7 @@
/* Determine the source of the image which is the subject of
* the dependency and get it's version.
*/
- dep_slot = slot_usage[dep->image_id].active_slot;
+ dep_slot = state->slot_usage[dep->image_id].active_slot;
dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver;
rc = boot_version_cmp(dep_version, &dep->image_min_version);
@@ -2948,13 +3045,11 @@
* if they are all satisfied.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 if dependencies are met; nonzero otherwise.
*/
static int
-boot_verify_slot_dependencies(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_verify_slot_dependencies_ram(struct boot_loader_state *state)
{
uint32_t active_slot;
const struct flash_area *fap;
@@ -2965,7 +3060,7 @@
int area_id;
int rc;
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
area_id = flash_area_id_from_multi_image_slot(BOOT_CURR_IMG(state),
active_slot);
@@ -3007,7 +3102,7 @@
goto done;
}
- rc = boot_verify_slot_dependency(state, slot_usage, &dep);
+ rc = boot_verify_slot_dependency_ram(state, &dep);
if (rc != 0) {
/* Dependency not satisfied. */
goto done;
@@ -3025,29 +3120,30 @@
* case of MCUBOOT_RAM_LOAD strategy) and its slot is set to unavailable.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 if dependencies are met; nonzero otherwise.
*/
static int
-boot_verify_dependencies(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_verify_dependencies_ram(struct boot_loader_state *state)
{
int rc = -1;
uint32_t active_slot;
IMAGES_ITER(BOOT_CURR_IMG(state)) {
- rc = boot_verify_slot_dependencies(state, slot_usage);
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+ rc = boot_verify_slot_dependencies_ram(state);
if (rc != 0) {
/* Dependencies not met or invalid dependencies. */
#ifdef MCUBOOT_RAM_LOAD
- boot_remove_image_from_sram(state, slot_usage);
+ boot_remove_image_from_sram(state);
#endif /* MCUBOOT_RAM_LOAD */
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
- slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
- slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
return rc;
}
@@ -3061,13 +3157,11 @@
* Tries to load a slot for all the images with validation.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 on success; nonzero on failure.
*/
fih_int
-boot_load_and_validate_images(struct boot_loader_state *state,
- struct slot_usage_t slot_usage[])
+boot_load_and_validate_images(struct boot_loader_state *state)
{
uint32_t active_slot;
int rc;
@@ -3079,16 +3173,14 @@
* means that a valid image found or already loaded. If no slot is
* found the function returns with error code. */
while (true) {
-
/* Go over all the slots and try to load one */
- active_slot = slot_usage[BOOT_CURR_IMG(state)].active_slot;
+ active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
if (active_slot != NO_ACTIVE_SLOT){
/* A slot is already active, go to next image. */
break;
}
- active_slot = find_slot_with_highest_version(state,
- slot_usage);
+ active_slot = find_slot_with_highest_version(state);
if (active_slot == NO_ACTIVE_SLOT) {
BOOT_LOG_INF("No slot to load for image %u",
(unsigned)BOOT_CURR_IMG(state));
@@ -3096,23 +3188,29 @@
}
/* Save the number of the active slot. */
- slot_usage[BOOT_CURR_IMG(state)].active_slot = active_slot;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = active_slot;
+
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
#ifdef MCUBOOT_DIRECT_XIP
- rc = boot_rom_address_check(state, slot_usage);
+ rc = boot_rom_address_check(state);
if (rc != 0) {
/* The image is placed in an unsuitable slot. */
- slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
- slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
continue;
}
#ifdef MCUBOOT_DIRECT_XIP_REVERT
- rc = boot_select_or_erase(state, slot_usage);
+ rc = boot_select_or_erase(state);
if (rc != 0) {
/* The selected image slot has been erased. */
- slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
- slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
continue;
}
#endif /* MCUBOOT_DIRECT_XIP_REVERT */
@@ -3124,24 +3222,24 @@
* when loading images from external (untrusted) flash to internal
* (trusted) RAM and image is authenticated before copying.
*/
- rc = boot_load_image_to_sram(state, slot_usage);
+ rc = boot_load_image_to_sram(state);
if (rc != 0 ) {
/* Image cannot be ramloaded. */
boot_remove_image_from_flash(state, active_slot);
- slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
- slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
continue;
}
#endif /* MCUBOOT_RAM_LOAD */
FIH_CALL(boot_validate_slot, fih_rc, state, active_slot, NULL);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
/* Image is invalid. */
#ifdef MCUBOOT_RAM_LOAD
- boot_remove_image_from_sram(state, slot_usage);
+ boot_remove_image_from_sram(state);
#endif /* MCUBOOT_RAM_LOAD */
- slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
- slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
+ state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
continue;
}
@@ -3150,6 +3248,7 @@
}
}
+ (void) rc;
FIH_RET(FIH_SUCCESS);
}
@@ -3157,13 +3256,11 @@
* Updates the security counter for the current image.
*
* @param state Boot loader status information.
- * @param slot_usage Information about the active and available slots.
*
* @return 0 on success; nonzero on failure.
*/
static int
-boot_update_hw_rollback_protection(struct boot_loader_state *state,
- const struct slot_usage_t slot_usage[])
+boot_update_hw_rollback_protection_ram(struct boot_loader_state *state)
{
#ifdef MCUBOOT_HW_ROLLBACK_PROT
int rc;
@@ -3177,11 +3274,11 @@
* has been confirmed at runtime (the image_ok flag has been set).
* This way a 'revert' can be performed when it's necessary.
*/
- if (slot_usage[BOOT_CURR_IMG(state)].swap_state.image_ok == BOOT_FLAG_SET) {
+ if (state->slot_usage[BOOT_CURR_IMG(state)].swap_state.image_ok == BOOT_FLAG_SET) {
#endif
rc = boot_update_security_counter(BOOT_CURR_IMG(state),
- slot_usage[BOOT_CURR_IMG(state)].active_slot,
- boot_img_hdr(state, slot_usage[BOOT_CURR_IMG(state)].active_slot));
+ state->slot_usage[BOOT_CURR_IMG(state)].active_slot,
+ boot_img_hdr(state, state->slot_usage[BOOT_CURR_IMG(state)].active_slot));
if (rc != 0) {
BOOT_LOG_ERR("Security counter update failed after image "
"validation.");
@@ -3195,22 +3292,17 @@
#else /* MCUBOOT_HW_ROLLBACK_PROT */
(void) (state);
- (void) (slot_usage);
return 0;
#endif
}
fih_int
-context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
+context_boot_go_ram(struct boot_loader_state *state, struct boot_rsp *rsp)
{
- struct slot_usage_t slot_usage[BOOT_IMAGE_NUMBER];
int rc;
- fih_int fih_rc = fih_int_encode(0);
+ fih_int fih_rc = FIH_FAILURE;
- memset(state, 0, sizeof(struct boot_loader_state));
- memset(slot_usage, 0, sizeof(struct slot_usage_t) * BOOT_IMAGE_NUMBER);
-
- rc = boot_get_slot_usage(state, slot_usage);
+ rc = boot_get_slot_usage(state);
if (rc != 0) {
goto out;
}
@@ -3218,13 +3310,13 @@
#if (BOOT_IMAGE_NUMBER > 1)
while (true) {
#endif
- FIH_CALL(boot_load_and_validate_images, fih_rc, state, slot_usage);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
+ FIH_CALL(boot_load_and_validate_images, fih_rc, state);
+ if (fih_eq(fih_rc, FIH_SUCCESS) != FIH_TRUE) {
goto out;
}
#if (BOOT_IMAGE_NUMBER > 1)
- rc = boot_verify_dependencies(state, slot_usage);
+ rc = boot_verify_dependencies_ram(state);
if (rc != 0) {
/* Dependency check failed for an image, it has been removed from
* SRAM in case of MCUBOOT_RAM_LOAD strategy, and set to
@@ -3238,12 +3330,17 @@
#endif
IMAGES_ITER(BOOT_CURR_IMG(state)) {
- rc = boot_update_hw_rollback_protection(state, slot_usage);
+#if BOOT_IMAGE_NUMBER > 1
+ if (state->img_mask[BOOT_CURR_IMG(state)]) {
+ continue;
+ }
+#endif
+ rc = boot_update_hw_rollback_protection_ram(state);
if (rc != 0) {
goto out;
}
- rc = boot_add_shared_data(state, slot_usage[BOOT_CURR_IMG(state)].active_slot);
+ rc = boot_add_shared_data(state, state->slot_usage[BOOT_CURR_IMG(state)].active_slot);
if (rc != 0) {
goto out;
}
@@ -3251,16 +3348,16 @@
/* All image loaded successfully. */
#ifdef MCUBOOT_HAVE_LOGGING
- print_loaded_images(state, slot_usage);
+ print_loaded_images(state);
#endif
- fill_rsp(state, slot_usage, rsp);
+ fill_rsp(state, rsp);
out:
close_all_flash_areas(state);
- if (fih_eq(fih_rc, FIH_SUCCESS)) {
- fih_rc = fih_int_encode(rc);
+ if (FIH_TRUE == fih_eq(fih_rc, FIH_SUCCESS)) {
+ fih_rc = fih_int_encode_zero_equality(rc);
}
FIH_RET(fih_rc);
@@ -3279,6 +3376,87 @@
boot_go(struct boot_rsp *rsp)
{
fih_int fih_rc = FIH_FAILURE;
- FIH_CALL(context_boot_go, fih_rc, &boot_data, rsp);
+
+ boot_state_clear(NULL);
+
+ FIH_CALL(context_boot_go_flash, fih_rc, &boot_data, rsp);
FIH_RET(fih_rc);
}
+
+/**
+ * Prepares the booting process, considering only a single image. This function
+ * moves images around in flash as appropriate, and tells you what address to
+ * boot from.
+ *
+ * @param rsp On success, indicates how booting should occur.
+ *
+ * @param image_id The image ID to prepare the boot process for.
+ *
+ * @return FIH_SUCCESS on success; nonzero on failure.
+ */
+fih_int
+boot_go_for_image_id(struct boot_rsp *rsp, uint32_t image_id)
+{
+ fih_int fih_rc = FIH_FAILURE;
+
+ if (image_id >= BOOT_IMAGE_NUMBER) {
+ FIH_RET(FIH_FAILURE);
+ }
+
+#if BOOT_IMAGE_NUMBER > 1
+ (void)memset(&boot_data.img_mask, 1, BOOT_IMAGE_NUMBER);
+ boot_data.img_mask[image_id] = 0;
+#endif
+
+ FIH_CALL(context_boot_go_flash, fih_rc, &boot_data, rsp);
+ FIH_RET(fih_rc);
+}
+
+#if defined(MCUBOOT_RAM_LOAD)
+/**
+ * Prepares the booting process, considering only a single image. This function
+ * moves images around in flash as appropriate, and tells you what address to
+ * boot from.
+ *
+ * @param rsp On success, indicates how booting should occur.
+ *
+ * @param image_id The image ID to prepare the boot process for.
+ *
+ * @return FIH_SUCCESS on success; nonzero on failure.
+ */
+fih_int
+boot_go_for_image_id_ram(struct boot_rsp *rsp, uint32_t image_id)
+{
+ fih_int fih_rc = FIH_FAILURE;
+
+ if (image_id >= BOOT_IMAGE_NUMBER) {
+ FIH_RET(FIH_FAILURE);
+ }
+
+#if BOOT_IMAGE_NUMBER > 1
+ (void)memset(&boot_data.img_mask, 1, BOOT_IMAGE_NUMBER);
+ boot_data.img_mask[image_id] = 0;
+#endif
+
+ FIH_CALL(context_boot_go_ram, fih_rc, &boot_data, rsp);
+ FIH_RET(fih_rc);
+}
+
+#endif /* MCUBOOT_RAM_LOAD */
+
+/**
+ * Clears the boot state, so that previous operations have no effect on new
+ * ones.
+ *
+ * @param state The state that should be cleared. If the value
+ * is NULL, the default bootloader state will be
+ * cleared.
+ */
+void boot_state_clear(struct boot_loader_state *state)
+{
+ if (state != NULL) {
+ (void)memset(state, 0, sizeof(struct boot_loader_state));
+ } else {
+ (void)memset(&boot_data, 0, sizeof(struct boot_loader_state));
+ }
+}