Skip to content

Commit e245347

Browse files
davidvinczed3zd3z
authored andcommitted
Boot: Save image sequence number to image trailer
Overload the swap_type field in image trailer to store as an addition the image sequence number. It indicates which image's swap was interrupted. It is required by multi image boot to determine which image the trailer belongs to if boot status is found on scratch area when the swap operation is resumed. Change-Id: I6820fd8277931aff4f0db408376eae8b42a030ed Signed-off-by: Tamas Ban <[email protected]> Signed-off-by: David Vincze <[email protected]>
1 parent 853657c commit e245347

File tree

4 files changed

+88
-35
lines changed

4 files changed

+88
-35
lines changed

boot/bootutil/src/bootutil_misc.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
* under the License.
1818
*/
1919

20+
/*
21+
* Modifications are Copyright (c) 2019 Arm Limited.
22+
*/
23+
2024
#include <assert.h>
2125
#include <string.h>
2226
#include <inttypes.h>
@@ -194,7 +198,7 @@ boot_status_off(const struct flash_area *fap)
194198
}
195199

196200
uint32_t
197-
boot_swap_type_off(const struct flash_area *fap)
201+
boot_swap_info_off(const struct flash_area *fap)
198202
{
199203
return fap->fa_size - BOOT_MAGIC_SZ - BOOT_MAX_ALIGN * 3;
200204
}
@@ -232,6 +236,7 @@ boot_read_swap_state(const struct flash_area *fap,
232236
{
233237
uint32_t magic[BOOT_MAGIC_ARR_SZ];
234238
uint32_t off;
239+
uint8_t swap_info;
235240
int rc;
236241

237242
off = boot_magic_off(fap);
@@ -245,14 +250,19 @@ boot_read_swap_state(const struct flash_area *fap,
245250
state->magic = boot_magic_decode(magic);
246251
}
247252

248-
off = boot_swap_type_off(fap);
249-
rc = flash_area_read_is_empty(fap, off, &state->swap_type,
250-
sizeof state->swap_type);
253+
off = boot_swap_info_off(fap);
254+
rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
251255
if (rc < 0) {
252256
return BOOT_EFLASH;
253257
}
258+
259+
/* Extract the swap type and image number */
260+
state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
261+
state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
262+
254263
if (rc == 1 || state->swap_type > BOOT_SWAP_TYPE_REVERT) {
255264
state->swap_type = BOOT_SWAP_TYPE_NONE;
265+
state->image_num = 0;
256266
}
257267

258268
off = boot_copy_done_off(fap);
@@ -494,14 +504,18 @@ boot_write_image_ok(const struct flash_area *fap)
494504
* resume in case of an unexpected reset.
495505
*/
496506
int
497-
boot_write_swap_type(const struct flash_area *fap, uint8_t swap_type)
507+
boot_write_swap_info(const struct flash_area *fap, uint8_t swap_type,
508+
uint8_t image_num)
498509
{
499510
uint32_t off;
500-
501-
off = boot_swap_type_off(fap);
502-
BOOT_LOG_DBG("writing swap_type; fa_id=%d off=0x%x (0x%x), swap_type=0x%x",
503-
fap->fa_id, off, fap->fa_off + off, swap_type);
504-
return boot_write_trailer_byte(fap, off, swap_type);
511+
uint8_t swap_info;
512+
513+
BOOT_SET_SWAP_INFO(swap_info, image_num, swap_type);
514+
off = boot_swap_info_off(fap);
515+
BOOT_LOG_DBG("writing swap_info; fa_id=%d off=0x%x (0x%x), swap_type=0x%x"
516+
" image_num=0x%x",
517+
fap->fa_id, off, fap->fa_off + off, swap_type, image_num);
518+
return boot_write_trailer_byte(fap, off, swap_info);
505519
}
506520

507521
int
@@ -648,7 +662,7 @@ boot_set_pending(int permanent)
648662
} else {
649663
swap_type = BOOT_SWAP_TYPE_TEST;
650664
}
651-
rc = boot_write_swap_type(fap, swap_type);
665+
rc = boot_write_swap_info(fap, swap_type, 0);
652666
}
653667

654668
flash_area_close(fap);

boot/bootutil/src/bootutil_priv.h

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
* under the License.
1818
*/
1919

