Skip to content

Commit ee67c04

Browse files
nvlsianpuanangl
authored andcommitted
[nrf noup] 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]> (cherry picked from commit 8f4b472)
1 parent d2d11bf commit ee67c04

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
@@ -1188,6 +1188,87 @@ boot_update_security_counter(uint8_t image_index, int slot,
11881188
}
11891189
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
11901190

1191+
#if defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\
1192+
(defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP))
1193+
1194+
#define SEC_SLOT_VIRGIN 0
1195+
#define SEC_SLOT_TOUCHED 1
1196+
#define SEC_SLOT_ASSIGNED 2
1197+
1198+
#if (MCUBOOT_IMAGE_NUMBER == 2) && defined(PM_B0_ADDRESS) && \
1199+
!defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE)
1200+
/* This configuration is peculiar - the one physical secondary slot is
1201+
* mocking two logical secondary
1202+
*/
1203+
#define SEC_SLOT_PHYSICAL_CNT 1
1204+
#else
1205+
#define SEC_SLOT_PHYSICAL_CNT MCUBOOT_IMAGE_NUMBER
1206+
#endif
1207+
1208+
static uint8_t sec_slot_assignmnet[SEC_SLOT_PHYSICAL_CNT] = {0};
1209+
1210+
static inline void sec_slot_touch(struct boot_loader_state *state)
1211+
{
1212+
uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state);
1213+
1214+
if (SEC_SLOT_VIRGIN == sec_slot_assignmnet[idx]) {
1215+
sec_slot_assignmnet[idx] = SEC_SLOT_TOUCHED;
1216+
}
1217+
}
1218+
1219+
static inline void sec_slot_mark_assigned(struct boot_loader_state *state)
1220+
{
1221+
uint8_t idx = (SEC_SLOT_PHYSICAL_CNT == 1) ? 0 : BOOT_CURR_IMG(state);
1222+
1223+
sec_slot_assignmnet[idx] = SEC_SLOT_ASSIGNED;
1224+
}
1225+
1226+
/**
1227+
* Cleanu up all secondary slot which couldn't be assigned to any primary slot.
1228+
*
1229+
* This function erases content of each secondary slot which contains valid
1230+
* header but couldn't be assigned to any of supported primary images.
1231+
*
1232+
* This function is supposed to be called after boot_validated_swap_type()
1233+
* iterates over all the images in context_boot_go().
1234+
*/
1235+
static void sec_slot_cleanup_if_unusable(void)
1236+
{
1237+
uint8_t idx;
1238+
1239+
for (idx = 0; idx < SEC_SLOT_PHYSICAL_CNT; idx++) {
1240+
if (SEC_SLOT_TOUCHED == sec_slot_assignmnet[idx]) {
1241+
const struct flash_area *secondary_fa;
1242+
int rc;
1243+
1244+
rc = flash_area_open(flash_area_id_from_multi_image_slot(idx, BOOT_SECONDARY_SLOT),
1245+
&secondary_fa);
1246+
if (!rc) {
1247+
rc = flash_area_erase(secondary_fa, 0, secondary_fa->fa_size);
1248+
if (!rc) {
1249+
BOOT_LOG_ERR("Cleaned-up secondary slot of %d. image.", idx);
1250+
}
1251+
}
1252+
1253+
if (rc) {
1254+
BOOT_LOG_ERR("Can not cleanup secondary slot of %d. image.", idx);
1255+
}
1256+
}
1257+
}
1258+
}
1259+
#else
1260+
static inline void sec_slot_touch(struct boot_loader_state *state)
1261+
{
1262+
}
1263+
static inline void sec_slot_mark_assigned(struct boot_loader_state *state)
1264+
{
1265+
}
1266+
static inline void sec_slot_cleanup_if_unusable(void)
1267+
{
1268+
}
1269+
#endif /* defined(CONFIG_MCUBOOT_CLEANUP_UNUSABLE_SECONDARY) &&\
1270+
defined(PM_S1_ADDRESS) || defined(CONFIG_SOC_NRF5340_CPUAPP) */
1271+
11911272
#if !defined(MCUBOOT_DIRECT_XIP) && !defined(MCUBOOT_RAM_LOAD)
11921273
/**
11931274
* Determines which swap operation to perform, if any. If it is determined
@@ -1226,6 +1307,9 @@ boot_validated_swap_type(struct boot_loader_state *state,
12261307
if (rc != 0) {
12271308
return BOOT_SWAP_TYPE_FAIL;
12281309
}
1310+
1311+
sec_slot_touch(state);
1312+
12291313
#ifdef PM_S1_ADDRESS
12301314
#ifdef PM_CPUNET_B0N_ADDRESS
12311315
if(reset_addr < PM_CPUNET_B0N_ADDRESS)
@@ -1260,6 +1344,7 @@ boot_validated_swap_type(struct boot_loader_state *state,
12601344
}
12611345
#else
12621346
return BOOT_SWAP_TYPE_NONE;
1347+
12631348
#endif
12641349

12651350
} else if (reset_addr > (primary_fa->fa_off + primary_fa->fa_size)) {
@@ -1268,7 +1353,9 @@ boot_validated_swap_type(struct boot_loader_state *state,
12681353
}
12691354
}
12701355
#endif /* PM_S1_ADDRESS */
1356+
sec_slot_mark_assigned(state);
12711357
}
1358+
12721359
#endif /* PM_S1_ADDRESS || CONFIG_SOC_NRF5340_CPUAPP */
12731360

12741361
swap_type = boot_swap_type_multi(BOOT_CURR_IMG(state));
@@ -2329,6 +2416,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp)
23292416
}
23302417
}
23312418

2419+
/* cleanup secondary slots which were recognized unusable*/
2420+
sec_slot_cleanup_if_unusable();
2421+
23322422
#if (BOOT_IMAGE_NUMBER > 1)
23332423
if (has_upgrade) {
23342424
/* Iterate over all the images and verify whether the image dependencies

0 commit comments

Comments
 (0)