Skip to content

Commit 9200785

Browse files
nordicjmrlubos
authored andcommitted
[nrf noup] boot: zephyr: Add bm firmware loader code
Adds firmware loader code for use in baremetal mode Signed-off-by: Jamie McCrae <[email protected]> (cherry picked from commit f123819)
1 parent 002515b commit 9200785

File tree

3 files changed

+496
-4
lines changed

3 files changed

+496
-4
lines changed

boot/zephyr/CMakeLists.txt

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,17 @@ endif()
6464
# Zephyr port-specific sources.
6565
zephyr_library_sources(
6666
main.c
67-
io.c
6867
flash_map_extended.c
6968
os.c
7069
keys.c
7170
)
7271

72+
if(CONFIG_NCS_BM)
73+
zephyr_library_sources(io_bm.c)
74+
else()
75+
zephyr_library_sources(io.c)
76+
endif()
77+
7378
if(DEFINED CONFIG_ENABLE_MGMT_PERUSER)
7479
zephyr_library_sources(
7580
boot_serial_extensions.c
@@ -150,9 +155,15 @@ elseif(CONFIG_SINGLE_APPLICATION_SLOT)
150155
)
151156
zephyr_library_include_directories(${BOOT_DIR}/bootutil/src)
152157
elseif(CONFIG_BOOT_FIRMWARE_LOADER)
153-
zephyr_library_sources(
154-
${BOOT_DIR}/zephyr/firmware_loader.c
155-
)
158+
if(CONFIG_NCS_BM)
159+
zephyr_library_sources(
160+
${BOOT_DIR}/zephyr/firmware_loader_bm.c
161+
)
162+
else()
163+
zephyr_library_sources(
164+
${BOOT_DIR}/zephyr/firmware_loader.c
165+
)
166+
endif()
156167
zephyr_library_include_directories(${BOOT_DIR}/bootutil/src)
157168
else()
158169
zephyr_library_sources(

boot/zephyr/firmware_loader_bm.c

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <assert.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/devicetree.h>
10+
#include <zephyr/drivers/gpio.h>
11+
#include <zephyr/storage/flash_map.h>
12+
#include "bootutil/image.h"
13+
#include "bootutil_priv.h"
14+
#include "bootutil/bootutil_log.h"
15+
#include "bootutil/bootutil_public.h"
16+
#include "bootutil/fault_injection_hardening.h"
17+
#include <bm_installs.h>
18+
19+
#include "io/io.h"
20+
#include "mcuboot_config/mcuboot_config.h"
21+
22+
#define IMAGE_TLV_INSTALLER_IMAGE 0xa0
23+
24+
BOOT_LOG_MODULE_DECLARE(mcuboot);
25+
26+
static struct flash_area fa_app_installer = {
27+
.fa_id = 1,
28+
.fa_off = FIXED_PARTITION_OFFSET(slot0_partition),
29+
.fa_size = FIXED_PARTITION_SIZE(slot0_partition),
30+
.fa_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)),
31+
};
32+
33+
static struct image_header hdr_app_installer = { 0 };
34+
35+
static struct flash_area fa_softdevice = {
36+
.fa_id = 2,
37+
.fa_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)),
38+
};
39+
40+
static struct image_header hdr_softdevice = { 0 };
41+
42+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER
43+
static struct flash_area fa_firmware_loader = {
44+
.fa_id = 3,
45+
.fa_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_flash_controller)),
46+
};
47+
48+
static struct image_header hdr_firmware_loader = { 0 };
49+
#endif
50+
51+
/**
52+
* Validate hash of a primary boot image.
53+
*
54+
* @param[in] fa_p flash area pointer
55+
* @param[in] hdr boot image header pointer
56+
*
57+
* @return FIH_SUCCESS on success, error code otherwise
58+
*/
59+
static fih_ret validate_image(const struct flash_area *fap, struct image_header *hdr)
60+
{
61+
static uint8_t tmpbuf[BOOT_TMPBUF_SZ];
62+
FIH_DECLARE(fih_rc, FIH_FAILURE);
63+
64+
FIH_CALL(bootutil_img_validate, fih_rc, NULL, hdr, fap, tmpbuf, BOOT_TMPBUF_SZ, NULL, 0, NULL);
65+
FIH_RET(fih_rc);
66+
}
67+
68+
/**
69+
* Gather information on image and prepare for booting. Will boot from main
70+
* image if none of the enabled entrance modes for the firmware loader are set,
71+
* otherwise will boot the firmware loader. Note: firmware loader must be a
72+
* valid signed image with the same signing key as the application image.
73+
*
74+
* @param[out] rsp Parameters for booting image, on success
75+
*
76+
* @return FIH_SUCCESS on success; non-zero on failure.
77+
*/
78+
fih_ret
79+
boot_go(struct boot_rsp *rsp)
80+
{
81+
bool boot_firmware_loader = false;
82+
FIH_DECLARE(fih_rc, FIH_FAILURE);
83+
bool softdevice_area_valid = false;
84+
bool firmware_loader_area_valid = false;
85+
int rc;
86+
bool app_installer_image_valid = false;
87+
bool softdevice_image_valid = false;
88+
bool firmware_loader_image_valid = false;
89+
bool app_installer_is_installer_image = false;
90+
91+
bm_installs_init();
92+
93+
if (bm_installs_is_valid()) {
94+
off_t start_address = 0;
95+
size_t image_size = 0;
96+
97+
rc = bm_installs_get_image_data(BM_INSTALLS_IMAGE_INDEX_SOFTDEVICE, &start_address,
98+
&image_size);
99+
100+
if (!rc) {
101+
fa_softdevice.fa_off = start_address;
102+
fa_softdevice.fa_size = image_size;
103+
104+
if (start_address < fa_app_installer.fa_off) {
105+
/* Invalid start address for SoftDevice */
106+
goto invalid_softdevice;
107+
}
108+
109+
fa_app_installer.fa_size = start_address - fa_app_installer.fa_off;
110+
111+
rc = boot_image_load_header(&fa_softdevice, &hdr_softdevice);
112+
113+
if (!rc) {
114+
softdevice_area_valid = true;
115+
}
116+
}
117+
118+
invalid_softdevice:
119+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER
120+
start_address = 0;
121+
image_size = 0;
122+
rc = bm_installs_get_image_data(BM_INSTALLS_IMAGE_INDEX_FIRMWARE_LOADER, &start_address,
123+
&image_size);
124+
125+
if (!rc) {
126+
fa_firmware_loader.fa_off = start_address;
127+
fa_firmware_loader.fa_size = image_size;
128+
129+
if (start_address < fa_app_installer.fa_off) {
130+
/* Invalid start address for firmware loader */
131+
goto invalid_firmware_loader;
132+
}
133+
134+
fa_app_installer.fa_size = start_address - fa_app_installer.fa_off;
135+
136+
rc = boot_image_load_header(&fa_firmware_loader, &hdr_softdevice);
137+
138+
if (!rc) {
139+
firmware_loader_area_valid = true;
140+
}
141+
}
142+
#endif
143+
}
144+
145+
invalid_firmware_loader:
146+
rc = boot_image_load_header(&fa_app_installer, &hdr_app_installer);
147+
148+
if (rc) {
149+
BOOT_LOG_ERR("Failed loading application/installer image header: %d", rc);
150+
} else {
151+
FIH_CALL(validate_image, fih_rc, &fa_app_installer, &hdr_app_installer);
152+
153+
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
154+
struct image_tlv_iter it;
155+
uint32_t off2;
156+
uint16_t len2;
157+
158+
app_installer_image_valid = true;
159+
160+
if (hdr_app_installer.ih_protect_tlv_size > 0) {
161+
rc = bootutil_tlv_iter_begin(&it, &hdr_app_installer, &fa_app_installer,
162+
IMAGE_TLV_INSTALLER_IMAGE, true);
163+
164+
if (rc == 0) {
165+
rc = bootutil_tlv_iter_next(&it, &off2, &len2, NULL);
166+
167+
if (rc == 0 && len2 == sizeof(app_installer_is_installer_image)) {
168+
rc = LOAD_IMAGE_DATA(&hdr_app_installer, &fa_app_installer, off2,
169+
&app_installer_is_installer_image, len2);
170+
171+
if (rc != 0) {
172+
app_installer_is_installer_image = false;
173+
}
174+
}
175+
}
176+
}
177+
}
178+
}
179+
180+
if (softdevice_area_valid) {
181+
fih_rc = FIH_FAILURE;
182+
rc = boot_image_load_header(&fa_softdevice, &hdr_softdevice);
183+
184+
if (rc) {
185+
BOOT_LOG_ERR("Failed loading SoftDevice image header: %d", rc);
186+
} else {
187+
FIH_CALL(validate_image, fih_rc, &fa_softdevice, &hdr_softdevice);
188+
189+
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
190+
softdevice_image_valid = true;
191+
}
192+
}
193+
}
194+
195+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER
196+
if (firmware_loader_area_valid) {
197+
fih_rc = FIH_FAILURE;
198+
rc = boot_image_load_header(&fa_firmware_loader, &hdr_firmware_loader);
199+
200+
if (rc) {
201+
BOOT_LOG_ERR("Failed loading firmware loader image header: %d", rc);
202+
} else {
203+
FIH_CALL(validate_image, fih_rc, &fa_firmware_loader, &hdr_firmware_loader);
204+
205+
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
206+
firmware_loader_image_valid = true;
207+
}
208+
}
209+
}
210+
#endif
211+
212+
BOOT_LOG_DBG("Application/installer partition offset: 0x%lx, size: 0x%x, type: %d",
213+
fa_app_installer.fa_off, fa_app_installer.fa_size,
214+
app_installer_is_installer_image);
215+
BOOT_LOG_DBG("SoftDevice partition offset: 0x%lx, size: 0x%x", fa_softdevice.fa_off,
216+
fa_softdevice.fa_size);
217+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER
218+
BOOT_LOG_DBG("Firmware loader off: 0x%lx, size: 0x%x", fa_firmware_loader.fa_off,
219+
fa_firmware_loader.fa_size);
220+
BOOT_LOG_DBG("SoftDevice area valid: %d, Firmware loader area valid: %d, "
221+
"Application/installer image valid: %d, SoftDevice image valid: %d, "
222+
"Firmware loader image valid: %d", softdevice_area_valid,
223+
firmware_loader_area_valid, app_installer_image_valid, softdevice_image_valid,
224+
firmware_loader_image_valid);
225+
#else
226+
BOOT_LOG_DBG("SoftDevice area valid: %d, Application/installer image valid: %d, "
227+
"SoftDevice image valid: %d", softdevice_area_valid, app_installer_image_valid,
228+
softdevice_image_valid);
229+
#endif
230+
231+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER_ENTRANCE_GPIO
232+
if (io_detect_pin() && !io_boot_skip_serial_recovery()) {
233+
BOOT_LOG_DBG("GPIO detected for firmware loader mode");
234+
boot_firmware_loader = true;
235+
}
236+
#endif
237+
238+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER_PIN_RESET
239+
if (io_detect_pin_reset()) {
240+
BOOT_LOG_DBG("Pin reset detected for firmware loader mode");
241+
boot_firmware_loader = true;
242+
}
243+
#endif
244+
245+
#ifdef CONFIG_BOOT_FIRMWARE_LOADER_BOOT_MODE
246+
if (io_detect_boot_mode()) {
247+
BOOT_LOG_DBG("Boot mode detected for firmware loader mode");
248+
boot_firmware_loader = true;
249+
}
250+
#endif
251+
252+
if (app_installer_image_valid == true && app_installer_is_installer_image == true) {
253+
/* Installer image is present, this gets priority */
254+
BOOT_LOG_DBG("Booting installer");
255+
rsp->br_image_off = flash_area_get_off(&fa_app_installer);
256+
rsp->br_hdr = &hdr_app_installer;
257+
} else if (boot_firmware_loader == true && softdevice_image_valid == true &&
258+
firmware_loader_image_valid == true) {
259+
/* Boot firmware loader */
260+
BOOT_LOG_INF("Booting firmware loader");
261+
rsp->br_image_off = flash_area_get_off(&fa_firmware_loader);
262+
rsp->br_hdr = &hdr_firmware_loader;
263+
} else if (app_installer_image_valid == true && softdevice_image_valid == true) {
264+
/* Boot main application */
265+
BOOT_LOG_INF("Booting main application");
266+
rsp->br_image_off = flash_area_get_off(&fa_app_installer);
267+
rsp->br_hdr = &hdr_app_installer;
268+
} else if (app_installer_image_valid == false && softdevice_image_valid == true &&
269+
firmware_loader_image_valid == true) {
270+
/* Boot firmware loader due to missing main image */
271+
BOOT_LOG_INF("Booting firmware loader due to missing application image");
272+
rsp->br_image_off = flash_area_get_off(&fa_firmware_loader);
273+
rsp->br_hdr = &hdr_firmware_loader;
274+
} else {
275+
/* Cannot boot in this configuration */
276+
BOOT_LOG_ERR("Error: no bootable configuration found");
277+
return -1;
278+
}
279+
280+
rsp->br_flash_dev_id = flash_area_get_device_id(&fa_app_installer);
281+
282+
return 0;
283+
}

0 commit comments

Comments
 (0)