Skip to content

Commit

Permalink
boot: add new copy with revert algorithm
Browse files Browse the repository at this point in the history
This algorithm uses three flash partitions to copy images to primary slot
without swap mechanism. This way much faster update process can be
achieved but more space on flash has to be allocated. This is basically
trade off between update speed and flash space taken for boot process.

The algorithm always keeps recovery image in either secondary or
tertiary slot and lets the user upload update image to the other one.
Once image is updated and confirmed, update slot is marked as recovery
(the image is already there uploaded by the user) and old recovery is
marked as new update -> user will upload new image there. This means
there are no writes to ota1 and ota2 partitions during boot process
except and therefore there is no speed limitation if usually slower
(compared to embedded flash) external NOR flash is used for these
partitions. The only exception is first update process where bootloader
has to create recovery image.

Overall, this algorithm allows to achieve the speed of overwrite only
algorithm while retaining the revert/recovery option. It is especially
useful for devices with larger images and a lot of free space on
external flash.

Signed-off-by: Michal Lenc <[email protected]>
  • Loading branch information
michallenc committed Feb 20, 2024
1 parent 460bea2 commit f8ec621
Show file tree
Hide file tree
Showing 9 changed files with 785 additions and 19 deletions.
1 change: 1 addition & 0 deletions boot/bootutil/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ target_sources(bootutil
src/bootutil_misc.c
src/bootutil_public.c
src/caps.c
src/copy.c
src/encrypted.c
src/fault_injection_hardening.c
src/fault_injection_hardening_delay_rng_mbedtls.c
Expand Down
35 changes: 35 additions & 0 deletions boot/bootutil/include/bootutil/bootutil_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Copyright (c) 2016-2019 JUUL Labs
* Copyright (c) 2019-2021 Arm Limited
* Copyright (c) 2020-2021 Nordic Semiconductor ASA
* Copyright (c) 2024 Elektroline Inc.
*
* Original license:
*
Expand Down Expand Up @@ -110,6 +111,8 @@ _Static_assert(MCUBOOT_BOOT_MAX_ALIGN >= 8 && MCUBOOT_BOOT_MAX_ALIGN <= 32,
#define BOOT_FLAG_BAD 2
#define BOOT_FLAG_UNSET 3
#define BOOT_FLAG_ANY 4 /* NOTE: control only, not dependent on sector */
#define BOOT_FLAG_UPDATED 5 /* NOTE: for copy with revert alg only */
#define BOOT_FLAG_AVAIL 6 /* NOTE: for copy with revert alg only */

#define BOOT_EFLASH 1
#define BOOT_EFILE 2
Expand Down Expand Up @@ -153,6 +156,25 @@ struct boot_swap_state {
uint8_t image_num; /* Boot status belongs to this image */
};

struct boot_copy_state {
int update; /* Number of update slot */
int recovery; /* Number of recovery slot */
bool recovery_valid; /* True if recovery image is valid */
};

/**
* @brief Determines the action, if any, that mcuboot will take on a image pair
* for copy with rever algorithm.
*
* @param image_index Image pair index.
* @param state Pointer to copy state structure.
*
* @return a BOOT_SWAP_TYPE_[...] constant on success, negative errno code on
* fail.
*/
int
boot_copy_type_multi(int image_index, struct boot_copy_state *state);

/**
* @brief Determines the action, if any, that mcuboot will take on a image pair.
*
Expand Down Expand Up @@ -258,6 +280,19 @@ int boot_read_image_ok(const struct flash_area *fap, uint8_t *image_ok);
int
boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state);

/**
* @brief Read the image copy state
*
* @param image_index Image index pair
* @param state Pointer to structure for storing copy state.
*
* @return 0 on success; non-zero error code on failure.
*/
#ifdef MCUBOOT_COPY_WITH_REVERT
int
boot_read_copy_state(int image_index, struct boot_copy_state *state);
#endif

/**
* @brief Read the image swap state
*
Expand Down
2 changes: 2 additions & 0 deletions boot/bootutil/src/bootutil_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,8 @@ uint32_t bootutil_max_image_size(const struct flash_area *fap)
*/
}
return flash_sector_get_off(&sector);
#elif defined(MCUBOOT_COPY_WITH_REVERT)
return boot_swap_info_off(fap);
#elif defined(MCUBOOT_OVERWRITE_ONLY)
return boot_swap_info_off(fap);
#elif defined(MCUBOOT_DIRECT_XIP)
Expand Down
16 changes: 13 additions & 3 deletions boot/bootutil/src/bootutil_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,12 @@ struct flash_area;

#define BOOT_TMPBUF_SZ 256

/** Number of image slots in flash; currently limited to two. */
#define BOOT_NUM_SLOTS 2
/** Number of image slots in flash; 3 if MCUBOOT_COPY_WITH_REVERT, 2 otherwise */
#ifdef MCUBOOT_COPY_WITH_REVERT
# define BOOT_NUM_SLOTS 3
#else
# define BOOT_NUM_SLOTS 2
#endif

#if (defined(MCUBOOT_OVERWRITE_ONLY) + \
defined(MCUBOOT_SWAP_USING_MOVE) + \
Expand All @@ -67,7 +71,8 @@ struct flash_area;
!defined(MCUBOOT_DIRECT_XIP) && \
!defined(MCUBOOT_RAM_LOAD) && \
!defined(MCUBOOT_SINGLE_APPLICATION_SLOT) && \
!defined(MCUBOOT_FIRMWARE_LOADER)
!defined(MCUBOOT_FIRMWARE_LOADER) && \
!defined(MCUBOOT_COPY_WITH_REVERT)
#define MCUBOOT_SWAP_USING_SCRATCH 1
#endif

Expand Down Expand Up @@ -197,6 +202,7 @@ _Static_assert(sizeof(boot_img_magic) == BOOT_MAGIC_SZ, "Invalid size for image

#define BOOT_PRIMARY_SLOT 0
#define BOOT_SECONDARY_SLOT 1
#define BOOT_TERTIARY_SLOT 2

#define BOOT_STATUS_SOURCE_NONE 0
#define BOOT_STATUS_SOURCE_SCRATCH 1
Expand Down Expand Up @@ -230,6 +236,10 @@ struct boot_loader_state {
} scratch;
#endif

#ifdef MCUBOOT_COPY_WITH_REVERT
struct boot_copy_state copy[BOOT_IMAGE_NUMBER];
#endif

uint8_t swap_type[BOOT_IMAGE_NUMBER];
uint32_t write_sz;

Expand Down
Loading

0 comments on commit f8ec621

Please sign in to comment.