20+
/*
21+
* Modifications are Copyright (c) 2019 Arm Limited.
22+
*/
23+
2024
#ifndef H_BOOTUTIL_PRIV_
2125
#define H_BOOTUTIL_PRIV_
2226

@@ -106,7 +110,7 @@ struct boot_status {
106110
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
107111
* | Swap size (4 octets) |
108112
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
109-
* | Swap type | 0xff padding (7 octets) |
113+
* | Swap info | 0xff padding (7 octets) |
110114
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111115
* | Copy done | 0xff padding (7 octets) |
112116
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -127,10 +131,26 @@ struct boot_swap_state {
127131
uint8_t swap_type; /* One of the BOOT_SWAP_TYPE_[...] values. */
128132
uint8_t copy_done; /* One of the BOOT_FLAG_[...] values. */
129133
uint8_t image_ok; /* One of the BOOT_FLAG_[...] values. */
134+
uint8_t image_num; /* Boot status belongs to this image */
130135
};
131136

132137
#define BOOT_MAX_IMG_SECTORS MCUBOOT_MAX_IMG_SECTORS
133138

139+
/*
140+
* Extract the swap type and image number from image trailers's swap_info
141+
* filed.
142+
*/
143+
#define BOOT_GET_SWAP_TYPE(swap_info) ((swap_info) & 0x0F)
144+
#define BOOT_GET_IMAGE_NUM(swap_info) ((swap_info) >> 4)
145+
146+
/* Construct the swap_info field from swap type and image number */
147+
#define BOOT_SET_SWAP_INFO(swap_info, image, type) { \
148+
assert((image) < 0xF); \
149+
assert((type) < 0xF); \
150+
(swap_info) = (image) << 4 \
151+
| (type); \
152+
}
153+
134154
/*
135155
* The current flashmap API does not check the amount of space allocated when
136156
* loading sector data from the flash device, allowing for smaller counts here
@@ -194,7 +214,7 @@ int boot_magic_compatible_check(uint8_t tbl_val, uint8_t val);
194214
uint32_t boot_trailer_sz(uint8_t min_write_sz);
195215
int boot_status_entries(const struct flash_area *fap);
196216
uint32_t boot_status_off(const struct flash_area *fap);
197-
uint32_t boot_swap_type_off(const struct flash_area *fap);
217+
uint32_t boot_swap_info_off(const struct flash_area *fap);
198218
int boot_read_swap_state(const struct flash_area *fap,
199219
struct boot_swap_state *state);
200220
int boot_read_swap_state_by_id(int flash_area_id,
@@ -204,7 +224,8 @@ int boot_write_status(struct boot_status *bs);
204224
int boot_schedule_test_swap(void);
205225
int boot_write_copy_done(const struct flash_area *fap);
206226
int boot_write_image_ok(const struct flash_area *fap);
207-
int boot_write_swap_type(const struct flash_area *fap, uint8_t swap_type);
227+
int boot_write_swap_info(const struct flash_area *fap, uint8_t swap_type,
228+
uint8_t image_num);
208229
int boot_write_swap_size(const struct flash_area *fap, uint32_t swap_size);
209230
int boot_read_swap_size(uint32_t *swap_size);
210231
#ifdef MCUBOOT_ENC_IMAGES

boot/bootutil/src/loader.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
* under the License.
1818
*/
1919

20+
/*
21+
* Modifications are Copyright (c) 2019 Arm Limited.
22+
*/
23+
2024
/**
2125
* This file provides an interface to the boot loader. Functions defined in
2226
* this file should only be called while the boot loader is running.
@@ -522,6 +526,7 @@ boot_read_status(struct boot_status *bs)
522526
{
523527
const struct flash_area *fap;
524528
uint32_t off;
529+
uint8_t swap_info;
525530
int status_loc;
526531
int area_id;
527532
int rc;
@@ -561,13 +566,15 @@ boot_read_status(struct boot_status *bs)
561566

562567
rc = boot_read_status_bytes(fap, bs);
563568
if (rc == 0) {
564-
off = boot_swap_type_off(fap);
565-
rc = flash_area_read_is_empty(fap, off, &bs->swap_type,
566-
sizeof bs->swap_type);
569+
off = boot_swap_info_off(fap);
570+
rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
567571
if (rc == 1) {
568-
bs->swap_type = BOOT_SWAP_TYPE_NONE;
572+
BOOT_SET_SWAP_INFO(swap_info, 0, BOOT_SWAP_TYPE_NONE);
569573
rc = 0;
570574
}
575+
576+
/* Extract the swap type info */
577+
bs->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
571578
}
572579

