Skip to content

Commit 17ac549

Browse files
tomchyahasztag
authored andcommitted
[nrf noup] 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 Ref: NCSDK-34429 Signed-off-by: Tomasz Chyrowicz <[email protected]>
1 parent 1fae83e commit 17ac549

File tree

9 files changed

+613
-5
lines changed

9 files changed

+613
-5
lines changed
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/bootutil_public.c

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@
5151
#include "bootutil_priv.h"
5252
#include "bootutil_misc.h"
5353

54+
#if defined(CONFIG_NRF_MCUBOOT_BOOT_REQUEST) && !defined(CONFIG_MCUBOOT)
55+
#include <bootutil/boot_request.h>
56+
#define SEND_BOOT_REQUEST
57+
#endif /* CONFIG_NRF_MCUBOOT_BOOT_REQUEST && !CONFIG_MCUBOOT */
58+
5459
#ifdef CONFIG_MCUBOOT
5560
BOOT_LOG_MODULE_DECLARE(mcuboot);
5661
#else
@@ -503,32 +508,79 @@ boot_write_copy_done(const struct flash_area *fap)
503508
return boot_write_trailer_flag(fap, off, BOOT_FLAG_SET);
504509
}
505510

506-
#ifndef MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP
511+
#ifdef SEND_BOOT_REQUEST
512+
static int
513+
send_boot_request(uint8_t magic, bool confirm, int image_id, uint32_t slot_id)
514+
{
515+
int rc = BOOT_EBADIMAGE;
507516

508-
static int flash_area_to_image(const struct flash_area *fa)
517+
/* Handle write-protected active image. */
518+
if ((magic == BOOT_MAGIC_GOOD) || (magic == BOOT_MAGIC_UNSET)) {
519+
if (confirm) {
520+
BOOT_LOG_DBG("Confirm image: %d, %d", image_id, slot_id);
521+
rc = boot_request_confirm_slot(image_id, slot_id);
522+
} else {
523+
BOOT_LOG_DBG("Set image preference: %d, %d", image_id, slot_id);
524+
rc = boot_request_set_preferred_slot(image_id, slot_id);
525+
}
526+
if (rc != 0) {
527+
rc = BOOT_EBADIMAGE;
528+
}
529+
}
530+
531+
return rc;
532+
}
533+
#endif /* SEND_BOOT_REQUEST */
534+
535+
#if defined(SEND_BOOT_REQUEST) || (!defined(MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP))
536+
static int flash_area_to_image_slot(const struct flash_area *fa, uint32_t *slot)
509537
{
538+
int id = flash_area_get_id(fa);
510539
#if BOOT_IMAGE_NUMBER > 1
511540
uint8_t i = 0;
512-
int id = flash_area_get_id(fa);
513541

514542
while (i < BOOT_IMAGE_NUMBER) {
515-
if (FLASH_AREA_IMAGE_PRIMARY(i) == id || (FLASH_AREA_IMAGE_SECONDARY(i) == id)) {
543+
if (FLASH_AREA_IMAGE_PRIMARY(i) == id) {
544+
if (slot != NULL) {
545+
*slot = 0;
546+
}
547+
return i;
548+
} else if (FLASH_AREA_IMAGE_SECONDARY(i) == id) {
549+
if (slot != NULL) {
550+
*slot = 1;
551+
}
516552
return i;
517553
}
518554

519555
++i;
520556
}
521557
#else
522558
(void)fa;
559+
if (slot != NULL) {
560+
if (FLASH_AREA_IMAGE_PRIMARY(0) == id) {
561+
*slot = 0;
562+
} else if (FLASH_AREA_IMAGE_SECONDARY(0) == id) {
563+
*slot = 1;
564+
} else {
565+
*slot = UINT32_MAX;
566+
}
567+
}
523568
#endif
524569
return 0;
525570
}
571+
#endif /* defined(SEND_BOOT_REQUEST) || (!defined(MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP)) */
526572

573+
#ifndef MCUBOOT_BOOTUTIL_LIB_FOR_DIRECT_XIP
527574
int
528575
boot_set_next(const struct flash_area *fa, bool active, bool confirm)
529576
{
530577
struct boot_swap_state slot_state;
531578
int rc;
579+
int image_id;
580+
uint32_t slot_id;
581+
582+
BOOT_LOG_DBG("boot_set_next: fa %p active == %d, confirm == %d",
583+
fa, (int)active, (int)confirm);
532584

533585
if (active) {
534586
confirm = true;
@@ -539,6 +591,15 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm)
539591
return rc;
540592
}
541593

594+
image_id = flash_area_to_image_slot(fa, &slot_id);
595+
596+
#ifdef SEND_BOOT_REQUEST
597+
rc = send_boot_request(slot_state.magic, confirm, image_id, slot_id);
598+
if ((rc != 0) || active) {
599+
return rc;
600+
}
601+
#endif
602+
542603
switch (slot_state.magic) {
543604
case BOOT_MAGIC_GOOD:
544605
/* If non-active then swap already scheduled, else confirm needed.*/
@@ -569,7 +630,7 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm)
569630
} else {
570631
swap_type = BOOT_SWAP_TYPE_TEST;
571632
}
572-
rc = boot_write_swap_info(fa, swap_type, flash_area_to_image(fa));
633+
rc = boot_write_swap_info(fa, swap_type, image_id);
573634
}
574635
}
575636
break;
@@ -600,6 +661,10 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm)
600661
{
601662
struct boot_swap_state slot_state;
602663
int rc;
664+
#ifdef SEND_BOOT_REQUEST
665+
int image_id;
666+
uint32_t slot_id;
667+
#endif
603668

604669
BOOT_LOG_DBG("boot_set_next: fa %p active == %d, confirm == %d",
605670
fa, (int)active, (int)confirm);
@@ -618,6 +683,15 @@ boot_set_next(const struct flash_area *fa, bool active, bool confirm)
618683
return rc;
619684
}
620685

686+
#ifdef SEND_BOOT_REQUEST
687+
image_id = flash_area_to_image_slot(fa, &slot_id);
688+
689+
rc = send_boot_request(slot_state.magic, confirm, image_id, slot_id);
690+
if ((rc != 0) || active) {
691+
return rc;
692+
}
693+
#endif
694+
621695
switch (slot_state.magic) {
622696
case BOOT_MAGIC_UNSET:
623697
/* Magic is needed for MCUboot to even consider booting an image */

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_NRF_MCUBOOT_BOOT_REQUEST)
20+
zephyr_library_sources_ifdef(CONFIG_NRF_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)