@@ -43,26 +43,78 @@ BUILD_ASSERT((CONFIG_IMG_BLOCK_BUF_SIZE % FLASH_WRITE_BLOCK_SIZE == 0),
4343 "FLASH_WRITE_BLOCK_SIZE" );
4444#endif
4545
46+ static int scramble_mcuboot_trailer (struct flash_img_context * ctx )
47+ {
48+ int rc = 0 ;
49+
50+ #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
51+ if (stream_flash_bytes_written (& ctx -> stream ) == 0 ) {
52+ off_t toff = boot_get_trailer_status_offset (ctx -> flash_area -> fa_size );
53+ off_t offset ;
54+ size_t size ;
55+ const struct flash_parameters * fparams =
56+ flash_get_parameters (flash_area_get_device (ctx -> flash_area ));
57+ #ifdef CONFIG_STREAM_FLASH_ERASE
58+ /* for erasable devices prgressive-erase works only along with
59+ * CONFIG_STREAM_FLASH_ERASE option.
60+ */
61+ if (flash_params_get_erase_cap (fparams ) & FLASH_ERASE_C_EXPLICIT ) {
62+ /* On devices with explicit erase we are aligning to page
63+ * layout.
64+ */
65+ struct flash_pages_info info ;
66+
67+ rc = flash_get_page_info_by_offs (flash_area_get_device (ctx -> flash_area ),
68+ toff , & info );
69+ if (rc != 0 ) {
70+ return rc ;
71+ }
72+ offset = info .start_offset ;
73+ size = info .size ;
74+
75+ } else
76+ #endif
77+ {
78+ /* On devices with no erase, we are aligning to write block
79+ * size.
80+ */
81+ offset = (toff + fparams -> write_block_size - 1 ) &
82+ ~(fparams -> write_block_size - 1 );
83+ /* No alignment correction needed here, offset is corrected already
84+ * and, size should be aligned.
85+ */
86+ size = ctx -> flash_area -> fa_size - offset ;
87+ }
88+
89+ rc = flash_area_flatten (ctx -> flash_area , offset , size );
90+ }
91+ #endif
92+
93+ return rc ;
94+ }
95+
96+
4697int flash_img_buffered_write (struct flash_img_context * ctx , const uint8_t * data ,
4798 size_t len , bool flush )
4899{
49100 int rc ;
50101
51- rc = stream_flash_buffered_write (& ctx -> stream , data , len , flush );
52- if (!flush ) {
102+ /* If there is a need to erase the trailer, that should happen before any
103+ * write is done to partition.
104+ */
105+ rc = scramble_mcuboot_trailer (ctx );
106+ if (rc != 0 ) {
53107 return rc ;
54108 }
55109
56- #ifdef CONFIG_IMG_ERASE_PROGRESSIVELY
57- ssize_t status_offset = boot_get_trailer_status_offset (
58- ctx -> flash_area -> fa_size );
59- rc = stream_flash_erase_page (& ctx -> stream ,
60- ctx -> flash_area -> fa_off +
61- status_offset );
62- if (rc ) {
110+
111+ /* if CONFIG_IMG_ERASE_PROGRESSIVELY is enabled the enabled CONFIG_STREAM_FLASH_ERASE
112+ * ensures that stream_flash erases flash progresively.
113+ */
114+ rc = stream_flash_buffered_write (& ctx -> stream , data , len , flush );
115+ if (!flush ) {
63116 return rc ;
64117 }
65- #endif
66118
67119 flash_area_close (ctx -> flash_area );
68120 ctx -> flash_area = NULL ;
0 commit comments