Commit 9d3fd7f7 authored by Jamie McCrae's avatar Jamie McCrae Committed by Andrzej Puzdrowski
Browse files

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: default avatarJamie McCrae <jamie.mccrae@nordicsemi.no>
parent 8724081f
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -511,7 +511,38 @@ bs_upload(char *buf, int len)

    BOOT_LOG_INF("Writing at 0x%x until 0x%x", curr_off, curr_off + img_chunk_len);
    /* Write flash aligned chunk, note that img_chunk_len now holds aligned length */
#if defined(MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE) && MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE > 0
    if (flash_area_align(fap) > 1 &&
        (((size_t)img_chunk) & (flash_area_align(fap) - 1)) != 0) {
        /* Buffer address incompatible with write address, use buffer to write */
        uint8_t write_size = MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE;
        uint8_t wbs_aligned[MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE];

        while (img_chunk_len >= flash_area_align(fap)) {
            if (write_size > img_chunk_len) {
                write_size = img_chunk_len;
            }

            memset(wbs_aligned, flash_area_erased_val(fap), sizeof(wbs_aligned));
            memcpy(wbs_aligned, img_chunk, write_size);

            rc = flash_area_write(fap, curr_off, wbs_aligned, write_size);

            if (rc != 0) {
                goto out;
            }

            curr_off += write_size;
            img_chunk += write_size;
            img_chunk_len -= write_size;
        }
    } else {
        rc = flash_area_write(fap, curr_off, img_chunk, img_chunk_len);
    }
#else
    rc = flash_area_write(fap, curr_off, img_chunk, img_chunk_len);
#endif

    if (rc == 0 && rem_bytes) {
        /* Non-zero rem_bytes means that last chunk needs alignment; the aligned
         * part, in the img_chunk_len - rem_bytes count bytes, has already been
+8 −0
Original line number Diff line number Diff line
@@ -51,6 +51,14 @@ config MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD
	  Note that 0 is default upload target when no explicit
	  selection is done.

config BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
	int "Stack buffer for unaligned memory writes"
	default 64
	help
	  Specifies the stack usage for a buffer which is used for unaligned
	  memory access when data is written to a device with memory alignment
	  requirements. Set to 0 to disable.

config BOOT_MAX_LINE_INPUT_LEN
	int "Maximum input line length"
	default 512
+4 −0
Original line number Diff line number Diff line
@@ -245,6 +245,10 @@
#define MCUBOOT_SERIAL_MAX_RECEIVE_SIZE CONFIG_BOOT_SERIAL_MAX_RECEIVE_SIZE
#endif

#ifdef CONFIG_BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
#define MCUBOOT_SERIAL_UNALIGNED_BUFFER_SIZE CONFIG_BOOT_SERIAL_UNALIGNED_BUFFER_SIZE
#endif

/* Support 32-byte aligned flash sizes */
#if DT_HAS_CHOSEN(zephyr_flash)
    #if DT_PROP_OR(DT_CHOSEN(zephyr_flash), write_block_size, 0) > 8