Skip to content

Commit

Permalink
boot: bootutil: swap_offset: Skip erasing/copying empty sectors
Browse files Browse the repository at this point in the history
Only erases and copies sectors where there is data present

Signed-off-by: Jamie McCrae <[email protected]>
  • Loading branch information
nordicjm committed Feb 3, 2025
1 parent 96b7008 commit 9a02794
Showing 1 changed file with 72 additions and 36 deletions.
108 changes: 72 additions & 36 deletions boot/bootutil/src/swap_offset.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ int swap_status_source(struct boot_loader_state *state)

static void boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *state,
struct boot_status *bs, const struct flash_area *fap_pri,
const struct flash_area *fap_sec)
const struct flash_area *fap_sec, bool skip_primary,
bool skip_secondary)
{
uint32_t pri_off;
uint32_t sec_off;
Expand All @@ -466,31 +467,41 @@ static void boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *st
sec_up_off = boot_img_sector_off(state, BOOT_PRIMARY_SLOT, (idx + 1));

if (bs->state == BOOT_STATUS_STATE_0) {
/* Copy from slot 0 X to slot 1 X */
BOOT_LOG_DBG("Erasing secondary 0x%x of 0x%x", sec_off, sz);
rc = boot_erase_region(fap_sec, sec_off, sz);
assert(rc == 0);
if (skip_primary == true) {
BOOT_LOG_DBG("Skipping erase of secondary 0x%x and copy from primary 0x%x", sec_off,
pri_off);
} else {
/* Copy from slot 0 X to slot 1 X */
BOOT_LOG_DBG("Erasing secondary 0x%x of 0x%x", sec_off, sz);
rc = boot_erase_region(fap_sec, sec_off, sz);
assert(rc == 0);

BOOT_LOG_DBG("Copying primary 0x%x -> secondary 0x%x of 0x%x", pri_off, sec_off, sz);
rc = BOOT_COPY_REGION(state, fap_pri, fap_sec, pri_off, sec_off, sz, 0);
assert(rc == 0);
BOOT_LOG_DBG("Copying primary 0x%x -> secondary 0x%x of 0x%x", pri_off, sec_off, sz);
rc = BOOT_COPY_REGION(state, fap_pri, fap_sec, pri_off, sec_off, sz, 0);
assert(rc == 0);
}

rc = boot_write_status(state, bs);
bs->state = BOOT_STATUS_STATE_1;
BOOT_STATUS_ASSERT(rc == 0);
}

if (bs->state == BOOT_STATUS_STATE_1) {
/* Erase slot 0 X */
BOOT_LOG_DBG("Erasing primary 0x%x of 0x%x", pri_off, sz);
rc = boot_erase_region(fap_pri, pri_off, sz);
assert(rc == 0);
if (skip_secondary == true) {
BOOT_LOG_DBG("Skipping erase of primary 0x%x and copy from secondary 0x%x", pri_off,
sec_up_off);
} else {
/* Erase slot 0 X */
BOOT_LOG_DBG("Erasing primary 0x%x of 0x%x", pri_off, sz);
rc = boot_erase_region(fap_pri, pri_off, sz);
assert(rc == 0);

/* Copy from slot 1 (X + 1) to slot 0 X */
BOOT_LOG_DBG("Copying secondary 0x%x -> primary 0x%x of 0x%x", sec_up_off, pri_off,
sz);
rc = BOOT_COPY_REGION(state, fap_sec, fap_pri, sec_up_off, pri_off, sz, 0);
assert(rc == 0);
/* Copy from slot 1 (X + 1) to slot 0 X */
BOOT_LOG_DBG("Copying secondary 0x%x -> primary 0x%x of 0x%x", sec_up_off, pri_off,
sz);
rc = BOOT_COPY_REGION(state, fap_sec, fap_pri, sec_up_off, pri_off, sz, 0);
assert(rc == 0);
}

rc = boot_write_status(state, bs);
bs->idx++;
Expand All @@ -501,7 +512,8 @@ static void boot_swap_sectors(int idx, uint32_t sz, struct boot_loader_state *st

static void boot_swap_sectors_revert(int idx, uint32_t sz, struct boot_loader_state *state,
struct boot_status *bs, const struct flash_area *fap_pri,
const struct flash_area *fap_sec, uint32_t sector_sz)
const struct flash_area *fap_sec, uint32_t sector_sz,
bool skip_primary, bool skip_secondary)
{
uint32_t pri_off;
uint32_t sec_off;
Expand All @@ -516,31 +528,41 @@ static void boot_swap_sectors_revert(int idx, uint32_t sz, struct boot_loader_st
sec_up_off = boot_img_sector_off(state, BOOT_PRIMARY_SLOT, idx);

if (bs->state == BOOT_STATUS_STATE_0) {
/* Copy from slot 0 X to slot 1 X */
BOOT_LOG_DBG("Erasing secondary 0x%x of 0x%x", sec_off, sz);
rc = boot_erase_region(fap_sec, sec_off, sz);
assert(rc == 0);
if (skip_primary == true) {
BOOT_LOG_DBG("Skipping erase of secondary 0x%x and copy from primary 0x%x", sec_off,
pri_off);
} else {
/* Copy from slot 0 X to slot 1 X */
BOOT_LOG_DBG("Erasing secondary 0x%x of 0x%x", sec_off, sz);
rc = boot_erase_region(fap_sec, sec_off, sz);
assert(rc == 0);

BOOT_LOG_DBG("Copying primary 0x%x -> secondary 0x%x of 0x%x", pri_off, sec_off, sz);
rc = BOOT_COPY_REGION(state, fap_pri, fap_sec, pri_off, sec_off, sz, sector_sz);
assert(rc == 0);
BOOT_LOG_DBG("Copying primary 0x%x -> secondary 0x%x of 0x%x", pri_off, sec_off, sz);
rc = BOOT_COPY_REGION(state, fap_pri, fap_sec, pri_off, sec_off, sz, sector_sz);
assert(rc == 0);
}

rc = boot_write_status(state, bs);
bs->state = BOOT_STATUS_STATE_1;
BOOT_STATUS_ASSERT(rc == 0);
}

if (bs->state == BOOT_STATUS_STATE_1) {
/* Erase slot 0 X */
BOOT_LOG_DBG("Erasing primary 0x%x of 0x%x", pri_off, sz);
rc = boot_erase_region(fap_pri, pri_off, sz);
assert(rc == 0);
if (skip_secondary == true) {
BOOT_LOG_DBG("Skipping erase of primary 0x%x and copy from secondary 0x%x", pri_off,
sec_up_off);
} else {
/* Erase slot 0 X */
BOOT_LOG_DBG("Erasing primary 0x%x of 0x%x", pri_off, sz);
rc = boot_erase_region(fap_pri, pri_off, sz);
assert(rc == 0);

/* Copy from slot 1 (X + 1) to slot 0 X */
BOOT_LOG_DBG("Copying secondary 0x%x -> primary 0x%x of 0x%x", sec_up_off, pri_off,
sz);
rc = BOOT_COPY_REGION(state, fap_sec, fap_pri, sec_up_off, pri_off, sz, 0);
assert(rc == 0);
/* Copy from slot 1 (X + 1) to slot 0 X */
BOOT_LOG_DBG("Copying secondary 0x%x -> primary 0x%x of 0x%x", sec_up_off, pri_off,
sz);
rc = BOOT_COPY_REGION(state, fap_sec, fap_pri, sec_up_off, pri_off, sz, 0);
assert(rc == 0);
}

rc = boot_write_status(state, bs);
bs->idx++;
Expand Down Expand Up @@ -601,6 +623,8 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs,
uint32_t trailer_sz;
uint32_t first_trailer_idx;
uint32_t last_idx;
uint32_t used_sectors_pri;
uint32_t used_sectors_sec;
uint8_t image_index;
const struct flash_area *fap_pri;
const struct flash_area *fap_sec;
Expand Down Expand Up @@ -663,6 +687,14 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs,

bs->op = BOOT_STATUS_OP_SWAP;
idx = 0;
used_sectors_pri = ((state->imgs[BOOT_CURR_IMG(state)][BOOT_PRIMARY_SLOT].hdr.ih_hdr_size +
state->imgs[BOOT_CURR_IMG(state)][BOOT_PRIMARY_SLOT].hdr.ih_protect_tlv_size +
state->imgs[BOOT_CURR_IMG(state)][BOOT_PRIMARY_SLOT].hdr.ih_img_size) + sector_sz - 1) /
sector_sz;
used_sectors_sec = ((state->imgs[BOOT_CURR_IMG(state)][BOOT_SECONDARY_SLOT].hdr.ih_hdr_size +
state->imgs[BOOT_CURR_IMG(state)][BOOT_SECONDARY_SLOT].hdr.ih_protect_tlv_size +
state->imgs[BOOT_CURR_IMG(state)][BOOT_SECONDARY_SLOT].hdr.ih_img_size) + sector_sz - 1) /
sector_sz;

if (bs->swap_type == BOOT_SWAP_TYPE_REVERT ||
boot_swap_type_multi(BOOT_CURR_IMG(state)) == BOOT_SWAP_TYPE_REVERT) {
Expand All @@ -671,7 +703,9 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs,
uint32_t mirror_idx = last_idx - idx;

boot_swap_sectors_revert(mirror_idx, sector_sz, state, bs, fap_pri, fap_sec,
sector_sz);
sector_sz,
(mirror_idx > used_sectors_pri ? true : false),
(mirror_idx > used_sectors_sec ? true : false));
}

idx++;
Expand All @@ -689,7 +723,9 @@ void swap_run(struct boot_loader_state *state, struct boot_status *bs,
} else {
while (idx <= last_idx) {
if (idx >= (bs->idx - BOOT_STATUS_IDX_0)) {
boot_swap_sectors(idx, sector_sz, state, bs, fap_pri, fap_sec);
boot_swap_sectors(idx, sector_sz, state, bs, fap_pri, fap_sec,
(idx > used_sectors_pri ? true : false),
(idx > used_sectors_sec ? true : false));
}

idx++;
Expand Down

0 comments on commit 9a02794

Please sign in to comment.