blob: 1a4fc5c3933ad311779d4b5ac0835da4e4766ff4 [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
David Vinczeba3bd602019-06-17 16:01:43 +020020<!--
21 Modifications are Copyright (c) 2019 Arm Limited.
22-->
23
David Brown17e20d12017-09-12 11:53:20 -060024# Boot Loader
25
26## Summary
Christopher Collins92ea77f2016-12-12 15:59:26 -080027
Fabio Utzigac834962017-07-20 13:20:48 -030028mcuboot comprises two packages:
Christopher Collins92ea77f2016-12-12 15:59:26 -080029
David Brown17e20d12017-09-12 11:53:20 -060030* The bootutil library (boot/bootutil)
31* The boot application (each port has its own at boot/<port>)
Christopher Collins92ea77f2016-12-12 15:59:26 -080032
33The bootutil library performs most of the functions of a boot loader. In
34particular, the piece that is missing is the final step of actually jumping to
35the main image. This last step is instead implemented by the boot application.
36Boot loader functionality is separated in this manner to enable unit testing of
37the boot loader. A library can be unit tested, but an application can't.
38Therefore, functionality is delegated to the bootutil library when possible.
39
David Brown17e20d12017-09-12 11:53:20 -060040## Limitations
Christopher Collins92ea77f2016-12-12 15:59:26 -080041
42The boot loader currently only supports images with the following
43characteristics:
David Brown17e20d12017-09-12 11:53:20 -060044* Built to run from flash.
45* Built to run from a fixed location (i.e., not position-independent).
Christopher Collins92ea77f2016-12-12 15:59:26 -080046
David Brown17e20d12017-09-12 11:53:20 -060047## Image Format
Christopher Collins92ea77f2016-12-12 15:59:26 -080048
49The following definitions describe the image format.
50
David Brown17e20d12017-09-12 11:53:20 -060051``` c
Fabio Utzigea422c22017-09-11 11:02:47 -030052#define IMAGE_MAGIC 0x96f3b83d
Christopher Collins92ea77f2016-12-12 15:59:26 -080053
54#define IMAGE_HEADER_SIZE 32
55
56struct image_version {
57 uint8_t iv_major;
58 uint8_t iv_minor;
59 uint16_t iv_revision;
60 uint32_t iv_build_num;
61};
62
63/** Image header. All fields are in little endian byte order. */
64struct image_header {
65 uint32_t ih_magic;
Fabio Utzigea422c22017-09-11 11:02:47 -030066 uint32_t ih_load_addr;
David Vinczee32483f2019-06-13 10:46:24 +020067 uint16_t ih_hdr_size; /* Size of image header (bytes). */
68 uint16_t ih_protect_tlv_size; /* Size of protected TLV area (bytes). */
69 uint32_t ih_img_size; /* Does not include header. */
70 uint32_t ih_flags; /* IMAGE_F_[...]. */
Christopher Collins92ea77f2016-12-12 15:59:26 -080071 struct image_version ih_ver;
David Vinczee32483f2019-06-13 10:46:24 +020072 uint32_t _pad1;
Christopher Collins92ea77f2016-12-12 15:59:26 -080073};
74
Fabio Utzigea422c22017-09-11 11:02:47 -030075/** Image TLV header. All fields in little endian. */
76struct image_tlv_info {
77 uint16_t it_magic;
78 uint16_t it_tlv_tot; /* size of TLV area (including tlv_info header) */
79};
80
Christopher Collins92ea77f2016-12-12 15:59:26 -080081/** Image trailer TLV format. All fields in little endian. */
82struct image_tlv {
83 uint8_t it_type; /* IMAGE_TLV_[...]. */
84 uint8_t _pad;
Marti Bolivar49b29172017-08-04 14:50:51 -040085 uint16_t it_len; /* Data length (not including TLV header). */
Christopher Collins92ea77f2016-12-12 15:59:26 -080086};
87
88/*
89 * Image header flags.
90 */
Marti Bolivar7c057e92017-08-04 14:46:39 -040091#define IMAGE_F_PIC 0x00000001 /* Not supported. */
Marti Bolivar7c057e92017-08-04 14:46:39 -040092#define IMAGE_F_NON_BOOTABLE 0x00000010 /* Split image app. */
Fabio Utzigea422c22017-09-11 11:02:47 -030093#define IMAGE_F_RAM_LOAD 0x00000020
Christopher Collins92ea77f2016-12-12 15:59:26 -080094
95/*
96 * Image trailer TLV types.
97 */
Fabio Utzigea422c22017-09-11 11:02:47 -030098#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
David Brown27648b82017-08-31 10:40:29 -060099#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
Marko Kiiskila8dd56f32017-08-22 21:40:49 -0700100#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
David Brown27648b82017-08-31 10:40:29 -0600101#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output */
102#define IMAGE_TLV_ECDSA256 0x22 /* ECDSA of hash output */
Fabio Utzig3501c012019-05-13 15:07:25 -0700103#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
Fabio Utzig195411f2019-06-28 07:48:21 -0300104#define IMAGE_TLV_ED25519 0x24 /* ED25519 of hash output */
David Vinczee32483f2019-06-13 10:46:24 +0200105#define IMAGE_TLV_ENC_RSA2048 0x30 /* Key encrypted with RSA-OAEP-2048 */
106#define IMAGE_TLV_ENC_KW128 0x31 /* Key encrypted with AES-KW-128 */
107#define IMAGE_TLV_DEPENDENCY 0x40 /* Image depends on other image */
David Brown17e20d12017-09-12 11:53:20 -0600108```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800109
110Optional type-length-value records (TLVs) containing image metadata are placed
111after the end of the image.
112
David Vinczee32483f2019-06-13 10:46:24 +0200113The `ih_protect_tlv_size` field indicates the length of the protected TLV area.
114If dependency TLVs are present then the TLV info header and the dependency TLVs
115are also protected and have to be included in the hash calculation. Otherwise
116the hash is only calculated over the image header and the image itself. In this
117case the value of the `ih_protect_tlv_size` field is 0.
118
David Brown17e20d12017-09-12 11:53:20 -0600119The `ih_hdr_size` field indicates the length of the header, and therefore the
Christopher Collins92ea77f2016-12-12 15:59:26 -0800120offset of the image itself. This field provides for backwards compatibility in
121case of changes to the format of the image header.
122
David Brown17e20d12017-09-12 11:53:20 -0600123## Flash Map
Christopher Collins92ea77f2016-12-12 15:59:26 -0800124
Fabio Utzigac834962017-07-20 13:20:48 -0300125A device's flash is partitioned according to its _flash map_. At a high
Christopher Collins92ea77f2016-12-12 15:59:26 -0800126level, the flash map maps numeric IDs to _flash areas_. A flash area is a
127region of disk with the following properties:
David Brown17e20d12017-09-12 11:53:20 -06001281. An area can be fully erased without affecting any other areas.
1292. A write to one area does not restrict writes to other areas.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800130
Marti Bolivar4e64d562017-08-04 14:53:33 -0400131The boot loader uses the following flash area IDs:
David Vinczeb75c12a2019-03-22 14:58:33 +0100132```c
133/* Independent from multiple image boot */
David Vincze2d736ad2019-02-18 11:50:22 +0100134#define FLASH_AREA_BOOTLOADER 0
David Vinczeb75c12a2019-03-22 14:58:33 +0100135#define FLASH_AREA_IMAGE_SCRATCH 3
136```
137```c
138/* If the boot loader is working with the first image */
David Vincze2d736ad2019-02-18 11:50:22 +0100139#define FLASH_AREA_IMAGE_PRIMARY 1
140#define FLASH_AREA_IMAGE_SECONDARY 2
David Vinczeb75c12a2019-03-22 14:58:33 +0100141```
142```c
143/* If the boot loader is working with the second image */
144#define FLASH_AREA_IMAGE_PRIMARY 5
145#define FLASH_AREA_IMAGE_SECONDARY 6
David Brown17e20d12017-09-12 11:53:20 -0600146```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800147
Marti Bolivar4e64d562017-08-04 14:53:33 -0400148The bootloader area contains the bootloader image itself. The other areas are
David Vinczeb75c12a2019-03-22 14:58:33 +0100149described in subsequent sections. The flash could contain multiple executable
150images therefore the flash area IDs of primary and secondary areas are mapped
151based on the number of the active image (on which the bootloader is currently
152working).
Marti Bolivar4e64d562017-08-04 14:53:33 -0400153
David Brown17e20d12017-09-12 11:53:20 -0600154## Image Slots
Christopher Collins92ea77f2016-12-12 15:59:26 -0800155
David Vinczeb75c12a2019-03-22 14:58:33 +0100156A portion of the flash memory can be partitioned into multiple image areas, each
157contains two image slots: a primary slot and a secondary slot.
158The boot loader will only run an image from the primary slot, so images must be
159built such that they can run from that fixed location in flash. If the boot
160loader needs to run the image resident in the secondary slot, it must copy its
161contents into the primary slot before doing so, either by swapping the two
162images or by overwriting the contents of the primary slot. The bootloader
163supports either swap- or overwrite-based image upgrades, but must be configured
164at build time to choose one of these two strategies.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800165
David Vinczeb75c12a2019-03-22 14:58:33 +0100166In addition to the slots of image areas, the boot loader requires a scratch
167area to allow for reliable image swapping. The scratch area must have a size
168that is enough to store at least the largest sector that is going to be swapped.
169Many devices have small equally sized flash sectors, eg 4K, while others have
David Vincze2d736ad2019-02-18 11:50:22 +0100170variable sized sectors where the largest sectors might be 128K or 256K, so the
171scratch must be big enough to store that. The scratch is only ever used when
172swapping firmware, which means only when doing an upgrade. Given that, the main
173reason for using a larger size for the scratch is that flash wear will be more
174evenly distributed, because a single sector would be written twice the number of
175times than using two sectors, for example. To evaluate the ideal size of the
176scratch for your use case the following parameters are relevant:
Fabio Utziga722f5a2017-12-12 14:04:53 -0200177
178* the ratio of image size / scratch size
179* the number of erase cycles supported by the flash hardware
180
181The image size is used (instead of slot size) because only the slot's sectors
182that are actually used for storing the image are copied. The image/scratch ratio
183is the number of times the scratch will be erased on every upgrade. The number
184of erase cycles divided by the image/scratch ratio will give you the number of
185times an upgrade can be performed before the device goes out of spec.
186
187```
188num_upgrades = number_of_erase_cycles / (image_size / scratch_size)
189```
190
191Let's assume, for example, a device with 10000 erase cycles, an image size of
192150K and a scratch of 4K (usual minimum size of 4K sector devices). This would
193result in a total of:
194
195`10000 / (150 / 4) ~ 267`
196
197Increasing the scratch to 16K would give us:
198
199`10000 / (150 / 16) ~ 1067`
200
201There is no *best* ratio, as the right size is use-case dependent. Factors to
202consider include the number of times a device will be upgraded both in the field
David Vincze2d736ad2019-02-18 11:50:22 +0100203and during development, as well as any desired safety margin on the
204manufacturer's specified number of erase cycles. In general, using a ratio that
205allows hundreds to thousands of field upgrades in production is recommended.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800206
Marti Bolivara91674f2017-08-04 14:56:08 -0400207The overwrite upgrade strategy is substantially simpler to implement than the
208image swapping strategy, especially since the bootloader must work properly
209even when it is reset during the middle of an image swap. For this reason, the
210rest of the document describes its behavior when configured to swap images
211during an upgrade.
212
David Brown17e20d12017-09-12 11:53:20 -0600213## Boot Swap Types
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800214
Marti Bolivar048d8d82017-08-04 17:14:24 -0400215When the device first boots under normal circumstances, there is an up-to-date
David Vinczeba3bd602019-06-17 16:01:43 +0200216firmware image in each primary slot, which mcuboot can validate and then
David Vincze2d736ad2019-02-18 11:50:22 +0100217chain-load. In this case, no image swaps are necessary. During device upgrades,
David Vinczeba3bd602019-06-17 16:01:43 +0200218however, new candidate image(s) is present in the secondary slot(s), which
219mcuboot must swap into the primary slot(s) before booting as discussed above.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800220
Marti Bolivar048d8d82017-08-04 17:14:24 -0400221Upgrading an old image with a new one by swapping can be a two-step process. In
222this process, mcuboot performs a "test" swap of image data in flash and boots
David Vinczeba3bd602019-06-17 16:01:43 +0200223the new image or it will be executed during operation. The new image can then
224update the contents of flash at runtime to mark itself "OK", and mcuboot will
225then still choose to run it during the next boot. When this happens, the swap is
226made "permanent". If this doesn't happen, mcuboot will perform a "revert" swap
227during the next boot by swapping the image(s) back into its original location(s)
228, and attempting to boot the old image(s).
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800229
Marti Bolivar048d8d82017-08-04 17:14:24 -0400230Depending on the use case, the first swap can also be made permanent directly.
231In this case, mcuboot will never attempt to revert the images on the next reset.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800232
Marti Bolivar048d8d82017-08-04 17:14:24 -0400233Test swaps are supported to provide a rollback mechanism to prevent devices
234from becoming "bricked" by bad firmware. If the device crashes immediately
235upon booting a new (bad) image, mcuboot will revert to the old (working) image
236at the next device reset, rather than booting the bad image again. This allows
237device firmware to make test swaps permanent only after performing a self-test
238routine.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800239
David Vinczeba3bd602019-06-17 16:01:43 +0200240On startup, mcuboot inspects the contents of flash to decide for each images
241which of these "swap types" to perform; this decision determines how it
242proceeds.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800243
Marti Bolivar048d8d82017-08-04 17:14:24 -0400244The possible swap types, and their meanings, are:
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800245
David Brown17e20d12017-09-12 11:53:20 -0600246- `BOOT_SWAP_TYPE_NONE`: The "usual" or "no upgrade" case; attempt to boot the
David Vincze2d736ad2019-02-18 11:50:22 +0100247 contents of the primary slot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800248
David Vincze2d736ad2019-02-18 11:50:22 +0100249- `BOOT_SWAP_TYPE_TEST`: Boot the contents of the secondary slot by swapping
250 images. Unless the swap is made permanent, revert back on the next boot.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800251
David Brown17e20d12017-09-12 11:53:20 -0600252- `BOOT_SWAP_TYPE_PERM`: Permanently swap images, and boot the upgraded image
Marti Bolivar048d8d82017-08-04 17:14:24 -0400253 firmware.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800254
David Vincze2d736ad2019-02-18 11:50:22 +0100255- `BOOT_SWAP_TYPE_REVERT`: A previous test swap was not made permanent;
256 swap back to the old image whose data are now in the secondary slot. If the
257 old image marks itself "OK" when it boots, the next boot will have swap type
258 `BOOT_SWAP_TYPE_NONE`.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800259
David Brown17e20d12017-09-12 11:53:20 -0600260- `BOOT_SWAP_TYPE_FAIL`: Swap failed because image to be run is not valid.
Marti Bolivar048d8d82017-08-04 17:14:24 -0400261
David Brown17e20d12017-09-12 11:53:20 -0600262- `BOOT_SWAP_TYPE_PANIC`: Swapping encountered an unrecoverable error.
Marti Bolivar048d8d82017-08-04 17:14:24 -0400263
264The "swap type" is a high-level representation of the outcome of the
265boot. Subsequent sections describe how mcuboot determines the swap type from
266the bit-level contents of flash.
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800267
David Brown17e20d12017-09-12 11:53:20 -0600268## Image Trailer
Christopher Collins92ea77f2016-12-12 15:59:26 -0800269
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300270For the bootloader to be able to determine the current state and what actions
Marti Bolivar42818032017-08-04 15:45:01 -0400271should be taken during the current boot operation, it uses metadata stored in
272the image flash areas. While swapping, some of this metadata is temporarily
273copied into and out of the scratch area.
274
275This metadata is located at the end of the image flash areas, and is called an
276image trailer. An image trailer has the following structure:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800277
David Brown17e20d12017-09-12 11:53:20 -0600278```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800279 0 1 2 3
280 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
281 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collins92ea77f2016-12-12 15:59:26 -0800282 ~ ~
Fabio Utzig2c05f1b2018-04-04 10:35:17 -0300283 ~ Swap status (BOOT_MAX_IMG_SECTORS * min-write-size * 3) ~
Christopher Collins92ea77f2016-12-12 15:59:26 -0800284 ~ ~
285 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700286 | Encryption key 0 (16 octets) [*] |
287 | |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800288 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700289 | Encryption key 1 (16 octets) [*] |
290 | |
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300291 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700292 | Swap size (4 octets) |
Fabio Utzigea422c22017-09-11 11:02:47 -0300293 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Vinczee2453472019-06-17 12:31:59 +0200294 | Swap info | 0xff padding (7 octets) |
Fabio Utzigea422c22017-09-11 11:02:47 -0300295 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Christopher Collinsa1c12042019-05-23 14:00:28 -0700296 | Copy done | 0xff padding (7 octets) |
297 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
298 | Image OK | 0xff padding (7 octets) |
299 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
300 | MAGIC (16 octets) |
301 | |
Christopher Collins92ea77f2016-12-12 15:59:26 -0800302 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Brown17e20d12017-09-12 11:53:20 -0600303```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800304
Christopher Collinsa1c12042019-05-23 14:00:28 -0700305[*]: Only present if the encryption option is enabled (`MCUBOOT_ENC_IMAGES`).
306
Marti Bolivar42818032017-08-04 15:45:01 -0400307The offset immediately following such a record represents the start of the next
308flash area.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800309
310Note: "min-write-size" is a property of the flash hardware. If the hardware
311allows individual bytes to be written at arbitrary addresses, then
312min-write-size is 1. If the hardware only allows writes at even addresses,
313then min-write-size is 2, and so on.
314
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400315An image trailer contains the following fields:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800316
Marti Bolivar1dcb6852017-08-04 15:59:32 -04003171. Swap status: A series of records which records the progress of an image
David Vincze2d736ad2019-02-18 11:50:22 +0100318 swap. To swap entire images, data are swapped between the two image areas
319 one or more sectors at a time, like this:
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400320
David Vincze2d736ad2019-02-18 11:50:22 +0100321 - sector data in the primary slot is copied into scratch, then erased
322 - sector data in the secondary slot is copied into the primary slot,
323 then erased
324 - sector data in scratch is copied into the secondary slot
Marti Bolivar1dcb6852017-08-04 15:59:32 -0400325
326As it swaps images, the bootloader updates the swap status field in a way that
327allows it to compute how far this swap operation has progressed for each
328sector. The swap status field can thus used to resume a swap operation if the
329bootloader is halted while a swap operation is ongoing and later reset. The
David Vincze2d736ad2019-02-18 11:50:22 +0100330`BOOT_MAX_IMG_SECTORS` value is the configurable maximum number of sectors
331mcuboot supports for each image; its value defaults to 128, but allows for
332either decreasing this size, to limit RAM usage, or to increase it in devices
333that have massive amounts of Flash or very small sized sectors and thus require
334a bigger configuration to allow for the handling of all slot's sectors.
335The factor of min-write-sz is due to the behavior of flash hardware. The factor
336of 3 is explained below.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300337
Christopher Collinsa1c12042019-05-23 14:00:28 -07003382. Encryption keys: key-encrypting keys (KEKs). These keys are needed for
339 image encryption and decryption. See the
340 [encrypted images](encrypted_images.md) document for more information.
341
3423. Swap size: When beginning a new swap operation, the total size that needs
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +0000343 to be swapped (based on the slot with largest image + TLVs) is written to
David Vincze2d736ad2019-02-18 11:50:22 +0100344 this location for easier recovery in case of a reset while performing the
345 swap.
Fabio Utzigea422c22017-09-11 11:02:47 -0300346
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +00003474. Swap info: A single byte which encodes the following information:
David Vinczee2453472019-06-17 12:31:59 +0200348 - Swap type: Stored in bits 0-3. Indicating the type of swap operation in
349 progress. When mcuboot resumes an interrupted swap, it uses this field to
350 determine the type of operation to perform. This field contains one of the
351 following values in the table below.
352 - Image number: Stored in bits 4-7. It has always 0 value at single image
353 boot. In case of multi image boot it indicates, which image was swapped when
354 interrupt happened. The same scratch area is used during in case of all
355 image swap operation. Therefore this field is used to determine which image
356 the trailer belongs to if boot status is found on scratch area when the swap
357 operation is resumed.
Christopher Collinsa1c12042019-05-23 14:00:28 -0700358
359| Name | Value |
360| ------------------------- | ----- |
361| `BOOT_SWAP_TYPE_TEST` | 2 |
362| `BOOT_SWAP_TYPE_PERM` | 3 |
363| `BOOT_SWAP_TYPE_REVERT` | 4 |
364
365
3665. Copy done: A single byte indicating whether the image in this slot is
David Brown17e20d12017-09-12 11:53:20 -0600367 complete (0x01=done; 0xff=not done).
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300368
Christopher Collinsa1c12042019-05-23 14:00:28 -07003696. Image OK: A single byte indicating whether the image in this slot has been
David Brown17e20d12017-09-12 11:53:20 -0600370 confirmed as good by the user (0x01=confirmed; 0xff=not confirmed).
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300371
Christopher Collinsa1c12042019-05-23 14:00:28 -07003727. MAGIC: The following 16 bytes, written in host-byte-order:
Christopher Collins92ea77f2016-12-12 15:59:26 -0800373
David Brown17e20d12017-09-12 11:53:20 -0600374``` c
Christopher Collins92ea77f2016-12-12 15:59:26 -0800375 const uint32_t boot_img_magic[4] = {
376 0xf395c277,
377 0x7fefd260,
378 0x0f505235,
379 0x8079b62c,
380 };
David Brown17e20d12017-09-12 11:53:20 -0600381```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800382
David Brown17e20d12017-09-12 11:53:20 -0600383## IMAGE TRAILERS
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300384
Marti Bolivar048d8d82017-08-04 17:14:24 -0400385At startup, the boot loader determines the boot swap type by inspecting the
386image trailers. When using the term "image trailers" what is meant is the
387aggregate information provided by both image slot's trailers.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300388
Christopher Collinsa1c12042019-05-23 14:00:28 -0700389### New swaps (non-resumes)
390
391For new swaps, mcuboot must inspect a collection of fields to determine which
392swap operation to perform.
393
David Vincze2d736ad2019-02-18 11:50:22 +0100394The image trailers records are structured around the limitations imposed by
395flash hardware. As a consequence, they do not have a very intuitive design, and
396it is difficult to get a sense of the state of the device just by looking at the
Marti Bolivar048d8d82017-08-04 17:14:24 -0400397image trailers. It is better to map all the possible trailer states to the swap
398types described above via a set of tables. These tables are reproduced below.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300399
400Note: An important caveat about the tables described below is that they must
401be evaluated in the order presented here. Lower state numbers must have a
402higher priority when testing the image trailers.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800403
David Brown17e20d12017-09-12 11:53:20 -0600404```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800405 State I
David Vincze2d736ad2019-02-18 11:50:22 +0100406 | primary slot | secondary slot |
407 -----------------+--------------+----------------|
408 magic | Any | Good |
409 image-ok | Any | Unset |
410 copy-done | Any | Any |
411 -----------------+--------------+----------------'
412 result: BOOT_SWAP_TYPE_TEST |
413 -------------------------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300414
Christopher Collins92ea77f2016-12-12 15:59:26 -0800415
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300416 State II
David Vincze2d736ad2019-02-18 11:50:22 +0100417 | primary slot | secondary slot |
418 -----------------+--------------+----------------|
419 magic | Any | Good |
420 image-ok | Any | 0x01 |
421 copy-done | Any | Any |
422 -----------------+--------------+----------------'
423 result: BOOT_SWAP_TYPE_PERM |
424 -------------------------------------------------'
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300425
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800426
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300427 State III
David Vincze2d736ad2019-02-18 11:50:22 +0100428 | primary slot | secondary slot |
429 -----------------+--------------+----------------|
430 magic | Good | Unset |
431 image-ok | 0xff | Any |
432 copy-done | 0x01 | Any |
433 -----------------+--------------+----------------'
434 result: BOOT_SWAP_TYPE_REVERT |
435 -------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600436```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800437
Marti Bolivar048d8d82017-08-04 17:14:24 -0400438Any of the above three states results in mcuboot attempting to swap images.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800439
Marti Bolivar048d8d82017-08-04 17:14:24 -0400440Otherwise, mcuboot does not attempt to swap images, resulting in one of the
441other three swap types, as illustrated by State IV.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300442
David Brown17e20d12017-09-12 11:53:20 -0600443```
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300444 State IV
David Vincze2d736ad2019-02-18 11:50:22 +0100445 | primary slot | secondary slot |
446 -----------------+--------------+----------------|
447 magic | Any | Any |
448 image-ok | Any | Any |
449 copy-done | Any | Any |
450 -----------------+--------------+----------------'
451 result: BOOT_SWAP_TYPE_NONE, |
452 BOOT_SWAP_TYPE_FAIL, or |
453 BOOT_SWAP_TYPE_PANIC |
454 -------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600455```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800456
Marti Bolivar048d8d82017-08-04 17:14:24 -0400457In State IV, when no errors occur, mcuboot will attempt to boot the contents of
David Vincze2d736ad2019-02-18 11:50:22 +0100458the primary slot directly, and the result is `BOOT_SWAP_TYPE_NONE`. If the image
459in the primary slot is not valid, the result is `BOOT_SWAP_TYPE_FAIL`. If a
460fatal error occurs during boot, the result is `BOOT_SWAP_TYPE_PANIC`. If the
461result is either `BOOT_SWAP_TYPE_FAIL` or `BOOT_SWAP_TYPE_PANIC`, mcuboot hangs
462rather than booting an invalid or compromised image.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300463
Marti Bolivar048d8d82017-08-04 17:14:24 -0400464Note: An important caveat to the above is the result when a swap is requested
David Vincze2d736ad2019-02-18 11:50:22 +0100465 and the image in the secondary slot fails to validate, due to a hashing or
466 signing error. This state behaves as State IV with the extra action of
467 marking the image in the primary slot as "OK", to prevent further attempts
468 to swap.
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300469
Christopher Collinsa1c12042019-05-23 14:00:28 -0700470### Resumed swaps
471
472If mcuboot determines that it is resuming an interrupted swap (i.e., a reset
473occurred mid-swap), it fully determines the operation to resume by reading the
David Vinczee2453472019-06-17 12:31:59 +0200474`swap info` field from the active trailer and extracting the swap type from bits
4750-3. The set of tables in the previous section are not necessary in the resume
476case.
Christopher Collinsa1c12042019-05-23 14:00:28 -0700477
David Brown17e20d12017-09-12 11:53:20 -0600478## High-Level Operation
Christopher Collins92ea77f2016-12-12 15:59:26 -0800479
480With the terms defined, we can now explore the boot loader's operation. First,
481a high-level overview of the boot process is presented. Then, the following
482sections describe each step of the process in more detail.
483
484Procedure:
485
David Brown17e20d12017-09-12 11:53:20 -06004861. Inspect swap status region; is an interrupted swap being resumed?
Fabio Utzig75b34412019-09-06 08:30:43 -0300487 + Yes: Complete the partial swap operation; skip to step 3.
488 + No: Proceed to step 2.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800489
David Brown17e20d12017-09-12 11:53:20 -06004902. Inspect image trailers; is a swap requested?
Fabio Utzig75b34412019-09-06 08:30:43 -0300491 + Yes:
492 1. Is the requested image valid (integrity and security check)?
493 + Yes.
494 a. Perform swap operation.
495 b. Persist completion of swap procedure to image trailers.
496 c. Proceed to step 3.
497 + No.
498 a. Erase invalid image.
499 b. Persist failure of swap procedure to image trailers.
500 c. Proceed to step 3.
501
502 + No: Proceed to step 3.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800503
David Vincze2d736ad2019-02-18 11:50:22 +01005043. Boot into image in primary slot.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800505
David Vinczeba3bd602019-06-17 16:01:43 +0200506### Multiple Image Boot
507
508When the flash contains multiple executable images the boot loader's operation
509is a bit more complex but similar to the previously described procedure with
510one image. Every image can be updated independently therefore the flash is
511partitioned further to arrange two slots for each image.
512```
513+--------------------+
514| MCUBoot |
515+--------------------+
516 ~~~~~ <- memory might be not contiguous
517+--------------------+
518| Image 0 |
519| primary slot |
520+--------------------+
521| Image 0 |
522| secondary slot |
523+--------------------+
524 ~~~~~ <- memory might be not contiguous
525+--------------------+
526| Image N |
527| primary slot |
528+--------------------+
529| Image N |
530| secondary slot |
531+--------------------+
532| Scratch |
533+--------------------+
534```
David Vinczee32483f2019-06-13 10:46:24 +0200535MCUBoot is also capable of handling dependencies between images. For example
536if an image needs to be reverted it might be necessary to revert another one too
537(e.g. due to API incompatibilities) or simply to prevent from being updated
538because of an unsatisfied dependency. Therefore all aborted swaps have to be
539completed and all the swap types have to be determined for each image before
540the dependency checks. Dependency handling is described in more detail in a
541following section. The multiple image boot procedure is organized in loops which
542iterate over all the firmware images. The high-level overview of the boot
543process is presented below.
David Vinczeba3bd602019-06-17 16:01:43 +0200544
545+ ###### Loop 1. Iterate over all images
546 1. Inspect swap status region of current image; is an interrupted swap being
547 resumed?
548 + Yes:
549 + Review the validity of previously determined swap types
550 of other images.
551 + Complete the partial swap operation.
552 + Mark the swap type as `None`.
553 + Skip to next image.
554 + No: Proceed to step 2.
555
556 2. Inspect image trailers in the primary and secondary slot; is an image
557 swap requested?
558 + Yes: Review the validity of previously determined swap types of other
559 images. Is the requested image valid (integrity and security
560 check)?
561 + Yes:
562 + Set the previously determined swap type for the current image.
563 + Skip to next image.
564 + No:
565 + Erase invalid image.
566 + Persist failure of swap procedure to image trailers.
567 + Mark the swap type as `Fail`.
568 + Skip to next image.
569 + No:
570 + Mark the swap type as `None`.
571 + Skip to next image.
572
573+ ###### Loop 2. Iterate over all images
David Vinczee32483f2019-06-13 10:46:24 +0200574 1. Does the current image depend on other image(s)?
575 + Yes: Are all the image dependencies satisfied?
576 + Yes: Skip to next image.
577 + No:
578 + Modify swap type depending on what the previous type was.
579 + Restart dependency check from the first image.
580 + No: Skip to next image.
David Vinczeba3bd602019-06-17 16:01:43 +0200581
David Vinczee32483f2019-06-13 10:46:24 +0200582+ ###### Loop 3. Iterate over all images
David Vinczeba3bd602019-06-17 16:01:43 +0200583 1. Is an image swap requested?
584 + Yes:
585 + Perform image update operation.
586 + Persist completion of swap procedure to image trailers.
587 + Skip to next image.
588 + No: Skip to next image.
589
David Vinczee32483f2019-06-13 10:46:24 +0200590+ ###### Loop 4. Iterate over all images
David Vinczeba3bd602019-06-17 16:01:43 +0200591 1. Validate image in the primary slot (integrity and security check) or
592 at least do a basic sanity check to avoid booting into an empty flash
593 area.
594
595+ Boot into image in the primary slot of the 0th image position\
596 (other image in the boot chain is started by another image).
597
David Brown17e20d12017-09-12 11:53:20 -0600598## Image Swapping
Christopher Collins92ea77f2016-12-12 15:59:26 -0800599
600The boot loader swaps the contents of the two image slots for two reasons:
Fabio Utzig75b34412019-09-06 08:30:43 -0300601
602 * User has issued a "set pending" operation; the image in the secondary slot
603 should be run once (state II) or repeatedly (state III), depending on
604 whether a permanent swap was specified.
605 * Test image rebooted without being confirmed; the boot loader should
606 revert to the original image currently in the secondary slot (state IV).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800607
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300608If the image trailers indicates that the image in the secondary slot should be
Christopher Collins92ea77f2016-12-12 15:59:26 -0800609run, the boot loader needs to copy it to the primary slot. The image currently
610in the primary slot also needs to be retained in flash so that it can be used
611later. Furthermore, both images need to be recoverable if the boot loader
612resets in the middle of the swap operation. The two images are swapped
613according to the following procedure:
614
Fabio Utzig60319ac2019-09-06 08:29:50 -03006151. Determine if both slots are compatible enough to have their images swapped.
616 To be compatible, both have to have only sectors that can fit into the
617 scratch area and if one of them has larger sectors than the other, it must
618 be able to entirely fit some rounded number of sectors from the other slot.
6192. Iterate the list of sector indices in descending order (i.e., starting
620 with the greatest index); only sectors that are predetermined to be part of
621 the image are copied; current element = "index".
622 + a. Erase scratch area.
623 + b. Copy secondary_slot[index] to scratch area.
624 - If this is the last sector in the slot, scratch area has a temporary
625 status area initialized to store the initial state, because the
626 primary slot's last sector will have to be erased. In this case,
627 only the data that was calculated to amount to the image is copied.
628 - Else if this is the first swapped sector but not the last sector in
629 the slot, initialize the status area in primary slot and copy the
630 full sector contents.
631 - Else, copy entire sector contents.
632 + c. Write updated swap status (i).
633 + d. Erase secondary_slot[index]
634 + e. Copy primary_slot[index] to secondary_slot[index] according to amount
635 previosly copied at step b.
636 - If this is not the last sector in the slot, erase the trailer in the
637 secondary slot, to always use the one in the primary slot.
638 + f. Write updated swap status (ii).
639 + g. Erase primary_slot[index].
640 + h. Copy scratch area to primary_slot[index] according to amount
641 previously copied at step b.
642 - If this is the last sector in the slot, the status is read from
643 scratch (where it was stored temporarily) and written anew in the
644 primary slot.
645 + i. Write updated swap status (iii).
6463. Persist completion of swap procedure to the primary slot image trailer.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800647
David Vincze2d736ad2019-02-18 11:50:22 +0100648The additional caveats in step 2f are necessary so that the secondary slot image
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800649trailer can be written by the user at a later time. With the image trailer
David Vincze2d736ad2019-02-18 11:50:22 +0100650unwritten, the user can test the image in the secondary slot
651(i.e., transition to state II).
Christopher Collins92ea77f2016-12-12 15:59:26 -0800652
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300653Note1: If the sector being copied is the last sector, then swap status is
654temporarily maintained on scratch for the duration of this operation, always
David Vincze2d736ad2019-02-18 11:50:22 +0100655using the primary slot's area otherwise.
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300656
657Note2: The bootloader tries to copy only used sectors (based on largest image
658installed on any of the slots), minimizing the amount of sectors copied and
659reducing the amount of time required for a swap operation.
660
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800661The particulars of step 3 vary depending on whether an image is being tested,
David Vincze2d736ad2019-02-18 11:50:22 +0100662permanently used, reverted or a validation failure of the secondary slot
663happened when a swap was requested:
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300664
Christopher Collins92ea77f2016-12-12 15:59:26 -0800665 * test:
David Vincze2d736ad2019-02-18 11:50:22 +0100666 o Write primary_slot.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800667 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100668 primary_slot.magic = BOOT_MAGIC
669 primary_slot.image_ok = Unset)
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800670
671 * permanent:
David Vincze2d736ad2019-02-18 11:50:22 +0100672 o Write primary_slot.copy_done = 1
Christopher Collinsfd7eb5c2016-12-21 13:46:08 -0800673 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100674 primary_slot.magic = BOOT_MAGIC
675 primary_slot.image_ok = 0x01)
Christopher Collins92ea77f2016-12-12 15:59:26 -0800676
677 * revert:
David Vincze2d736ad2019-02-18 11:50:22 +0100678 o Write primary_slot.copy_done = 1
679 o Write primary_slot.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300680 (swap caused the following values to be written:
David Vincze2d736ad2019-02-18 11:50:22 +0100681 primary_slot.magic = BOOT_MAGIC)
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300682
David Vincze2d736ad2019-02-18 11:50:22 +0100683 * failure to validate the secondary slot:
684 o Write primary_slot.image_ok = 1
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300685
David Vincze2d736ad2019-02-18 11:50:22 +0100686After completing the operations as described above the image in the primary slot
687should be booted.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800688
David Brown17e20d12017-09-12 11:53:20 -0600689## Swap Status
Christopher Collins92ea77f2016-12-12 15:59:26 -0800690
691The swap status region allows the boot loader to recover in case it restarts in
692the middle of an image swap operation. The swap status region consists of a
693series of single-byte records. These records are written independently, and
694therefore must be padded according to the minimum write size imposed by the
695flash hardware. In the below figure, a min-write-size of 1 is assumed for
696simplicity. The structure of the swap status region is illustrated below. In
697this figure, a min-write-size of 1 is assumed for simplicity.
698
David Brown17e20d12017-09-12 11:53:20 -0600699```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800700 0 1 2 3
701 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
702 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
703 |sec127,state 0 |sec127,state 1 |sec127,state 2 |sec126,state 0 |
704 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
705 |sec126,state 1 |sec126,state 2 |sec125,state 0 |sec125,state 1 |
706 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
707 |sec125,state 2 | |
708 +-+-+-+-+-+-+-+-+ +
709 ~ ~
710 ~ [Records for indices 124 through 1 ~
711 ~ ~
712 ~ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
713 ~ |sec000,state 0 |sec000,state 1 |sec000,state 2 |
714 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
David Brown17e20d12017-09-12 11:53:20 -0600715```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800716
717The above is probably not helpful at all; here is a description in English.
718
719Each image slot is partitioned into a sequence of flash sectors. If we were to
720enumerate the sectors in a single slot, starting at 0, we would have a list of
721sector indices. Since there are two image slots, each sector index would
722correspond to a pair of sectors. For example, sector index 0 corresponds to
David Vincze2d736ad2019-02-18 11:50:22 +0100723the first sector in the primary slot and the first sector in the secondary slot.
724Finally, reverse the list of indices such that the list starts with index
725`BOOT_MAX_IMG_SECTORS - 1` and ends with 0. The swap status region is a
726representation of this reversed list.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800727
728During a swap operation, each sector index transitions through four separate
729states:
David Brown17e20d12017-09-12 11:53:20 -0600730```
David Vincze2d736ad2019-02-18 11:50:22 +01007310. primary slot: image 0, secondary slot: image 1, scratch: N/A
7321. primary slot: image 0, secondary slot: N/A, scratch: image 1 (1->s, erase 1)
7332. primary slot: N/A, secondary slot: image 0, scratch: image 1 (0->1, erase 0)
7343. primary slot: image 1, secondary slot: image 0, scratch: N/A (s->0)
David Brown17e20d12017-09-12 11:53:20 -0600735```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800736
737Each time a sector index transitions to a new state, the boot loader writes a
738record to the swap status region. Logically, the boot loader only needs one
739record per sector index to keep track of the current swap state. However, due
740to limitations imposed by flash hardware, a record cannot be overwritten when
741an index's state changes. To solve this problem, the boot loader uses three
742records per sector index rather than just one.
743
744Each sector-state pair is represented as a set of three records. The record
745values map to the above four states as follows
746
David Brown17e20d12017-09-12 11:53:20 -0600747```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800748 | rec0 | rec1 | rec2
749 --------+------+------+------
750 state 0 | 0xff | 0xff | 0xff
751 state 1 | 0x01 | 0xff | 0xff
752 state 2 | 0x01 | 0x02 | 0xff
753 state 3 | 0x01 | 0x02 | 0x03
David Brown17e20d12017-09-12 11:53:20 -0600754```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800755
Fabio Utzig2c05f1b2018-04-04 10:35:17 -0300756The swap status region can accommodate `BOOT_MAX_IMG_SECTORS` sector indices.
David Vincze2d736ad2019-02-18 11:50:22 +0100757Hence, the size of the region, in bytes, is
758`BOOT_MAX_IMG_SECTORS * min-write-size * 3`. The only requirement for the index
759count is that it is great enough to account for a maximum-sized image
760(i.e., at least as great as the total sector count in an image slot). If a
761device's image slots have been configured with `BOOT_MAX_IMG_SECTORS: 128` and
762use less than 128 sectors, the first record that gets written will be somewhere
763in the middle of the region. For example, if a slot uses 64 sectors, the first
764sector index that gets swapped is 63, which corresponds to the exact halfway
765point within the region.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800766
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300767Note: since the scratch area only ever needs to record swapping of the last
768sector, it uses at most min-write-size * 3 bytes for its own status area.
769
David Brown17e20d12017-09-12 11:53:20 -0600770## Reset Recovery
Christopher Collins92ea77f2016-12-12 15:59:26 -0800771
772If the boot loader resets in the middle of a swap operation, the two images may
773be discontiguous in flash. Bootutil recovers from this condition by using the
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300774image trailers to determine how the image parts are distributed in flash.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800775
776The first step is determine where the relevant swap status region is located.
777Because this region is embedded within the image slots, its location in flash
Fabio Utzig86fe4b22017-07-28 18:56:29 -0300778changes during a swap operation. The below set of tables map image trailers
Christopher Collins92ea77f2016-12-12 15:59:26 -0800779contents to swap status location. In these tables, the "source" field
David Vinczeba3bd602019-06-17 16:01:43 +0200780indicates where the swap status region is located. In case of multi image boot
781the images primary area and the single scratch area is always examined in pairs.
782If swap status found on scratch area then it might not belong to the current
783image. The swap_info field of swap status stores the corresponding image number.
784If it does not match then "source: none" is returned.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800785
David Brown17e20d12017-09-12 11:53:20 -0600786```
David Vincze2d736ad2019-02-18 11:50:22 +0100787 | primary slot | scratch |
788 ----------+--------------+--------------|
789 magic | Good | Any |
790 copy-done | 0x01 | N/A |
791 ----------+--------------+--------------'
792 source: none |
793 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400794
David Vincze2d736ad2019-02-18 11:50:22 +0100795 | primary slot | scratch |
796 ----------+--------------+--------------|
797 magic | Good | Any |
798 copy-done | 0xff | N/A |
799 ----------+--------------+--------------'
800 source: primary slot |
801 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400802
David Vincze2d736ad2019-02-18 11:50:22 +0100803 | primary slot | scratch |
804 ----------+--------------+--------------|
805 magic | Any | Good |
806 copy-done | Any | N/A |
807 ----------+--------------+--------------'
808 source: scratch |
809 ----------------------------------------'
Marti Bolivar49b29172017-08-04 14:50:51 -0400810
David Vincze2d736ad2019-02-18 11:50:22 +0100811 | primary slot | scratch |
812 ----------+--------------+--------------|
813 magic | Unset | Any |
814 copy-done | 0xff | N/A |
815 ----------+--------------+--------------|
816 source: primary slot |
817 ----------------------------------------+------------------------------+
818 This represents one of two cases: |
819 o No swaps ever (no status to read, so no harm in checking). |
820 o Mid-revert; status in the primary slot. |
821 For this reason we assume the primary slot as source, to trigger a |
822 check of the status area and find out if there was swapping under way. |
823 -----------------------------------------------------------------------'
David Brown17e20d12017-09-12 11:53:20 -0600824```
Christopher Collins92ea77f2016-12-12 15:59:26 -0800825
Christopher Collinsa1c12042019-05-23 14:00:28 -0700826If the swap status region indicates that the images are not contiguous, mcuboot
827determines the type of swap operation that was interrupted by reading the `swap
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +0000828info` field in the active image trailer and extracting the swap type from bits
David Vinczee2453472019-06-17 12:31:59 +02008290-3 then resumes the operation. In other words, it applies the procedure defined
830in the previous section, moving image 1 into the primary slot and image 0 into
831the secondary slot. If the boot status indicates that an image part is present
832in the scratch area, this part is copied into the correct location by starting
833at step e or step h in the area-swap procedure, depending on whether the part
834belongs to image 0 or image 1.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800835
836After the swap operation has been completed, the boot loader proceeds as though
837it had just been started.
838
David Brown17e20d12017-09-12 11:53:20 -0600839## Integrity Check
Christopher Collins92ea77f2016-12-12 15:59:26 -0800840
841An image is checked for integrity immediately before it gets copied into the
Fabio Utzig5bd4e582017-07-20 08:55:38 -0300842primary slot. If the boot loader doesn't perform an image swap, then it can
David Vincze2d736ad2019-02-18 11:50:22 +0100843perform an optional integrity check of the image in the primary slot if
844`MCUBOOT_VALIDATE_PRIMARY_SLOT` is set, otherwise it doesn't perform an
845integrity check.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800846
847During the integrity check, the boot loader verifies the following aspects of
848an image:
Fabio Utzig75b34412019-09-06 08:30:43 -0300849
850 * 32-bit magic number must be correct (0x96f3b83d).
851 * Image must contain an `image_tlv_info` struct, identified by its magic
852 (0x6907) exactly following the firmware (hdr_size + img_size).
853 * Image must contain a SHA256 TLV.
854 * Calculated SHA256 must match SHA256 TLV contents.
855 * Image *may* contain a signature TLV. If it does, it must also have a
856 KEYHASH TLV with the hash of the key that was used to sign. The list of
857 keys will then be iterated over looking for the matching key, which then
858 will then be used to verify the image contents.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800859
David Brown17e20d12017-09-12 11:53:20 -0600860## Security
Christopher Collins92ea77f2016-12-12 15:59:26 -0800861
862As indicated above, the final step of the integrity check is signature
863verification. The boot loader can have one or more public keys embedded in it
864at build time. During signature verification, the boot loader verifies that an
Håkon Øye Amundsencbf30472019-07-24 08:34:03 +0000865image was signed with a private key that corresponds to the embedded KEYHASH
Fabio Utzigea422c22017-09-11 11:02:47 -0300866TLV.
Christopher Collins92ea77f2016-12-12 15:59:26 -0800867
868For information on embedding public keys in the boot loader, as well as
Fabio Utzig4dce6aa2018-02-12 15:31:32 -0200869producing signed images, see: [signed_images](signed_images.md).
Fabio Utzigcdfa11a2018-10-01 09:45:54 -0300870
871If you want to enable and use encrypted images, see:
872[encrypted_images](encrypted_images.md).
David Vinczee32483f2019-06-13 10:46:24 +0200873
874## Dependency Check
875
876MCUBoot can handle multiple firmware images. It is possible to update them
877independently but in many cases it can be desired to be able to describe
878dependencies between the images (e.g. to ensure API compliance and avoid
879interoperability issues).
880
881The dependencies between images can be described with additional TLV entries in
882the TLV area after the end of an image. There can be more than one dependency
883entry, but in practice if the platform only supports two individual images then
884there can be maximum one entry which reflects to the other image.
885
886If the TLV area contains dependency TLV entries, then these are required to be
887integrity and authenticity protected. In this case the SHA256 has to be
888calculated over not just the image header and the image but also the TLV info
889header and the dependency TLVs.
890```
891A +---------------------+
892 | Header | <- struct image_header
893 +---------------------+
894 | Payload |
895 +---------------------+
896 | TLV area |
897 | +-----------------+ |
898 | | TLV area header | | <- struct image_tlv_info
899 | +-----------------+ |
900 | | Dependency | | <- Dependency entry (struct image_tlv)
901B | +-----------------+ |
902 | | SHA256 hash | | <- hash from A - B (struct image_tlv)
903C | +-----------------+ |
904 | | Keyhash | | <- indicates which pub. key for sig (struct image_tlv)
905 | +-----------------+ |
906 | | Signature | | <- signature from B - C (struct image_tlv), only hash
907 | +-----------------+ |
908 +---------------------+
909```
910At the phase of dependency check all aborted swaps are finalized if there were
911any. During the dependency check the boot loader verifies whether the image
912dependencies are all satisfied. If at least one of the dependencies of an image
913is not fulfilled then the swap type of that image has to be modified
914accordingly and the dependency check needs to be restarted. This way the number
915of unsatisfied dependencies will decrease or remain the same. There is always at
916least 1 valid configuration. In worst case, the system returns to the initial
917state after dependency check.
918
919For more information on adding dependency entries to an image,
920see: [imgtool](imgtool.md).