diff --git a/boot/bootutil/include/bootutil/boot_hooks.h b/boot/bootutil/include/bootutil/boot_hooks.h index ef7a89b28..f5b10e8c7 100644 --- a/boot/bootutil/include/bootutil/boot_hooks.h +++ b/boot/bootutil/include/bootutil/boot_hooks.h @@ -82,6 +82,18 @@ #endif /* MCUBOOT_BOOT_GO_HOOKS */ +#ifdef MCUBOOT_FIND_NEXT_SLOT_HOOKS + +#define BOOT_HOOK_FIND_SLOT_CALL(f, ret_default, ...) \ + DO_HOOK_CALL(f, ret_default, __VA_ARGS__) + +#else + +#define BOOT_HOOK_FIND_SLOT_CALL(f, ret_default, ...) \ + HOOK_CALL_NOP(f, ret_default, __VA_ARGS__) + +#endif /* MCUBOOT_FIND_NEXT_SLOT_HOOKS */ + #ifdef MCUBOOT_FLASH_AREA_HOOKS #define BOOT_HOOK_FLASH_AREA_CALL(f, ret_default, ...) \ @@ -260,4 +272,16 @@ int flash_area_get_device_id_hook(const struct flash_area *fa, #define BOOT_RESET_REQUEST_HOOK_CHECK_FAILED 3 #define BOOT_RESET_REQUEST_HOOK_INTERNAL_ERROR 4 +/** + * Finds the preferred slot containing the image. + * + * @param[in] state Boot loader status information. + * @param[in] image Image, for which the slot should be found. + * @param[out] active_slot Number of the preferred slot. + * + * @return 0 if a slot was requested; + * BOOT_HOOK_REGULAR follow the normal execution path. + */ +int boot_find_next_slot_hook(struct boot_loader_state *state, uint8_t image, uint32_t *active_slot); + #endif /*H_BOOTUTIL_HOOKS*/ diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index d30cd6c9c..2bde6f9fe 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -2818,7 +2818,12 @@ boot_load_and_validate_images(struct boot_loader_state *state) break; } - active_slot = find_slot_with_highest_version(state); + rc = BOOT_HOOK_FIND_SLOT_CALL(boot_find_next_slot_hook, BOOT_HOOK_REGULAR, + state, BOOT_CURR_IMG(state), &active_slot); + if (rc == BOOT_HOOK_REGULAR) { + active_slot = find_slot_with_highest_version(state); + } + if (active_slot == NO_ACTIVE_SLOT) { BOOT_LOG_INF("No slot to load for image %d", BOOT_CURR_IMG(state)); @@ -2865,7 +2870,12 @@ boot_load_and_validate_images(struct boot_loader_state *state) break; } - active_slot = find_slot_with_highest_version(state); + rc = BOOT_HOOK_FIND_SLOT_CALL(boot_find_next_slot_hook, BOOT_HOOK_REGULAR, + state, BOOT_CURR_IMG(state), &active_slot); + if (rc == BOOT_HOOK_REGULAR) { + active_slot = find_slot_with_highest_version(state); + } + if (active_slot == NO_ACTIVE_SLOT) { BOOT_LOG_INF("No slot to load for image %d", BOOT_CURR_IMG(state)); diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 4de80ec0e..a59a256ca 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1096,6 +1096,13 @@ config MCUBOOT_ACTION_HOOKS 'mcuboot_status_type_t' is listed in boot/bootutil/include/bootutil/mcuboot_status.h +config FIND_NEXT_SLOT_HOOKS + bool "Enable hooks for finding the next active slot" + help + Allow to provide procedures for override or extend the search policy + for the best slot to boot in the Direct XIP mode. + By default a slot with the highest version is selected. + config BOOT_DISABLE_CACHES bool "Disable I/D caches before chain-loading application" depends on CPU_HAS_ICACHE || CPU_HAS_DCACHE diff --git a/boot/zephyr/hooks_sample.c b/boot/zephyr/hooks_sample.c index a5a729314..fc7bd2fa4 100644 --- a/boot/zephyr/hooks_sample.c +++ b/boot/zephyr/hooks_sample.c @@ -93,3 +93,8 @@ int boot_img_install_stat_hook(int image_index, int slot, int *img_install_stat) { return BOOT_HOOK_REGULAR; } + +int boot_find_next_slot_hook(struct boot_loader_state *state, uint8_t image, uint32_t *active_slot) +{ + return BOOT_HOOK_REGULAR; +} diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 49043051d..5f5a685fe 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -278,6 +278,10 @@ #define MCUBOOT_FLASH_AREA_HOOKS #endif +#ifdef CONFIG_FIND_NEXT_SLOT_HOOKS +#define MCUBOOT_FIND_NEXT_SLOT_HOOKS +#endif + #ifdef CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS #define MCUBOOT_VERIFY_IMG_ADDRESS #endif