Skip to content

Commit c601ade

Browse files
committed
bootloader: Add bootloader requests
Add a capability inside the Zephyr bootloader to handle memory-based bootloader requests to: - Boot recovery firmware - Boot firmware loader - Confirm an image - Set the slot preference Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent d24b28f commit c601ade

File tree

14 files changed

+623
-2
lines changed

14 files changed

+623
-2
lines changed

boot/bootutil/include/bootutil/boot_hooks.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@
8282

8383
#endif /* MCUBOOT_BOOT_GO_HOOKS */
8484

85+
#ifdef MCUBOOT_FIND_NEXT_SLOT_HOOKS
86+
87+
#define BOOT_HOOK_FIND_SLOT_CALL(f, ret_default, ...) \
88+
DO_HOOK_CALL(f, ret_default, __VA_ARGS__)
89+
90+
#else
91+
92+
#define BOOT_HOOK_FIND_SLOT_CALL(f, ret_default, ...) \
93+
HOOK_CALL_NOP(f, ret_default, __VA_ARGS__)
94+
95+
#endif /* MCUBOOT_FIND_NEXT_SLOT_HOOKS */
96+
8597
#ifdef MCUBOOT_FLASH_AREA_HOOKS
8698

8799
#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,
260272
#define BOOT_RESET_REQUEST_HOOK_CHECK_FAILED 3
261273
#define BOOT_RESET_REQUEST_HOOK_INTERNAL_ERROR 4
262274

275+
/**
276+
* Finds the preferred slot containing the image.
277+
*
278+
* @param[in] state Boot loader status information.
279+
* @param[in] image Image, for which the slot should be found.
280+
* @param[out] active_slot Number of the preferred slot.
281+
*
282+
* @return 0 if a slot was requested;
283+
* BOOT_HOOK_REGULAR follow the normal execution path.
284+
*/
285+
int boot_find_next_slot_hook(struct boot_loader_state *state, uint8_t image, uint32_t *active_slot);
286+
263287
#endif /*H_BOOTUTIL_HOOKS*/
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* Copyright (c) 2025 Nordic Semiconductor ASA
5+
*/
6+
7+
#ifndef __BOOT_REQUEST_H__
8+
#define __BOOT_REQUEST_H__
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
#include <stdint.h>
15+
#include <stdbool.h>
16+
17+
/** Special value, indicating that there is no preferred slot. */
18+
#define BOOT_REQUEST_NO_PREFERRED_SLOT UINT32_MAX
19+
20+
/**
21+
* @brief Request a bootloader to confirm the specified slot of an image.
22+
*
23+
* @param[in] image Image number.
24+
* @param[in] slot Slot number.
25+
*
26+
* @return 0 if requested, negative error code otherwise.
27+
*/
28+
int boot_request_confirm_slot(uint8_t image, uint32_t slot);
29+
30+
/**
31+
* @brief Request a bootloader to boot the specified slot of an image.
32+
*
33+
* @param[in] image Image number.
34+
* @param[in] slot Slot number.
35+
*
36+
* @return 0 if requested, negative error code otherwise.
37+
*/
38+
int boot_request_set_preferred_slot(uint8_t image, uint32_t slot);
39+
40+
/**
41+
* @brief Request a bootloader to boot recovery image.
42+
*
43+
* @return 0 if requested, negative error code otherwise.
44+
*/
45+
int boot_request_enter_recovery(void);
46+
47+
/**
48+
* @brief Request a bootloader to boot firmware loader image.
49+
*
50+
* @return 0 if requested, negative error code otherwise.
51+
*/
52+
int boot_request_enter_firmware_loader(void);
53+
54+
/**
55+
* @brief Check if there is a request to confirm the specified slot of an image.
56+
*
57+
* @param[in] image Image number.
58+
* @param[in] slot Slot number.
59+
*
60+
* @return true if requested, false otherwise.
61+
*/
62+
bool boot_request_check_confirmed_slot(uint8_t image, uint32_t slot);
63+
64+
/**
65+
* @brief Find if there is a request to boot certain slot of the specified image.
66+
*
67+
* @param[in] image Image number.
68+
*
69+
* @return slot number if requested, BOOT_REQUEST_NO_PREFERRED_SLOT otherwise.
70+
*/
71+
uint32_t boot_request_get_preferred_slot(uint8_t image);
72+
73+
/**
74+
* @brief Check if there is a request to boot recovery image.
75+
*
76+
* @return true if requested, false otherwise.
77+
*/
78+
bool boot_request_detect_recovery(void);
79+
80+
/**
81+
* @brief Check if there is a request to boot firmware loader image.
82+
*
83+
* @return true if requested, false otherwise.
84+
*/
85+
bool boot_request_detect_firmware_loader(void);
86+
87+
/**
88+
* @brief Initialize boot requests module.
89+
*
90+
* @return 0 if successful, negative error code otherwise.
91+
*/
92+
int boot_request_init(void);
93+
94+
/**
95+
* @brief Clear/drop all requests.
96+
*
97+
* @return 0 if successful, negative error code otherwise.
98+
*/
99+
int boot_request_clear(void);
100+
101+
#ifdef __cplusplus
102+
}
103+
#endif
104+
105+
#endif /* __BOOT_REQUEST_H__ */

boot/bootutil/src/loader.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3605,7 +3605,12 @@ boot_load_and_validate_images(struct boot_loader_state *state)
36053605
break;
36063606
}
36073607

3608-
active_slot = find_slot_with_highest_version(state);
3608+
rc = BOOT_HOOK_FIND_SLOT_CALL(boot_find_next_slot_hook, BOOT_HOOK_REGULAR,
3609+
state, BOOT_CURR_IMG(state), &active_slot);
3610+
if (rc == BOOT_HOOK_REGULAR) {
3611+
active_slot = find_slot_with_highest_version(state);
3612+
}
3613+
36093614
if (active_slot == NO_ACTIVE_SLOT) {
36103615
BOOT_LOG_INF("No slot to load for image %d",
36113616
BOOT_CURR_IMG(state));
@@ -3652,7 +3657,12 @@ boot_load_and_validate_images(struct boot_loader_state *state)
36523657
break;
36533658
}
36543659

3655-
active_slot = find_slot_with_highest_version(state);
3660+
rc = BOOT_HOOK_FIND_SLOT_CALL(boot_find_next_slot_hook, BOOT_HOOK_REGULAR,
3661+
state, BOOT_CURR_IMG(state), &active_slot);
3662+
if (rc == BOOT_HOOK_REGULAR) {
3663+
active_slot = find_slot_with_highest_version(state);
3664+
}
3665+
36563666
if (active_slot == NO_ACTIVE_SLOT) {
36573667
BOOT_LOG_INF("No slot to load for image %d",
36583668
BOOT_CURR_IMG(state));

boot/bootutil/zephyr/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ zephyr_library_named(mcuboot_util)
1616
zephyr_library_sources(
1717
../src/bootutil_public.c
1818
)
19+
if(CONFIG_MCUBOOT_BOOT_REQUEST)
20+
zephyr_library_sources_ifdef(CONFIG_MCUBOOT_BOOT_REQUEST_IMPL_RETENTION
21+
src/boot_request_retention.c
22+
)
23+
endif()
1924

2025
# Sensitivity to the TEST_BOOT_IMAGE_ACCESS_HOOKS define is implemented for
2126
# allowing the test-build with the hooks feature enabled.

0 commit comments

Comments
 (0)