Skip to content

Instantly share code, notes, and snippets.

@utzig
Created February 8, 2023 00:53
Show Gist options
  • Save utzig/97276ce3447c09c884f7d779b05ea132 to your computer and use it in GitHub Desktop.
Save utzig/97276ce3447c09c884f7d779b05ea132 to your computer and use it in GitHub Desktop.
Swap move reset fix
--- sdk-mcuboot-1.9.99-ncs1/boot/bootutil/src/swap_move.c.orig 2022-05-24 08:15:45.000000000 -0300
+++ sdk-mcuboot-1.9.99-ncs1/boot/bootutil/src/swap_move.c 2023-02-07 21:50:22.259499220 -0300
@@ -47,7 +47,26 @@
#define BOOT_STATUS_ASSERT(x) ASSERT(x)
#endif
-static uint32_t g_last_idx = UINT32_MAX;
+uint32_t
+find_last_idx(struct boot_loader_state *state, uint32_t swap_size)
+{
+ uint32_t sector_sz;
+ uint32_t sz;
+ uint32_t last_idx;
+
+ sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
+ sz = 0;
+ last_idx = 0;
+ while (1) {
+ sz += sector_sz;
+ last_idx++;
+ if (sz >= swap_size) {
+ break;
+ }
+ }
+
+ return last_idx;
+}
int
boot_read_image_header(struct boot_loader_state *state, int slot,
@@ -56,6 +75,8 @@
const struct flash_area *fap;
uint32_t off;
uint32_t sz;
+ uint32_t last_idx;
+ uint32_t swap_size;
int area_id;
int rc;
@@ -64,25 +85,29 @@
#endif
off = 0;
- if (bs) {
+ if (bs && !boot_status_is_reset(bs)) {
+ rc = boot_read_swap_size(BOOT_CURR_IMG(state), &swap_size);
+ if (rc) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+
+ last_idx = find_last_idx(state, swap_size);
sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
- if (bs->op == BOOT_STATUS_OP_MOVE) {
- if (slot == 0 && bs->idx > g_last_idx) {
- /* second sector */
- off = sz;
- }
+
+ /*
+ * Find the correct offset or slot where the image header is expected to
+ * be found for the steps where it is moved or swapped.
+ */
+ if (bs->op == BOOT_STATUS_OP_MOVE && slot == 0 && bs->idx > last_idx) {
+ off = sz;
} else if (bs->op == BOOT_STATUS_OP_SWAP) {
- if (bs->idx > 1 && bs->idx <= g_last_idx) {
- if (slot == 0) {
- slot = 1;
- } else {
- slot = 0;
- }
+ if (bs->idx > 1 && bs->idx <= last_idx) {
+ slot = (slot == 0) ? 1 : 0;
} else if (bs->idx == 1) {
if (slot == 0) {
off = sz;
- }
- if (slot == 1 && bs->state == 2) {
+ } else if (slot == 1 && bs->state == 2) {
slot = 0;
}
}
@@ -457,6 +482,7 @@
uint32_t idx;
uint32_t trailer_sz;
uint32_t first_trailer_idx;
+ uint32_t last_idx;
uint8_t image_index;
const struct flash_area *fap_pri;
const struct flash_area *fap_sec;
@@ -465,17 +491,8 @@
BOOT_LOG_INF("Starting swap using move algorithm.");
sz = 0;
- g_last_idx = 0;
-
+ last_idx = find_last_idx(state, copy_size);
sector_sz = boot_img_sector_size(state, BOOT_PRIMARY_SLOT, 0);
- while (1) {
- sz += sector_sz;
- /* Skip to next sector because all sectors will be moved up. */
- g_last_idx++;
- if (sz >= copy_size) {
- break;
- }
- }
/*
* When starting a new swap upgrade, check that there is enough space.
@@ -493,10 +510,10 @@
first_trailer_idx--;
}
- if (g_last_idx >= first_trailer_idx) {
+ if (last_idx >= first_trailer_idx) {
BOOT_LOG_WRN("Not enough free space to run swap upgrade");
BOOT_LOG_WRN("required %d bytes but only %d are available",
- (g_last_idx + 1) * sector_sz ,
+ (last_idx + 1) * sector_sz,
first_trailer_idx * sector_sz);
bs->swap_type = BOOT_SWAP_TYPE_NONE;
return;
@@ -514,9 +531,9 @@
fixup_revert(state, bs, fap_sec);
if (bs->op == BOOT_STATUS_OP_MOVE) {
- idx = g_last_idx;
+ idx = last_idx;
while (idx > 0) {
- if (idx <= (g_last_idx - bs->idx + 1)) {
+ if (idx <= (last_idx - bs->idx + 1)) {
boot_move_sector_up(idx, sector_sz, state, bs, fap_pri, fap_sec);
}
idx--;
@@ -527,7 +544,7 @@
bs->op = BOOT_STATUS_OP_SWAP;
idx = 1;
- while (idx <= g_last_idx) {
+ while (idx <= last_idx) {
if (idx >= bs->idx) {
boot_swap_sectors(idx, sector_sz, state, bs, fap_pri, fap_sec);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment