• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..--

images/18-Mar-2025-

release-notes.d/18-Mar-2025-10680

.gitignoreD18-Mar-202520 32

CNAMED18-Mar-202516 11

GemfileD18-Mar-2025900 2719

Gemfile.lockD18-Mar-20257.2 KiB267263

PORTING.mdD18-Mar-20258.4 KiB196158

SECURITY.mdD18-Mar-20251.8 KiB5740

SubmittingPatches.mdD18-Mar-20253.2 KiB9065

_config.ymlD18-Mar-202547 43

compression_format.mdD18-Mar-20255.1 KiB173132

design.mdD18-Mar-202570.4 KiB1,5711,282

ecdsa.mdD18-Mar-20253.7 KiB9169

encrypted_images.mdD18-Mar-20258.8 KiB184127

imgtool.mdD18-Mar-202510.8 KiB192164

index.mdD18-Mar-20254.4 KiB9475

readme-espressif.mdD18-Mar-202546.8 KiB1,258971

readme-mbed.mdD18-Mar-20252.8 KiB4226

readme-mynewt.mdD18-Mar-20251.7 KiB5338

readme-nuttx.mdD18-Mar-20255.2 KiB5332

readme-riot.mdD18-Mar-20252 KiB4834

readme-zephyr.mdD18-Mar-202511.6 KiB257198

release-notes.mdD18-Mar-202524.3 KiB554469

release.mdD18-Mar-20254.7 KiB13499

serial_recovery.mdD18-Mar-20254.3 KiB12978

signed_images.mdD18-Mar-20253.3 KiB10153

testplan-mynewt.mdD18-Mar-20254.2 KiB163104

testplan-zephyr.mdD18-Mar-20251.9 KiB7245

readme-espressif.md

