Skip to content

Commit 646f116

Browse files
nordicjmnashif
authored andcommitted
mcuboot: Add support for RAM load mode
Adds supporting code that allows the RAM load mode of MCUboot to be used and for applications to build successfully with it. Sysbuild can be used to build images for this mode Signed-off-by: Jamie McCrae <[email protected]>
1 parent 8774f15 commit 646f116

File tree

8 files changed

+139
-6
lines changed

8 files changed

+139
-6
lines changed

cmake/mcuboot.cmake

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,21 @@ function(zephyr_mcuboot_tasks)
114114
set(imgtool_args --key "${keyfile}" ${imgtool_args})
115115
endif()
116116

117-
# Use overwrite-only instead of swap upgrades.
118117
if(CONFIG_MCUBOOT_IMGTOOL_OVERWRITE_ONLY)
118+
# Use overwrite-only instead of swap upgrades.
119119
set(imgtool_args --overwrite-only --align 1 ${imgtool_args})
120+
elseif(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
121+
# RAM load requires setting the location of where to load the image to
122+
dt_chosen(chosen_ram PROPERTY "zephyr,sram")
123+
dt_reg_addr(chosen_ram_address PATH ${chosen_ram})
124+
dt_nodelabel(slot0_partition NODELABEL "slot0_partition" REQUIRED)
125+
dt_reg_addr(slot0_partition_address PATH ${slot0_partition})
126+
dt_nodelabel(slot1_partition NODELABEL "slot1_partition" REQUIRED)
127+
dt_reg_addr(slot1_partition_address PATH ${slot1_partition})
128+
129+
set(imgtool_args --align 1 --load-addr ${chosen_ram_address} ${imgtool_args})
130+
set(imgtool_args_alt_slot ${imgtool_args} --hex-addr ${slot1_partition_address})
131+
set(imgtool_args ${imgtool_args} --hex-addr ${slot0_partition_address})
120132
else()
121133
set(imgtool_args --align ${write_block_size} ${imgtool_args})
122134
endif()
@@ -156,6 +168,27 @@ function(zephyr_mcuboot_tasks)
156168
${imgtool_sign} ${imgtool_args} --encrypt "${keyfile_enc}" ${output}.bin
157169
${output}.signed.encrypted.bin)
158170
endif()
171+
172+
if(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
173+
list(APPEND byproducts ${output}.slot1.signed.encrypted.bin)
174+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
175+
${imgtool_sign} ${imgtool_args_alt_slot} ${output}.bin
176+
${output}.slot1.signed.bin)
177+
178+
if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE)
179+
list(APPEND byproducts ${output}.slot1.signed.confirmed.bin)
180+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
181+
${imgtool_sign} ${imgtool_args_alt_slot} --pad --confirm ${output}.bin
182+
${output}.slot1.signed.confirmed.bin)
183+
endif()
184+
185+
if(NOT "${keyfile_enc}" STREQUAL "")
186+
list(APPEND byproducts ${output}.slot1.signed.encrypted.bin)
187+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
188+
${imgtool_sign} ${imgtool_args_alt_slot} --encrypt "${keyfile_enc}"
189+
${output}.bin ${output}.slot1.signed.encrypted.bin)
190+
endif()
191+
endif()
159192
endif()
160193

161194
# Set up .hex outputs.
@@ -187,8 +220,28 @@ function(zephyr_mcuboot_tasks)
187220
${imgtool_sign} ${imgtool_args} --encrypt "${keyfile_enc}" ${output}.hex
188221
${output}.signed.encrypted.hex)
189222
endif()
190-
endif()
191223

224+
if(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
225+
list(APPEND byproducts ${output}.slot1.signed.hex)
226+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
227+
${imgtool_sign} ${imgtool_args_alt_slot} ${output}.hex
228+
${output}.slot1.signed.hex)
229+
230+
if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE)
231+
list(APPEND byproducts ${output}.slot1.signed.confirmed.hex)
232+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
233+
${imgtool_sign} ${imgtool_args_alt_slot} --pad --confirm ${output}.hex
234+
${output}.slot1.signed.confirmed.hex)
235+
endif()
236+
237+
if(NOT "${keyfile_enc}" STREQUAL "")
238+
list(APPEND byproducts ${output}.slot1.signed.encrypted.hex)
239+
set_property(GLOBAL APPEND PROPERTY extra_post_build_commands COMMAND
240+
${imgtool_sign} ${imgtool_args_alt_slot} --encrypt "${keyfile_enc}"
241+
${output}.hex ${output}.slot1.signed.encrypted.hex)
242+
endif()
243+
endif()
244+
endif()
192245
set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts ${byproducts})
193246
endfunction()
194247

