Skip to content

Zephyr: introduce bootloader requests #477

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

tomchy
Copy link
Contributor

@tomchy tomchy commented Jul 24, 2025

In some cases, a Zephyr platform is not able to use the RAM-based retention subsystem. This results in no ability to communicate with the bootloader to:

  • Request the recovery mode from the main application
  • Request the firmware loader mode from the main application

The other case in which the application wants to communicate with the bootloader are platforms that want to have the active slot configured as read-only. In such case, the following flow can be introduced to mitigate this restriction:

  • The main application sends a request to the bootloader informing which image should be confirmed.
  • The main application reboots the device.
  • The device reboots and resets memory permissions so that the bootloader can perform the updates.
  • In the permitted state, the bootloader processes the confirmation requests, before analyzing the state of the slots.
  • The bootloader continues the logic as if the application had confirmed the slot.

There is also a third use case for the application requests in the Direct XIP mode:

  • Currently, the decision of which slot to boot is based only on the version number.
  • Even if there are two valid slots on the device, a user cannot request a temporary rollback to the previous firmware.
  • By introducing a request for slot preference, the slot selection logic may be extended with custom logic that runs as part of the main application and sends such a request to the bootloader to alter the default behavior.

This PR introduces an API that can be used to collect all of the above requests in a single module.
The Kconfig to select or extend the boot request format is located in the configuration file of the mcuboot module in the Zephyr repository.
In addition, a simple integration with bootutil library is included, allowing this feature to be used with an existing MCUmgr implementation.

@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from 832b4c9 to ce1a921 Compare July 25, 2025 12:15
@tomchy tomchy requested a review from ahasztag July 25, 2025 12:23
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from ce1a921 to f6f21a3 Compare July 28, 2025 10:50
@tomchy tomchy marked this pull request as ready for review July 28, 2025 11:07
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from f6f21a3 to 0b5d331 Compare July 28, 2025 14:30
@tomchy tomchy requested a review from nordicjm July 28, 2025 14:34
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from 0b5d331 to 911bb8c Compare July 29, 2025 09:38
@tomchy tomchy requested a review from ahasztag July 29, 2025 09:38
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from 911bb8c to 2be0d3d Compare July 29, 2025 10:31
@tomchy tomchy requested a review from ahasztag July 29, 2025 10:35
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch 3 times, most recently from 4e1ece5 to 9be377a Compare July 31, 2025 14:48
Comment on lines +40 to +52
/**
* @brief Request a bootloader to boot recovery image.
*
* @return 0 if requested, negative error code otherwise.
*/
int boot_request_enter_recovery(void);

/**
* @brief Request a bootloader to boot firmware loader image.
*
* @return 0 if requested, negative error code otherwise.
*/
int boot_request_enter_firmware_loader(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can both be combined into boot_request_enter_recovery there is either serial recovery or firmware loader, not both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not really like to enter firmware loader by calling boot_request_enter_recovery API.

Comment on lines +73 to +85
/**
* @brief Check if there is a request to boot recovery image.
*
* @return true if requested, false otherwise.
*/
bool boot_request_detect_recovery(void);

/**
* @brief Check if there is a request to boot firmware loader image.
*
* @return true if requested, false otherwise.
*/
bool boot_request_detect_firmware_loader(void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above


enum boot_request_type {
/** Invalid request. */
BOOT_REQUEST_INVALID = 0,
Copy link
Contributor

@nordicjm nordicjm Aug 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit. enums start at 0 and count up anyway, the values don't need to be explicitly set

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to keep explicit values in enums if they define a value, that is shared between two contexts (app and bl), even if they follow the "automatic" assignment.

Comment on lines 102 to 108
*slot = 0;
break;
case BOOT_REQUEST_IMG_PREFERENCE:
*slot = 1 + image * BOOT_REQUEST_PER_IMAGE;
break;
case BOOT_REQUEST_IMG_CONFIRM:
*slot = 2 + image * BOOT_REQUEST_PER_IMAGE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use enum for what these values mean, can actually then have a _COUNT in the enum and use that for the number of states instead of just defining to 2 separately

Comment on lines 150 to 155
case 0:
value = BOOT_REQUEST_SLOT_PRIMARY;
break;
case 1:
value = BOOT_REQUEST_SLOT_SECONDARY;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above

Comment on lines 207 to 212
case 0:
value = BOOT_REQUEST_SLOT_PRIMARY;
break;
case 1:
value = BOOT_REQUEST_SLOT_SECONDARY;
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and further below

* @return 0 on success; nonzero on failure.
*/
static int
boot_request_slot_find(enum boot_request_type type, boot_request_img_t image, size_t *slot)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

slot term is used for image partitions in MCUboot.
Can we have different name there - index, reqest_idx, req_idx, entry_idx?
And so one for any code related to request entries?

Copy link
Contributor Author

@tomchy tomchy Aug 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to go with the entry name instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wonder whether flash_area_to_image() -> flash_area_to_image() can more associated with a upstream patch?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yet I do not have an argument, why this change is needed there...

@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch 2 times, most recently from ad1c9eb to dc8f8c6 Compare August 1, 2025 11:14
@tomchy tomchy requested review from nordicjm and nvlsianpu August 1, 2025 11:21
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from dc8f8c6 to cb3eee7 Compare August 1, 2025 14:16
@tomchy tomchy force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from cb3eee7 to 0ac02e0 Compare August 1, 2025 15:19
tomchy added 2 commits August 18, 2025 08:58
Add a bootloader hook to alter the logic of the active slot selection in
Direct XIP modes.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
(cherry picked from commit 7c4ec9a)
Add a Kconfig option to enable a bootloader hook to alter
the logic of the active slot selection in Direct XIP modes.

Signed-off-by: Tomasz Chyrowicz <[email protected]>
(cherry picked from commit d5f84b4)
@ahasztag ahasztag force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from 0ac02e0 to 8e08f2f Compare August 18, 2025 06:59
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

Ref: NCSDK-34429

Signed-off-by: Tomasz Chyrowicz <[email protected]>
@ahasztag ahasztag force-pushed the feature/zephyr/NCSDK-NONE_boot_requests_nrf branch from 8e08f2f to 17ac549 Compare August 18, 2025 08:07
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants