Skip to content

Commit 323fb66

Browse files
committed
[nrf noup] boot/bootutil/loader: introduced cleanup of unusable secondary slot
Added procedure which clean-up content of all the secondary slot which contains valid header but couldn't be assigned to any of supported primary images. This behavior is needed when configuration allows to use one secondary slot for collecting image for multiple primary slots. Signed-off-by: Andrzej Puzdrowski <[email protected]>
1 parent cb64eca commit 323fb66

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

boot/bootutil/src/loader.c

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,87 @@ boot_update_security_counter(uint8_t image_index, int slot,
951951
}
952952
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
953953

954+
#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\
955+
(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP))
956+
957+
#define SEC_SLOT_VIRGIN 0
958+
#define SEC_SLOT_TOUCHED 1
959+
#define SEC_SLOT_ASSIGNED 2
960+
961+
#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \
962+
!defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE)
963+
/* This configuration is peculiar - the one physical secondary slot is
964+
* mocking two logical secondary
965+
*/
966+
#define SEC_SLOT_PHYSICAL_CNT 1
967+
#else
968+
#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER
969+
#endif
970+
971+
static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0};
972+
973+
static inline void sec_slot_touch(struct boot_loader_state *state)
974+
{
975+
uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state);
976+
977+
if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) {
978+
sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED;
979+
}
980+
}
981+
982+
static inline void sec_slot_mark_assigned(struct boot_loader_state *state)
983+
{
984+
uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state);
985+
986+
sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED;
987+
}
988+
989+
/**
990+
* Cleanu up all secondary slot which couldn't be assigned to any primary slot.
991+
*
992+
* This function erases content of each secondary slot which contains valid
993+
* header but couldn't be assigned to any of supported primary images.
994+
*
995+
* This function is supposed to be called after boot_validated_swap_type()
996+
* iterates over all the images in context_boot_go().
997+
*/
998+
static void sec_slot_cleanup_if_unusable(void)
999+
{
1000+
uint8_t idx;
1001+
1002+
for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) {
1003+
if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) {
1004+
const struct flash_area *secondary_fa;
1005+
int rc;
1006+
1007+
rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT),
1008+
&secondary_fa);
1009+
if (!rc) {
1010+
rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size);
1011+
if (!rc) {
1012+
BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx);
1013+
}
1014+
}
1015+
1016+
if (rc) {
1017+
BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx);
1018+
}
1019+
}
1020+
}
1021+
}
1022+
#else
1023+
static inline void sec_slot_touch(struct boot_loader_state *state)
1024+
{
1025+
}
1026+
static inline void sec_slot_mark_assigned(struct boot_loader_state *state)
1027+
{
1028+
}
1029+
static inline void sec_slot_cleanup_if_unusable(void)
1030+
{
1031+
}
1032+
#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\
1033+
defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */
1034+
9541035
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
9551036
/**
9561037
* Determines which swap operation to perform, if any. If it is determined
@@ -989,6 +1070,9 @@ boot_validated_swap_type(struct boot_loader_state *state,
9891070
if (rc != 0) {
9901071
return BOOT_SWAP_TYPE_FAIL;
9911072
}
1073+
1074+
sec_slot_touch(state);
1075+
9921076
#ifdef PM_S1_ADDRESS
9931077
#ifdef PM_CPUNET_B0N_ADDRESS
9941078
if(reset_addr < PM_CPUNET_B0N_ADDRESS)
@@ -1023,6 +1107,7 @@ boot_validated_swap_type(struct boot_loader_state *state,
10231107
}
10241108
#else
10251109
return BOOT_SWAP_TYPE_NONE;
1110+
10261111
#endif
10271112

10281113
} else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) {
@@ -1031,7 +1116,9 @@ boot_validated_swap_type(struct boot_loader_state *state,
10311116
}
10321117
}
10331118
#endif /* PM_S1_ADDRESS */
1119+
sec_slot_mark_assigned(state);
10341120
}
1121+
10351122
#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */
10361123

10371124
swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state));
@@ -2256,6 +2343,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
22562343
}
22572344
}
22582345

2346+
/* cleanup secondary slots which were recognized unusable*/
2347+
sec_slot_cleanup_if_unusable();
2348+
22592349
#if (BOOT_IMAGE_NUMBER > 1)
22602350
if (has_upgrade) {
22612351
/* Iterate over all the images and verify whether the image dependencies

0 commit comments

Comments
 (0)