Skip to content

Commit 766be5d

Browse files
Mads Bligaard NielsenMads Bligaard Nielsen
authored andcommitted
boot: serial: "image list" enhanced, client can program correct mcuboot_sX.bin
* added CONFIG_MCUBOOT_SERIAL_MCUMGR_SIMPLE_IMAGE_INDEX (default "n") The "image update" can now specify simple index "-n <index>", where n=1+(image*2+slot) from "image list" * added CONFIG_MCUBOOT_SERIAL_MCUMGR_VERSION_DECORATE (default "n") The "image list" can now provide more details about what each slot contains. This is appended to version string, to make it somehow compatible with existing mcumgr clients * information for all slots always returned (e.g. 4 for b0/2-stage boot) version field can be: headerErased, headerInvalid, imageInvalid (hash) * bootable=true for all slots that are valid * flags.active=true for the active mcuboot slot * hash provided, this is sha256_sum of hdr_size(0x200)+image_size, e.g. not including the signing chunk (0x200) located after image * reject if trying to update the active mcuboot slot. note: current mcumgr (mynewt-newtmgr) is very poor to handle errors, just hangs without any timeout if something goes wrong Example: mcumgr --conntype serial --connstring /dev/ttymxc2,baud=1000000 image list Images: image=0 slot=0 version: 1.0.0.0 # app n=1 id=0xc dev=0 off=0x30000 size=0x68000 img_size=0x4c12c bootable: true flags: hash: 2d44911cef7a7ec2636ca329894d66d0a322a874a267e54794cb72f42c3d1052 image=0 slot=1 version: 0.0.0.0 # net n=2 id=0x10 dev=0 off=0x98000 size=0x68000 img_size=0x5668 bootable: true flags: hash: bd7571d32c5fed6cc6aa8b5eb756ff2fc31750b999bb97de5a3572644bc2f35c image=1 slot=0 version: 0.0.0.0 # boot0 n=3 id=0x2 dev=0 off=0x8000 size=0x10200 img_size=0xcf9c bootable: true flags: active hash: b7fe6803a2a9bb0d3e3ac4803098133e4a130688bd5749499d01aecb8c014341 image=1 slot=1 version: 0.0.0.0 # boot1 n=4 id=0x7 dev=0 off=0x1c000 size=0x10200 img_size=0xcf9c bootable: true flags: hash: fee1de2cb54d1cca52d74eab6cbf2d0605290df89df13cbe1fe9dc8db6617a7a
1 parent e6456ee commit 766be5d

File tree

3 files changed

+135
-14
lines changed

3 files changed

+135
-14
lines changed

boot/boot_serial/src/boot_serial.c

Lines changed: 105 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,11 @@ BOOT_LOG_MODULE_DECLARE(mcuboot);
8282
#define MCUBOOT_SERIAL_MAX_RECEIVE_SIZE 512
8383
#endif
8484

85+
#ifndef CONFIG_MCUBOOT_SERIAL_MCUMGR_VERSION_DECORATE
8586
#define BOOT_SERIAL_OUT_MAX (128 * BOOT_IMAGE_NUMBER)
87+
#else
88+
#define BOOT_SERIAL_OUT_MAX (512 * BOOT_IMAGE_NUMBER)
89+
#endif
8690

8791
#ifdef __ZEPHYR__
8892
/* base64 lib encodes data to null-terminated string */
@@ -205,14 +209,76 @@ bs_list_img_ver(char *dst, int maxlen, struct image_version *ver)
205209
}
206210
#endif /* !MCUBOOT_USE_SNPRINTF */
207211

