From 7223ba74362567f8eab198150e382c4dfdfc6ad6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Tue, 17 Sep 2024 12:17:13 +0100 Subject: [PATCH] [nrf noup] treewide: Add child/parent support back for image numbers Adds support for child/parent images into the new dynamic image number system, without supporting any of the new features. This commit is scheduled to be removed from the tree when child/parent support is dropped so is purposely kept separate Signed-off-by: Jamie McCrae --- boot/bootutil/src/loader.c | 66 +++++++++++++++++++++- boot/zephyr/CMakeLists.txt | 19 +++++++ boot/zephyr/include/sysflash/pm_sysflash.h | 29 ++++++++-- 3 files changed, 106 insertions(+), 8 deletions(-) diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 410d620f0..39bc9e56c 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -161,6 +161,14 @@ boot_read_image_headers(struct boot_loader_state *state, bool require_all, if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER && i == 0) { continue; } +#elif defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED) + /* Patch needed for NCS. The primary slot of the second image + * (image 1) will not contain a valid image header until an upgrade + * of mcuboot has happened (filling S1 with the new version). + */ + if (BOOT_CURR_IMG(state) == LEGACY_CHILD_PARENT_S0_S1_UPDATE_IMAGE_ID && i == 0) { + continue; + } #endif /* CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 */ if (i > 0 && !require_all) { return 0; @@ -1157,10 +1165,13 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION) if (slot != BOOT_PRIMARY_SLOT) { /* Check if version of secondary slot is sufficient */ - #if defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) \ && defined(CONFIG_PCD_APP) && defined(CONFIG_PCD_READ_NETCORE_APP_VERSION) +#if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { +#elif defined(LEGACY_CHILD_PARENT_NETWORK_CORE_UPDATE_ENABLED) + if (BOOT_CURR_IMG(state) == LEGACY_CHILD_PARENT_NETWORK_CORE_UPDATE_IMAGE_ID) { +#endif rc = pcd_version_cmp_net(fap, boot_img_hdr(state, BOOT_SECONDARY_SLOT)); } else { rc = boot_version_cmp( @@ -1243,12 +1254,18 @@ boot_validate_slot(struct boot_loader_state *state, int slot, * Its flash_area hasn't got relevant boundaries. * Therfore need to override its boundaries for the check. */ +#if CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER != -1 if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_NETWORK_CORE_IMAGE_NUMBER) { +#elif defined(LEGACY_CHILD_PARENT_NETWORK_CORE_UPDATE_ENABLED) + if (BOOT_CURR_IMG(state) == LEGACY_CHILD_PARENT_NETWORK_CORE_UPDATE_IMAGE_ID) { +#endif min_addr = PM_CPUNET_APP_ADDRESS; max_addr = PM_CPUNET_APP_ADDRESS + PM_CPUNET_APP_SIZE; check_addresses = true; } else #endif +#ifndef LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED + /* Sysbuild */ #if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { #if (CONFIG_NCS_IS_VARIANT_IMAGE) @@ -1276,6 +1293,23 @@ boot_validate_slot(struct boot_loader_state *state, int slot, #endif check_addresses = true; } +#else + /* Legacy child/parent support */ + if (BOOT_CURR_IMG(state) == LEGACY_CHILD_PARENT_S0_S1_UPDATE_IMAGE_ID) { +#if (CONFIG_NCS_IS_VARIANT_IMAGE) + min_addr = MIN(pri_fa->fa_off, PM_S0_ADDRESS); + max_addr = MAX((pri_fa->fa_off + pri_fa->fa_size), (PM_S0_ADDRESS + PM_S0_SIZE)); +#else + min_addr = MIN(pri_fa->fa_off, PM_S1_ADDRESS); + max_addr = MAX((pri_fa->fa_off + pri_fa->fa_size), (PM_S1_ADDRESS + PM_S1_SIZE)); +#endif + check_addresses = true; + } else { + min_addr = pri_fa->fa_off; + max_addr = pri_fa->fa_off + pri_fa->fa_size; + check_addresses = true; + } +#endif /* !LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED */ if (check_addresses == true && (reset_value < min_addr || reset_value > max_addr)) { BOOT_LOG_ERR("Reset address of image in secondary slot is not in the primary slot"); @@ -1490,13 +1524,18 @@ boot_validated_swap_type(struct boot_loader_state *state, #else if (reset_addr >= PM_S1_ADDRESS && PM_S1_ADDRESS <= (PM_S1_ADDRESS + PM_S1_SIZE)) { #endif +#if !defined(LEGACY_CHILD_PARENT_BUILD) + /* Sysbuild */ if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_APPLICATION_IMAGE_NUMBER) { /* This is not the s0/s1 upgrade image but the application image, pretend * there is no image so the NSIB update can be loaded */ return BOOT_SWAP_TYPE_NONE; } -#if 0 && defined(CONFIG_SOC_NRF5340_CPUAPP) && defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) +#else +#if defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED) && defined(CONFIG_SOC_NRF5340_CPUAPP) && \ +defined(CONFIG_NRF53_MULTI_IMAGE_UPDATE) + /* Legacy parent/child image */ const struct flash_area *nsib_fa; /* NSIB upgrade slot */ @@ -1512,6 +1551,7 @@ boot_validated_swap_type(struct boot_loader_state *state, /* Set primary to be NSIB upgrade slot */ BOOT_IMG_AREA(state, 0) = nsib_fa; +#endif #endif owner_nsib[BOOT_CURR_IMG(state)] = true; #if (CONFIG_NCS_IS_VARIANT_IMAGE) @@ -2068,9 +2108,15 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs) flash_area_close(fap); } -#if defined(PM_S1_ADDRESS) && !MCUBOOT_OVERWRITE_ONLY && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 +#if defined(PM_S1_ADDRESS) && !MCUBOOT_OVERWRITE_ONLY && (CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED)) if (owner_nsib[BOOT_CURR_IMG(state)]) { +#ifndef LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED + /* Sysbuild */ if (BOOT_CURR_IMG(state) == CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER) { +#else + /* Legacy child/parent support */ + if (BOOT_CURR_IMG(state) == LEGACY_CHILD_PARENT_S0_S1_UPDATE_IMAGE_ID) { +#endif /* For NSIB, move the image instead of swapping it */ nsib_swap_run(state, bs); @@ -2749,6 +2795,15 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) rc = boot_perform_update(state, &bs); } assert(rc == 0); + +#if defined(LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED) && defined(PM_S1_ADDRESS) && \ +defined(CONFIG_REBOOT) + /* Legacy child/parent support */ + if (owner_nsib[BOOT_CURR_IMG(state)]) { + sys_reboot(SYS_REBOOT_COLD); + } +#endif + break; case BOOT_SWAP_TYPE_FAIL: @@ -2823,7 +2878,12 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) * does not need to also be validated by MCUBoot. */ bool image_validated_by_nsib = BOOT_CURR_IMG(state) == +#ifndef LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER; +#else + LEGACY_CHILD_PARENT_S0_S1_UPDATE_IMAGE_ID; +#endif + if (!image_validated_by_nsib) #endif { diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index 4587681e5..e26bc59e5 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -134,6 +134,19 @@ zephyr_library_sources( ) endif() +if(NOT SYSBUILD) + # Check if this is a legacy child/parent image build + cmake_path(GET CMAKE_BINARY_DIR PARENT_PATH parent_build_dir) + string(LENGTH ${parent_build_dir} parent_build_dir_len) + math(EXPR parent_build_dir_len "${parent_build_dir_len} + 1") + string(SUBSTRING ${CMAKE_BINARY_DIR} ${parent_build_dir_len} -1 current_dir_name) + + if("${current_dir_name}" STREQUAL "mcuboot" AND EXISTS ${parent_build_dir}/image_preload.cmake) + zephyr_compile_definitions(LEGACY_CHILD_PARENT_BUILD=1) + set(LEGACY_CHILD_PARENT_BUILD y) + endif() +endif() + if(CONFIG_SINGLE_APPLICATION_SLOT) zephyr_library_sources( ${BOOT_DIR}/zephyr/single_loader.c @@ -154,6 +167,12 @@ zephyr_library_sources( ) if(NOT CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER EQUAL "-1" AND NOT CONFIG_BOOT_UPGRADE_ONLY) + # Sysbuild + zephyr_library_sources( + ${BOOT_DIR}/bootutil/src/swap_nsib.c + ) + elseif(LEGACY_CHILD_PARENT_BUILD AND CONFIG_SOC_NRF5340_CPUAPP AND (CONFIG_UPDATEABLE_IMAGE_NUMBER GREATER "2" OR (CONFIG_UPDATEABLE_IMAGE_NUMBER EQUAL "2" AND NOT CONFIG_PCD_APP)) AND NOT CONFIG_BOOT_UPGRADE_ONLY) + # Legacy child/parent image support zephyr_library_sources( ${BOOT_DIR}/bootutil/src/swap_nsib.c ) diff --git a/boot/zephyr/include/sysflash/pm_sysflash.h b/boot/zephyr/include/sysflash/pm_sysflash.h index 67aca2fc1..e5b818083 100644 --- a/boot/zephyr/include/sysflash/pm_sysflash.h +++ b/boot/zephyr/include/sysflash/pm_sysflash.h @@ -21,23 +21,42 @@ #define FLASH_AREA_IMAGE_2_SLOTS PM_MCUBOOT_PRIMARY_2_ID, PM_MCUBOOT_SECONDARY_2_ID, #define FLASH_AREA_IMAGE_3_SLOTS PM_MCUBOOT_PRIMARY_3_ID, PM_MCUBOOT_SECONDARY_3_ID, +#ifndef LEGACY_CHILD_PARENT_BUILD +/* Sysbuild */ #if CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 #ifdef CONFIG_NCS_IS_VARIANT_IMAGE #define MCUBOOT_S0_S1_SLOTS PM_S0_ID, PM_MCUBOOT_SECONDARY_ID, #else #define MCUBOOT_S0_S1_SLOTS PM_S1_ID, PM_MCUBOOT_SECONDARY_ID, #endif -#define MCUBOOT_IMAGE_NUMBER_WITHOUT_MCUBOOT_S0_S1 (MCUBOOT_IMAGE_NUMBER - 1) #else -#define MCUBOOT_IMAGE_NUMBER_WITHOUT_MCUBOOT_S0_S1 MCUBOOT_IMAGE_NUMBER +#define MCUBOOT_S0_S1_SLOTS +#endif +#else +/* Legacy child/parent image */ +#if defined(PM_B0_ADDRESS) +/* If B0 is present then two bootloaders are present, and we must use + * a single secondary slot for both primary slots. + */ +extern uint32_t _image_1_primary_slot_id[]; +#define MCUBOOT_S0_S1_SLOTS (uint32_t)_image_1_primary_slot_id, PM_MCUBOOT_SECONDARY_ID, +#define LEGACY_CHILD_PARENT_S0_S1_UPDATE_ENABLED 1 +#define LEGACY_CHILD_PARENT_S0_S1_UPDATE_IMAGE_ID 1 +#else +#define MCUBOOT_S0_S1_SLOTS +#endif /* defined(PM_B0_ADDRESS) */ +#if defined(PM_CPUNET_APP_ADDRESS) +#define LEGACY_CHILD_PARENT_NETWORK_CORE_UPDATE_ENABLED 1 +#define LEGACY_CHILD_PARENT_NETWORK_CORE_UPDATE_IMAGE_ID 1 +#endif /* defined(PM_CPUNET_APP_ADDRESS) */ #endif -#if (MCUBOOT_IMAGE_NUMBER == 1) || (MCUBOOT_IMAGE_NUMBER == 2 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) +#if ((MCUBOOT_IMAGE_NUMBER == 1) || (MCUBOOT_IMAGE_NUMBER == 2 && (CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || (defined(LEGACY_CHILD_PARENT_BUILD) && defined(PM_B0_ADDRESS))))) #define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 2) || (MCUBOOT_IMAGE_NUMBER == 3 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) +#elif ((MCUBOOT_IMAGE_NUMBER == 2) || (MCUBOOT_IMAGE_NUMBER == 3 && (CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || (defined(LEGACY_CHILD_PARENT_BUILD) && defined(PM_B0_ADDRESS))))) #define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ FLASH_AREA_IMAGE_1_SLOTS -#elif (MCUBOOT_IMAGE_NUMBER == 3) || (MCUBOOT_IMAGE_NUMBER == 4 && CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1) +#elif ((MCUBOOT_IMAGE_NUMBER == 3) || (MCUBOOT_IMAGE_NUMBER == 4 && (CONFIG_MCUBOOT_MCUBOOT_IMAGE_NUMBER != -1 || (defined(LEGACY_CHILD_PARENT_BUILD) && defined(PM_B0_ADDRESS))))) #define ALL_AVAILABLE_SLOTS FLASH_AREA_IMAGE_0_SLOTS \ FLASH_AREA_IMAGE_1_SLOTS \ FLASH_AREA_IMAGE_2_SLOTS