@@ -120,15 +120,15 @@ boot_slots_trailer_sz(uint8_t min_write_sz)
120120{
121121 return /* state for all sectors */
122122 BOOT_STATUS_MAX_ENTRIES * BOOT_STATUS_STATE_COUNT * min_write_sz +
123- BOOT_MAX_ALIGN * 2 /* copy_done + image_ok */ +
123+ BOOT_MAX_ALIGN * 3 /* copy_done + image_ok + swap_size */ +
124124 BOOT_MAGIC_SZ ;
125125}
126126
127127static uint32_t
128128boot_scratch_trailer_sz (uint8_t min_write_sz )
129129{
130130 return BOOT_STATUS_STATE_COUNT * min_write_sz + /* state for one sector */
131- BOOT_MAX_ALIGN + /* image_ok */
131+ BOOT_MAX_ALIGN * 2 + /* image_ok + swap_size */
132132 BOOT_MAGIC_SZ ;
133133}
134134
@@ -186,6 +186,20 @@ boot_image_ok_off(const struct flash_area *fap)
186186 return fap -> fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN ;
187187}
188188
189+ static uint32_t
190+ boot_swap_size_off (const struct flash_area * fap )
191+ {
192+ /*
193+ * The "swap_size" field if located just before the trailer.
194+ * The scratch slot doesn't store "copy_done"...
195+ */
196+ if (fap -> fa_id == FLASH_AREA_IMAGE_SCRATCH ) {
197+ return fap -> fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 2 ;
198+ }
199+
200+ return fap -> fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 3 ;
201+ }
202+
189203int
190204boot_read_swap_state (const struct flash_area * fap ,
191205 struct boot_swap_state * state )
@@ -203,14 +217,14 @@ boot_read_swap_state(const struct flash_area *fap,
203217
204218 if (fap -> fa_id != FLASH_AREA_IMAGE_SCRATCH ) {
205219 off = boot_copy_done_off (fap );
206- rc = flash_area_read (fap , off , & state -> copy_done , 1 );
220+ rc = flash_area_read (fap , off , & state -> copy_done , sizeof state -> copy_done );
207221 if (rc != 0 ) {
208222 return BOOT_EFLASH ;
209223 }
210224 }
211225
212226 off = boot_image_ok_off (fap );
213- rc = flash_area_read (fap , off , & state -> image_ok , 1 );
227+ rc = flash_area_read (fap , off , & state -> image_ok , sizeof state -> image_ok );
214228 if (rc != 0 ) {
215229 return BOOT_EFLASH ;
216230 }
@@ -245,6 +259,68 @@ boot_read_swap_state_by_id(int flash_area_id, struct boot_swap_state *state)
245259 return rc ;
246260}
247261
262+ int
263+ boot_read_swap_size (uint32_t * swap_size )
264+ {
265+ uint32_t magic [BOOT_MAGIC_SZ ];
266+ uint32_t off ;
267+ const struct flash_area * fap ;
268+ int rc ;
269+
270+ /*
271+ * In the middle a swap, tries to locate the saved swap size. Looks
272+ * for a valid magic, first on Slot 0, then on scratch. Both "slots"
273+ * can end up being temporary storage for a swap and it is assumed
274+ * that if magic is valid then swap size is too, because magic is
275+ * always written in the last step.
276+ */
277+
278+ rc = flash_area_open (FLASH_AREA_IMAGE_0 , & fap );
279+ if (rc != 0 ) {
280+ return BOOT_EFLASH ;
281+ }
282+
283+ off = boot_magic_off (fap );
284+ rc = flash_area_read (fap , off , magic , BOOT_MAGIC_SZ );
285+ if (rc != 0 ) {
286+ rc = BOOT_EFLASH ;
287+ goto out ;
288+ }
289+
290+ if (memcmp (magic , boot_img_magic , BOOT_MAGIC_SZ ) != 0 ) {
291+ /*
292+ * If Slot 0 's magic is not valid, try scratch...
293+ */
294+
295+ flash_area_close (fap );
296+
297+ rc = flash_area_open (FLASH_AREA_IMAGE_SCRATCH , & fap );
298+ if (rc != 0 ) {
299+ return BOOT_EFLASH ;
300+ }
301+
302+ off = boot_magic_off (fap );
303+ rc = flash_area_read (fap , off , magic , BOOT_MAGIC_SZ );
304+ if (rc != 0 ) {
305+ rc = BOOT_EFLASH ;
306+ goto out ;
307+ }
308+
309+ assert (memcmp (magic , boot_img_magic , BOOT_MAGIC_SZ ) == 0 );
310+ }
311+
312+ off = boot_swap_size_off (fap );
313+ rc = flash_area_read (fap , off , swap_size , sizeof * swap_size );
314+ if (rc != 0 ) {
315+ rc = BOOT_EFLASH ;
316+ }
317+
318+ out :
319+ flash_area_close (fap );
320+ return rc ;
321+ }
322+
323+
248324int
249325boot_write_magic (const struct flash_area * fap )
250326{
@@ -305,6 +381,31 @@ boot_write_image_ok(const struct flash_area *fap)
305381 return boot_write_flag (BOOT_FLAG_IMAGE_OK , fap );
306382}
307383
384+ int
385+ boot_write_swap_size (const struct flash_area * fap , uint32_t swap_size )
386+ {
387+ uint32_t off ;
388+ int rc ;
389+ uint8_t buf [BOOT_MAX_ALIGN ];
390+ uint8_t align ;
391+
392+ off = boot_swap_size_off (fap );
393+ align = hal_flash_align (fap -> fa_device_id );
394+ assert (align <= BOOT_MAX_ALIGN );
395+ if (align < sizeof swap_size ) {
396+ align = sizeof swap_size ;
397+ }
398+ memset (buf , 0xFF , BOOT_MAX_ALIGN );
399+ memcpy (buf , (uint8_t * )& swap_size , sizeof swap_size );
400+
401+ rc = flash_area_write (fap , off , buf , align );
402+ if (rc != 0 ) {
403+ return BOOT_EFLASH ;
404+ }
405+
406+ return 0 ;
407+ }
408+
308409int
309410boot_swap_type (void )
310411{
0 commit comments