Skip to content

Commit

Permalink
zephyr: Add support for swap using offset mode
Browse files Browse the repository at this point in the history
Adds support for using this mode to zephyr

Signed-off-by: Jamie McCrae <[email protected]>
  • Loading branch information
nordicjm committed Jan 2, 2025
1 parent d7f3058 commit 03b483b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
39 changes: 32 additions & 7 deletions boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,23 @@ else()
zephyr_library_sources(
${BOOT_DIR}/bootutil/src/loader.c
${BOOT_DIR}/bootutil/src/swap_misc.c
${BOOT_DIR}/bootutil/src/swap_scratch.c
${BOOT_DIR}/bootutil/src/swap_move.c
${BOOT_DIR}/bootutil/src/caps.c
)
endif()

if(CONFIG_BOOT_RAM_LOAD OR CONFIG_SINGLE_APPLICATION_SLOT_RAM_LOAD)
if(CONFIG_BOOT_SWAP_USING_MOVE)
zephyr_library_sources(
${BOOT_DIR}/bootutil/src/swap_move.c
)
elseif(CONFIG_BOOT_SWAP_USING_OFFSET)
zephyr_library_sources(
${BOOT_DIR}/bootutil/src/swap_offset.c
)
elseif(CONFIG_BOOT_SWAP_USING_SCRATCH)
zephyr_library_sources(
${BOOT_DIR}/bootutil/src/swap_scratch.c
)
elseif(CONFIG_BOOT_RAM_LOAD OR CONFIG_SINGLE_APPLICATION_SLOT_RAM_LOAD)
zephyr_library_sources(
${BOOT_DIR}/bootutil/src/ram_load.c
)
Expand Down Expand Up @@ -417,7 +427,7 @@ dt_get_parent(slot0_flash)
dt_prop(erase_size_slot0 PATH "${slot0_flash}" PROPERTY "erase-block-size")
dt_prop(write_size_slot0 PATH "${slot0_flash}" PROPERTY "write-block-size")