212+
#ifdef CONFIG_MCUBOOT_SERIAL_MCUMGR_VERSION_DECORATE
213+
static int flash_upload_id_from_image_slot(uint32_t image_index, uint32_t slot)
214+
{
215+
#ifdef CONFIG_MCUBOOT_SERIAL_MCUMGR_SIMPLE_IMAGE_INDEX
216+
return 1 + image_index * 2 + slot;
217+
#elif defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
218+
uint8_t i;
219+
for (i = 1; i <= BOOT_IMAGE_NUMBER*2; i++) {
220+
int r = flash_area_id_from_direct_image(i);
221+
if (r == area_id) {
222+
return i;
223+
}
224+
}
225+
return -1;
226+
#else
227+
(void)slot;
228+
return img_num, 0;
229+
#endif
230+
}
231+
232+
const char* flash_slot_name_from_image_slot(uint32_t image_index, uint32_t slot)
233+
{
234+
#ifdef CONFIG_MCUBOOT_SERIAL_MCUMGR_SIMPLE_IMAGE_INDEX
235+
/* NRF mapping */
236+
switch (flash_upload_id_from_image_slot(image_index, slot))
237+
{
238+
case 1: return "app";
239+
case 2: return "net";
240+
case 3: return "boot0";
241+
case 4: return "boot1";
242+
}
243+
#endif
244+
return "unknown";
245+
}
246+
#endif /* #ifdef CONFIG_MCUBOOT_SERIAL_MCUMGR_VERSION_DECORATE */
247+
248+
static int flash_area_id_from_upload_id(uint32_t upload_id)
249+
{
250+
#ifdef CONFIG_MCUBOOT_SERIAL_MCUMGR_SIMPLE_IMAGE_INDEX
251+
if (upload_id >= 1) {
252+
uint32_t image_index = (upload_id - 1) / 2;
253+
uint32_t slot = (upload_id - 1) % 2;
254+
return flash_area_id_from_multi_image_slot(image_index, slot);
255+
}
256+
return -1;
257+
#elif defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
258+
return flash_area_id_from_multi_image_slot(upload_id, 0);
259+
#else
260+
return flash_area_id_from_direct_image(upload_id);
261+
#endif
262+
}
263+
264+
static bool flash_area_is_active_bootloader(const struct flash_area *fap)
265+
{
266+
uint32_t mcuboot_xip_addr = (uint32_t)(&flash_area_is_active_bootloader);
267+
if (mcuboot_xip_addr >= fap->fa_off && mcuboot_xip_addr < fap->fa_off + fap->fa_size) {
268+
return true;
269+
}
270+
return false;
271+
}
272+
208273
/*
209274
* List images.
210275
*/
211276
static void
212277
bs_list(char *buf, int len)
213278
{
214279
struct image_header hdr;
215-
uint8_t tmpbuf[64];
280+
uint8_t tmpbuf[128];
281+
uint8_t hash_sha256[32];
216282
uint32_t slot, area_id;
217283
const struct flash_area *fap;
218284
uint8_t image_index;
@@ -223,6 +289,7 @@ bs_list(char *buf, int len)
223289
image_index = 0;
224290
IMAGES_ITER(image_index) {
225291
for (slot = 0; slot < 2; slot++) {
292+
const char* errorInfo = NULL;
226293
area_id = flash_area_id_from_multi_image_slot(image_index, slot);
227294
if (flash_area_open(area_id, &fap)) {
228295
continue;
@@ -256,16 +323,19 @@ bs_list(char *buf, int len)
256323
}
257324
#endif
258325
FIH_CALL(bootutil_img_validate, fih_rc, NULL, 0, &hdr, fap, tmpbuf, sizeof(tmpbuf),
259-
NULL, 0, NULL);
326+
NULL, 0, &hash_sha256[0]);
327+
if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
328+
errorInfo = "imageInvalid";
329+
}
260330
}
331+
} else if (hdr.ih_magic == 0xFFFFFFFF) {
332+
errorInfo = "headerErased";
333+
} else {
334+
errorInfo = "headerInvalid";
261335
}
262336

263337
flash_area_close(fap);
264338

265-
if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
266-
continue;
267-
}
268-
269339
zcbor_map_start_encode(cbor_state, 20);
270340

271341
#if (BOOT_IMAGE_NUMBER > 1)
@@ -275,9 +345,30 @@ bs_list(char *buf, int len)
275345

