From e3a823c52c2ec13df13e3bbd554af574792a296e Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 12 Nov 2024 21:23:29 +0100 Subject: [PATCH] zephyr: Add support for devices without erase and reduced erases Add Kconfig options: - CONFIG_MCUBOOT_STORAGE_WITHOUT_ERASE that enables MCUboot configuration MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE - CONFIG_MCUBOOT_STORAGE_WITH_ERASE that enables MCUboot configuration MCUBOOT_SUPPORT_DEV_WITH_ERASE - CONFIG_MCUBOOT_STORAGE_MINIMAL_SCRAMBLE that enables MCUboot configuration MCUBOOT_MINIMAL_SCRAMBLE Adds implementation of flash_area_erase_required, which is required when MCUBOOT_STORAGE_DEV_WITHOUT_ERASE is enabled. Signed-off-by: Dominik Ermel --- boot/zephyr/Kconfig | 38 +++++++++++++++++++ .../flash_map_backend/flash_map_backend.h | 17 +++++++++ .../include/mcuboot_config/mcuboot_config.h | 23 +++++++++++ 3 files changed, 78 insertions(+) diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index d93014192..bb4b29a17 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -838,6 +838,44 @@ endif # BOOT_DECOMPRESSION_SUPPORT endmenu +config MCUBOOT_STORAGE_WITHOUT_ERASE + bool "Support for devices without erase" + depends on FLASH_HAS_NO_EXPLICIT_ERASE + help + Not all devices require erase before write and, depending on driver, + may emulate erase by write, as a way to scramble data rather then + by hardware requirement. This unfortunately means that code that + does erase before write, when not needed, will write device twice + which not only reduces device life time but also doubles time + of any write operation (one write for erase and one write for actual + write). + When this option is enabled, MCUboot will check for type of device + and will avoid erase where not needed. + +# The depends on FLASH_HAS_EXPLICIT_ERASE is intentionlally missing for now +# as so far Zephyr emulates erase on such devices anyway. +config MCUBOOT_STORAGE_WITH_ERASE + bool "Support for devices with erase" + default y + help + Support for devices with erase + +config MCUBOOT_STORAGE_MINIMAL_SCRAMBLE + bool "Do minimal required work to remove data" + help + In some cases MCUboot has to remove data, which usually means make + it non-viable for MCUboot rather then completely destroyed. + For example when MCUboot does not want to bother with broken image + in some slot it will remove it. + The same can be achieved with just removal of header, leaving the + rest of image untouched, as without header MCUboot will not be able + to recognize image in slot as bootable. + When this option is enabled, MCUboot will not attempt to erase + entire slot or image, instead it will just remove enough of + data from slot to not recognize it as image anymore. + Depending on type of device this may be done by erase of minimal + number of pages or overwrite of part of image. + config MCUBOOT_DEVICE_SETTINGS # Hidden selector for device-specific settings bool 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 e5408a18a..81a183259 100644 --- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h +++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h @@ -106,6 +106,23 @@ static inline uint32_t flash_sector_get_size(const struct flash_sector *fs) int flash_area_get_sector(const struct flash_area *fa, off_t off, struct flash_sector *fs); + +#if defined(CONFIG_MCUBOOT) +static inline bool flash_area_erase_required(const struct flash_area *fa) +{ +#if defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) && defined(CONFIG_FLASH_HAS_NO_EXPLICIT_ERASE) + const struct flash_parameters *fp = flash_get_parameters(flash_area_get_device(fa)); + + return flash_params_get_erase_cap(flash_get_parameters(flash_area_get_device(fa))) & + FLASH_ERASE_C_EXPLICIT; +#elif defined(CONFIG_FLASH_HAS_EXPLICIT_ERASE) + return true; +#else + return false; +#endif +} +#endif + #ifdef __cplusplus } #endif diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 573155b39..6545e1026 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -280,6 +280,29 @@ #define MCUBOOT_ERASE_PROGRESSIVELY #endif +/* + * Devices that do not require erase prior to write or do not support + * erase should avoid emulation of erase by additional write. + * The emulation is also taking time which doubles required write time + * for such devices. + */ +#ifdef CONFIG_MCUBOOT_STORAGE_WITHOUT_ERASE +#define MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE +#endif + +#ifdef CONFIG_MCUBOOT_STORAGE_WITH_ERASE +#define MCUBOOT_SUPPORT_DEV_WITH_ERASE +#endif + +/* + * MCUboot often calls erase on device just to remove data or make application + * image not recognizable. In such instances it may be faster to just remove + * portion of data to make image unrecognizable. + */ +#ifdef CONFIG_MCUBOOT_STORAGE_MINIMAL_SCRAMBLE +#define MCUBOOT_MINIMAL_SCRAMBLE +#endif + /* * Enabling this option uses newer flash map APIs. This saves RAM and * avoids deprecated API usage.