blob: 5c3d1b95db51c98329fc2bd3ceb7df536a506854 [file] [log] [blame] [view]
David Brown17e20d12017-09-12 11:53:20 -06001<!--
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
Christopher Collins92ea77f2016-12-12 15:59:26 -08009
David Brown17e20d12017-09-12 11:53:20 -060010 http://www.apache.org/licenses/LICENSE-2.0
Christopher Collins92ea77f2016-12-12 15:59:26 -080011
David Brown17e20d12017-09-12 11:53:20 -060012 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
Christopher Collins92ea77f2016-12-12 15:59:26 -080023
Fabio Utzigac834962017-07-20 13:20:48 -030024mcuboot comprises two packages:
Christopher Collins92ea77f2016-12-12 15:59:26 -080025
David Brown17e20d12017-09-12 11:53:20 -060026* The bootutil library (boot/bootutil)
27* 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
David Brown17e20d12017-09-12 11:53:20 -060036## Limitations
Christopher Collins92ea77f2016-12-12 15:59:26 -080037
38The boot loader currently only supports images with the following
39characteristics:
David Brown17e20d12017-09-12 11:53:20 -060040* Built to run from flash.
41* Built to run from a fixed location (i.e., not position-independent).
Christopher Collins92ea77f2016-12-12 15:59:26 -080042
David Brown17e20d12017-09-12 11:53:20 -060043## Image Format
Christopher Collins92ea77f2016-12-12 15:59:26 -080044
45The following definitions describe the image format.
46
David Brown17e20d12017-09-12 11:53:20 -060047``` c
Fabio Utzigea422c22017-09-11 11:02:47 -030048#define IMAGE_MAGIC 0x96f3b83d
Christopher Collins92ea77f2016-12-12 15:59:26 -080049
50#define IMAGE_HEADER_SIZE 32
51
52struct image_version {
53 uint8_t iv_major;
54 uint8_t iv_minor;
55 uint16_t iv_revision;
56 uint32_t iv_build_num;
57};
58
59/** Image header. All fields are in little endian byte order. */
60struct image_header {
61 uint32_t ih_magic;
Fabio Utzigea422c22017-09-11 11:02:47 -030062 uint32_t ih_load_addr;
Christopher Collins92ea77f2016-12-12 15:59:26 -080063 uint16_t ih_hdr_size; /* Size of image header (bytes). */
64 uint16_t _pad2;
65 uint32_t ih_img_size; /* Does not include header. */
Fabio Utzigea422c22017-09-11 11:02:47 -030066 uint32_t ih_flags; /* IMAGE_F_[...]. */
Christopher Collins92ea77f2016-12-12 15:59:26 -080067 struct image_version ih_ver;
68 uint32_t _pad3;
69};
70
Fabio Utzigea422c22017-09-11 11:02:47 -030071/** Image TLV header. All fields in little endian. */
72struct image_tlv_info {
73 uint16_t it_magic;
74 uint16_t it_tlv_tot; /* size of TLV area (including tlv_info header) */
75};
76
Christopher Collins92ea77f2016-12-12 15:59:26 -080077/** Image trailer TLV format. All fields in little endian. */
78struct image_tlv {
79 uint8_t it_type; /* IMAGE_TLV_[...]. */
80 uint8_t _pad;
Marti Bolivar49b29172017-08-04 14:50:51 -040081 uint16_t it_len; /* Data length (not including TLV header). */
Christopher Collins92ea77f2016-12-12 15:59:26 -080082};
83
84/*
85 * Image header flags.
86 */
Marti Bolivar7c057e92017-08-04 14:46:39 -040087#define IMAGE_F_PIC 0x00000001 /* Not supported. */
Marti Bolivar7c057e92017-08-04 14:46:39 -040088#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
Fabio Utzigea422c22017-09-11 11:02:47 -030089#define IMAGE_F_RAM_LOAD 0x00000020
Christopher Collins92ea77f2016-12-12 15:59:26 -080090
91/*
92 * Image trailer TLV types.
93 */
Fabio Utzigea422c22017-09-11 11:02:47 -030094#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
David Brown27648b82017-08-31 10:40:29 -060095#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
Marko Kiiskila8dd56f32017-08-22 21:40:49 -070096#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
David Brown27648b82017-08-31 10:40:29 -060097#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output */
98#define IMAGE_TLV_ECDSA256 0x22 /* ECDSA of hash output */
Fabio Utzig3501c012019-05-13 15:07:25 -070099#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
David Brown17e20d12017-09-12 11:53:20 -0600100```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800101
102Optional type-length-value records (TLVs) containing image metadata are placed
103after the end of the image.
104
David Brown17e20d12017-09-12 11:53:20 -0600105The `ih_hdr_size` field indicates the length of the header, and therefore the
Christopher Collins92ea77f2016-12-12 15:59:26 -0800106offset of the image itself. This field provides for backwards compatibility in
107case of changes to the format of the image header.
108
David Brown17e20d12017-09-12 11:53:20 -0600109## Flash Map
Christopher Collins92ea77f2016-12-12 15:59:26 -0800110
Fabio Utzigac834962017-07-20 13:20:48 -0300111A device's flash is partitioned according to its _flash map_. At a high
Christopher Collins92ea77f2016-12-12 15:59:26 -0800112level, the flash map maps numeric IDs to _flash areas_. A flash area is a
113region of disk with the following properties:
David Brown17e20d12017-09-12 11:53:20 -06001141. An area can be fully erased without affecting any other areas.
1152. A write to one area does not restrict writes to other areas.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800116
Marti Bolivar4e64d562017-08-04 14:53:33 -0400117The boot loader uses the following flash area IDs:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800118
David Brown17e20d12017-09-12 11:53:20 -0600119``` c
David Vincze2d736ad2019-02-18 11:50:22 +0100120#define FLASH_AREA_BOOTLOADER 0
121#define FLASH_AREA_IMAGE_PRIMARY 1
122#define FLASH_AREA_IMAGE_SECONDARY 2
123#define FLASH_AREA_IMAGE_SCRATCH 3
David Brown17e20d12017-09-12 11:53:20 -0600124```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800125
Marti Bolivar4e64d562017-08-04 14:53:33 -0400126The bootloader area contains the bootloader image itself. The other areas are
127described in subsequent sections.
128
David Brown17e20d12017-09-12 11:53:20 -0600129## Image Slots
Christopher Collins92ea77f2016-12-12 15:59:26 -0800130
131A portion of the flash memory is partitioned into two image slots: a primary
132slot (0) and a secondary slot (1). The boot loader will only run an image from
133the primary slot, so images must be built such that they can run from that
134fixed location in flash. If the boot loader needs to run the image resident in
Marti Bolivara91674f2017-08-04 14:56:08 -0400135the secondary slot, it must copy its contents into the primary slot before doing
136so, either by swapping the two images or by overwriting the contents of the
137primary slot. The bootloader supports either swap- or overwrite-based image
138upgrades, but must be configured at build time to choose one of these two
139strategies.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800140
141In addition to the two image slots, the boot loader requires a scratch area to
Fabio Utziga722f5a2017-12-12 14:04:53 -0200142allow for reliable image swapping. The scratch area must have a size that is
143enough to store at least the largest sector that is going to be swapped. Many
David Vincze2d736ad2019-02-18 11:50:22 +0100144devices have small equally sized flash sectors, eg 4K, while others have
145variable sized sectors where the largest sectors might be 128K or 256K, so the
146scratch must be big enough to store that. The scratch is only ever used when
147swapping firmware, which means only when doing an upgrade. Given that, the main
148reason for using a larger size for the scratch is that flash wear will be more
149evenly distributed, because a single sector would be written twice the number of
150times than using two sectors, for example. To evaluate the ideal size of the
151scratch for your use case the following parameters are relevant:
Fabio Utziga722f5a2017-12-12 14:04:53 -0200152
153* the ratio of image size / scratch size
154* the number of erase cycles supported by the flash hardware
155
156The image size is used (instead of slot size) because only the slot's sectors
157that are actually used for storing the image are copied. The image/scratch ratio
158is the number of times the scratch will be erased on every upgrade. The number
159of erase cycles divided by the image/scratch ratio will give you the number of
160times an upgrade can be performed before the device goes out of spec.
161
162```
163num_upgrades = number_of_erase_cycles / (image_size / scratch_size)
164```
165
166Let's assume, for example, a device with 10000 erase cycles, an image size of
167150K and a scratch of 4K (usual minimum size of 4K sector devices). This would
168result in a total of:
169
170`10000 / (150 / 4) ~ 267`
171
172Increasing the scratch to 16K would give us:
173
174`10000 / (150 / 16) ~ 1067`
175
176There is no *best* ratio, as the right size is use-case dependent. Factors to
177consider include the number of times a device will be upgraded both in the field
David Vincze2d736ad2019-02-18 11:50:22 +0100178and during development, as well as any desired safety margin on the
179manufacturer's specified number of erase cycles. In general, using a ratio that
180allows hundreds to thousands of field upgrades in production is recommended.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800181
Marti Bolivara91674f2017-08-04 14:56:08 -0400182The overwrite upgrade strategy is substantially simpler to implement than the
183image swapping strategy, especially since the bootloader must work properly
184even when it is reset during the middle of an image swap. For this reason, the
185rest of the document describes its behavior when configured to swap images
186during an upgrade.
187
David Brown17e20d12017-09-12 11:53:20 -0600188## Boot Swap Types
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800189
Marti Bolivar048d8d82017-08-04 17:14:24 -0400190When the device first boots under normal circumstances, there is an up-to-date
David Vincze2d736ad2019-02-18 11:50:22 +0100191firmware image in the primary slot, which mcuboot can validate and then
192chain-load. In this case, no image swaps are necessary. During device upgrades,
193however, new candidate images are present in the secondary slot, which mcuboot
194must swap into the primary slot before booting as discussed above.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800195
Marti Bolivar048d8d82017-08-04 17:14:24 -0400196Upgrading an old image with a new one by swapping can be a two-step process. In
197this process, mcuboot performs a "test" swap of image data in flash and boots
198the new image. The new image can then update the contents of flash at runtime
199to mark itself "OK", and mcuboot will then still choose to run it during the
200next boot. When this happens, the swap is made "permanent". If this doesn't
201happen, mcuboot will perform a "revert" swap during the next boot by swapping
202the images back into their original locations, and attempting to boot the old
203image.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800204
Marti Bolivar048d8d82017-08-04 17:14:24 -0400205Depending on the use case, the first swap can also be made permanent directly.
206In this case, mcuboot will never attempt to revert the images on the next reset.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800207
Marti Bolivar048d8d82017-08-04 17:14:24 -0400208Test swaps are supported to provide a rollback mechanism to prevent devices
209from becoming "bricked" by bad firmware. If the device crashes immediately
210upon booting a new (bad) image, mcuboot will revert to the old (working) image
211at the next device reset, rather than booting the bad image again. This allows
212device firmware to make test swaps permanent only after performing a self-test
213routine.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800214
Marti Bolivar048d8d82017-08-04 17:14:24 -0400215On startup, mcuboot inspects the contents of flash to decide which of these
216"swap types" to perform; this decision determines how it proceeds.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800217
Marti Bolivar048d8d82017-08-04 17:14:24 -0400218The possible swap types, and their meanings, are:
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800219
David Brown17e20d12017-09-12 11:53:20 -0600220- `BOOT_SWAP_TYPE_NONE`: The "usual" or "no upgrade" case; attempt to boot the
David Vincze2d736ad2019-02-18 11:50:22 +0100221 contents of the primary slot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800222
David Vincze2d736ad2019-02-18 11:50:22 +0100223- `BOOT_SWAP_TYPE_TEST`: Boot the contents of the secondary slot by swapping
224 images. Unless the swap is made permanent, revert back on the next boot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800225
David Brown17e20d12017-09-12 11:53:20 -0600226- `BOOT_SWAP_TYPE_PERM`: Permanently swap images, and boot the upgraded image
Marti Bolivar048d8d82017-08-04 17:14:24 -0400227 firmware.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800228
David Vincze2d736ad2019-02-18 11:50:22 +0100229- `BOOT_SWAP_TYPE_REVERT`: A previous test swap was not made permanent;
230 swap back to the old image whose data are now in the secondary slot. If the
231 old image marks itself "OK" when it boots, the next boot will have swap type
232 `BOOT_SWAP_TYPE_NONE`.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800233
David Brown17e20d12017-09-12 11:53:20 -0600234- `BOOT_SWAP_TYPE_FAIL`: Swap failed because image to be run is not valid.
Marti Bolivar048d8d82017-08-04 17:14:24 -0400235
David Brown17e20d12017-09-12 11:53:20 -0600236- `BOOT_SWAP_TYPE_PANIC`: Swapping encountered an unrecoverable error.
Marti Bolivar048d8d82017-08-04 17:14:24 -0400237
238The "swap type" is a high-level representation of the outcome of the
239boot. Subsequent sections describe how mcuboot determines the swap type from
240the bit-level contents of flash.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800241
David Brown17e20d12017-09-12 11:53:20 -0600242## Image Trailer
Christopher Collins92ea77f2016-12-12 15:59:26 -0800243
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300244For the bootloader to be able to determine the current state and what actions
Marti Bolivar42818032017-08-04 15:45:01 -0400245should be taken during the current boot operation, it uses metadata stored in
246the image flash areas. While swapping, some of this metadata is temporarily
247copied into and out of the scratch area.
248
249This metadata is located at the end of the image flash areas, and is called an
250image trailer. An image trailer has the following structure:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800251
David Brown17e20d12017-09-12 11:53:20 -0600252```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800253 0 1 2 3
254 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
255 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collins92ea77f2016-12-12 15:59:26 -0800256 ~ ~
Fabio Utzig2c05f1b2018-04-04 10:35:17 -0300257 ~ Swap status (BOOT_MAX_IMG_SECTORS * min-write-size * 3) ~
Christopher Collins92ea77f2016-12-12 15:59:26 -0800258 ~ ~
259 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fabio Utzigea422c22017-09-11 11:02:47 -0300260 | Swap size |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800261 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fabio Utzigea422c22017-09-11 11:02:47 -0300262 | 0xff padding (4 octets) |
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300263 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Fabio Utzigea422c22017-09-11 11:02:47 -0300264 | Copy done | 0xff padding (7 octets) ~
265 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
266 | Image OK | 0xff padding (7 octets) ~
267 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
268 ~ MAGIC (16 octets) ~
Christopher Collins92ea77f2016-12-12 15:59:26 -0800269 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Brown17e20d12017-09-12 11:53:20 -0600270```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800271
Marti Bolivar42818032017-08-04 15:45:01 -0400272The offset immediately following such a record represents the start of the next
273flash area.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800274
275Note: "min-write-size" is a property of the flash hardware. If the hardware
276allows individual bytes to be written at arbitrary addresses, then
277min-write-size is 1. If the hardware only allows writes at even addresses,
278then min-write-size is 2, and so on.
279
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400280An image trailer contains the following fields:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800281
Marti Bolivar1dcb6852017-08-04 15:59:32 -04002821. Swap status: A series of records which records the progress of an image
David Vincze2d736ad2019-02-18 11:50:22 +0100283 swap. To swap entire images, data are swapped between the two image areas
284 one or more sectors at a time, like this:
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400285
David Vincze2d736ad2019-02-18 11:50:22 +0100286 - sector data in the primary slot is copied into scratch, then erased
287 - sector data in the secondary slot is copied into the primary slot,
288 then erased
289 - sector data in scratch is copied into the secondary slot
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400290
291As it swaps images, the bootloader updates the swap status field in a way that
292allows it to compute how far this swap operation has progressed for each
293sector. The swap status field can thus used to resume a swap operation if the
294bootloader is halted while a swap operation is ongoing and later reset. The
David Vincze2d736ad2019-02-18 11:50:22 +0100295`BOOT_MAX_IMG_SECTORS` value is the configurable maximum number of sectors
296mcuboot supports for each image; its value defaults to 128, but allows for
297either decreasing this size, to limit RAM usage, or to increase it in devices
298that have massive amounts of Flash or very small sized sectors and thus require
299a bigger configuration to allow for the handling of all slot's sectors.
300The factor of min-write-sz is due to the behavior of flash hardware. The factor
301of 3 is explained below.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300302
Fabio Utzigea422c22017-09-11 11:02:47 -03003032. Swap size: When beginning a new swap operation, the total size that needs
David Vincze2d736ad2019-02-18 11:50:22 +0100304 to be swapped (based on the slot with largest image + tlvs) is written to
305 this location for easier recovery in case of a reset while performing the
306 swap.
Fabio Utzigea422c22017-09-11 11:02:47 -0300307
3083. Copy done: A single byte indicating whether the image in this slot is
David Brown17e20d12017-09-12 11:53:20 -0600309 complete (0x01=done; 0xff=not done).
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300310
Fabio Utzigea422c22017-09-11 11:02:47 -03003114. Image OK: A single byte indicating whether the image in this slot has been
David Brown17e20d12017-09-12 11:53:20 -0600312 confirmed as good by the user (0x01=confirmed; 0xff=not confirmed).
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300313
Fabio Utzigea422c22017-09-11 11:02:47 -03003145. MAGIC: The following 16 bytes, written in host-byte-order:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800315
David Brown17e20d12017-09-12 11:53:20 -0600316``` c
Christopher Collins92ea77f2016-12-12 15:59:26 -0800317 const uint32_t boot_img_magic[4] = {
318 0xf395c277,
319 0x7fefd260,
320 0x0f505235,
321 0x8079b62c,
322 };
David Brown17e20d12017-09-12 11:53:20 -0600323```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800324
David Brown17e20d12017-09-12 11:53:20 -0600325## IMAGE TRAILERS
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300326
Marti Bolivar048d8d82017-08-04 17:14:24 -0400327At startup, the boot loader determines the boot swap type by inspecting the
328image trailers. When using the term "image trailers" what is meant is the
329aggregate information provided by both image slot's trailers.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300330
David Vincze2d736ad2019-02-18 11:50:22 +0100331The image trailers records are structured around the limitations imposed by
332flash hardware. As a consequence, they do not have a very intuitive design, and
333it is difficult to get a sense of the state of the device just by looking at the
Marti Bolivar048d8d82017-08-04 17:14:24 -0400334image trailers. It is better to map all the possible trailer states to the swap
335types described above via a set of tables. These tables are reproduced below.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300336
337Note: An important caveat about the tables described below is that they must
338be evaluated in the order presented here. Lower state numbers must have a
339higher priority when testing the image trailers.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800340
David Brown17e20d12017-09-12 11:53:20 -0600341```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800342 State I
David Vincze2d736ad2019-02-18 11:50:22 +0100343 | primary slot | secondary slot |
344 -----------------+--------------+----------------|
345 magic | Any | Good |
346 image-ok | Any | Unset |
347 copy-done | Any | Any |
348 -----------------+--------------+----------------'
349 result: BOOT_SWAP_TYPE_TEST |
350 -------------------------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300351
Christopher Collins92ea77f2016-12-12 15:59:26 -0800352
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300353 State II
David Vincze2d736ad2019-02-18 11:50:22 +0100354 | primary slot | secondary slot |
355 -----------------+--------------+----------------|
356 magic | Any | Good |
357 image-ok | Any | 0x01 |
358 copy-done | Any | Any |
359 -----------------+--------------+----------------'
360 result: BOOT_SWAP_TYPE_PERM |
361 -------------------------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300362
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800363
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300364 State III
David Vincze2d736ad2019-02-18 11:50:22 +0100365 | primary slot | secondary slot |
366 -----------------+--------------+----------------|
367 magic | Good | Unset |
368 image-ok | 0xff | Any |
369 copy-done | 0x01 | Any |
370 -----------------+--------------+----------------'
371 result: BOOT_SWAP_TYPE_REVERT |
372 -------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600373```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800374
Marti Bolivar048d8d82017-08-04 17:14:24 -0400375Any of the above three states results in mcuboot attempting to swap images.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800376
Marti Bolivar048d8d82017-08-04 17:14:24 -0400377Otherwise, mcuboot does not attempt to swap images, resulting in one of the
378other three swap types, as illustrated by State IV.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300379
David Brown17e20d12017-09-12 11:53:20 -0600380```
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300381 State IV
David Vincze2d736ad2019-02-18 11:50:22 +0100382 | primary slot | secondary slot |
383 -----------------+--------------+----------------|
384 magic | Any | Any |
385 image-ok | Any | Any |
386 copy-done | Any | Any |
387 -----------------+--------------+----------------'
388 result: BOOT_SWAP_TYPE_NONE, |
389 BOOT_SWAP_TYPE_FAIL, or |
390 BOOT_SWAP_TYPE_PANIC |
391 -------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600392```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800393
Marti Bolivar048d8d82017-08-04 17:14:24 -0400394In State IV, when no errors occur, mcuboot will attempt to boot the contents of
David Vincze2d736ad2019-02-18 11:50:22 +0100395the primary slot directly, and the result is `BOOT_SWAP_TYPE_NONE`. If the image
396in the primary slot is not valid, the result is `BOOT_SWAP_TYPE_FAIL`. If a
397fatal error occurs during boot, the result is `BOOT_SWAP_TYPE_PANIC`. If the
398result is either `BOOT_SWAP_TYPE_FAIL` or `BOOT_SWAP_TYPE_PANIC`, mcuboot hangs
399rather than booting an invalid or compromised image.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300400
Marti Bolivar048d8d82017-08-04 17:14:24 -0400401Note: An important caveat to the above is the result when a swap is requested
David Vincze2d736ad2019-02-18 11:50:22 +0100402 and the image in the secondary slot fails to validate, due to a hashing or
403 signing error. This state behaves as State IV with the extra action of
404 marking the image in the primary slot as "OK", to prevent further attempts
405 to swap.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300406
David Brown17e20d12017-09-12 11:53:20 -0600407## High-Level Operation
Christopher Collins92ea77f2016-12-12 15:59:26 -0800408
409With the terms defined, we can now explore the boot loader's operation. First,
410a high-level overview of the boot process is presented. Then, the following
411sections describe each step of the process in more detail.
412
413Procedure:
414
David Brown17e20d12017-09-12 11:53:20 -06004151. Inspect swap status region; is an interrupted swap being resumed?
416 Yes: Complete the partial swap operation; skip to step 3.
417 No: Proceed to step 2.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800418
David Brown17e20d12017-09-12 11:53:20 -06004192. Inspect image trailers; is a swap requested?
Christopher Collins92ea77f2016-12-12 15:59:26 -0800420 Yes.
David Vincze2d736ad2019-02-18 11:50:22 +0100421 ​ 1. Is the requested image valid (integrity and security check)?
422 ​ Yes.
423 ​ a. Perform swap operation.
424 ​ b. Persist completion of swap procedure to image trailers.
425 ​ c. Proceed to step 3.
426 ​ No.
427 ​ a. Erase invalid image.
428 ​ b. Persist failure of swap procedure to image trailers.
429 ​ c. Proceed to step 3.
David Brown17e20d12017-09-12 11:53:20 -0600430 No: Proceed to step 3.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800431
David Vincze2d736ad2019-02-18 11:50:22 +01004323. Boot into image in primary slot.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800433
David Brown17e20d12017-09-12 11:53:20 -0600434## Image Swapping
Christopher Collins92ea77f2016-12-12 15:59:26 -0800435
436The boot loader swaps the contents of the two image slots for two reasons:
David Vincze2d736ad2019-02-18 11:50:22 +0100437 * User has issued a "set pending" operation; the image in the secondary slot
438 should be run once (state II) or repeatedly (state III), depending on
439 whether a permanent swap was specified.
440​ * Test image rebooted without being confirmed; the boot loader should
441 revert to the original image currently in the secondary slot (state IV).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800442
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300443If the image trailers indicates that the image in the secondary slot should be
Christopher Collins92ea77f2016-12-12 15:59:26 -0800444run, the boot loader needs to copy it to the primary slot. The image currently
445in the primary slot also needs to be retained in flash so that it can be used
446later. Furthermore, both images need to be recoverable if the boot loader
447resets in the middle of the swap operation. The two images are swapped
448according to the following procedure:
449
David Brown17e20d12017-09-12 11:53:20 -0600450<!-- Markdown doesn't do nested numbered lists. It will do nested
451bulletted lists, so maybe that is better. -->
David Vincze2d736ad2019-02-18 11:50:22 +0100452​ 1. Determine how many flash sectors each image slot consists of. This
453​ number must be the same for both slots.
454​ 2. Iterate the list of sector indices in descending order (i.e., starting
455​ with the greatest index); current element = "index".
456​ b. Erase scratch area.
457​ c. Copy secondary_slot[index] to scratch area.
458​ - If these are the last sectors (i.e., first swap being perfomed),
459​ copy the full sector *except* the image trailer.
460​ - Else, copy entire sector contents.
461​ d. Write updated swap status (i).
462​ e. Erase secondary_slot[index]
463​ f. Copy primary_slot[index] to secondary_slot[index]
464​ - If these are the last sectors (i.e., first swap being perfomed),
465​ copy the full sector *except* the image trailer.
466​ - Else, copy entire sector contents.
467​ g. Write updated swap status (ii).
468​ h. Erase primary_slot[index].
469​ i. Copy scratch area to primary_slot[index].
470​ - If these are the last sectors (i.e., first swap being perfomed),
471​ copy the full sector *except* the image trailer.
472​ - Else, copy entire sector contents.
473​ j. Write updated swap status (iii).
474​ 3. Persist completion of swap procedure to the primary slot image trailer.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800475
David Vincze2d736ad2019-02-18 11:50:22 +0100476The additional caveats in step 2f are necessary so that the secondary slot image
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800477trailer can be written by the user at a later time. With the image trailer
David Vincze2d736ad2019-02-18 11:50:22 +0100478unwritten, the user can test the image in the secondary slot
479(i.e., transition to state II).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800480
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300481Note1: If the sector being copied is the last sector, then swap status is
482temporarily maintained on scratch for the duration of this operation, always
David Vincze2d736ad2019-02-18 11:50:22 +0100483using the primary slot's area otherwise.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300484
485Note2: The bootloader tries to copy only used sectors (based on largest image
486installed on any of the slots), minimizing the amount of sectors copied and
487reducing the amount of time required for a swap operation.
488
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800489The particulars of step 3 vary depending on whether an image is being tested,
David Vincze2d736ad2019-02-18 11:50:22 +0100490permanently used, reverted or a validation failure of the secondary slot
491happened when a swap was requested:
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300492
Christopher Collins92ea77f2016-12-12 15:59:26 -0800493 * test:
David Vincze2d736ad2019-02-18 11:50:22 +0100494 o Write primary_slot.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800495 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100496 primary_slot.magic = BOOT_MAGIC
497 primary_slot.image_ok = Unset)
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800498
499 * permanent:
David Vincze2d736ad2019-02-18 11:50:22 +0100500 o Write primary_slot.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800501 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100502 primary_slot.magic = BOOT_MAGIC
503 primary_slot.image_ok = 0x01)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800504
505 * revert:
David Vincze2d736ad2019-02-18 11:50:22 +0100506 o Write primary_slot.copy_done = 1
507 o Write primary_slot.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300508 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100509 primary_slot.magic = BOOT_MAGIC)
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300510
David Vincze2d736ad2019-02-18 11:50:22 +0100511 * failure to validate the secondary slot:
512 o Write primary_slot.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300513
David Vincze2d736ad2019-02-18 11:50:22 +0100514After completing the operations as described above the image in the primary slot
515should be booted.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800516
David Brown17e20d12017-09-12 11:53:20 -0600517## Swap Status
Christopher Collins92ea77f2016-12-12 15:59:26 -0800518
519The swap status region allows the boot loader to recover in case it restarts in
520the middle of an image swap operation. The swap status region consists of a
521series of single-byte records. These records are written independently, and
522therefore must be padded according to the minimum write size imposed by the
523flash hardware. In the below figure, a min-write-size of 1 is assumed for
524simplicity. The structure of the swap status region is illustrated below. In
525this figure, a min-write-size of 1 is assumed for simplicity.
526
David Brown17e20d12017-09-12 11:53:20 -0600527```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800528 0 1 2 3
529 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
530 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
531 |sec127,state 0 |sec127,state 1 |sec127,state 2 |sec126,state 0 |
532 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
533 |sec126,state 1 |sec126,state 2 |sec125,state 0 |sec125,state 1 |
534 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
535 |sec125,state 2 | |
536 +-+-+-+-+-+-+-+-+ +
537 ~ ~
538 ~ [Records for indices 124 through 1 ~
539 ~ ~
540 ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
541 ~ |sec000,state 0 |sec000,state 1 |sec000,state 2 |
542 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Brown17e20d12017-09-12 11:53:20 -0600543```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800544
545The above is probably not helpful at all; here is a description in English.
546
547Each image slot is partitioned into a sequence of flash sectors. If we were to
548enumerate the sectors in a single slot, starting at 0, we would have a list of
549sector indices. Since there are two image slots, each sector index would
550correspond to a pair of sectors. For example, sector index 0 corresponds to
David Vincze2d736ad2019-02-18 11:50:22 +0100551the first sector in the primary slot and the first sector in the secondary slot.
552Finally, reverse the list of indices such that the list starts with index
553`BOOT_MAX_IMG_SECTORS - 1` and ends with 0. The swap status region is a
554representation of this reversed list.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800555
556During a swap operation, each sector index transitions through four separate
557states:
David Brown17e20d12017-09-12 11:53:20 -0600558```
David Vincze2d736ad2019-02-18 11:50:22 +01005590. primary slot: image 0, secondary slot: image 1, scratch: N/A
5601. primary slot: image 0, secondary slot: N/A, scratch: image 1 (1->s, erase 1)
5612. primary slot: N/A, secondary slot: image 0, scratch: image 1 (0->1, erase 0)
5623. primary slot: image 1, secondary slot: image 0, scratch: N/A (s->0)
David Brown17e20d12017-09-12 11:53:20 -0600563```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800564
565Each time a sector index transitions to a new state, the boot loader writes a
566record to the swap status region. Logically, the boot loader only needs one
567record per sector index to keep track of the current swap state. However, due
568to limitations imposed by flash hardware, a record cannot be overwritten when
569an index's state changes. To solve this problem, the boot loader uses three
570records per sector index rather than just one.
571
572Each sector-state pair is represented as a set of three records. The record
573values map to the above four states as follows
574
David Brown17e20d12017-09-12 11:53:20 -0600575```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800576 | rec0 | rec1 | rec2
577 --------+------+------+------
578 state 0 | 0xff | 0xff | 0xff
579 state 1 | 0x01 | 0xff | 0xff
580 state 2 | 0x01 | 0x02 | 0xff
581 state 3 | 0x01 | 0x02 | 0x03
David Brown17e20d12017-09-12 11:53:20 -0600582```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800583
Fabio Utzig2c05f1b2018-04-04 10:35:17 -0300584The swap status region can accommodate `BOOT_MAX_IMG_SECTORS` sector indices.
David Vincze2d736ad2019-02-18 11:50:22 +0100585Hence, the size of the region, in bytes, is
586`BOOT_MAX_IMG_SECTORS * min-write-size * 3`. The only requirement for the index
587count is that it is great enough to account for a maximum-sized image
588(i.e., at least as great as the total sector count in an image slot). If a
589device's image slots have been configured with `BOOT_MAX_IMG_SECTORS: 128` and
590use less than 128 sectors, the first record that gets written will be somewhere
591in the middle of the region. For example, if a slot uses 64 sectors, the first
592sector index that gets swapped is 63, which corresponds to the exact halfway
593point within the region.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800594
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300595Note: since the scratch area only ever needs to record swapping of the last
596sector, it uses at most min-write-size * 3 bytes for its own status area.
597
David Brown17e20d12017-09-12 11:53:20 -0600598## Reset Recovery
Christopher Collins92ea77f2016-12-12 15:59:26 -0800599
600If the boot loader resets in the middle of a swap operation, the two images may
601be discontiguous in flash. Bootutil recovers from this condition by using the
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300602image trailers to determine how the image parts are distributed in flash.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800603
604The first step is determine where the relevant swap status region is located.
605Because this region is embedded within the image slots, its location in flash
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300606changes during a swap operation. The below set of tables map image trailers
Christopher Collins92ea77f2016-12-12 15:59:26 -0800607contents to swap status location. In these tables, the "source" field
608indicates where the swap status region is located.
609
David Brown17e20d12017-09-12 11:53:20 -0600610```
David Vincze2d736ad2019-02-18 11:50:22 +0100611 | primary slot | scratch |
612 ----------+--------------+--------------|
613 magic | Good | Any |
614 copy-done | 0x01 | N/A |
615 ----------+--------------+--------------'
616 source: none |
617 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400618
David Vincze2d736ad2019-02-18 11:50:22 +0100619 | primary slot | scratch |
620 ----------+--------------+--------------|
621 magic | Good | Any |
622 copy-done | 0xff | N/A |
623 ----------+--------------+--------------'
624 source: primary slot |
625 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400626
David Vincze2d736ad2019-02-18 11:50:22 +0100627 | primary slot | scratch |
628 ----------+--------------+--------------|
629 magic | Any | Good |
630 copy-done | Any | N/A |
631 ----------+--------------+--------------'
632 source: scratch |
633 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400634
David Vincze2d736ad2019-02-18 11:50:22 +0100635 | primary slot | scratch |
636 ----------+--------------+--------------|
637 magic | Unset | Any |
638 copy-done | 0xff | N/A |
639 ----------+--------------+--------------|
640 source: primary slot |
641 ----------------------------------------+------------------------------+
642 This represents one of two cases: |
643 o No swaps ever (no status to read, so no harm in checking). |
644 o Mid-revert; status in the primary slot. |
645 For this reason we assume the primary slot as source, to trigger a |
646 check of the status area and find out if there was swapping under way. |
647 -----------------------------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600648```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800649
650If the swap status region indicates that the images are not contiguous,
651bootutil completes the swap operation that was in progress when the system was
652reset. In other words, it applies the procedure defined in the previous
David Vincze2d736ad2019-02-18 11:50:22 +0100653section, moving image 1 into the primary slot and image 0 into the secondary
654slot. If the boot status file indicates that an image part is present in the
655scratch area, this part is copied into the correct location by starting at step
656e or step h in the area-swap procedure, depending on whether the part belongs to
657image 0 or image 1.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800658
659After the swap operation has been completed, the boot loader proceeds as though
660it had just been started.
661
David Brown17e20d12017-09-12 11:53:20 -0600662## Integrity Check
Christopher Collins92ea77f2016-12-12 15:59:26 -0800663
664An image is checked for integrity immediately before it gets copied into the
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300665primary slot. If the boot loader doesn't perform an image swap, then it can
David Vincze2d736ad2019-02-18 11:50:22 +0100666perform an optional integrity check of the image in the primary slot if
667`MCUBOOT_VALIDATE_PRIMARY_SLOT` is set, otherwise it doesn't perform an
668integrity check.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800669
670During the integrity check, the boot loader verifies the following aspects of
671an image:
David Vincze2d736ad2019-02-18 11:50:22 +0100672​ * 32-bit magic number must be correct (0x96f3b83d).
673​ * Image must contain an `image_tlv_info` struct, identified by its magic
674​ (0x6907) exactly following the firmware (hdr_size + img_size).
675​ * Image must contain a SHA256 TLV.
676​ * Calculated SHA256 must match SHA256 TLV contents.
677​ * Image *may* contain a signature TLV. If it does, it must also have a
678​ KEYHASH TLV with the hash of the key that was used to sign. The list of
679​ keys will then be iterated over looking for the matching key, which then
680​ will then be used to verify the image contents.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800681
David Brown17e20d12017-09-12 11:53:20 -0600682## Security
Christopher Collins92ea77f2016-12-12 15:59:26 -0800683
684As indicated above, the final step of the integrity check is signature
685verification. The boot loader can have one or more public keys embedded in it
686at build time. During signature verification, the boot loader verifies that an
Fabio Utzigea422c22017-09-11 11:02:47 -0300687image was signed with a private key that corresponds to the embedded keyhash
688TLV.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800689
690For information on embedding public keys in the boot loader, as well as
Fabio Utzig4dce6aa2018-02-12 15:31:32 -0200691producing signed images, see: [signed_images](signed_images.md).
Fabio Utzigcdfa11a2018-10-01 09:45:54 -0300692
693If you want to enable and use encrypted images, see:
694[encrypted_images](encrypted_images.md).