Skip to content

Commit 9d3fd7f

Browse files
nordicjmnvlsianpu
authored andcommitted
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. Signed-off-by: Jamie McCrae <[email protected]>
1 parent 8724081 commit 9d3fd7f

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
@@ -511,7 +511,38 @@ bs_upload(char *buf, int len)
511511

512512
BOOT_LOG_INF("Writing at 0x%x until 0x%x", curr_off, curr_off + img_chunk_len);
513513
/* Write flash aligned chunk, note that img_chunk_len now holds aligned length */
514+
#if defined(MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE) && MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE > 0
515+
if (flash_area_align(fap) > 1 &&
516+
(((size_t)img_chunk) & (flash_area_align(fap) - 1)) != 0) {
517+
/* Buffer address incompatible with write address, use buffer to write */
518+
uint8_t write_size = MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE;
519+
uint8_t wbs_aligned[MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE];
520+
521+
while (img_chunk_len >= flash_area_align(fap)) {
522+
if (write_size > img_chunk_len) {
523+
write_size = img_chunk_len;
524+
}
525+
526+
memset(wbs_aligned, flash_area_erased_val(fap), sizeof(wbs_aligned));
527+
memcpy(wbs_aligned, img_chunk, write_size);
528+
529+
rc = flash_area_write(fap, curr_off, wbs_aligned, write_size);
530+
531+
if (rc != 0) {
532+
goto out;
533+
}
534+
535+
curr_off += write_size;
536+
img_chunk += write_size;
537+
img_chunk_len -= write_size;
538+
}
539+
} else {
540+
rc = flash_area_write(fap, curr_off, img_chunk, img_chunk_len);
541+
}
542+
#else
514543
rc = flash_area_write(fap, curr_off, img_chunk, img_chunk_len);
544+
#endif
545+
515546
if (rc == 0 && rem_bytes) {
516547
/* Non-zero rem_bytes means that last chunk needs alignment; the aligned
517548
* 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
@@ -51,6 +51,14 @@ config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
5151
Note that 0 is default upload target when no explicit
5252
selection is done.
5353

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

boot/zephyr/include/mcuboot_config/mcuboot_config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@
245245
#define MCUBOOT_SERIAL_MAX_RECEIVE_SIZE CONFIG_BOOT_SERIAL_MAX_RECEIVE_SIZE
246246
#endif
247247

248+
#ifdef CONFIG_BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
249+
#define MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE CONFIG_BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
250+
#endif
251+
248252
/* Support 32-byte aligned flash sizes */
249253
#if DT_HAS_CHOSEN(zephyr_flash)
250254
#if DT_PROP_OR(DT_CHOSEN(zephyr_flash), write_block_size, 0) > 8

0 commit comments

Comments
 (0)