276346
zcbor_tstr_put_lit_cast(cbor_state, "slot");
277347
zcbor_uint32_put(cbor_state, slot);
278-
zcbor_tstr_put_lit_cast(cbor_state, "version");
348+
if (!errorInfo) {
349+
if (flash_area_is_active_bootloader(fap)) {
350+
zcbor_tstr_put_lit_cast(cbor_state, "active");
351+
zcbor_bool_put(cbor_state, true);
352+
}
353+
zcbor_tstr_put_lit_cast(cbor_state, "bootable");
354+
zcbor_bool_put(cbor_state, true);
279355

280-
bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
356+
zcbor_tstr_put_lit_cast(cbor_state, "hash"); /* hashAreaSize=ih_hdr_size+ih_img_size) */
357+
zcbor_tstr_encode_ptr(cbor_state, hash_sha256, sizeof(hash_sha256));
358+
359+
bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
360+
} else {
361+
strncpy(tmpbuf, errorInfo, sizeof(tmpbuf));
362+
}
363+
zcbor_tstr_put_lit_cast(cbor_state, "version");
364+
#ifdef CONFIG_MCUBOOT_SERIAL_MCUMGR_VERSION_DECORATE
365+
// append details for diagnostic
366+
snprintf(tmpbuf+strlen(tmpbuf), sizeof(tmpbuf)-strlen(tmpbuf),
367+
" # %s n=%d id=0x%x dev=%d off=0x%lx size=0x%x img_size=0x%x",
368+
flash_slot_name_from_image_slot(image_index, slot),
369+
flash_upload_id_from_image_slot(image_index, slot),
370+
area_id, fap->fa_device_id, fap->fa_off, fap->fa_size, errorInfo ? 0 : hdr.ih_img_size);
371+
#endif
281372
zcbor_tstr_encode_ptr(cbor_state, tmpbuf, strlen((char *)tmpbuf));
282373
zcbor_map_end_encode(cbor_state, 20);
283374
}
@@ -414,16 +505,17 @@ bs_upload(char *buf, int len)
414505
goto out_invalid_data;
415506
}
416507

417-
#if !defined(MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD)
418-
rc = flash_area_open(flash_area_id_from_multi_image_slot(img_num, 0), &fap);
419-
#else
420-
rc = flash_area_open(flash_area_id_from_direct_image(img_num), &fap);
421-
#endif
508+
rc = flash_area_open(flash_area_id_from_upload_id(img_num), &fap);
422509
if (rc) {
423510
rc = MGMT_ERR_EINVAL;
424511
goto out;
425512
}
426513

514+
if (flash_area_is_active_bootloader(fap)) {
515+
rc = MGMT_ERR_EINVAL;
516+
goto out;
517+
}
518+
427519
if (img_chunk_off == 0) {
428520
/* Receiving chunk with 0 offset resets the upload state; this basically
429521
* means that upload has started from beginning.

boot/zephyr/Kconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,25 @@ config SINGLE_APPLICATION_SLOT
6767
uploading a new application overwrites the one that previously
6868
occupied the area.
6969

70+
config MCUBOOT_SERIAL_MCUMGR_SIMPLE_IMAGE_INDEX
71+
bool "mcumgr:image_upload assumes n=1+image*2+slot"
72+
default n
73+
help
74+
This option enables a simple mapping between
75+
image/slot listed by "mcumgr:image list" and
76+
the n argument used by "mcumgr:image upload"
77+
If unsure, leave at the default value.
78+
79+
config MCUBOOT_SERIAL_MCUMGR_VERSION_DECORATE
80+
bool "mcumgr:image_list appends info to version"
81+
default n
82+
help
83+
This option helps understand details about
84+
the different image/slots listed.
85+
Decided to append it to version property to
86+
make it visible with standard mcumgr clients.
87+
If unsure, leave at the default value.
88+
7089
choice BOOT_SIGNATURE_TYPE
7190
prompt "Signature type"
7291
default BOOT_SIGNATURE_TYPE_RSA

boot/zephyr/include/sysflash/sysflash.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,28 @@
2323

2424
extern uint32_t _image_1_primary_slot_id[];
2525

26+
#ifndef CONFIG_MCUBOOT_SERIAL_MCUMGR_SIMPLE_IMAGE_INDEX
27+
/* note: _image_1_primary_slot_id is the other/inactive mcuboot slot, generated by linker defs */
2628
#define FLASH_AREA_IMAGE_PRIMARY(x) \
2729
((x == 0) ? \
2830
PM_MCUBOOT_PRIMARY_ID : \
2931
(x == 1) ? \
3032
(uint32_t)_image_1_primary_slot_id : \
3133
255 )
34+
#else
35+
#define FLASH_AREA_IMAGE_PRIMARY(x) \
36+
((x == 0) ? \
37+
PM_MCUBOOT_PRIMARY_ID : \
38+
(x == 1) ? \
39+
PM_S0_ID : \
40+
255 )
41+
#endif
3242

3343
#define FLASH_AREA_IMAGE_SECONDARY(x) \
3444
((x == 0) ? \
3545
PM_MCUBOOT_SECONDARY_ID: \
3646
(x == 1) ? \
37-
PM_MCUBOOT_SECONDARY_ID: \
47+
PM_S1_ID : \
3848
255 )
3949
#else
4050

0 commit comments

Comments
 (0)