Skip to content

Commit da841f5

Browse files
nordicjmmbolivar-nordic
authored andcommitted
[nrf fromlist] boot_serial: Add unaligned stack buffer writing
Fixes a bug when writing to devices which have memory alignment requirements with data being using directly from a zcbor-response whereby the alignment of the buffer data does not meet the requirements of the flash driver. Upstream PR: mcu-tools/mcuboot#1533 Signed-off-by: Jamie McCrae <[email protected]> (cherry picked from commit 11c5149)
1 parent 0cf02a5 commit da841f5

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

boot/boot_serial/src/boot_serial.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,38 @@ bs_upload(char *buf, int len)
508508

509509
BOOT_LOG_INF("Writing at 0x%x until 0x%x", curr_off, curr_off + img_chunk_len);
510510
/* Write flash aligned chunk, note that img_chunk_len now holds aligned length */
511+
#if defined(MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE) && MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE > 0
512+
if (flash_area_align(fap) > 1 &&
513+
(((size_t)img_chunk) & (flash_area_align(fap) - 1)) != 0) {
514+
/* Buffer address incompatible with write address, use buffer to write */
515+
uint8_t write_size = MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE;
516+
uint8_t wbs_aligned[MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE];
517+
518+
while (img_chunk_len >= flash_area_align(fap)) {
519+
if (write_size > img_chunk_len) {
520+
write_size = img_chunk_len;
521+
}
522+
523+
memset(wbs_aligned, flash_area_erased_val(fap), sizeof(wbs_aligned));
524+
memcpy(wbs_aligned, img_chunk, write_size);
525+
526+
rc = flash_area_write(fap, curr_off, wbs_aligned, write_size);
527+
528+
if (rc != 0) {
529+
break;
530+
}
531+
532+
curr_off += write_size;
533+
img_chunk += write_size;
534+
img_chunk_len -= write_size;
535+
}
536+
} else {
537+
rc = flash_area_write(fap, curr_off, img_chunk, img_chunk_len);
538+
}
539+
#else
511540
rc = flash_area_write(fap, curr_off, img_chunk, img_chunk_len);
541+
#endif
542+
512543
if (rc == 0 && rem_bytes) {
513544
/* Non-zero rem_bytes means that last chunk needs alignment; the aligned
514545
* part, in the img_chunk_len - rem_bytes count bytes, has already been

boot/zephyr/Kconfig.serial_recovery

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
5050
Note that 0 is default upload target when no explicit
5151
selection is done.
5252

53+
config BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
54+
int "Stack buffer for unaligned memory writes"
55+
default 64
56+
help
57+
Specifies the stack usage for a buffer which is used for unaligned
58+
memory access when data is written to a device with memory alignment
59+
requirements. Set to 0 to disable.
60+
5361
config BOOT_MAX_LINE_INPUT_LEN
5462
int "Maximum command line length"
5563
default 512

boot/zephyr/include/mcuboot_config/mcuboot_config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,10 @@
240240
#define MCUBOOT_MAX_IMG_SECTORS 128
241241
#endif
242242

243+
#ifdef CONFIG_BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
244+
#define MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE CONFIG_BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
245+
#endif
246+
243247
/* Support 32-byte aligned flash sizes */
244248
#if DT_HAS_CHOSEN(zephyr_flash)
245249
#if DT_PROP_OR(DT_CHOSEN(zephyr_flash), write_block_size, 0) > 8

0 commit comments

Comments
 (0)