From eaae6500a7bd825d9ad882739a1975e1e9b7eac1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 25 Jul 2024 14:36:46 +0100 Subject: [PATCH] zephyr: Add support for automatically calculcating max sectors Adds a feature that will calculate the maximum number of sectors that are needed for a build. Can be disabled to revert back to the old behaviour by disabling CONFIG_BOOT_MAX_IMG_SECTORS_AUTO Signed-off-by: Jamie McCrae --- boot/zephyr/CMakeLists.txt | 73 +++++++++++++++---- boot/zephyr/Kconfig | 12 +++ .../include/mcuboot_config/mcuboot_config.h | 6 +- 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 45548e0c3..d02f93a40 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -363,23 +363,66 @@ if(CONFIG_MCUBOOT_BOOT_BANNER) zephyr_sources(kernel/banner.c) endif() -if(SYSBUILD) - function(align_up num align result) - math(EXPR out "(((${num}) + ((${align}) - 1)) & ~((${align}) - 1))") - set(${result} "${out}" PARENT_SCOPE) - endfunction() +function(align_up num align result) + math(EXPR out "(((${num}) + ((${align}) - 1)) & ~((${align}) - 1))") + set(${result} "${out}" PARENT_SCOPE) +endfunction() + +function(dt_get_parent node) + string(FIND "${${node}}" "/" pos REVERSE) + + if(pos EQUAL -1) + message(ERROR "Unable to get parent of node: ${${node}}") + endif() - function(dt_get_parent node) - string(FIND "${${node}}" "/" pos REVERSE) + string(SUBSTRING "${${node}}" 0 ${pos} ${node}) + set(${node} "${${node}}" PARENT_SCOPE) +endfunction() + +if(CONFIG_BOOT_MAX_IMG_SECTORS_AUTO) + dt_nodelabel(slot0_flash NODELABEL "slot0_partition") + dt_prop(slot0_size PATH "${slot0_flash}" PROPERTY "reg" INDEX 1) + dt_get_parent(slot0_flash) + dt_get_parent(slot0_flash) + dt_prop(erase_size_slot0 PATH "${slot0_flash}" PROPERTY "erase-block-size") + + if(NOT DEFINED slot0_size) + message(WARNING "Unable to determine size of slot0 partition, cannot calculate minimum sector usage") + elseif(NOT DEFINED erase_size_slot0) + message(WARNING "Unable to determine erase size of slot0 partition, cannot calculate minimum sector usage") + else() + math(EXPR slot_min_sectors "${slot0_size} / ${erase_size_slot0}") + endif() + + if(NOT CONFIG_SINGLE_APPLICATION_SLOT) + dt_nodelabel(slot1_flash NODELABEL "slot1_partition") + dt_prop(slot1_size PATH "${slot1_flash}" PROPERTY "reg" INDEX 1) + dt_get_parent(slot1_flash) + dt_get_parent(slot1_flash) + dt_prop(erase_size_slot1 PATH "${slot1_flash}" PROPERTY "erase-block-size") + + if(NOT DEFINED slot1_size) + message(WARNING "Unable to determine size of slot1 partition, cannot calculate minimum sector usage") + elseif(NOT DEFINED erase_size_slot1) + message(WARNING "Unable to determine erase size of slot1 partition, cannot calculate minimum sector usage") + else() + math(EXPR slot1_min_sectors "${slot1_size} / ${erase_size_slot1}") - if(pos EQUAL -1) - message(ERROR "Unable to get parent of node: ${${node}}") + if("${slot1_min_sectors}" GREATER "${slot_min_sectors}") + set(slot_min_sectors ${slot1_min_sectors}) + endif() endif() + endif() - string(SUBSTRING "${${node}}" 0 ${pos} ${node}) - set(${node} "${${node}}" PARENT_SCOPE) - endfunction() + if(DEFINED slot_min_sectors AND "${slot_min_sectors}" GREATER "0") + zephyr_compile_definitions("MIN_SECTOR_COUNT=${slot_min_sectors}") + message("Calculated maximum number of sectors: ${slot_min_sectors}") + else() + message(WARNING "Unable to calculate minimum number of sector sizes, falling back to 128 sector default. Please disable CONFIG_BOOT_MAX_IMG_SECTORS_AUTO and set CONFIG_BOOT_MAX_IMG_SECTORS to the required value") + endif() +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) # TODO: RAM LOAD support dt_nodelabel(slot0_flash NODELABEL "slot0_partition") @@ -495,7 +538,11 @@ if(SYSBUILD) endif() if(CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE) - math(EXPR boot_status_data_size "${CONFIG_BOOT_MAX_IMG_SECTORS} * (3 * ${write_size})") + 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} * (3 * ${write_size})") + else() + math(EXPR boot_status_data_size "${CONFIG_BOOT_MAX_IMG_SECTORS} * (3 * ${write_size})") + endif() else() set(boot_status_data_size 0) endif() diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index effedfb4f..bf772cac7 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -380,9 +380,21 @@ config BOOT_ENCRYPTION_KEY_FILE with the public key information will be written in a format expected by MCUboot. +config BOOT_MAX_IMG_SECTORS_AUTO + bool "Calculate maximum sectors automatically" + default y + help + If this option is enabled then the maximum number of supported sectors per image will + be calculated automatically from the flash erase sizes and size of each partition for + the first image. + + If this information is not available, or multiple images are used, then this option + should be disabled and BOOT_MAX_IMG_SECTORS should be set instead + config BOOT_MAX_IMG_SECTORS int "Maximum number of sectors per image slot" default 128 + depends on !BOOT_MAX_IMG_SECTORS_AUTO help This option controls the maximum number of sectors that each of the two image areas can contain. Smaller values reduce MCUboot's diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 8f5d17bf5..ab2e8baec 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -270,7 +270,11 @@ # endif #endif -#ifdef CONFIG_BOOT_MAX_IMG_SECTORS +#if defined(CONFIG_BOOT_MAX_IMG_SECTORS_AUTO) && defined(MIN_SECTOR_COUNT) + +#define MCUBOOT_MAX_IMG_SECTORS MIN_SECTOR_COUNT + +#elif defined(CONFIG_BOOT_MAX_IMG_SECTORS) #define MCUBOOT_MAX_IMG_SECTORS CONFIG_BOOT_MAX_IMG_SECTORS