diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index ed490e6ee6..d22fefa9ff 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -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 ) @@ -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() @@ -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() @@ -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) @@ -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() @@ -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) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index d930141925..333fb56b46 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -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 @@ -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 @@ -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 @@ -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 diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 573155b39a..551f6644f7 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -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 diff --git a/boot/zephyr/include/sysflash/sysflash.h b/boot/zephyr/include/sysflash/sysflash.h index 1952950b92..16d2222805 100644 --- a/boot/zephyr/include/sysflash/sysflash.h +++ b/boot/zephyr/include/sysflash/sysflash.h @@ -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