modules/Kconfig.mcuboot

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ config MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY
183183
that the overwrite will not happen unless the version of secondary
184184
slot is higher than the version in primary slot.
185185

186+
config MCUBOOT_BOOTLOADER_MODE_RAM_LOAD
187+
bool "MCUboot has been configured for RAM LOAD operation"
188+
select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE
189+
select MCUBOOT_BOOTLOADER_NO_DOWNGRADE
190+
help
191+
MCUboot expects slot0_partition and slot1_partition to exist in DT. In this mode, MCUboot
192+
will select the image with the higher version number, copy it to RAM and begin execution
193+
from there. The image must be linked to execute from RAM, the address that it is copied
194+
to is specified using the load-addr argument when running imgtool.
195+
This option automatically selectes MCUBOOT_BOOTLOADER_NO_DOWNGRADE as it is not possible
196+
to swap back to older version of the application.
197+
186198
config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP
187199
bool "MCUboot has been configured for DirectXIP operation"
188200
select MCUBOOT_BOOTLOADER_MODE_HAS_NO_DOWNGRADE

share/sysbuild/image_configurations/MAIN_image_default.cmake

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ if(SB_CONFIG_BOOTLOADER_MCUBOOT)
3333
elseif(SB_CONFIG_MCUBOOT_MODE_DIRECT_XIP_WITH_REVERT)
3434
set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT y)
3535
elseif(SB_CONFIG_MCUBOOT_MODE_RAM_LOAD)
36-
# Not yet supported in zephyr code
36+
# RAM load mode requires XIP be disabled and flash size be set to 0
37+
set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD y)
38+
set_config_bool(${ZCMAKE_APPLICATION} CONFIG_XIP n)
39+
set_config_int(${ZCMAKE_APPLICATION} CONFIG_FLASH_SIZE 0)
3740
elseif(SB_CONFIG_MCUBOOT_MODE_FIRMWARE_UPDATER)
3841
set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_BOOTLOADER_MODE_FIRMWARE_UPDATER y)
3942
endif()

subsys/dfu/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
menuconfig IMG_MANAGER
1111
bool "DFU image manager"
1212
depends on STREAM_FLASH
13+
depends on !MCUBOOT_BOOTLOADER_MODE_RAM_LOAD || RETENTION_BOOTLOADER_INFO_OUTPUT_FUNCTION
1314
help
1415
Enable support for managing DFU image.
1516

subsys/dfu/boot/mcuboot.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,23 @@
1212
#include <zephyr/storage/flash_map.h>
1313
#include <zephyr/kernel.h>
1414
#include <zephyr/init.h>
15+
#include <zephyr/logging/log.h>
1516

1617
#include <zephyr/sys/__assert.h>
1718
#include <zephyr/sys/byteorder.h>
1819

1920
#include "bootutil/bootutil_public.h"
2021
#include <zephyr/dfu/mcuboot.h>
2122

23+
#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
24+
#include <bootutil/boot_status.h>
25+
#include <zephyr/retention/blinfo.h>
26+
#endif
27+
2228
#include "mcuboot_priv.h"
2329

30+
LOG_MODULE_REGISTER(mcuboot_dfu, LOG_LEVEL_DBG);
31+
2432
/*
2533
* Helpers for image headers and trailers, as defined by mcuboot.
2634
*/
@@ -34,8 +42,15 @@
3442
#define BOOT_HEADER_MAGIC_V1 0x96f3b83d
3543
#define BOOT_HEADER_SIZE_V1 32
3644

45+
#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
46+
/* For RAM LOAD mode, the active image must be fetched from the bootloader */
47+
static uint8_t boot_fetch_active_slot(void);
48+
#define ACTIVE_SLOT_FLASH_AREA_ID boot_fetch_active_slot()
49+
#define INVALID_SLOT_ID 255
50+
#else
3751
/* Get active partition. zephyr,code-partition chosen node must be defined */
3852
#define ACTIVE_SLOT_FLASH_AREA_ID DT_FIXED_PARTITION_ID(DT_CHOSEN(zephyr_code_partition))
53+
#endif
3954