1# [Building and using MCUboot with Espressif's chips](#building-and-using-mcuboot-with-espressifs-chips)
2
3The MCUBoot Espressif's port depends on HAL (Hardware Abstraction Layer) sources based on ESP-IDF
4or 3rd party frameworks as such as Zephyr-RTOS (`zephyrproject-rtos/hal_espressif/`) or NuttX RTOS
5(`espressif/esp-hal-3rdparty`). Building the MCUboot Espressif's port and its features is platform
6dependent, therefore, the system environment including toolchains, must be set accordingly. A
7standalone build version means that ESP-IDF and its toolchain are used as source. For 3rd parties
8framework, HAL path and toolchain must be set.
9
10Documentation about the MCUboot bootloader design, operation and features can be found in the
11[design document](design.md).
12
13## [SoC support availability](#soc-support-availability)
14
15The current port is available for use in the following SoCs within the OSes:
16
17|        | ESP32     | ESP32-S2  | ESP32-C3  | ESP32-S3  | ESP32-C2    | ESP32-C6  | ESP32-H2    |
18| :----: | :-------: | :-------: | :-------: | :-------: | :---------: | :-------: | :---------: |
19| Zephyr | Supported | Supported | Supported | Supported | Supported   | Supported | In progress |
20| NuttX  | Supported | Supported | Supported | Supported | In progress | Supported | Supported   |
21
22Notice that any customization in the memory layout from the OS application must be done aware of
23the bootloader own memory layout to avoid overlapping. More information on the section
24[Memory map organization for OS compatibility](#memory-map-organization-for-os-compatibility).
25
26## [Installing requirements and dependencies](#installing-requirements-and-dependencies)
27
28The following instructions considers a MCUboot Espressif port standalone build.
29
301. Install additional packages required for development with MCUboot:
31
32    ```bash
33    cd ~/mcuboot  # or to your directory where MCUboot is cloned
34    ```
35
36    ```bash
37    pip3 install --user -r scripts/requirements.txt
38    ```
39
402. Update the Mbed TLS submodule required by MCUboot:
41
42    ```bash
43    git submodule update --init --recursive ext/mbedtls
44    ```
45
463. If ESP-IDF is the chosen option for use as HAL layer and the system already have ESP-IDF
47   installed, ensure that the environment is set:
48
49    ```bash
50    <IDF_PATH>/install.sh
51    ```
52
53    ```bash
54    . <IDF_PATH>/export.sh
55    ```
56
57    ---
58    ***Note***
59
60    *If desirable, instructions for ESP-IDF installation can be found
61    [here](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html#manual-installation)*
62
63    ---
64
65    ---
66    ***Note***
67
68    *The other HALs mentioned above like `hal_espressif` from Zephyr RTOS or `esp-hal-3rdparty`
69    from NuttX RTOS environments also can be used for the bootloader standalone build, however as
70    eventually code revision may differ from what is currently expected, it is recommended using
71    them only within their RTOS build system.*
72
73    ---
74
754. If ESP-IDF is not installed and will not be used, install `esptool`:
76
77    ```bash
78    pip3 install esptool
79    ```
80
81## [Building the bootloader itself](#building-the-bootloader-itself)
82
83The MCUboot Espressif port bootloader is built using the toolchain and tools provided by Espressif.
84Additional configuration related to MCUboot features and slot partitioning may be made using the
85`port/<TARGET>/bootloader.conf` file or passing a custom config file using the
86`-DMCUBOOT_CONFIG_FILE` argument on the first step below.
87
88---
89***Note***
90
91*Replace `<TARGET>` with the target ESP32 family (like `esp32`, `esp32s2` and others).*
92
93---
94
951. Compile and generate the BIN:
96
97    ```bash
98    cd <MCUBOOT_DIR>/boot/espressif
99    ```
100
101    ```bash
102    cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-<TARGET>.cmake -DMCUBOOT_TARGET=<TARGET> -DESP_HAL_PATH=<ESP_HAL_PATH> -DMCUBOOT_FLASH_PORT=<PORT> -B build -GNinja
103    ```
104
105    ```bash
106    ninja -C build/
107    ```
108
109    ---
110    ***Note***
111
112    *If using ESP-IDF as HAL layer source, `ESP_HAL_PATH` can be ommited.*
113
114    *If desirable, `<TOOLCHAIN_BIN_DIR>` can be defined with the path for a different compatible
115    toolchain, however it is recommended to actually create a CMake toolchain file and
116    pass it through `<CMAKE_TOOLCHAIN_FILE>` variable since it may require a distinct set of
117    compilation flags.*
118
119    ---
120
1212. Flash MCUboot in your device:
122
123    ```bash
124    ninja -C build/ flash
125    ```
126
127    If `MCUBOOT_FLASH_PORT` arg was not passed to `cmake`, the default `PORT` for flashing will be
128    `/dev/ttyUSB0`.
129
130    Alternatively:
131
132    ```bash
133    esptool.py -p <PORT> -b <BAUD> --before default_reset --after no_reset --chip <TARGET> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> build/mcuboot_<TARGET>.bin
134    ```
135
136    ---
137    ***Note***
138
139    You may adjust the port `<PORT>` (like `/dev/ttyUSB0`) and baud rate `<BAUD>` (like `2000000`)
140    according to the connection with your board. You can also skip `<PORT>` and `<BAUD>` parameters
141    so that esptool tries to automatically detect it.
142
143    *`<FLASH_SIZE>` can be found using the command below:*
144
145    ```bash
146    esptool.py -p <PORT> -b <BAUD> flash_id
147    ```
148
149    The output contains device information and its flash size:
150
151    ```
152    Detected flash size: 4MB
153    ```
154
155    *`<BOOTLOADER_FLASH_OFFSET>` value must follow one of the addresses below:*
156
157    | ESP32   | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 |
158    | :-----: | :-----:  | :-----:  | :-----:  | :-----:  | :-----:  | :-----:  |
159    | 0x1000  | 0x1000   | 0x0000   | 0x0000   | 0x0000   | 0x0000   | 0x0000   |
160
161    ---
162
1633. Reset your device
164
165## [Signing and flashing an application](#signing-and-flashing-an-application)
166
1671. Images can be regularly signed with the `scripts/imgtool.py` script:
168
169    ```bash
170    imgtool.py sign --align 4 -v 0 -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN>
171    ```
172
173    ---
174
175    ***Note***
176
177    `<SLOT_SIZE>` is the size of the slot to be used.
178    Default slot0 size is `0x100000`, but it can change as per application flash partitions.
179
180    For Zephyr images, `--pad-header` is not needed as it already has the padding for MCUboot
181    header.
182
183    ---
184
185    :warning: ***ATTENTION***
186
187    *This is the basic signing needed for adding MCUboot headers and trailers.
188    For signing with a crypto key and guarantee the authenticity of the image being booted, see the
189    section [MCUboot image signature verification](#mcuboot-image-signature-verification) below.*
190
191    ---
192
1932. Flash the signed application:
194
195    ```bash
196    esptool.py -p <PORT> -b <BAUD> --before default_reset --after hard_reset --chip <TARGET>  write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <SLOT_OFFSET> <SIGNED_BIN>
197    ```
198
199# [Downgrade prevention](#downgrade-prevention)
200
201Downgrade prevention (avoid updating of images to an older version) can be enabled using the
202following configuration:
203
204```
205CONFIG_ESP_DOWNGRADE_PREVENTION=y
206```
207
208MCUboot will then verify and compare the new image version number with the current one before
209perform an update swap.
210
211Version number is added to the image when signing it with `imgtool` (`-v` parameter, e.g.
212`-v 1.0.0`).
213
214### [Downgrade prevention with security counter](#downgrade-prevention-with-security-counter)
215
216It is also possible to rely on a security counter, also added to the image when signing with
217`imgtool` (`-s` parameter), apart from version number. This allows image downgrade at some extent,
218since any update must have greater or equal security counter value. Enable using the following
219configuration:
220
221```
222CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y
223```
224
225E.g.: if the current image was signed using `-s 1` parameter, an eventual update image must have
226been signed using security counter `-s 1` or greater.
227
228# [Security Chain on Espressif port](#security-chain-on-espressif-port)
229
230[MCUboot encrypted images](encrypted_images.md) do not provide full code confidentiality when only
231external storage is available (see [Threat model](encrypted_images.md#threat-model)) since by
232MCUboot design the image in Primary Slot, from where the image is executed, is stored plaintext.
233Espressif chips have off-chip flash memory, so to ensure a security chain along with MCUboot image
234signature verification, the hardware-assisted Secure Boot and Flash Encryption were made available
235on the MCUboot Espressif port.
236
237## [MCUboot image signature verification](#mcuboot-image-signature-verification)
238
239The image that MCUboot is booting can be signed with 4 types of keys: RSA-2048, RSA-3072, EC256 and
240ED25519. In order to enable the feature, the **bootloader** must be compiled with the following
241configurations:
242
243---
244***Note***
245
246*It is strongly recommended to generate a new signing key using `imgtool` instead of use the
247existent samples.*
248
249---
250
251#### For EC256 algorithm use
252
253```
254CONFIG_ESP_SIGN_EC256=y
255
256# Use Tinycrypt lib for EC256 or ED25519 signing
257CONFIG_ESP_USE_TINYCRYPT=y
258
259CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
260```
261
262#### For ED25519 algorithm use
263
264```
265CONFIG_ESP_SIGN_ED25519=y
266
267# Use Tinycrypt lib for EC256 or ED25519 signing
268CONFIG_ESP_USE_TINYCRYPT=y
269
270CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
271```
272
273#### For RSA (2048 or 3072) algorithm use
274
275```
276CONFIG_ESP_SIGN_RSA=y
277# RSA_LEN is 2048 or 3072
278CONFIG_ESP_SIGN_RSA_LEN=<RSA_LEN>
279
280# Use Mbed TLS lib for RSA image signing
281CONFIG_ESP_USE_MBEDTLS=y
282
283CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem>
284```
285
286Notice that the public key will be embedded in the bootloader code, since the hardware key storage
287is not supported by Espressif port.
288
289### [Signing the image](#signing-the-image)
290
291Now you need to sign the **image binary**, use the `imgtool` with `-k` parameter:
292
293```bash
294imgtool.py sign -k <YOUR_SIGNING_KEY.pem> --pad --pad-sig --align 4 -v 0 -H 32 --pad-header -S 0x00100000 <BIN_IN> <BIN_OUT>
295```
296
297If signing a Zephyr image, the `--pad-header` is not needed, as it already have the padding for
298MCUboot header.
299
300
301## [Secure Boot](#secure-boot)
302
303The Secure Boot implementation is based on
304[IDF's Secure Boot V2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v2.html),
305is hardware-assisted and RSA based - except ESP32-C2 that uses ECDSA signing scheme - and has the
306role for ensuring that only authorized code will be executed on the device. This is done through
307bootloader signature checking by the ROM bootloader.
308
309***Note***: ROM bootloader is the First Stage Bootloader, while the Espressif MCUboot port is the
310Second Stage Bootloader.
311
312### [Building bootloader with Secure Boot](#building-bootloader-with-secure-boot)
313
314In order to build the bootloader with the feature on, the following configurations must be enabled:
315
316```
317CONFIG_SECURE_BOOT=1
318CONFIG_SECURE_BOOT_V2_ENABLED=1
319CONFIG_SECURE_SIGNED_ON_BOOT=1
320```
321
322For the currently supported chips, with exception of ESP32-C2, enable RSA signing scheme:
323
324```
325CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1
326CONFIG_SECURE_BOOT_SUPPORTS_RSA=1
327```
328
329For ESP32-C2, enable ECDSA signing scheme and, if working with Flash Encryption too, enable the
330configuration to burn keys to efuse together:
331
332```
333CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME=1
334
335CONFIG_SECURE_BOOT_FLASH_ENC_KEYS_BURN_TOGETHER=1
336```
337
338---
339:warning: ***ATTENTION***
340
341*On development phase is recommended add the following configuration in order to keep the debugging
342enabled and also to avoid any unrecoverable/permanent state change:*
343
344```
345CONFIG_SECURE_BOOT_ALLOW_JTAG=1
346CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
347
348# Options for enabling eFuse emulation in Flash
349CONFIG_EFUSE_VIRTUAL=1
350CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
351```
352---
353
354---
355:warning: ***ATTENTION***
356
357*You can disable UART Download Mode by adding the following configuration:*
358
359```
360CONFIG_SECURE_DISABLE_ROM_DL_MODE=1
361```
362
363*This may be suitable for __production__ builds. __After disabling UART Download Mode you will not
364be able to flash other images through UART.__*
365
366*Otherwise, you can switch the UART ROM Download Mode to the Secure Download Mode. It will limit
367the use of Download Mode functions to simple flash read, write and erase operations.*
368
369```
370CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1
371```
372
373*Once the device makes its first full boot, these configurations cannot be reverted*
374
375---
376
377Once the **bootloader image** is built, the resulting binary file is required to be signed with
378`espsecure.py` tool.
379
380First create a signing key:
381
382```bash
383espsecure.py generate_signing_key --version 2 <BOOTLOADER_SIGNING_KEY.pem>
384```
385
386Then sign the bootloader image:
387
388```bash
389espsecure.py sign_data --version 2 --keyfile <BOOTLOADER_SIGNING_KEY.pem> -o <BOOTLOADER_BIN_OUT> <BOOTLOADER_BIN_IN>
390```
391
392---
393:warning: ***ATTENTION***
394
395*Once the bootloader is flashed and the device resets, the **first boot will enable Secure Boot**
396and the bootloader and key **no longer can be modified**. So **ENSURE** that both bootloader and
397key are correct and you did not forget anything before flashing.*
398
399---
400
401Flash the bootloader as following, with `--after no_reset` flag, so you can reset the device only
402when assured:
403
404```bash
405esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> <SIGNED_BOOTLOADER_BIN>
406```
407
408### [Secure Boot Process](#secure-boot-process)
409
410Secure boot uses a signature block appended to the bootloader image in order to verify the
411authenticity. The signature block contains the RSA-3072 signature of that image and the RSA-3072
412public key.
413
414On its **first boot** the Secure Boot is not enabled on the device eFuses yet, neither the key nor
415digests. So the first boot will have the following process:
416
4171. On startup, since it is the first boot, the ROM bootloader will not verify the bootloader image
418   (the Secure Boot bit in the eFuse is disabled) yet, so it proceeds to execute it (our MCUboot
419   bootloader port).
4202. Bootloader calculates the SHA-256 hash digest of the public key and writes the result to eFuse.
4213. Bootloader validates the application images and prepare the booting process (MCUboot phase).
4224. Bootloader burns eFuse to enable Secure Boot V2.
4235. Bootloader proceeds to load the Primary image.
424
425After that the Secure Boot feature is permanently enabled and on every next boot the ROM bootloader
426will verify the MCUboot bootloader image. The process of an usual boot:
427
4281. On startup, the ROM bootloader checks the Secure Boot enable bit in the eFuse. If it is enabled,
429   the boot will proceed as following.
4302. ROM bootloader verifies the bootloader's signature block integrity (magic number and CRC).
431   Interrupt boot if it fails.
4323. ROM bootloader verifies the bootloader image, interrupt boot if any step fails:
433    1. Compare the SHA-256 hash digest of the public key embedded in the bootloader’s signature
434       block with the digest saved in the eFuses.
435    2. Generate the application image digest and match it with the image digest in the signature
436       block.
437    3. Use the public key to verify the signature of the bootloader image, using RSA-PSS with the
438       image digest calculated from previous step for comparison.
4394. ROM bootloader executes the bootloader image.
4405. Bootloader does the usual verification (MCUboot phase).
4416. Proceeds to boot the Primary image.
442
443## [Flash Encryption](#flash-encryption)
444
445The Espressif Flash Encryption is hardware-assisted, transparent to the MCUboot process and is an
446additional security measure beyond MCUboot existent features.
447The Flash Encryption implementation is also based on
448[IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/flash-encryption.html)
449and is intended for encrypting off-chip flash memory contents, so it is protected against physical
450reading.
451
452When enabling the Flash Encryption, the user can encrypt the content either using a **device
453generated key** (remains unknown and unreadable) or a **host generated key** (owner is responsible
454for keeping the key private and safe). After the flash encryption gets enabled through eFuse
455burning on the device, all read and write operations are decrypted/encrypted in runtime.
456
457### [Building bootloader with Flash Encryption](#building-bootloader-with-flash-encryption)
458
459In order to build the bootloader with the feature on, the following configurations must be enabled:
460
461For **release mode**:
462
463```
464CONFIG_SECURE_FLASH_ENC_ENABLED=1
465CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1
466```
467
468For **development mode**:
469
470```
471CONFIG_SECURE_FLASH_ENC_ENABLED=1
472CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1
473```
474
475---
476:warning: ***ATTENTION***
477
478*On development phase is strongly recommended adding the following configuration in order to keep
479the debugging enabled and also to avoid any unrecoverable/permanent state change:*
480
481```
482CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1
483CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1
484CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1
485CONFIG_SECURE_BOOT_ALLOW_JTAG=1
486
487# Options for enabling eFuse emulation in Flash
488CONFIG_EFUSE_VIRTUAL=1
489CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1
490```
491---
492
493---
494:warning: ***ATTENTION***
495
496*Unless the recommended flags for __DEVELOPMENT MODE__ were enabled, the actions made by Flash
497Encryption process are __PERMANENT__.* \
498*Once the bootloader is flashed and the device resets, the __first boot will enable Flash
499Encryption, encrypt the flash content including bootloader and image slots, burn the eFuses that no
500longer can be modified__ and if device generated the key __it will not be recoverable__.* \
501*When on __RELEASE MODE__, __ENSURE__ that the application with an update agent is flashed before
502reset the device.*
503
504*In the same way as Secure Boot feature, you can disable UART Download Mode by adding the following
505configuration:*
506
507```
508CONFIG_SECURE_DISABLE_ROM_DL_MODE=1
509```
510
511*This may be suitable for __production__ builds. __After disabling UART Download Mode you will not
512be able to flash other images through UART.__*
513
514*Otherwise, you can switch the UART Download Mode to the Secure Download Mode. It will limit the
515use of Download Mode functions to simple flash read, write and erase operations.*
516
517```
518CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1
519```
520
521*These configurations cannot be reverted after the device's first boot*
522
523---
524
525### [Signing the image when working with Flash Encryption](#signing-the-image-when-working-with-flash-encryption)
526
527When enabling flash encryption, it is required to signed the image using 32-byte alignment:
528`--align 32 --max-align 32`.
529
530Command example:
531
532```bash
533imgtool.py sign -k <YOUR_SIGNING_KEY.pem> --pad --pad-sig --align 32 --max-align 32 -v 0 -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <BIN_OUT>
534```
535
536### [Device generated key](#device-generated-key)
537
538First ensure that the application image is able to perform encrypted read and write operations to
539the SPI Flash. Flash the bootloader and application normally:
540
541```bash
542esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> <BOOTLOADER_BIN>
543```
544
545```bash
546esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <PRIMARY_SLOT_FLASH_OFFSET> <APPLICATION_BIN>
547```
548
549On the **first boot**, the bootloader will:
550
5511. Generate Flash Encryption key and write to eFuse.
5522. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch.
5533. Burn eFuse to enable Flash Encryption.
5544. Reset system to ensure Flash Encryption cache resets properly.
555
556### [Host generated key](#host-generated-key)
557
558First ensure that the application image is able to perform encrypted read and write operations to
559the SPI Flash. Also ensure that the **UART ROM Download Mode is not disabled** - or that the
560**Secure Download Mode is enabled**. Before flashing, generate the encryption key using
561`espsecure.py` tool:
562
563```bash
564espsecure.py generate_flash_encryption_key <FLASH_ENCRYPTION_KEY.bin>
565```
566
567Burn the key into the device's eFuse (keep a copy on the host), this action can be done **only
568once**:
569
570---
571:warning: ***ATTENTION***
572
573*eFuse emulation in Flash configuration options do not have any effect, so if the key burning
574command below is used, it will actually burn the physical eFuse.*
575
576---
577
578- ESP32
579
580```bash
581espefuse.py --port PORT burn_key flash_encryption <FLASH_ENCRYPTION_KEY.bin>
582```
583
584- ESP32S2, ESP32C3 and ESP32S3
585
586```bash
587espefuse.py --port PORT burn_key BLOCK <FLASH_ENCRYPTION_KEY.bin> <KEYPURPOSE>
588```
589
590`BLOCK` is a free keyblock between `BLOCK_KEY0` and `BLOCK_KEY5`. And `KEYPURPOSE` is either
591`XTS_AES_128_KEY`, `XTS_AES_256_KEY_1`, `XTS_AES_256_KEY_2` (AES XTS 256 is available only in
592ESP32S2).
593
594Now, similar as the Device generated key, the bootloader and application can be flashed plaintext.
595The **first boot** will encrypt the flash content using the host key burned in the eFuse instead
596of generate a new one.
597
598Flashing the bootloader and application:
599
600```bash
601esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <BOOTLOADER_FLASH_OFFSET> <BOOTLOADER_BIN>
602```
603
604```bash
605esptool.py -p <PORT> -b 2000000 --after no_reset --chip <ESP_CHIP> write_flash --flash_mode dio --flash_size <FLASH_SIZE> --flash_freq 40m <PRIMARY_SLOT_FLASH_OFFSET> <APPLICATION_BIN>
606```
607
608On the **first boot**, the bootloader will:
609
6101. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch using the
611   written key.
6122. Burn eFuse to enable Flash Encryption.
6133. Reset system to ensure Flash Encryption cache resets properly.
614
615Encrypting data on the host:
616
617- ESP32
618
619```bash
620espsecure.py encrypt_flash_data --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA>
621```
622
623- ESP32-S2, ESP32-C3 and ESP32-S3
624
625```bash
626espsecure.py encrypt_flash_data --aes_xts --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA>
627```
628
629---
630***Note***
631
632OTA updates are required to be sent plaintext. The reason is that, as said before, after the Flash
633Encryption is enabled all read/write operations are decrypted/encrypted in runtime, so as e.g. if
634pre-encrypted data is sent for an OTA update, it would be wrongly double-encrypted when the update
635agent writes to the flash.
636
637For updating with an image encrypted on the host, flash it through serial using `esptool.py` as
638above. **UART ROM Download Mode must not be disabled**.
639
640---
641
642## [Security Chain scheme](#security-chain-scheme)
643
644Using the 3 features, Secure Boot, Image signature verification and Flash Encryption, a Security
645Chain can be established so only trusted code is executed, and also the code and content residing
646in the off-chip flash are protected against undesirable reading.
647
648The overall final process when all features are enabled:
649
6501. ROM bootloader validates the MCUboot bootloader using RSA signature verification.
6512. MCUboot bootloader validates the image using the chosen algorithm EC256/RSA/ED25519. It also
652   validates an upcoming image when updating.
6533. Flash Encryption guarantees that code and data are not exposed.
654
655### [Size Limitation](#size-limitation)
656
657When all 3 features are enable at same time, the bootloader size may exceed the fixed limit for
658the ROM bootloader checking on the Espressif chips **depending on which algorithm** was chosen for
659MCUboot image signing. The issue <https://github.com/mcu-tools/mcuboot/issues/1262> was created to
660track this limitation.
661
662## [Multi image](#multi-image)
663
664The multi image feature (currently limited to 2 images) allows the images to be updated separately
665(each one has its own primary and secondary slot) by MCUboot.
666
667The Espressif port bootloader handles the boot in two different approaches:
668
669### [Host OS boots second image](#host-os-boots-second-image)
670
671Host OS from the *first image* is responsible for booting the *second image*, therefore the
672bootloader is aware of the second image regions and can update it, however it does not load
673neither boots it.
674
675Configuration example (`bootloader.conf`):
676
677```
678CONFIG_ESP_BOOTLOADER_SIZE=0xF000
679CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
680
681# Enables multi image, if it is not defined, its assumed
682# only one updatable image
683CONFIG_ESP_IMAGE_NUMBER=2
684
685# Example of values to be used when multi image is enabled
686# Notice that the OS layer and update agent must be aware
687# of these regions
688CONFIG_ESP_APPLICATION_SIZE=0x50000
689CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
690CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000
691CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000
692CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000
693CONFIG_ESP_SCRATCH_OFFSET=0x150000
694CONFIG_ESP_SCRATCH_SIZE=0x40000
695```
696
697### [Multi boot](#multi-boot)
698
699In the multi boot approach the bootloader is responsible for booting two different images in two
700different CPUs, firstly the *second image* on the APP CPU and then the *first image* on the PRO
701CPU (current CPU), it is also responsible for update both images as well. Thus multi boot will be
702only supported by Espressif multi core chips - currently only ESP32 is implemented.
703
704---
705***Note***
706
707*The host OSes in each CPU must handle how the resources are divided/controlled between then.*
708
709---
710
711Configuration example:
712
713```
714CONFIG_ESP_BOOTLOADER_SIZE=0xF000
715CONFIG_ESP_MCUBOOT_WDT_ENABLE=y
716
717# Enables multi image, if it is not defined, its assumed
718# only one updatable image
719CONFIG_ESP_IMAGE_NUMBER=2
720
721# Enables multi image boot on independent processors
722# (main host OS is not responsible for booting the second image)
723# Use only with CONFIG_ESP_IMAGE_NUMBER=2
724CONFIG_ESP_MULTI_PROCESSOR_BOOT=y
725
726# Example of values to be used when multi image is enabled
727# Notice that the OS layer and update agent must be aware
728# of these regions
729CONFIG_ESP_APPLICATION_SIZE=0x50000
730CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000
731CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000
732CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000
733CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000
734CONFIG_ESP_SCRATCH_OFFSET=0x150000
735CONFIG_ESP_SCRATCH_SIZE=0x40000
736```
737
738### [Image version dependency](#image-version-dependency)
739
740MCUboot allows version dependency check between the images when updating them. As `imgtool.py`
741allows a version assigment when signing an image, it is also possible to add the version
742dependency constraint:
743
744```bash
745imgtool.py sign --align 4 -v <VERSION> -d "(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)" -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN>
746```
747
748- `<VERSION>` defines the version of the image being signed.
749- `"(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)"` defines the minimum version and from which image is
750  needed to satisfy the dependency.
751
752---
753Example:
754
755```bash
756imgtool.py sign --align 4 -v 1.0.0 -d "(1, 0.0.1+0)" -H 32 --pad-header -S 0x100000 image0.bin image0-signed.bin
757```
758
759Supposing that the image 0 is being signed, its version is 1.0.0 and it depends on image 1 with
760version at least 0.0.1+0.
761
762---
763
764## [Serial recovery mode](#serial-recovery-mode)
765
766Serial recovery mode allows management through MCUMGR (more information and how to install it:
767<https://github.com/apache/mynewt-mcumgr-cli>) for communicating and uploading a firmware to the
768device.
769
770Configuration example:
771
772```
773# Enables the MCUboot Serial Recovery, that allows the use of
774# MCUMGR to upload a firmware through the serial port
775CONFIG_ESP_MCUBOOT_SERIAL=y
776# GPIO used to boot on Serial Recovery
777CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=32
778# GPIO input type (0 for Pull-down, 1 for Pull-up)
779CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
780# GPIO signal value
781CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
782# Delay time for identify the GPIO signal
783CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
784# UART port used for serial communication
785CONFIG_ESP_SERIAL_BOOT_UART_NUM=1
786# GPIO for Serial RX signal
787CONFIG_ESP_SERIAL_BOOT_GPIO_RX=25
788# GPIO for Serial TX signal
789CONFIG_ESP_SERIAL_BOOT_GPIO_TX=26
790```
791
792When enabled, the bootloader checks the if the GPIO `<CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT>`
793configured has the signal value `<CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL>` for approximately
794`<CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S>` seconds for entering the Serial recovery mode. Example:
795a button configured on GPIO 32 pressed for 5 seconds.
796
797Serial mode then uses the UART port configured for communication
798(`<CONFIG_ESP_SERIAL_BOOT_UART_NUM>`, pins `<CONFIG_ESP_SERIAL_BOOT_GPIO_RX>`,
799`<CONFIG_ESP_SERIAL_BOOT_GPIO_RX>`).
800
801### [Serial Recovery through USB JTAG Serial port](#serial-recovery-through-usb-jtag-serial-port)
802
803Some chips, like ESP32-C3 and ESP32-S3 have an integrated USB JTAG Serial Controller that
804implements a serial port (CDC) that can also be used for handling MCUboot Serial Recovery.
805More information about the USB pins and hardware configuration:
806
807- ESP32-C3: <https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html>
808- ESP32-S3: <https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/usb-serial-jtag-console.html>
809- ESP32-C6: <https://docs.espressif.com/projects/esp-idf/en/latest/esp32c6/api-guides/usb-serial-jtag-console.html>
810- ESP32-H2: <https://docs.espressif.com/projects/esp-idf/en/latest/esp32h2/api-guides/usb-serial-jtag-console.html>
811
812Configuration example:
813
814```
815# Use Serial through USB JTAG Serial port for Serial Recovery
816CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y
817# Use sector erasing (recommended) instead of entire image size
818# erasing when uploading through Serial Recovery
819CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y
820# GPIO used to boot on Serial Recovery
821CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5
822# GPIO input type (0 for Pull-down, 1 for Pull-up)
823CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0
824# GPIO signal value
825CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1
826# Delay time for identify the GPIO signal
827CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5
828```
829
830---
831:warning: ***ATTENTION***
832
833*When working with Flash Encryption enabled, `CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY` must be
834__disabled__, although it is recommended for common Serial Recovery usage*
835
836---
837
838### [MCUMGR image upload example](#mcumgr-image-upload-example)
839
840After entering the Serial recovery mode on the device, MCUMGR can be used as following:
841
842Configure the connection:
843```bash
844mcumgr conn add esp type="serial" connstring="dev=<PORT>,baud=115200,mtu=256"
845```
846
847Upload the image (the process may take some time):
848```bash
849mcumgr -c esp image upload <IMAGE_BIN>
850```
851
852Reset the device:
853```bash
854mcumgr -c esp reset
855```
856
857---
858:warning: ***ATTENTION***
859
860*Serial recovery mode uploads the image to the PRIMARY_SLOT, therefore if the upload process gets
861interrupted the image may be corrupted and unable to boot*
862
863---
864
865## [Memory map organization for OS compatibility](#memory-map-organization-for-os-compatibility)
866
867When adding support for this MCUboot port to an OS or even customizing an already supported
868application memory layout, it is mandatory for the OS linker script to avoid overlaping on
869`iram_loader_seg` and `dram_seg` bootloader RAM regions. Although part of the RAM becomes initially
870unavailable, it is reclaimable by the OS after boot as heap.
871
872Therefore, the application must be designed aware of the bootloader memory usage.
873
874---
875***Note***
876
877*Mostly of the Espressif chips have a separation on the address space for the same physical memory
878ammount: IRAM (accessed by the instruction bus) and DRAM (accessed by the data bus), which means
879that they need to be accessed by different addresses ranges depending on type, but refer to the
880same region. More information on the
881[Espressif TRMs](https://www.espressif.com/en/support/documents/technical-documents?keys=&field_download_document_type_tid%5B%5D=963).*
882
883---
884
885The following diagrams illustrate a memory organization from the bootloader point of view (notice
886that the addresses and sizes may vary depending on the chip), they reflect the linker script
887`boot/espressif/port/<TARGET>/ld/bootloader.ld`:
888
889### ESP32
890
891#### ESP32 standard
892
893```
894  SRAM0
895                                     IRAM ADDR  / DRAM ADDR
896 *  +--------+--------------+------+ 0x40070000 / --------- - SRAM0 START
897 *  |        ^                    |
898 *  |        | PRO CPU Cache      |  *NOT CLAIMABLE BY OS RAM
899 *  |        v                    |
900 *  +--------+--------------+------+ 0x40078000 / ----------
901 *  |        ^                    |
902 *  |        |                    |  *NOT CLAIMABLE BY OS RAM
903 *  |        | iram_loader_seg    |  *Region usable as iram_loader_seg during boot
904 *  |        | (APP CPU Cache)    |   as APP CPU is not initialized yet
905 *  |        |                    |
906 *  |        v                    |
907 *  +--------+--------------+------+ 0x40080000 / ----------
908 *  |        ^                    |
909 *  |        | FREE               |  *CLAIMABLE BY OS RAM
910 *  |        v                    |
911 *  +------------------------------+ 0x40090000 / ----------
912 *  |        ^                    |
913 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
914 *  |        |                    |
915 *  |        v                    |
916 *  +--------+--------------+------+ 0x40099000 / ----------
917 *  |        | FREE               |  *CLAIMABLE BY OS RAM
918 *  +------------------------------+ 0x4009FFFF / ---------- - SRAM0 END
919
920  SRAM1
921                                     IRAM ADDR  / DRAM ADDR
922 *  +------------------------------+ 0x400A0000 / 0x3FFFFFFF - SRAM1 START
923 *  |        ^                    |
924 *  |        |                    |  *** SHOULD NOT BE OVERLAPPED ***
925 *  |        | dram_seg           |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
926 *  |        v                    |
927 *  +--------+--------------+------+ 0x400AB900 / 0x3FFF4700
928 *  |        ^                    |
929 *  |        |                    |
930 *  |        |                    |
931 *  |        | FREE               |  *CLAIMABLE BY OS RAM
932 *  |        |                    |
933 *  |        |                    |
934 *  |        v                    |
935 *  +--------+--------------+------+ 0x400BFFFF / 0x3FFE0000 - SRAM1 END
936 Note: On ESP32 the SRAM1 addresses are accessed in reverse order comparing Instruction
937 bus (IRAM) and Data bus (DRAM), but refer to the same location. See the TRM for more
938 information.
939
940  SRAM2
941                                     IRAM ADDR  / DRAM ADDR
942 *  +--------+--------------+------+ ---------- / 0x3FFAE000 - SRAM2 START
943 *  |        | FREE               |  *CLAIMABLE BY OS RAM
944 *  +--------+--------------+------+ ---------- / 0x3FFDFFFF - SRAM2 END
945```
946
947#### ESP32 Multi Processor Boot
948
949This is the linker script mapping when the `CONFIG_ESP_MULTI_PROCESSOR_BOOT` is enabled
950([Multi boot](#multi-boot)) since APP CPU Cache region cannot be used for `iram_loader_seg` region
951as there would be conflict when the bootloader starts the APP CPU before jump to the main
952application.
953
954```
955  SRAM0
956                                     IRAM ADDR  / DRAM ADDR
957 *  +--------+--------------+------+ 0x40070000 / --------- - SRAM0 START
958 *  |        ^                    |
959 *  |        |                    |
960 *  |        | Cache              |  *Used by PRO CPU and APP CPU as Cache
961 *  |        |                    |
962 *  |        v                    |
963 *  +--------+--------------+------+ 0x40080000 / ----------
964 *  |        ^                    |
965 *  |        | FREE               |  *CLAIMABLE BY OS RAM
966 *  |        v                    |
967 *  +------------------------------+ 0x40090000 / ----------
968 *  |        ^                    |
969 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
970 *  |        |                    |
971 *  |        v                    |
972 *  +--------+--------------+------+ 0x40099000 / ----------
973 *  |        | FREE               |  *CLAIMABLE BY OS RAM
974 *  +------------------------------+ 0x4009FFFF / ---------- - SRAM0 END
975
976  SRAM1
977                                     IRAM ADDR  / DRAM ADDR
978 *  +------------------------------+ 0x400A0000 / 0x3FFFFFFF - SRAM1 START
979 *  |        ^                    |
980 *  |        |                    |  *** SHOULD NOT BE OVERLAPPED ***
981 *  |        | dram_seg           |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
982 *  |        v                    |
983 *  +--------+--------------+------+ 0x400AB900 / 0x3FFF4700
984 *  |        ^                    |
985 *  |        |                    |  *** SHOULD NOT BE OVERLAPPED ***
986 *  |        | iram_loader_seg    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
987 *  |        |                    |
988 *  |        v                    |
989 *  +------------------------------+ 0x400B1E00 / 0x3FFEE200
990 *  |        ^                    |
991 *  |        |                    |
992 *  |        | FREE               |  *CLAIMABLE BY OS RAM
993 *  |        |                    |
994 *  |        v                    |
995 *  +--------+--------------+------+ 0x400BFFFF / 0x3FFE0000 - SRAM1 END
996 Note: On ESP32 the SRAM1 addresses are accessed in reverse order comparing Instruction
997 bus (IRAM) and Data bus (DRAM), but refer to the same location. See the TRM for more
998 information.
999
1000  SRAM2
1001                                     IRAM ADDR  / DRAM ADDR
1002 *  +--------+--------------+------+ ---------- / 0x3FFAE000 - SRAM2 START
1003 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1004 *  +--------+--------------+------+ ---------- / 0x3FFDFFFF - SRAM2 END
1005```
1006
1007### ESP32-S2
1008
1009```
1010  SRAM0
1011                                     IRAM ADDR  / DRAM ADDR
1012 *  +--------+--------------+------+ 0x40020000 / 0x3FFB0000 - SRAM0 START
1013 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1014 *  +--------+--------------+------+ 0x40027FFF / 0x3FFB7FFF - SRAM0 END
1015
1016  SRAM1
1017                                     IRAM ADDR  / DRAM ADDR
1018 *  +--------+--------------+------+ 0x40028000 / 0x3FFB8000 - SRAM1 START
1019 *  |        ^                    |
1020 *  |        |                    |
1021 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1022 *  |        |                    |
1023 *  |        v                    |
1024 *  +--------+--------------+------+ 0x40047000 / 0x3FFD7000
1025 *  |        ^                    |
1026 *  |        |                    |
1027 *  |        |                    |
1028 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
1029 *  |        |                    |
1030 *  |        |                    |
1031 *  |        v                    |
1032 *  +------------------------------+ 0x40050000 / 0x3FFE0000
1033 *  |        ^                    |
1034 *  |        |                    |
1035 *  |        |                    |
1036 *  |        | iram_loader_seg    |  *** SHOULD NOT BE OVERLAPPED ***
1037 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1038 *  |        |                    |
1039 *  |        v                    |
1040 *  +------------------------------+ 0x40056000 / 0x3FFE6000
1041 *  |        ^                    |
1042 *  |        |                    |
1043 *  |        | dram_seg           |  *** SHOULD NOT BE OVERLAPPED ***
1044 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1045 *  |        v                    |
1046 *  +--------+--------------+------+ 0x4006FFFF / 0x3FFFFFFF - SRAM1 END
1047```
1048
1049### ESP32-S3
1050
1051```
1052  SRAM0
1053                                     IRAM ADDR  / DRAM ADDR
1054 *  +--------+--------------+------+ 0x40370000 / ---------- - SRAM0 START
1055 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1056 *  +--------+--------------+------+ 0x40377FFF / ---------- - SRAM0 END
1057
1058  SRAM1
1059                                     IRAM ADDR  / DRAM ADDR
1060 *  +--------+--------------+------+ 0x40378000 / 0x3FC88000 - SRAM1 START
1061 *  |        ^                    |
1062 *  |        |                    |
1063 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1064 *  |        |                    |
1065 *  |        v                    |
1066 *  +--------+--------------+------+ 0x403B0000 / 0x3FCC0000
1067 *  |        ^                    |
1068 *  |        |                    |
1069 *  |        |                    |
1070 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
1071 *  |        |                    |
1072 *  |        |                    |
1073 *  |        v                    |
1074 *  +------------------------------+ 0x403BA000 / 0x3FCCA000
1075 *  |        ^                    |
1076 *  |        |                    |
1077 *  |        |                    |
1078 *  |        | iram_loader_seg    |  *** SHOULD NOT BE OVERLAPPED ***
1079 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1080 *  |        |                    |
1081 *  |        v                    |
1082 *  +------------------------------+ 0x403C0000 / 0x3FCD0000
1083 *  |        ^                    |
1084 *  |        |                    |
1085 *  |        | dram_seg           |  *** SHOULD NOT BE OVERLAPPED ***
1086 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1087 *  |        v                    |
1088 *  +--------+--------------+------+ 0x403DFFFF / 0x3FCEFFFF - SRAM1 END
1089
1090  SRAM2
1091                                     IRAM ADDR  / DRAM ADDR
1092 *  +--------+--------------+------+ ---------- / 0x3FCF0000 - SRAM2 START
1093 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1094 *  +--------+--------------+------+ ---------- / 0x3FCFFFFF - SRAM2 END
1095```
1096
1097### ESP32-C2
1098
1099```
1100  SRAM0
1101                                     IRAM ADDR  / DRAM ADDR
1102 *  +--------+--------------+------+ 0x4037C000 / ---------- - SRAM0 START
1103 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1104 *  +--------+--------------+------+ 0x4037FFFF / ---------- - SRAM0 END
1105
1106  SRAM1
1107                                     IRAM ADDR  / DRAM ADDR
1108 *  +--------+--------------+------+ 0x40380000 / 0x3FCA0000 - SRAM1 START
1109 *  |        ^                    |
1110 *  |        |                    |
1111 *  |        |                    |
1112 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1113 *  |        |                    |
1114 *  |        |                    |
1115 *  |        v                    |
1116 *  +--------+--------------+------+ 0x403A1370 / 0x3FCC1370
1117 *  |        ^                    |
1118 *  |        |                    |
1119 *  |        |                    |
1120 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
1121 *  |        |                    |
1122 *  |        |                    |
1123 *  |        v                    |
1124 *  +------------------------------+ 0x403A9B70 / 0x3FCC9B70
1125 *  |        ^                    |
1126 *  |        |                    |
1127 *  |        |                    |
1128 *  |        | iram_loader_seg    |  *** SHOULD NOT BE OVERLAPPED ***
1129 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1130 *  |        |                    |
1131 *  |        v                    |
1132 *  +------------------------------+ 0x403B0B70 / 0x3FCD0B70
1133 *  |        ^                    |
1134 *  |        |                    |
1135 *  |        | dram_seg           |  *** SHOULD NOT BE OVERLAPPED ***
1136 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1137 *  |        v                    |
1138 *  +--------+--------------+------+ 0x403BFFFF / 0x3FCDFFFF - SRAM1 END
1139```
1140
1141### ESP32-C3
1142
1143```
1144  SRAM0
1145                                     IRAM ADDR  / DRAM ADDR
1146 *  +--------+--------------+------+ 0x4037C000 / ---------- - SRAM0 START
1147 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1148 *  +--------+--------------+------+ 0x4037FFFF / ---------- - SRAM0 END
1149
1150  SRAM1
1151                                     IRAM ADDR  / DRAM ADDR
1152 *  +--------+--------------+------+ 0x40380000 / 0x3FC80000 - SRAM1 START
1153 *  |        ^                    |
1154 *  |        |                    |
1155 *  |        |                    |
1156 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1157 *  |        |                    |
1158 *  |        |                    |
1159 *  |        v                    |
1160 *  +--------+--------------+------+ 0x403C7000 / 0x3FCC7000
1161 *  |        ^                    |
1162 *  |        |                    |
1163 *  |        |                    |
1164 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
1165 *  |        |                    |
1166 *  |        |                    |
1167 *  |        v                    |
1168 *  +------------------------------+ 0x403D0000 / 0x3FCD0000
1169 *  |        ^                    |
1170 *  |        |                    |
1171 *  |        |                    |
1172 *  |        | iram_loader_seg    |  *** SHOULD NOT BE OVERLAPPED ***
1173 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1174 *  |        |                    |
1175 *  |        v                    |
1176 *  +------------------------------+ 0x403D5400 / 0x3FCD5400
1177 *  |        ^                    |
1178 *  |        |                    |
1179 *  |        | dram_seg           |  *** SHOULD NOT BE OVERLAPPED ***
1180 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1181 *  |        v                    |
1182 *  +--------+--------------+------+ 0x403DFFFF / 0x3FCDFFFF - SRAM1 END
1183```
1184
1185### ESP32-C6
1186
1187```
1188                                     IRAM ADDR  / DRAM ADDR
1189 *  +--------+--------------+------+ 0x40800000 / 0x40800000 - HP SRAM START
1190 *  |        ^                    |
1191 *  |        |                    |
1192 *  |        |                    |
1193 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1194 *  |        |                    |
1195 *  |        |                    |
1196 *  |        v                    |
1197 *  +--------+--------------+------+ 0x40860610 / 0x40860610
1198 *  |        ^                    |
1199 *  |        |                    |
1200 *  |        |                    |
1201 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
1202 *  |        |                    |
1203 *  |        |                    |
1204 *  |        v                    |
1205 *  +------------------------------+ 0x40869610 / 0x40869610
1206 *  |        ^                    |
1207 *  |        |                    |
1208 *  |        |                    |
1209 *  |        | iram_loader_seg    |  *** SHOULD NOT BE OVERLAPPED ***
1210 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1211 *  |        |                    |
1212 *  |        v                    |
1213 *  +------------------------------+ 0x40870610 / 0x40870610
1214 *  |        ^                    |
1215 *  |        |                    |
1216 *  |        | dram_seg           |  *** SHOULD NOT BE OVERLAPPED ***
1217 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1218 *  |        v                    |
1219 *  +--------+--------------+------+ 0x4087FFFF / 0x4087FFFF - HP SRAM END
1220```
1221
1222### ESP32-H2
1223
1224```
1225                                     IRAM ADDR  / DRAM ADDR
1226 *  +--------+--------------+------+ 0x40800000 / 0x40800000 - HP SRAM START
1227 *  |        ^                    |
1228 *  |        |                    |
1229 *  |        |                    |
1230 *  |        | FREE               |  *CLAIMABLE BY OS RAM
1231 *  |        |                    |
1232 *  |        |                    |
1233 *  |        v                    |
1234 *  +--------+--------------+------+ 0x408317D0 / 0x408317D0
1235 *  |        ^                    |
1236 *  |        |                    |
1237 *  |        |                    |
1238 *  |        | iram_seg           |  *CLAIMABLE BY OS RAM
1239 *  |        |                    |
1240 *  |        |                    |
1241 *  |        v                    |
1242 *  +------------------------------+ 0x40839FD0 / 0x40839FD0
1243 *  |        ^                    |
1244 *  |        |                    |
1245 *  |        |                    |
1246 *  |        | iram_loader_seg    |  *** SHOULD NOT BE OVERLAPPED ***
1247 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1248 *  |        |                    |
1249 *  |        v                    |
1250 *  +------------------------------+ 0x40840FD0 / 0x40840FD0
1251 *  |        ^                    |
1252 *  |        |                    |
1253 *  |        | dram_seg           |  *** SHOULD NOT BE OVERLAPPED ***
1254 *  |        |                    |  *** OS CAN RECLAIM IT AFTER BOOT LATER AS HEAP ***
1255 *  |        v                    |
1256 *  +--------+--------------+------+ 0x4084FFFF / 0x4084FFFF - HP SRAM END
1257```
1258

readme-mbed.md

1# MCUboot port for Mbed OS
2
3This is an MCUboot port for Mbed OS.
4
5## Using MCUboot
6
7Note: The following is a general overview. It does not cover MCUboot or Mbed OS basics.
8
9See https://github.com/AGlass0fMilk/mbed-mcuboot-demo as a detailed example.
10
11### Basic configurations
12
13To use MCUboot, you need to create an Mbed OS project with the following configurations:
14* `"mcuboot.primary-slot-address"`: address of the primary slot in the internal flash
15* `"mcuboot.slot-size"`: size of an image slot (only one image, two slots are currently supported)
16* `"mcuboot.max-img-sectors"`: maximum number of sectors, should be at least the number of sectors in each slot
17* `"target.restrict_size"`: the maximum size of the bootloader, such that it does not overlap with the primary slot
18
19More configurations such as signing algorithm, slot swapping, etc. can be found in [mbed_lib.json](https://github.com/mcu-tools/mcuboot/tree/main/boot/mbed/mbed_lib.json). Please note that certain features are not currently supported.
20
21### Providing a secondary slot
22
23You need to provide an instance of `mbed::BlockDevice` as the secondary slot. It can be any types of internal or external storage provided that:
24* Its size equals the `"mcuboot.slot-size"` you have set
25* Its minimum supported read and write sizes (granularities) are _no larger than_ 16 byte, which MCUboot's read/write operations are aligned to. If the read size is larger than _one byte_, you need to set `"mcuboot.read-granularity"` to the read size of the storage - this buffers smaller read operations.
26
27In order for MCUboot to access your secondary slot, the interface to implement is
28```cpp
29mbed::BlockDevice* get_secondary_bd(void);
30```
31which should return an uninitialized instance of BlockDevice.
32
33### Building the bootloader
34
35To build a bootloader based on MCUboot, make sure `"mcuboot.bootloader-build"` is `true` (already the default) and you have provided configurations and a secondary slot BlockDevice as explained above.
36
37### Building a user application
38
39To build a user application, set `"mcuboot.bootloader-build"` to `false` so MCUboot is built as a _library only_ without a bootloader application. This is useful if your user application needs to confirm the current image with `boot_set_confirmed()` after an update, or set a new image in the secondary slot as pending with `boot_set_pending()` in order to trigger an update upon reboot.
40
41As your application starts in the primary slots (instead of the beginning of the whole flash), you need to set the start address (`"target.mbed_app_start"`) to be equal to `"mcuboot.primary-slot-address"` + `"mcuboot.header-size"` of your bootloader. And its size (`"target.mbed_app_size"`) must be no larger than `"mcuboot.slot-size"` - `"mcuboot.header-size"`, and some space must be left for the image trailer too (see [this](design.md#image-trailer)).
42

readme-mynewt.md

1# Running mynewt apps with MCUboot
2
3Due to small differences between Mynewt's bundled bootloader and MCUboot,
4when building an app that will be run with MCUboot as the bootloader and
5which at the same time requires to use `newtmgr` to manage images, MCUboot
6must be added as a new dependency for this app.
7
8First you need to add the repo to your `project.yml`:
9
10```
11    project.repositories:
12        - mcuboot
13
14    repository.mcuboot:
15        type: github
16        vers: 0-dev
17        user: mcu-tools
18        repo: mcuboot
19```
20
21Then update your app's `pkg.yml` adding the extra dependency:
22
23```
24    pkg.deps:
25        - "@mcuboot/boot/bootutil"
26```
27
28Also remove any dependency on `boot/bootutil` (mynewt's bundled bootloader)
29which might exist.
30
31To configure MCUboot check all the options available in
32`boot/mynewt/mcuboot_config/syscfg.yml`.
33
34Also, MCUboot uses a different image header struct as well as slightly
35different TLV structure, so images created by `newt` have to be generated
36in this new format. That is done by passing the extra parameter `-2` as in:
37
38`newt create-image <target> <version> <pubkey> -2`
39
40# Boot serial functionality with Mynewt
41
42Building with `BOOT_SERIAL: 1` enables some basic management functionality
43like listing images and uploading a new image to `slot0`. The serial bootloader
44requires that `mtu` is set to a value that is less than or equal to `256`.
45This can be done either by editing `~/.newtmgr.cp.json` and setting the `mtu`
46for the connection profile, or specifying you connection string manually as in:
47
48```
49newtmgr --conntype serial --connstring "dev=/dev/ttyUSB0,mtu=256" image upload -e blinky.img
50```
51
52where `/dev/ttyUSB0` is your serial port.
53

readme-nuttx.md

1# MCUboot port for NuttX
2
3## Description
4
5The NuttX port of MCUboot secure boot library expects that the platform provides a Flash storage with the following partitions:
6- `CONFIG_MCUBOOT_PRIMARY_SLOT_PATH`: MTD partition for the application firmware image PRIMARY slot;
7- `CONFIG_MCUBOOT_SECONDARY_SLOT_PATH`: MTD partition for the application firmware image SECONDARY slot;
8- `CONFIG_MCUBOOT_SCRATCH_PATH`: MTD partition for the Scratch area;
9
10Also, these are optional features that may be enabled:
11
12- `CONFIG_MCUBOOT_WATCHDOG`: If `CONFIG_WATCHDOG` is enabled, MCUboot shall reset the watchdog timer indicated by `CONFIG_MCUBOOT_WATCHDOG_DEVPATH` to the current timeout value, preventing any imminent watchdog timeouts.
13
14The porting layer of MCUboot library consists of the following interfaces:
15- `<flash_map_backend/flash_map_backend.h>`, for enabling MCUboot to manage the application firmware image slots in the device storage.
16- `<mcuboot_config/mcuboot_config.h>`, for configuration of MCUboot's features.
17- `<mcuboot_config/mcuboot_logging.h>`, for providing logging capabilities.
18- `<os/os_malloc.h>`, for providing MCUboot access to the OS memory management interfaces.
19- `<sysflash/sysflash.h>`, for configuration of the system's flash area organization.
20
21The NuttX port of MCUboot is implemented at application-level and requires minimal knowledge about characteristics of the underlying storage device. This is achieved by means of the `BCH` and `FTL` subsystems, which enable MCUboot to manage MTD partitions via character device drivers using standard POSIX filesystem operations (e.g. `open()` / `close()` / `read()` / `write()`).
22
23## Creating MCUboot-compatible application firmware images
24
25One common use case for MCUboot is to integrate it to a firmware update agent, which is an important component of a secure firmware update subsystem. Through MCUboot APIs an application is able to install a newly received application firmware image and, once this application firmware image is assured to be valid, the application may confirm it as a stable image. In case that application firmware image is deemed bogus, MCUboot provides an API for invalidating that update, which will induce a rollback procedure to the most recent stable application firmware image.
26
27The `CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE` example demonstrates this workflow by downloading an application firmware image from a webserver, installing it and triggering the firmware update process for the next boot after a system reset. There is also the `CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE`, which is a fairly simple example that just calls an MCUboot API for confirming the executing application firmware image as stable.
28
29## Using MCUboot on NuttX as a secure boot solution
30
31NuttX port for MCUboot also enables the creation of a secure bootloader application requiring minimal platform-specific implementation. The logical implementation for the secure boot is performed at application-level by the MCUboot library. Once MCUboot validates the application firmware image, it delegates the loading and execution of the application firmware image to a platform-specific routine, which is accessed via `boardctl(BOARDIOC_BOOT_IMAGE)` call. Each platform must then provide an implementation for the `board_boot_image()` for executing the required actions in order to boot a new application firmware image (e.g. deinitialize peripherals, load the Program Counter register with the application firmware image entry point address).
32
33The MCUboot bootloader application may be enabled by selecting the `CONFIG_MCUBOOT_BOOTLOADER` option.
34
35## Assumptions
36
37### IOCTL MTD commands
38
39The implementation of `<flash_map_backend/flash_map_backend.h>` expects that the MTD driver for a given image partition handles the following `ioctl` commands:
40- `MTDIOC_GEOMETRY`, for retrieving information about the geometry of the MTD, required for the configuration of the size of each flash area.
41- `MTDIOC_ERASESTATE`, for retrieving the byte value of an erased cell of the MTD, required for the implementation of `flash_area_erased_val()` interface.
42
43### Write access alignment
44
45Through `flash_area_align()` interface MCUboot expects that the implementation provides the shortest data length that may be written via `flash_area_write()` interface. The NuttX implementation passes through the `BCH` and `FTL` layers, which appropriately handle the write alignment restrictions of the underlying MTD. So The NuttX implementation of `flash_area_align()` is able to return a fixed value of 1 byte, even if the MTD does not support byte operations.
46
47## Limitations
48
49### `<flash_map_backend/flash_map_backend.h>` functions are not multitasking-safe
50
51MCUboot's documentation imposes no restrictions regarding the usage of its public interfaces, which doesn't mean they are thread-safe.
52But, regarding NuttX implementation of the `<flash_map_backend/flash_map_backend.h>`, it is safe to state that they are **not** multitasking-safe. NuttX implementation manages the MTD partitions via character device drivers. As file-descriptors cannot be shared between different tasks, if one task calls `flash_area_open` and another task calls `flash_area_<read/write/close>` passing the same `struct flash_area` instance, it will result in failure.
53

readme-riot.md

1# Building and using MCUboot with RIOT
2
3MCUboot began its life as the bootloader for Mynewt.  It has since
4acquired the ability to be used as a bootloader for RIOT as well.
5Currently the support is limited to the nrf52dk platform.
6
7## Building the bootloader itself
8
9In this first version, a prebuilt Mynewt binary is downloaded at
10compile time.  This binary was compiled to do an integrity check, but
11not a signature check. In order to configure the bootloader for
12signature check it is necessary to re-compile it either with Mynewt
13or Zephyr, following the provided instructions.
14
15In the next version, it is planned to compile MCUboot using RIOT,
16which should be able to boot any of the supported OS images.
17
18## Building applications for the bootloader
19
20A compatible MCUboot image can be compiled by typing: `make mcuboot`.
21
22The only variable which needs to be set is `IMAGE_VERSION` loaded
23with a valid formatted value. The format is `major.minor.patch+other`
24(e.g. `export IMAGE_VERSION= 1.1.1+1`. This variable can be either
25exported in the Makefile or manually, prior to the compilation process.
26
27The goal is to produce an ELF file which is linked to be flashed at a
28`BOOTLOADER_OFFSET` offset rather than the beginning of ROM.  MCUboot
29also expects an image padded with some specific headers containing the
30version information, and trailer type-length-value records (TLVs) with
31hash and signing information. This is done through the imgtool.py
32application, which is executed automatically by the RIOT build system.
33
34### Signing the application
35
36The application will be automatically signed with the provided key.
37If no key is provided, a new key will be automatically generated. The
38default key type is RSA-2048.
39
40In order to use your provided key, you need to recompile the bootloader
41using you public key, either in Zephyr or Mynewt by following the
42provided procedure for the selected OS.
43
44### Flashing the application
45
46The application can be flashed by typing: `make flash-mcuboot`.
47This will flash both the bootloader and the application.
48

readme-zephyr.md

1# Building and using MCUboot with Zephyr
2
3MCUboot began its life as the bootloader for Mynewt.  It has since
4acquired the ability to be used as a bootloader for Zephyr as well.
5There are some pretty significant differences in how apps are built
6for Zephyr, and these are documented here.
7
8Please see the [design document](design.md) for documentation on the design
9and operation of the bootloader itself. This functionality should be the same
10on all supported RTOSs.
11
12The first step required for Zephyr is making sure your board has flash
13partitions defined in its device tree. These partitions are:
14
15- `boot_partition`: for MCUboot itself
16- `slot0_partition`: the primary slot of Image 0
17- `slot1_partition`: the secondary slot of Image 0
18
19It is not recommended to use the swap-using-scratch algorithm of MCUboot, but
20if this operating mode is desired then the following flash partition is also
21needed (see end of this help file for details on creating a scratch partition
22and how to use the swap-using-scratch algorithm):
23
24- `scratch_partition`: the scratch slot
25
26Currently, the two image slots must be contiguous. If you are running
27MCUboot as your stage 1 bootloader, `boot_partition` must be configured
28so your SoC runs it out of reset. If there are multiple updateable images
29then the corresponding primary and secondary partitions must be defined for
30the rest of the images too (for example, `slot2_partition` and
31`slot3_partition` for Image 1).
32
33The flash partitions are typically defined in the Zephyr boards folder, in a
34file named `boards/<arch>/<board>/<board>.dts`. An example `.dts` file with
35flash partitions defined is the frdm_k64f's in
36`boards/arm/frdm_k64f/frdm_k64f.dts`. Make sure the DT node labels in your board's
37`.dts` file match the ones used there.
38
39## Installing requirements and dependencies
40
41Install additional packages required for development with MCUboot:
42
43```
44  cd ~/mcuboot  # or to your directory where MCUboot is cloned
45  pip3 install --user -r scripts/requirements.txt
46```
47
48## Building the bootloader itself
49
50The bootloader is an ordinary Zephyr application, at least from
51Zephyr's point of view.  There is a bit of configuration that needs to
52be made before building it.  Most of this can be done as documented in
53the `CMakeLists.txt` file in boot/zephyr.  There are comments there for
54guidance.  It is important to select a signature algorithm, and decide
55if the primary slot should be validated on every boot.
56
57To build MCUboot, create a build directory in boot/zephyr, and build
58it as usual:
59
60```
61  cd boot/zephyr
62  west build -b <board>
63```
64
65In addition to the partitions defined in DTS, some additional
66information about the flash layout is currently required to build
67MCUboot itself. All the needed configuration is collected in
68`boot/zephyr/include/target.h`. Depending on the board, this information
69may come from board-specific headers, Device Tree, or be configured by
70MCUboot on a per-SoC family basis.
71
72After building the bootloader, the binaries should reside in
73`build/zephyr/zephyr.{bin,hex,elf}`, where `build` is the build
74directory you chose when running `west build`. Use `west flash`
75to flash these binaries from the build directory. Depending
76on the target and flash tool used, this might erase the whole of the flash
77memory (mass erase) or only the sectors where the bootloader resides prior to
78programming the bootloader image itself.
79
80## Building applications for the bootloader
81
82In addition to flash partitions in DTS, some additional configuration
83is required to build applications for MCUboot.
84
85This is handled internally by the Zephyr configuration system and is wrapped
86in the `CONFIG_BOOTLOADER_MCUBOOT` Kconfig variable, which must be enabled in
87the application's `prj.conf` file.
88
89The directory `samples/zephyr/hello-world` in the MCUboot tree contains
90a simple application with everything you need. You can try it on your
91board and then just make a copy of it to get started on your own
92application; see samples/zephyr/README.md for a tutorial.
93
94The Zephyr `CONFIG_BOOTLOADER_MCUBOOT` configuration option
95[documentation](https://docs.zephyrproject.org/latest/kconfig.html#CONFIG_BOOTLOADER_MCUBOOT)
96provides additional details regarding the changes it makes to the image
97placement and generation in order for an application to be bootable by MCUboot.
98
99With this, build the application as your normally would.
100
101### Signing the application
102
103In order to upgrade to an image (or even boot it, if
104`MCUBOOT_VALIDATE_PRIMARY_SLOT` is enabled), the images must be signed.
105To make development easier, MCUboot is distributed with some example
106keys.  It is important to stress that these should never be used for
107production, since the private key is publicly available in this
108repository.  See below on how to make your own signatures.
109
110Images can be signed with the `scripts/imgtool.py` script.  It is best
111to look at `samples/zephyr/Makefile` for examples on how to use this.
112
113### Flashing the application
114
115The application itself can flashed with regular flash tools, but will
116need to be programmed at the offset of the primary slot for this particular
117target. Depending on the platform and flash tool you might need to manually
118specify a flash offset corresponding to the primary slot starting address. This
119is usually not relevant for flash tools that use Intel Hex images (.hex) instead
120of raw binary images (.bin) since the former include destination address
121information. Additionally you will need to make sure that the flash tool does
122not perform a mass erase (erasing the whole of the flash) or else you would be
123deleting MCUboot.
124These images can also be marked for upgrade, and loaded into the secondary slot,
125at which point the bootloader should perform an upgrade.  It is up to
126the image to mark the primary slot as "image ok" before the next reboot,
127otherwise the bootloader will revert the application.
128
129## Managing signing keys
130
131The signing keys used by MCUboot are represented in standard formats,
132and can be generated and processed using conventional tools.  However,
133`scripts/imgtool.py` is able to generate key pairs in all of the
134supported formats.  See [the docs](imgtool.md) for more details on
135this tool.
136
137### Generating a new keypair
138
139Generating a keypair with imgtool is a matter of running the keygen
140subcommand:
141
142```
143    $ ./scripts/imgtool.py keygen -k mykey.pem -t rsa-2048
144```
145
146The argument to `-t` should be the desired key type.  See the
147[the docs](imgtool.md) for more details on the possible key types.
148
149### Extracting the public key
150
151The generated keypair above contains both the public and the private
152key.  It is necessary to extract the public key and insert it into the
153bootloader.  Use the ``CONFIG_BOOT_SIGNATURE_KEY_FILE`` Kconfig option to
154provide the path to the key file so the build system can extract
155the public key in a format usable by the C compiler.
156The generated public key is saved in `build/zephyr/autogen-pubkey.h`, which is included
157by the `boot/zephyr/keys.c`.
158
159Currently, the Zephyr RTOS port limits its support to one keypair at the time,
160although MCUboot's key management infrastructure supports multiple keypairs.
161
162Once MCUboot is built, this new keypair file (`mykey.pem` in this
163example) can be used to sign images.
164
165## Using swap-using-scratch flash algorithm
166
167To use the swap-using-scratch flash algorithm, a scratch partition needs to be
168present for the target board which is used for holding the data being swapped
169from both slots, this section must be at least as big as the largest sector
170size of the 2 partitions (e.g. if a device has a primary slot in main flash
171with a sector size of 512 bytes and secondar slot in external off-chip flash
172with a sector size of 4KB then the scratch area must be at least 4KB in size).
173The number of sectors must also be evenly divisable by this sector size, e.g.
1744KB, 8KB, 12KB, 16KB are allowed, 7KB, 7.5KB are not. This scratch partition
175needs adding to the .dts file for the board, e.g. for the nrf52dk_nrf52832
176board thus would involve updating
177`<zephyr>/boards/nordic/nrf52dk/nrf52dk_nrf52832.dts` with:
178
179```
180    boot_partition: partition@0 {
181        label = "mcuboot";
182        reg = <0x00000000 0xc000>;
183    };
184    slot0_partition: partition@c000 {
185        label = "image-0";
186        reg = <0x0000C000 0x37000>;
187    };
188    slot1_partition: partition@43000 {
189        label = "image-1";
190        reg = <0x00043000 0x37000>;
191    };
192    scratch_partition: partition@7a000 {
193        label = "image-scratch";
194        reg = <0x0007a000 0x00006000>;
195    };
196```
197
198Which would make the application size 220KB and scratch size 24KB (the nRF52832
199has a 4KB sector size so the size of the scratch partition can be reduced at
200the cost of vastly reducing flash lifespan, e.g. for a 32KB firmware update
201with an 8KB scratch area, the scratch area would be erased and programmed 8
202times per image upgrade/revert). To configure MCUboot to work in
203swap-using-scratch mode, the Kconfig value must be set when building it:
204`CONFIG_BOOT_SWAP_USING_SCRATCH=y`.
205
206Note that it is possible for an application to get into a stuck state when
207swap-using-scratch is used whereby an application has loaded a firmware update
208and marked it as test/confirmed but MCUboot will not swap the images and
209erasing the secondary slot from the zephyr application returns an error
210because the slot is marked for upgrade.
211
212## Serial recovery
213
214### Interface selection
215
216A serial recovery protocol is available over either a hardware serial port or a USB CDC ACM virtual serial port.
217The SMP server implementation can be enabled by the ``CONFIG_MCUBOOT_SERIAL=y`` Kconfig option.
218To set a type of an interface, use the ``BOOT_SERIAL_DEVICE`` Kconfig choice, and select either the ``CONFIG_BOOT_SERIAL_UART`` or the ``CONFIG_BOOT_SERIAL_CDC_ACM`` value.
219Which interface belongs to the protocol shall be set by the devicetree-chosen node:
220- `zephyr,console` - If a hardware serial port is used.
221- `zephyr,cdc-acm-uart` - If a virtual serial port is used.
222
223### Entering the serial recovery mode
224
225To enter the serial recovery mode, the device has to initiate rebooting, and a triggering event has to occur (for example, pressing a button).
226
227By default, the serial recovery GPIO pin active state enters the serial recovery mode.
228Use the ``mcuboot_button0`` devicetree button alias to assign the GPIO pin to the MCUboot.
229
230Alternatively, MCUboot can wait for a limited time to check if DFU is invoked by receiving an MCUmgr command.
231Select ``CONFIG_BOOT_SERIAL_WAIT_FOR_DFU=y`` to use this mode. ``CONFIG_BOOT_SERIAL_WAIT_FOR_DFU_TIMEOUT`` option defines
232the amount of time in milliseconds the device will wait for the trigger.
233
234### Direct image upload
235
236By default, the SMP server implementation will only use the first slot.
237To change it, invoke the `image upload` MCUmgr command with a selected image number, and make sure the ``CONFIG_MCUBOOT_SERIAL_DIRECT_IMAGE_UPLOAD=y`` Kconfig option is enabled.
238Note that the ``CONFIG_UPDATEABLE_IMAGE_NUMBER`` Kconfig option adjusts the number of image-pairs supported by the MCUboot.
239
240The mapping of image number to partition is as follows:
241* 0 and 1 - image-0, the primary slot of the first image.
242* 2 - image-1, the secondary slot of the first image.
243* 3 - image-2.
244* 4 - image-3.
245
2460 is a default upload target when no explicit selection is done.
247
248### System-specific commands
249
250Use the ``CONFIG_ENABLE_MGMT_PERUSER=y`` Kconfig option to enable the following additional commands:
251* Storage erase - This command allows erasing the storage partition (enable with ``CONFIG_BOOT_MGMT_CUSTOM_STORAGE_ERASE=y``).
252* Custom image list - This command allows fetching version and installation status (custom properties) for all images (enable with ``CONFIG_BOOT_MGMT_CUSTOM_IMG_LIST=y``).
253
254### More configuration
255
256For details on other available configuration options for the serial recovery protocol, check the Kconfig options  (for example by using ``menuconfig``).
257