573580
flash_area_close(fap);
@@ -974,7 +981,9 @@ boot_status_init(const struct flash_area *fap, const struct boot_status *bs)
974981
assert(rc == 0);
975982

976983
if (bs->swap_type != BOOT_SWAP_TYPE_NONE) {
977-
rc = boot_write_swap_type(fap, bs->swap_type);
984+
rc = boot_write_swap_info(fap,
985+
bs->swap_type,
986+
0);
978987
assert(rc == 0);
979988
}
980989

@@ -1194,8 +1203,9 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs)
11941203
}
11951204

11961205
if (swap_state.swap_type != BOOT_SWAP_TYPE_NONE) {
1197-
rc = boot_write_swap_type(fap_primary_slot,
1198-
swap_state.swap_type);
1206+
rc = boot_write_swap_info(fap_primary_slot,
1207+
swap_state.swap_type,
1208+
0);
11991209
assert(rc == 0);
12001210
}
12011211

docs/design.md

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ image trailer. An image trailer has the following structure:
266266
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
267267
| Swap size (4 octets) |
268268
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
269-
| Swap type | 0xff padding (7 octets) |
269+
| Swap info | 0xff padding (7 octets) |
270270
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
271271
| Copy done | 0xff padding (7 octets) |
272272
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -319,10 +319,17 @@ of 3 is explained below.
319319
this location for easier recovery in case of a reset while performing the
320320
swap.
321321

322-
4. Swap type: A single byte indicating the type of swap operation in progress.
323-
When mcuboot resumes an interrupted swap, it uses this field to determine
324-
the type of operation to perform. This field contains one of the following
325-
values:
322+
4. Swap info: A single byte which encodes the following informations:
323+
- Swap type: Stored in bits 0-3. Indicating the type of swap operation in
324+
progress. When mcuboot resumes an interrupted swap, it uses this field to
325+
determine the type of operation to perform. This field contains one of the
326+
following values in the table below.
327+
- Image number: Stored in bits 4-7. It has always 0 value at single image
328+
boot. In case of multi image boot it indicates, which image was swapped when
329+
interrupt happened. The same scratch area is used during in case of all
330+
image swap operation. Therefore this field is used to determine which image
331+
the trailer belongs to if boot status is found on scratch area when the swap
332+
operation is resumed.
326333

327334
| Name | Value |
328335
| ------------------------- | ----- |
@@ -439,8 +446,9 @@ Note: An important caveat to the above is the result when a swap is requested
439446
440447
If mcuboot determines that it is resuming an interrupted swap (i.e., a reset
441448
occurred mid-swap), it fully determines the operation to resume by reading the
442-
`swap type` field from the active trailer. The set of tables in the previous
443-
section are not necessary in the resume case.
449+
`swap info` field from the active trailer and extracting the swap type from bits
450+
0-3. The set of tables in the previous section are not necessary in the resume
451+
case.
444452
445453
## High-Level Operation
446454
@@ -687,13 +695,13 @@ indicates where the swap status region is located.
687695
688696
If the swap status region indicates that the images are not contiguous, mcuboot
689697
determines the type of swap operation that was interrupted by reading the `swap
690-
type` field in the active image trailer, and then resumes the operation. In
691-
other words, it applies the procedure defined in the previous section, moving
692-
image 1 into the primary slot and image 0 into the secondary slot. If the boot
693-
status indicates that an image part is present in the scratch area, this part
694-
is copied into the correct location by starting at step e or step h in the
695-
area-swap procedure, depending on whether the part belongs to image 0 or image
696-
1.
698+
info` field in the active image trailer and extarcting the swap type from bits
699+
0-3 then resumes the operation. In other words, it applies the procedure defined
700+
in the previous section, moving image 1 into the primary slot and image 0 into
701+
the secondary slot. If the boot status indicates that an image part is present
702+
in the scratch area, this part is copied into the correct location by starting
703+
at step e or step h in the area-swap procedure, depending on whether the part
704+
belongs to image 0 or image 1.
697705
698706
After the swap operation has been completed, the boot loader proceeds as though
699707
it had just been started.

0 commit comments

Comments
 (0)