if(CONFIG_BOOT_SWAP_USING_MOVE)
if(CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_SWAP_USING_OFFSET)
if(DEFINED erase_size_slot0)
zephyr_compile_definitions("MCUBOOT_SLOT0_EXPECTED_ERASE_SIZE=${erase_size_slot0}")
endif()
Expand All @@ -435,7 +445,7 @@ if(NOT CONFIG_SINGLE_APPLICATION_SLOT AND NOT CONFIG_SINGLE_APPLICATION_SLOT_RAM
dt_prop(erase_size_slot1 PATH "${slot1_flash}" PROPERTY "erase-block-size")
dt_prop(write_size_slot1 PATH "${slot1_flash}" PROPERTY "write-block-size")

if(CONFIG_BOOT_SWAP_USING_MOVE)
if(CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_SWAP_USING_OFFSET)
if(DEFINED erase_size_slot1)
zephyr_compile_definitions("MCUBOOT_SLOT1_EXPECTED_ERASE_SIZE=${erase_size_slot1}")
endif()
Expand Down Expand Up @@ -477,12 +487,12 @@ if(CONFIG_BOOT_MAX_IMG_SECTORS_AUTO)
endif()
endif()

if((CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE) AND (DEFINED write_size_slot0 OR DEFINED write_size_slot1))
if((CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_SWAP_USING_OFFSET) AND (DEFINED write_size_slot0 OR DEFINED write_size_slot1))
zephyr_library_sources(flash_check.c)
endif()

if(SYSBUILD)
if(CONFIG_SINGLE_APPLICATION_SLOT OR CONFIG_BOOT_FIRMWARE_LOADER OR CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_UPGRADE_ONLY OR CONFIG_BOOT_DIRECT_XIP OR CONFIG_BOOT_RAM_LOAD)
if(CONFIG_SINGLE_APPLICATION_SLOT OR CONFIG_BOOT_FIRMWARE_LOADER OR CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_SWAP_USING_OFFSET OR CONFIG_BOOT_UPGRADE_ONLY OR CONFIG_BOOT_DIRECT_XIP OR CONFIG_BOOT_RAM_LOAD)
# TODO: RAM LOAD support
dt_nodelabel(slot0_flash NODELABEL "slot0_partition")
dt_get_parent(slot0_flash)
Expand Down Expand Up @@ -607,6 +617,17 @@ if(SYSBUILD)
math(EXPR boot_status_data_size "128 * (3 * ${write_size})")
endif()
endif()
elseif(CONFIG_BOOT_SWAP_USING_OFFSET)
if(CONFIG_BOOT_MAX_IMG_SECTORS_AUTO AND DEFINED slot_min_sectors AND "${slot_min_sectors}" GREATER "0")
math(EXPR boot_status_data_size "${slot_min_sectors} * (2 * ${write_size})")
else()
if(CONFIG_BOOT_MAX_IMG_SECTORS)
math(EXPR boot_status_data_size "${CONFIG_BOOT_MAX_IMG_SECTORS} * (2 * ${write_size})")
else()
message(WARNING "CONFIG_BOOT_MAX_IMG_SECTORS is not defined, falling back to 128 sector default. Please set CONFIG_BOOT_MAX_IMG_SECTORS to the required value")
math(EXPR boot_status_data_size "128 * (2 * ${write_size})")
endif()
endif()
else()
set(boot_status_data_size 0)
endif()
Expand All @@ -624,6 +645,10 @@ if(SYSBUILD)
if(CONFIG_BOOT_SWAP_USING_MOVE)
math(EXPR required_size "${required_size} + ${erase_size}")
math(EXPR required_upgrade_size "${required_upgrade_size} + ${erase_size}")
elseif(CONFIG_BOOT_SWAP_USING_OFFSET)
#todo: check how different slot sizes are...
# math(EXPR required_size "${required_size} + ${erase_size}")
# math(EXPR required_upgrade_size "${required_upgrade_size} + ${erase_size}")
endif()
else()
set(required_size 0)
Expand Down
27 changes: 25 additions & 2 deletions boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,17 @@ config BOOT_VALIDATE_SLOT0_ONCE
low end devices with as a compromise lowering the security level.
If unsure, leave at the default value.

config BOOT_PREFER_SWAP_OFFSET
bool "Prefer the newer swap offset algorithm"
# default y if SOC_FAMILY_NORDIC_NRF
# default y if !$(dt_nodelabel_enabled,scratch_partition)
help
If y, the BOOT_IMAGE_UPGRADE_MODE will default to using
"offset" instead of "scratch". This is a separate bool config
option, because Kconfig doesn't allow defaults to be
overridden in choice options. Most devices should be using
swap offset.

config BOOT_PREFER_SWAP_MOVE
bool "Prefer the newer swap move algorithm"
default y if SOC_FAMILY_NORDIC_NRF
Expand All @@ -272,6 +283,7 @@ config BOOT_PREFER_SWAP_MOVE
if !SINGLE_APPLICATION_SLOT
choice BOOT_IMAGE_UPGRADE_MODE
prompt "Image upgrade modes"
default BOOT_SWAP_USING_OFFSET if BOOT_PREFER_SWAP_OFFSET
default BOOT_SWAP_USING_MOVE if BOOT_PREFER_SWAP_MOVE
default BOOT_SWAP_USING_SCRATCH

Expand All @@ -288,8 +300,19 @@ config BOOT_UPGRADE_ONLY
of swapping them. This prevents the fallback recovery, but
uses a much simpler code path.

config BOOT_SWAP_USING_OFFSET
bool "Swap using offset mode without scratch partition"
help
If y, the swap upgrade is done by each sector X+1 in the secondary slot moved index X in
the primary slot, then the sector at X+1 in the primary is moved to index X in the
secondary.
This allows a swap upgrade without using a scratch partition, but is currently limited
to all sectors in both slots being of the same size. This mode offers faster swap times
with less flash endurance usage than swap using move, firmware updates must be placed at
the second sector in the second slot instead of the first.

config BOOT_SWAP_USING_MOVE
bool "Swap mode that can run without a scratch partition"
bool "Swap using mode mode without scratch partition"
help
If y, the swap upgrade is done in two steps, where first every
sector of the primary slot is moved up one sector, then for
Expand Down Expand Up @@ -727,7 +750,7 @@ config MCUBOOT_DOWNGRADE_PREVENTION
config MCUBOOT_DOWNGRADE_PREVENTION_SECURITY_COUNTER
bool "Use image security counter instead of version number"
depends on MCUBOOT_DOWNGRADE_PREVENTION
depends on (BOOT_SWAP_USING_MOVE || BOOT_SWAP_USING_SCRATCH)
depends on (BOOT_SWAP_USING_MOVE || BOOT_SWAP_USING_SCRATCH || BOOT_SWAP_USING_OFFSET)
help
Security counter is used for version eligibility check instead of pure
version. When this option is set, any upgrade must have greater or
Expand Down
4 changes: 4 additions & 0 deletions boot/zephyr/include/mcuboot_config/mcuboot_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@
#define MCUBOOT_SWAP_USING_MOVE 1
#endif

#ifdef CONFIG_BOOT_SWAP_USING_OFFSET
#define MCUBOOT_SWAP_USING_OFFSET 1
#endif

#ifdef CONFIG_BOOT_DIRECT_XIP
#define MCUBOOT_DIRECT_XIP
#endif
Expand Down
2 changes: 1 addition & 1 deletion boot/zephyr/include/sysflash/sysflash.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static inline uint32_t __flash_area_ids_for_slot(int img, int slot)
#define FLASH_AREA_IMAGE_PRIMARY(x) __flash_area_ids_for_slot(x, 0)
#define FLASH_AREA_IMAGE_SECONDARY(x) __flash_area_ids_for_slot(x, 1)

#if !defined(CONFIG_BOOT_SWAP_USING_MOVE)
#if !defined(CONFIG_BOOT_SWAP_USING_MOVE) && !defined(CONFIG_BOOT_SWAP_USING_OFFSET)
#define FLASH_AREA_IMAGE_SCRATCH FIXED_PARTITION_ID(scratch_partition)
#endif

Expand Down

0 comments on commit 03b483b

Please sign in to comment.