4055
/*
4156
* Raw (on-flash) representation of the v1 image header.
@@ -60,6 +75,26 @@ struct mcuboot_v1_raw_header {
6075
* End of strict defines
6176
*/
6277

78+
#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
79+
static uint8_t boot_fetch_active_slot(void)
80+
{
81+
int rc;
82+
uint8_t slot;
83+
84+
rc = blinfo_lookup(BLINFO_RUNNING_SLOT, &slot, sizeof(slot));
85+
86+
if (rc <= 0) {
87+
LOG_ERR("Failed to fetch active slot: %d", rc);
88+
89+
return INVALID_SLOT_ID;
90+
}
91+
92+
LOG_DBG("Active slot: %d", slot);
93+
94+
return slot;
95+
}
96+
#endif
97+
6398
static int boot_read_v1_header(uint8_t area_id,
6499
struct mcuboot_v1_raw_header *v1_raw)
65100
{

subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535
#include <mgmt/mcumgr/transport/smp_internal.h>
3636
#endif
3737

38+
#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
39+
#include <bootutil/boot_status.h>
40+
#include <zephyr/retention/blinfo.h>
41+
#endif
42+
43+
#if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
44+
3845
#ifndef CONFIG_FLASH_LOAD_OFFSET
3946
#error MCUmgr requires application to be built with CONFIG_FLASH_LOAD_OFFSET set \
4047
to be able to figure out application running slot.
@@ -75,6 +82,10 @@ BUILD_ASSERT(sizeof(struct image_header) == IMAGE_HEADER_SIZE,
7582
#define ACTIVE_IMAGE_IS 0
7683
#endif
7784

85+
#else
86+
#define ACTIVE_IMAGE_IS 0
87+
#endif
88+
7889
#define SLOTS_PER_IMAGE 2
7990

8091
LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL);
@@ -198,9 +209,23 @@ int img_mgmt_active_slot(int image)
198209
{
199210
int slot = 0;
200211

201-
/* Multi image does not support DirectXIP currently */
212+
/* Multi image does not support DirectXIP or RAM load currently */
202213
#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER > 1
203214
slot = (image << 1);
215+
#elif defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
216+
/* RAM load requires querying bootloader */
217+
int rc;
218+
uint8_t temp_slot;
219+
220+
rc = blinfo_lookup(BLINFO_RUNNING_SLOT, &temp_slot, sizeof(temp_slot));
221+
222+
if (rc <= 0) {
223+
LOG_ERR("Failed to fetch active slot: %d", rc);
224+
225+
return 255;
226+
}
227+
228+
slot = (int)temp_slot;
204229
#else
205230
/* This covers single image, including DirectXiP */
206231
if (FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition)) {
@@ -1056,7 +1081,8 @@ static int img_mgmt_translate_error_code(uint16_t err)
10561081
static const struct mgmt_handler img_mgmt_handlers[] = {
10571082
[IMG_MGMT_ID_STATE] = {
10581083
.mh_read = img_mgmt_state_read,
1059-
#ifdef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP
1084+
#if defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) || \
1085+
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
10601086
.mh_write = NULL
10611087
#else
10621088
.mh_write = img_mgmt_state_write,

subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,8 @@ img_mgmt_slot_in_use(int slot)
324324
int image = img_mgmt_slot_to_image(slot);
325325
int active_slot = img_mgmt_active_slot(image);
326326

327-
#if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP)
327+
#if !defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) && \
328+
!defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD)
328329
enum img_mgmt_next_boot_type type = NEXT_BOOT_TYPE_NORMAL;
329330
int nbs = img_mgmt_get_next_boot_slot(image, &type);
330331

subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,7 @@ int img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req,
570570
(defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) || \
571571
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) || \
572572
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) || \
573+
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD) || \
573574
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) || \
574575
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT)) && \
575576
CONFIG_MCUBOOT_UPDATE_FOOTER_SIZE > 0
@@ -645,6 +646,7 @@ int img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req,
645646
(defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH) || \
646647
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH) || \
647648
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_OVERWRITE_ONLY) || \
649+
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD) || \
648650
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP) || \
649651
defined(CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP_WITH_REVERT)) && \
650652
CONFIG_MCUBOOT_UPDATE_FOOTER_SIZE > 0

0 commit comments

Comments
 (0)