blob: 73037572f0da5784eab3302ce4af858aae7b97c8 [file] [log] [blame]
Christopher Collins92ea77f2016-12-12 15:59:26 -08001#
2# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
Marti Bolivar49b29172017-08-04 14:50:51 -04009#
Christopher Collins92ea77f2016-12-12 15:59:26 -080010# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
19
20****** BOOT LOADER
21
22*** SUMMARY
23
Fabio Utzigac834962017-07-20 13:20:48 -030024mcuboot comprises two packages:
Christopher Collins92ea77f2016-12-12 15:59:26 -080025
26 * The bootutil library (boot/bootutil)
Fabio Utzig5bd4e582017-07-20 08:55:38 -030027 * The boot application (each port has its own at boot/<port>)
Christopher Collins92ea77f2016-12-12 15:59:26 -080028
29The bootutil library performs most of the functions of a boot loader. In
30particular, the piece that is missing is the final step of actually jumping to
31the main image. This last step is instead implemented by the boot application.
32Boot loader functionality is separated in this manner to enable unit testing of
33the boot loader. A library can be unit tested, but an application can't.
34Therefore, functionality is delegated to the bootutil library when possible.
35
36*** LIMITATIONS
37
38The boot loader currently only supports images with the following
39characteristics:
40 * Built to run from flash.
Marti Bolivar49b29172017-08-04 14:50:51 -040041 * Built to run from a fixed location (i.e., not position-independent).
Christopher Collins92ea77f2016-12-12 15:59:26 -080042
43*** IMAGE FORMAT
44
45The following definitions describe the image format.
46
47#define IMAGE_MAGIC 0x96f3b83c
48
49#define IMAGE_HEADER_SIZE 32
50
51struct image_version {
52 uint8_t iv_major;
53 uint8_t iv_minor;
54 uint16_t iv_revision;
55 uint32_t iv_build_num;
56};
57
58/** Image header. All fields are in little endian byte order. */
59struct image_header {
60 uint32_t ih_magic;
61 uint16_t ih_tlv_size; /* Combined size of trailing TLVs (bytes). */
62 uint8_t ih_key_id; /* Which key image is signed with (0xff=unsigned). */
63 uint8_t _pad1;
64 uint16_t ih_hdr_size; /* Size of image header (bytes). */
65 uint16_t _pad2;
66 uint32_t ih_img_size; /* Does not include header. */
67 uint32_t ih_flags; /* IMAGE_F_[...] */
68 struct image_version ih_ver;
69 uint32_t _pad3;
70};
71
72/** Image trailer TLV format. All fields in little endian. */
73struct image_tlv {
74 uint8_t it_type; /* IMAGE_TLV_[...]. */
75 uint8_t _pad;
Marti Bolivar49b29172017-08-04 14:50:51 -040076 uint16_t it_len; /* Data length (not including TLV header). */
Christopher Collins92ea77f2016-12-12 15:59:26 -080077};
78
79/*
80 * Image header flags.
81 */
Marti Bolivar7c057e92017-08-04 14:46:39 -040082#define IMAGE_F_PIC 0x00000001 /* Not supported. */
83#define IMAGE_F_SHA256 0x00000002 /* Hash TLV is present */
84#define IMAGE_F_PKCS15_RSA2048_SHA256 0x00000004 /* PKCS15 w/RSA and SHA */
85#define IMAGE_F_ECDSA224_SHA256 0x00000008 /* ECDSA224 over SHA256 */
86#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
87#define IMAGE_F_ECDSA256_SHA256 0x00000020 /* ECDSA256 over SHA256 */
88#define IMAGE_F_PKCS1_PSS_RSA2048_SHA256 0x00000040 /* PKCS1 PSS */
Christopher Collins92ea77f2016-12-12 15:59:26 -080089
90/*
91 * Image trailer TLV types.
92 */
David Brown27648b82017-08-31 10:40:29 -060093#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
Marko Kiiskila8dd56f32017-08-22 21:40:49 -070094#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
David Brown27648b82017-08-31 10:40:29 -060095#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output */
96#define IMAGE_TLV_ECDSA256 0x22 /* ECDSA of hash output */
Christopher Collins92ea77f2016-12-12 15:59:26 -080097
98Optional type-length-value records (TLVs) containing image metadata are placed
99after the end of the image.
100
101The ih_hdr_size field indicates the length of the header, and therefore the
102offset of the image itself. This field provides for backwards compatibility in
103case of changes to the format of the image header.
104
105*** FLASH MAP
106
Fabio Utzigac834962017-07-20 13:20:48 -0300107A device's flash is partitioned according to its _flash map_. At a high
Christopher Collins92ea77f2016-12-12 15:59:26 -0800108level, the flash map maps numeric IDs to _flash areas_. A flash area is a
109region of disk with the following properties:
110 (1) An area can be fully erased without affecting any other areas.
111 (2) A write to one area does not restrict writes to other areas.
112
Marti Bolivar4e64d562017-08-04 14:53:33 -0400113The boot loader uses the following flash area IDs:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800114
115#define FLASH_AREA_BOOTLOADER 0
116#define FLASH_AREA_IMAGE_0 1
117#define FLASH_AREA_IMAGE_1 2
118#define FLASH_AREA_IMAGE_SCRATCH 3
119
Marti Bolivar4e64d562017-08-04 14:53:33 -0400120The bootloader area contains the bootloader image itself. The other areas are
121described in subsequent sections.
122
Christopher Collins92ea77f2016-12-12 15:59:26 -0800123*** IMAGE SLOTS
124
125A portion of the flash memory is partitioned into two image slots: a primary
126slot (0) and a secondary slot (1). The boot loader will only run an image from
127the primary slot, so images must be built such that they can run from that
128fixed location in flash. If the boot loader needs to run the image resident in
Marti Bolivara91674f2017-08-04 14:56:08 -0400129the secondary slot, it must copy its contents into the primary slot before doing
130so, either by swapping the two images or by overwriting the contents of the
131primary slot. The bootloader supports either swap- or overwrite-based image
132upgrades, but must be configured at build time to choose one of these two
133strategies.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800134
135In addition to the two image slots, the boot loader requires a scratch area to
136allow for reliable image swapping.
137
Marti Bolivara91674f2017-08-04 14:56:08 -0400138The overwrite upgrade strategy is substantially simpler to implement than the
139image swapping strategy, especially since the bootloader must work properly
140even when it is reset during the middle of an image swap. For this reason, the
141rest of the document describes its behavior when configured to swap images
142during an upgrade.
143
Marti Bolivar048d8d82017-08-04 17:14:24 -0400144*** BOOT SWAP TYPES
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800145
Marti Bolivar048d8d82017-08-04 17:14:24 -0400146When the device first boots under normal circumstances, there is an up-to-date
147firmware image in slot 0, which mcuboot can validate and then chain-load. In
148this case, no image swaps are necessary. During device upgrades, however, new
149candidate images are present in slot 1, which mcuboot must swap into slot 0
150before booting as discussed above.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800151
Marti Bolivar048d8d82017-08-04 17:14:24 -0400152Upgrading an old image with a new one by swapping can be a two-step process. In
153this process, mcuboot performs a "test" swap of image data in flash and boots
154the new image. The new image can then update the contents of flash at runtime
155to mark itself "OK", and mcuboot will then still choose to run it during the
156next boot. When this happens, the swap is made "permanent". If this doesn't
157happen, mcuboot will perform a "revert" swap during the next boot by swapping
158the images back into their original locations, and attempting to boot the old
159image.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800160
Marti Bolivar048d8d82017-08-04 17:14:24 -0400161Depending on the use case, the first swap can also be made permanent directly.
162In this case, mcuboot will never attempt to revert the images on the next reset.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800163
Marti Bolivar048d8d82017-08-04 17:14:24 -0400164Test swaps are supported to provide a rollback mechanism to prevent devices
165from becoming "bricked" by bad firmware. If the device crashes immediately
166upon booting a new (bad) image, mcuboot will revert to the old (working) image
167at the next device reset, rather than booting the bad image again. This allows
168device firmware to make test swaps permanent only after performing a self-test
169routine.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800170
Marti Bolivar048d8d82017-08-04 17:14:24 -0400171On startup, mcuboot inspects the contents of flash to decide which of these
172"swap types" to perform; this decision determines how it proceeds.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800173
Marti Bolivar048d8d82017-08-04 17:14:24 -0400174The possible swap types, and their meanings, are:
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800175
Marti Bolivar048d8d82017-08-04 17:14:24 -0400176- BOOT_SWAP_TYPE_NONE: The "usual" or "no upgrade" case; attempt to boot the
177 contents of slot 0.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800178
Marti Bolivar048d8d82017-08-04 17:14:24 -0400179- BOOT_SWAP_TYPE_TEST: Boot the contents of slot 1 by swapping images. Unless
180 the swap is made permanent, revert back on the next boot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800181
Marti Bolivar048d8d82017-08-04 17:14:24 -0400182- BOOT_SWAP_TYPE_PERM: Permanently swap images, and boot the upgraded image
183 firmware.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800184
Marti Bolivar048d8d82017-08-04 17:14:24 -0400185- BOOT_SWAP_TYPE_REVERT: A previous test swap was not made permanent; swap back
186 to the old image whose data are now in slot 1. If the old image marks itself
187 "OK" when it boots, the next boot will have swap type BOOT_SWAP_TYPE_NONE.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800188
Marti Bolivar048d8d82017-08-04 17:14:24 -0400189- BOOT_SWAP_TYPE_FAIL: Swap failed because image to be run is not valid.
190
191- BOOT_SWAP_TYPE_PANIC: Swapping encountered an unrecoverable error.
192
193The "swap type" is a high-level representation of the outcome of the
194boot. Subsequent sections describe how mcuboot determines the swap type from
195the bit-level contents of flash.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800196
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300197*** IMAGE TRAILER
Christopher Collins92ea77f2016-12-12 15:59:26 -0800198
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300199For the bootloader to be able to determine the current state and what actions
Marti Bolivar42818032017-08-04 15:45:01 -0400200should be taken during the current boot operation, it uses metadata stored in
201the image flash areas. While swapping, some of this metadata is temporarily
202copied into and out of the scratch area.
203
204This metadata is located at the end of the image flash areas, and is called an
205image trailer. An image trailer has the following structure:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800206
207 0 1 2 3
208 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
209 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collins92ea77f2016-12-12 15:59:26 -0800210 ~ ~
211 ~ Swap status (128 * min-write-size * 3) ~
212 ~ ~
213 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fabio Utzig2c305aa2017-07-20 13:14:25 -0300214 | Copy done | 0xff padding (7 octets) |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800215 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fabio Utzig2c305aa2017-07-20 13:14:25 -0300216 | Image OK | 0xff padding (7 octets) |
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300217 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
218 | MAGIC (16 octets) |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800219 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
220
Marti Bolivar42818032017-08-04 15:45:01 -0400221The offset immediately following such a record represents the start of the next
222flash area.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800223
224Note: "min-write-size" is a property of the flash hardware. If the hardware
225allows individual bytes to be written at arbitrary addresses, then
226min-write-size is 1. If the hardware only allows writes at even addresses,
227then min-write-size is 2, and so on.
228
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400229An image trailer contains the following fields:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800230
Marti Bolivar1dcb6852017-08-04 15:59:32 -04002311. Swap status: A series of records which records the progress of an image
232swap. To swap entire images, data are swapped between the two image areas one
233or more sectors at a time, like this:
234
235 - sector data in slot 0 is copied into scratch, then erased
236 - sector data in slot 1 is copied into slot 0, then erased
237 - sector data in scratch is copied into slot 1
238
239As it swaps images, the bootloader updates the swap status field in a way that
240allows it to compute how far this swap operation has progressed for each
241sector. The swap status field can thus used to resume a swap operation if the
242bootloader is halted while a swap operation is ongoing and later reset. The
243factor of 128 is the maximum number of sectors mcuboot supports for each image;
244its value is a bootloader design decision. The factor of min-write-sz is due to
245the behavior of flash hardware. The factor of 3 is explained below.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300246
2472. Copy done: A single byte indicating whether the image in this slot is
248complete (0x01=done; 0xff=not done).
249
2503. Image OK: A single byte indicating whether the image in this slot has been
251confirmed as good by the user (0x01=confirmed; 0xff=not confirmed).
252
2534. MAGIC: The following 16 bytes, written in host-byte-order:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800254
255 const uint32_t boot_img_magic[4] = {
256 0xf395c277,
257 0x7fefd260,
258 0x0f505235,
259 0x8079b62c,
260 };
261
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300262*** IMAGE TRAILERS
263
Marti Bolivar048d8d82017-08-04 17:14:24 -0400264At startup, the boot loader determines the boot swap type by inspecting the
265image trailers. When using the term "image trailers" what is meant is the
266aggregate information provided by both image slot's trailers.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300267
268The image trailers records are structured around the limitations imposed by flash
Christopher Collins92ea77f2016-12-12 15:59:26 -0800269hardware. As a consequence, they do not have a very intuitive design, and it
270is difficult to get a sense of the state of the device just by looking at the
Marti Bolivar048d8d82017-08-04 17:14:24 -0400271image trailers. It is better to map all the possible trailer states to the swap
272types described above via a set of tables. These tables are reproduced below.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300273
274Note: An important caveat about the tables described below is that they must
275be evaluated in the order presented here. Lower state numbers must have a
276higher priority when testing the image trailers.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800277
278
279 State I
280 | slot-0 | slot-1 |
281 -----------------+--------+--------|
Christopher Collins92ea77f2016-12-12 15:59:26 -0800282 magic | Any | Good |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800283 image-ok | Any | Unset |
Fabio Utzigf9d44282017-07-20 15:05:13 -0300284 copy-done | Any | Any |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800285 -----------------+--------+--------'
Marti Bolivar048d8d82017-08-04 17:14:24 -0400286 result: BOOT_SWAP_TYPE_TEST |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800287 -----------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300288
Christopher Collins92ea77f2016-12-12 15:59:26 -0800289
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300290 State II
Christopher Collins92ea77f2016-12-12 15:59:26 -0800291 | slot-0 | slot-1 |
292 -----------------+--------+--------|
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800293 magic | Any | Good |
294 image-ok | Any | 0x01 |
Fabio Utzigf9d44282017-07-20 15:05:13 -0300295 copy-done | Any | Any |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800296 -----------------+--------+--------'
Marti Bolivar048d8d82017-08-04 17:14:24 -0400297 result: BOOT_SWAP_TYPE_PERM |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800298 -----------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300299
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800300
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300301 State III
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800302 | slot-0 | slot-1 |
303 -----------------+--------+--------|
Christopher Collins92ea77f2016-12-12 15:59:26 -0800304 magic | Good | Unset |
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800305 image-ok | 0xff | Any |
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300306 copy-done | 0x01 | Any |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800307 -----------------+--------+--------'
Marti Bolivar048d8d82017-08-04 17:14:24 -0400308 result: BOOT_SWAP_TYPE_REVERT |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800309 -----------------------------------'
310
Marti Bolivar048d8d82017-08-04 17:14:24 -0400311Any of the above three states results in mcuboot attempting to swap images.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800312
Marti Bolivar048d8d82017-08-04 17:14:24 -0400313Otherwise, mcuboot does not attempt to swap images, resulting in one of the
314other three swap types, as illustrated by State IV.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300315
316
317 State IV
Christopher Collins92ea77f2016-12-12 15:59:26 -0800318 | slot-0 | slot-1 |
319 -----------------+--------+--------|
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300320 magic | Any | Any |
321 image-ok | Any | Any |
Fabio Utzigf9d44282017-07-20 15:05:13 -0300322 copy-done | Any | Any |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800323 -----------------+--------+--------'
Marti Bolivar048d8d82017-08-04 17:14:24 -0400324 result: BOOT_SWAP_TYPE_NONE, |
325 BOOT_SWAP_TYPE_FAIL, or |
326 BOOT_SWAP_TYPE_PANIC |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800327 -----------------------------------'
328
Marti Bolivar048d8d82017-08-04 17:14:24 -0400329In State IV, when no errors occur, mcuboot will attempt to boot the contents of
330slot 0 directly, and the result is BOOT_SWAP_TYPE_NONE. If the image in slot 0
331is not valid, the result is BOOT_SWAP_TYPE_FAIL. If a fatal error occurs during
332boot, the result is BOOT_SWAP_TYPE_PANIC. If the result is either
333BOOT_SWAP_TYPE_FAIL or BOOT_SWAP_TYPE_PANIC, mcuboot hangs rather than booting
334an invalid or compromised image.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300335
Marti Bolivar048d8d82017-08-04 17:14:24 -0400336Note: An important caveat to the above is the result when a swap is requested
337 and the image in slot 1 fails to validate, due to a hashing or signing
338 error. This state behaves as State IV with the extra action of marking
339 the image in slot 0 as "OK", to prevent further attempts to swap.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300340
341
Christopher Collins92ea77f2016-12-12 15:59:26 -0800342*** HIGH-LEVEL OPERATION
343
344With the terms defined, we can now explore the boot loader's operation. First,
345a high-level overview of the boot process is presented. Then, the following
346sections describe each step of the process in more detail.
347
348Procedure:
349
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300350A. Inspect swap status region; is an interrupted swap being resumed?
Christopher Collins92ea77f2016-12-12 15:59:26 -0800351 Yes: Complete the partial swap operation; skip to step C.
352 No: Proceed to step B.
353
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300354B. Inspect image trailers; is a swap requested?
Christopher Collins92ea77f2016-12-12 15:59:26 -0800355 Yes.
356 1. Is the requested image valid (integrity and security check)?
357 Yes.
358 a. Perform swap operation.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300359 b. Persist completion of swap procedure to image trailers.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800360 c. Proceed to step C.
361 No.
362 a. Erase invalid image.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300363 b. Persist failure of swap procedure to image trailers.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800364 c. Proceed to step C.
365 No: Proceed to step C.
366
367C. Boot into image in slot 0.
368
Christopher Collins92ea77f2016-12-12 15:59:26 -0800369*** IMAGE SWAPPING
370
371The boot loader swaps the contents of the two image slots for two reasons:
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800372 * User has issued a "set pending" operation; the image in slot-1 should be
373 run once (state II) or repeatedly (state III), depending on whether a
374 permanent swap was specified.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800375 * Test image rebooted without being confirmed; the boot loader should
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800376 revert to the original image currently in slot-1 (state IV).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800377
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300378If the image trailers indicates that the image in the secondary slot should be
Christopher Collins92ea77f2016-12-12 15:59:26 -0800379run, the boot loader needs to copy it to the primary slot. The image currently
380in the primary slot also needs to be retained in flash so that it can be used
381later. Furthermore, both images need to be recoverable if the boot loader
382resets in the middle of the swap operation. The two images are swapped
383according to the following procedure:
384
385 1. Determine how many flash sectors each image slot consists of. This
386 number must be the same for both slots.
387 2. Iterate the list of sector indices in descending order (i.e., starting
388 with the greatest index); current element = "index".
389 b. Erase scratch area.
390 c. Copy slot0[index] to scratch area.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300391 - If these are the last sectors (i.e., first swap being perfomed),
392 copy the full sector *except* the image trailer.
393 - Else, copy entire sector contents.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800394 d. Write updated swap status (i).
395
396 e. Erase slot1[index]
397 f. Copy slot0[index] to slot1[index]
398 - If these are the last sectors (i.e., first swap being perfomed),
399 copy the full sector *except* the image trailer.
400 - Else, copy entire sector contents.
401 g. Write updated swap status (ii).
402
403 h. Erase slot0[index].
404 i. Copy scratch area slot0[index].
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300405 - If these are the last sectors (i.e., first swap being perfomed),
406 copy the full sector *except* the image trailer.
407 - Else, copy entire sector contents.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800408 j. Write updated swap status (iii).
409
410 3. Persist completion of swap procedure to slot 0 image trailer.
411
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800412The additional caveats in step 2f are necessary so that the slot 1 image
413trailer can be written by the user at a later time. With the image trailer
414unwritten, the user can test the image in slot 1 (i.e., transition to state
415II).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800416
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300417Note1: If the sector being copied is the last sector, then swap status is
418temporarily maintained on scratch for the duration of this operation, always
419using slot0's area otherwise.
420
421Note2: The bootloader tries to copy only used sectors (based on largest image
422installed on any of the slots), minimizing the amount of sectors copied and
423reducing the amount of time required for a swap operation.
424
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800425The particulars of step 3 vary depending on whether an image is being tested,
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300426permanently used, reverted or a validation failure of slot 1 happened when a
427swap was requested:
428
Christopher Collins92ea77f2016-12-12 15:59:26 -0800429 * test:
430 o Write slot0.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800431 (swap caused the following values to be written:
432 slot0.magic = BOOT_MAGIC
433 slot0.image_ok = Unset)
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800434
435 * permanent:
436 o Write slot0.copy_done = 1
437 (swap caused the following values to be written:
438 slot0.magic = BOOT_MAGIC
439 slot0.image_ok = 0x01)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800440
441 * revert:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800442 o Write slot0.copy_done = 1
443 o Write slot0.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300444 (swap caused the following values to be written:
445 slot0.magic = BOOT_MAGIC)
446
447 * failure to validate slot 1:
448 o Write slot0.image_ok = 1
449
450After completing the operations as described above the image in slot 0 should
451be booted.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800452
453*** SWAP STATUS
454
455The swap status region allows the boot loader to recover in case it restarts in
456the middle of an image swap operation. The swap status region consists of a
457series of single-byte records. These records are written independently, and
458therefore must be padded according to the minimum write size imposed by the
459flash hardware. In the below figure, a min-write-size of 1 is assumed for
460simplicity. The structure of the swap status region is illustrated below. In
461this figure, a min-write-size of 1 is assumed for simplicity.
462
463 0 1 2 3
464 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
465 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
466 |sec127,state 0 |sec127,state 1 |sec127,state 2 |sec126,state 0 |
467 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
468 |sec126,state 1 |sec126,state 2 |sec125,state 0 |sec125,state 1 |
469 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
470 |sec125,state 2 | |
471 +-+-+-+-+-+-+-+-+ +
472 ~ ~
473 ~ [Records for indices 124 through 1 ~
474 ~ ~
475 ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
476 ~ |sec000,state 0 |sec000,state 1 |sec000,state 2 |
477 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
478
479The above is probably not helpful at all; here is a description in English.
480
481Each image slot is partitioned into a sequence of flash sectors. If we were to
482enumerate the sectors in a single slot, starting at 0, we would have a list of
483sector indices. Since there are two image slots, each sector index would
484correspond to a pair of sectors. For example, sector index 0 corresponds to
485the first sector in slot 0 and the first sector in slot 1. Furthermore, we
486impose a limit of 128 indices. If an image slot consists of more than 128
487sectors, the flash layout is not compatible with this boot loader. Finally,
488reverse the list of indices such that the list starts with index 127 and ends
489with 0. The swap status region is a representation of this reversed list.
490
491During a swap operation, each sector index transitions through four separate
492states:
493 0. slot 0: image 0, slot 1: image 1, scratch: N/A
494 1. slot 0: image 0, slot 1: N/A, scratch: image 1 (1->s, erase 1)
495 2. slot 0: N/A, slot 1: image 0, scratch: image 1 (0->1, erase 0)
496 3. slot 0: image 1, slot 1: image 0, scratch: N/A (s->0)
497
498Each time a sector index transitions to a new state, the boot loader writes a
499record to the swap status region. Logically, the boot loader only needs one
500record per sector index to keep track of the current swap state. However, due
501to limitations imposed by flash hardware, a record cannot be overwritten when
502an index's state changes. To solve this problem, the boot loader uses three
503records per sector index rather than just one.
504
505Each sector-state pair is represented as a set of three records. The record
506values map to the above four states as follows
507
508 | rec0 | rec1 | rec2
509 --------+------+------+------
510 state 0 | 0xff | 0xff | 0xff
511 state 1 | 0x01 | 0xff | 0xff
512 state 2 | 0x01 | 0x02 | 0xff
513 state 3 | 0x01 | 0x02 | 0x03
514
515The swap status region can accommodate 128 sector indices. Hence, the size of
516the region, in bytes, is 128 * min-write-size * 3. The number 128 is chosen
517somewhat arbitrarily and will likely be made configurable. The only
518requirement for the index count is that is is great enough to account for a
519maximum-sized image (i.e., at least as great as the total sector count in an
520image slot). If a device's image slots use less than 128 sectors, the first
521record that gets written will be somewhere in the middle of the region. For
522example, if a slot uses 64 sectors, the first sector index that gets swapped is
52363, which corresponds to the exact halfway point within the region.
524
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300525Note: since the scratch area only ever needs to record swapping of the last
526sector, it uses at most min-write-size * 3 bytes for its own status area.
527
Christopher Collins92ea77f2016-12-12 15:59:26 -0800528*** RESET RECOVERY
529
530If the boot loader resets in the middle of a swap operation, the two images may
531be discontiguous in flash. Bootutil recovers from this condition by using the
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300532image trailers to determine how the image parts are distributed in flash.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800533
534The first step is determine where the relevant swap status region is located.
535Because this region is embedded within the image slots, its location in flash
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300536changes during a swap operation. The below set of tables map image trailers
Christopher Collins92ea77f2016-12-12 15:59:26 -0800537contents to swap status location. In these tables, the "source" field
538indicates where the swap status region is located.
539
540 | slot-0 | scratch |
541 ----------+------------+------------|
542 magic | Good | Any |
543 copy-done | 0x01 | N/A |
544 ----------+------------+------------'
545 source: none |
546 ------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400547
Christopher Collins92ea77f2016-12-12 15:59:26 -0800548 | slot-0 | scratch |
549 ----------+------------+------------|
550 magic | Good | Any |
551 copy-done | 0xff | N/A |
552 ----------+------------+------------'
553 source: slot 0 |
554 ------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400555
Christopher Collins92ea77f2016-12-12 15:59:26 -0800556 | slot-0 | scratch |
557 ----------+------------+------------|
558 magic | Any | Good |
559 copy-done | Any | N/A |
560 ----------+------------+------------'
561 source: scratch |
562 ------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400563
Christopher Collins92ea77f2016-12-12 15:59:26 -0800564 | slot-0 | scratch |
565 ----------+------------+------------|
566 magic | Unset | Any |
567 copy-done | 0xff | N/A |
568 ----------+------------+------------|
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300569 source: slot 0 |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800570 ------------------------------------+------------------------------+
571 This represents one of two cases: |
572 o No swaps ever (no status to read, so no harm in checking). |
573 o Mid-revert; status in slot 0. |
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300574 For this reason we assume slot 0 as source, to trigger a check |
575 of the status area and find out if there was swapping under way. |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800576 -------------------------------------------------------------------'
577
578
579If the swap status region indicates that the images are not contiguous,
580bootutil completes the swap operation that was in progress when the system was
581reset. In other words, it applies the procedure defined in the previous
582section, moving image 1 into slot 0 and image 0 into slot 1. If the boot
583status file indicates that an image part is present in the scratch area, this
584part is copied into the correct location by starting at step e or step h in the
585area-swap procedure, depending on whether the part belongs to image 0 or image
5861.
587
588After the swap operation has been completed, the boot loader proceeds as though
589it had just been started.
590
591*** INTEGRITY CHECK
592
593An image is checked for integrity immediately before it gets copied into the
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300594primary slot. If the boot loader doesn't perform an image swap, then it can
595perform an optional integrity check of the image in slot0 if
596MCUBOOT_VALIDATE_SLOT0 is set, otherwise it doesn't perform an integrity check.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800597
598During the integrity check, the boot loader verifies the following aspects of
599an image:
600 * 32-bit magic number must be correct (0x96f3b83c).
601 * Image must contain a SHA256 TLV.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300602 * Calculated SHA256 must match SHA256 TLV contents.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800603 * Image *may* contain a signature TLV. If it does, its contents must be
604 verifiable using a key embedded in the boot loader.
605
606*** SECURITY
607
608As indicated above, the final step of the integrity check is signature
609verification. The boot loader can have one or more public keys embedded in it
610at build time. During signature verification, the boot loader verifies that an
611image was signed with a private key that corresponds to one of its public keys.
612The image signature TLV indicates the index of the key that is has been signed
613with. The boot loader uses this index to identify the corresponding public
614key.
615
616For information on embedding public keys in the boot loader, as well as
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300617producing signed images, see: doc/signed_images.md