boot: bootutil: drop flash_area_read_is_empty
Removes the current `flash_area_read_is_empty` which lacked a bit of
clarity in its naming and error handling, as well as requiring an
extra API in the flash map, and switches to using an internal function
`bootutil_buffer_is_erased`.
Code that was previously using `flash_area_read_is_empty` must now be
updated to do a `flash_area_read` followed by a call to
`bootutil_buffer_is_erased` with the read buffer.
The proposal was previously discussed here:
https://github.com/zephyrproject-rtos/zephyr/pull/28519
Signed-off-by: Fabio Utzig <fabio.utzig@nordicsemi.no>
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index a8b6b47..57ceff4 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -291,6 +291,27 @@
}
#endif
+bool bootutil_buffer_is_erased(const struct flash_area *area,
+ const void *buffer, size_t len)
+{
+ size_t i;
+ uint8_t *u8b;
+ uint8_t erased_val;
+
+ if (buffer == NULL || len == 0) {
+ return false;
+ }
+
+ erased_val = flash_area_erased_val(area);
+ for (i = 0, u8b = (uint8_t *)buffer; i < len; i++) {
+ if (u8b[i] != erased_val) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
int
boot_read_swap_state(const struct flash_area *fap,
struct boot_swap_state *state)
@@ -301,18 +322,18 @@
int rc;
off = boot_magic_off(fap);
- rc = flash_area_read_is_empty(fap, off, magic, BOOT_MAGIC_SZ);
+ rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
if (rc < 0) {
return BOOT_EFLASH;
}
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap, magic, BOOT_MAGIC_SZ)) {
state->magic = BOOT_MAGIC_UNSET;
} else {
state->magic = boot_magic_decode(magic);
}
off = boot_swap_info_off(fap);
- rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
+ rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
if (rc < 0) {
return BOOT_EFLASH;
}
@@ -321,30 +342,31 @@
state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
- if (rc == 1 || state->swap_type > BOOT_SWAP_TYPE_REVERT) {
+ if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info) ||
+ state->swap_type > BOOT_SWAP_TYPE_REVERT) {
state->swap_type = BOOT_SWAP_TYPE_NONE;
state->image_num = 0;
}
off = boot_copy_done_off(fap);
- rc = flash_area_read_is_empty(fap, off, &state->copy_done,
- sizeof state->copy_done);
+ rc = flash_area_read(fap, off, &state->copy_done, sizeof state->copy_done);
if (rc < 0) {
return BOOT_EFLASH;
}
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap, &state->copy_done,
+ sizeof state->copy_done)) {
state->copy_done = BOOT_FLAG_UNSET;
} else {
state->copy_done = boot_flag_decode(state->copy_done);
}
off = boot_image_ok_off(fap);
- rc = flash_area_read_is_empty(fap, off, &state->image_ok,
- sizeof state->image_ok);
+ rc = flash_area_read(fap, off, &state->image_ok, sizeof state->image_ok);
if (rc < 0) {
return BOOT_EFLASH;
}
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap, &state->image_ok,
+ sizeof state->image_ok)) {
state->image_ok = BOOT_FLAG_UNSET;
} else {
state->image_ok = boot_flag_decode(state->image_ok);
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index be9de71..16ec64e 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -326,6 +326,16 @@
#endif
/**
+ * Checks that a buffer is erased according to what the erase value for the
+ * flash device provided in `flash_area` is.
+ *
+ * @returns true if the buffer is erased; false if any of the bytes is not
+ * erased, or when buffer is NULL, or when len == 0.
+ */
+bool bootutil_buffer_is_erased(const struct flash_area *area,
+ const void *buffer, size_t len);
+
+/**
* Safe (non-overflowing) uint32_t addition. Returns true, and stores
* the result in *dest if it can be done without overflow. Otherwise,
* returns false.
diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c
index 995becf..940d646 100644
--- a/boot/bootutil/src/swap_misc.c
+++ b/boot/bootutil/src/swap_misc.c
@@ -164,8 +164,12 @@
rc = swap_read_status_bytes(fap, state, bs);
if (rc == 0) {
off = boot_swap_info_off(fap);
- rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
- if (rc == 1) {
+ rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
+ if (rc != 0) {
+ return BOOT_EFLASH;
+ }
+
+ if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info)) {
BOOT_SET_SWAP_INFO(swap_info, 0, BOOT_SWAP_TYPE_NONE);
rc = 0;
}
diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c
index 7332414..8c59843 100644
--- a/boot/bootutil/src/swap_move.c
+++ b/boot/bootutil/src/swap_move.c
@@ -142,12 +142,12 @@
write_sz = BOOT_WRITE_SZ(state);
off = boot_status_off(fap);
for (i = max_entries; i > 0; i--) {
- rc = flash_area_read_is_empty(fap, off + (i - 1) * write_sz, &status, 1);
+ rc = flash_area_read(fap, off + (i - 1) * write_sz, &status, 1);
if (rc < 0) {
return BOOT_EFLASH;
}
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap, &status, 1)) {
if (rc != last_rc) {
erased_sections++;
}
diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c
index 99c57f0..55fa61f 100644
--- a/boot/bootutil/src/swap_scratch.c
+++ b/boot/bootutil/src/swap_scratch.c
@@ -110,13 +110,13 @@
found_idx = 0;
invalid = 0;
for (i = 0; i < max_entries; i++) {
- rc = flash_area_read_is_empty(fap, off + i * BOOT_WRITE_SZ(state),
+ rc = flash_area_read(fap, off + i * BOOT_WRITE_SZ(state),
&status, 1);
if (rc < 0) {
return BOOT_EFLASH;
}
- if (rc == 1) {
+ if (bootutil_buffer_is_erased(fap, &status, 1)) {
if (found && !found_idx) {
found_idx = i;
}
diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
index 8b5fd0c..08deca5 100644
--- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h
+++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
@@ -82,14 +82,6 @@
*/
uint8_t flash_area_erased_val(const struct flash_area *fap);
-/*
- * Reads len bytes from off, and checks if the read data is erased.
- *
- * Returns 1 if erased, 0 if non-erased, and -1 on failure.
- */
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
- void *dst, uint32_t len);
-
#ifdef __cplusplus
}
#endif