1# [Building and using MCUboot with Espressif's chips](#building-and-using-mcuboot-with-espressifs-chips) 2 3The Espressif port is build on top of ESP-IDF HAL, therefore it is required in order to build MCUboot for Espressif SoCs. 4 5Documentation about the MCUboot bootloader design, operation and features can be found in the [design document](design.md). 6 7## [SoC support availability](#soc-support-availability) 8 9The current port is available for use in the following SoCs within the OSes: 10 11| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | 12| :-----: | :-----: | :-----: | :-----: | :-----: | 13| Zephyr | Supported | Supported | Supported | WIP | 14| NuttX | Supported | Supported | Supported | WIP | 15 16## [Installing requirements and dependencies](#installing-requirements-and-dependencies) 17 181. Install additional packages required for development with MCUboot: 19```bash 20 cd ~/mcuboot # or to your directory where MCUboot is cloned 21``` 22```bash 23 pip3 install --user -r scripts/requirements.txt 24``` 25 262. Update the submodules needed by the Espressif port. This may take a while. 27```bash 28git submodule update --init --recursive --checkout boot/espressif/hal/esp-idf 29``` 30 313. Next, get the Mbed TLS submodule required by MCUboot. 32```bash 33git submodule update --init --recursive ext/mbedtls 34``` 35 364. Now we need to install IDF dependencies and set environment variables. This step may take some time: 37```bash 38cd boot/espressif/hal/esp-idf 39``` 40```bash 41./install.sh 42``` 43```bash 44. ./export.sh 45``` 46```bash 47cd ../.. 48``` 49 50## [Building the bootloader itself](#building-the-bootloader-itself) 51 52The MCUboot Espressif port bootloader is built using the toolchain and tools provided by ESP-IDF. Additional configuration related to MCUboot features and slot partitioning may be made using the `port/<TARGET>/bootloader.conf` file or passing a custom config file using the `-DMCUBOOT_CONFIG_FILE` argument on the first step below. 53 54--- 55***Note*** 56 57*Replace `<TARGET>` with the target ESP32 family (like `esp32`, `esp32s2` and others).* 58 59--- 60 611. Compile and generate the BIN: 62```bash 63cmake -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-<TARGET>.cmake -DMCUBOOT_TARGET=<TARGET> -DMCUBOOT_FLASH_PORT=<PORT> -B build -GNinja 64``` 65```bash 66ninja -C build/ 67``` 68 692. Flash MCUboot in your device: 70```bash 71ninja -C build/ flash 72``` 73 74If `MCUBOOT_FLASH_PORT` arg was not passed to `cmake`, the default `PORT` for flashing will be `/dev/ttyUSB0`. 75 76Alternatively: 77```bash 78esptool.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 79``` 80--- 81***Note*** 82 83You may adjust the port `<PORT>` (like `/dev/ttyUSB0`) and baud rate `<BAUD>` (like `2000000`) according to the connection with your board. 84You can also skip `<PORT>` and `<BAUD>` parameters so that esptool tries to automatically detect it. 85 86*`<FLASH_SIZE>` can be found using the command below:* 87```bash 88esptool.py -p <PORT> -b <BAUD> flash_id 89``` 90The output contains device information and its flash size: 91``` 92Detected flash size: 4MB 93``` 94 95 96*`<BOOTLOADER_FLASH_OFFSET>` value must follow one of the addresses below:* 97 98| ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | 99| :-----: | :-----: | :-----: | :-----: | 100| 0x1000 | 0x1000 | 0x0000 | 0x0000 | 101 102--- 103 1043. Reset your device 105 106## [Signing and flashing an application](#signing-and-flashing-an-application) 107 1081. Images can be regularly signed with the `scripts/imgtool.py` script: 109```bash 110imgtool.py sign --align 4 -v 0 -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN> 111``` 112 113--- 114 115***Note*** 116 117`<SLOT_SIZE>` is the size of the slot to be used. 118Default slot0 size is `0x100000`, but it can change as per application flash partitions. 119 120For Zephyr images, `--pad-header` is not needed as it already has the padding for MCUboot header. 121 122--- 123 124:warning: ***ATTENTION*** 125 126*This is the basic signing needed for adding MCUboot headers and trailers. 127For signing with a crypto key and guarantee the authenticity of the image being booted, see the section [MCUboot image signature verification](#mcuboot-image-signature-verification) below.* 128 129--- 130 1312. Flash the signed application: 132```bash 133esptool.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> 134``` 135 136# [Downgrade prevention](#downgrade-prevention) 137 138Downgrade prevention (avoid updating of images to an older version) can be enabled using the following configuration: 139 140``` 141CONFIG_ESP_DOWNGRADE_PREVENTION=y 142``` 143 144MCUboot will then verify and compare the new image version number with the current one before perform an update swap. 145 146Version number is added to the image when signing it with `imgtool` (`-v` parameter, e.g. `-v 1.0.0`). 147 148### [Downgrade prevention with security counter](#downgrade-prevention-with-security-counter) 149 150It is also possible to rely on a security counter, also added to the image when signing with `imgtool` (`-s` parameter), apart from version number. This allows image downgrade at some extent, since any update must have greater or equal security counter value. Enable using the following configuration: 151 152``` 153CONFIG_ESP_DOWNGRADE_PREVENTION_SECURITY_COUNTER=y 154``` 155 156E.g.: if the current image was signed using `-s 1` parameter, an eventual update image must have been signed using security counter `-s 1` or greater. 157 158# [Security Chain on Espressif port](#security-chain-on-espressif-port) 159 160[MCUboot encrypted images](encrypted_images.md) do not provide full code confidentiality when only external storage is available (see [Threat model](encrypted_images.md#threat-model)) since by MCUboot design the image in Primary Slot, from where the image is executed, is stored plaintext. 161Espressif chips have off-chip flash memory, so to ensure a security chain along with MCUboot image signature verification, the hardware-assisted Secure Boot and Flash Encryption were made available on the MCUboot Espressif port. 162 163## [MCUboot image signature verification](#mcuboot-image-signature-verification) 164 165The image that MCUboot is booting can be signed with 4 types of keys: RSA-2048, RSA-3072, EC256 and ED25519. In order to enable the feature, the **bootloader** must be compiled with the following configurations: 166 167--- 168***Note*** 169 170*It is strongly recommended to generate a new signing key using `imgtool` instead of use the existent samples.* 171 172--- 173 174#### For EC256 algorithm use 175``` 176CONFIG_ESP_SIGN_EC256=y 177 178# Use Tinycrypt lib for EC256 or ED25519 signing 179CONFIG_ESP_USE_TINYCRYPT=y 180 181CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem> 182``` 183 184#### For ED25519 algorithm use 185``` 186CONFIG_ESP_SIGN_ED25519=y 187 188# Use Tinycrypt lib for EC256 or ED25519 signing 189CONFIG_ESP_USE_TINYCRYPT=y 190 191CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem> 192``` 193 194#### For RSA (2048 or 3072) algorithm use 195``` 196CONFIG_ESP_SIGN_RSA=y 197# RSA_LEN is 2048 or 3072 198CONFIG_ESP_SIGN_RSA_LEN=<RSA_LEN> 199 200# Use Mbed TLS lib for RSA image signing 201CONFIG_ESP_USE_MBEDTLS=y 202 203CONFIG_ESP_SIGN_KEY_FILE=<YOUR_SIGNING_KEY.pem> 204``` 205 206Notice that the public key will be embedded in the bootloader code, since the hardware key storage is not supported by Espressif port. 207 208### [Signing the image](#signing-the-image) 209 210Now you need to sign the **image binary**, use the `imgtool` with `-k` parameter: 211```bash 212imgtool.py sign -k <YOUR_SIGNING_KEY.pem> --pad --pad-sig --align 4 -v 0 -H 32 --pad-header -S 0x00100000 <BIN_IN> <BIN_OUT> 213``` 214If signing a Zephyr image, the `--pad-header` is not needed, as it already have the padding for MCUboot header. 215 216 217## [Secure Boot](#secure-boot) 218 219The Secure Boot implementation is based on [IDF's Secure Boot V2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/secure-boot-v2.html), is hardware-assisted and RSA based, and has the role for ensuring that only authorized code will be executed on the device. This is done through bootloader signature checking by the ROM bootloader. \ 220***Note***: ROM bootloader is the First Stage Bootloader, while the Espressif MCUboot port is the Second Stage Bootloader. 221 222### [Building bootloader with Secure Boot](#building-bootloader-with-secure-boot) 223 224In order to build the bootloader with the feature on, the following configurations must be enabled: 225``` 226CONFIG_SECURE_BOOT=1 227CONFIG_SECURE_BOOT_V2_ENABLED=1 228CONFIG_SECURE_SIGNED_ON_BOOT=1 229CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME=1 230CONFIG_SECURE_BOOT_SUPPORTS_RSA=1 231``` 232 233--- 234:warning: ***ATTENTION*** 235 236*On development phase is recommended add the following configuration in order to keep the debugging enabled and also to avoid any unrecoverable/permanent state change:* 237``` 238CONFIG_SECURE_BOOT_ALLOW_JTAG=1 239CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1 240 241# Options for enabling eFuse emulation in Flash 242CONFIG_EFUSE_VIRTUAL=1 243CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1 244``` 245 246--- 247 248--- 249:warning: ***ATTENTION*** 250 251*You can disable UART Download Mode by adding the following configuration:* 252``` 253CONFIG_SECURE_DISABLE_ROM_DL_MODE=1 254``` 255 256*This may be suitable for **production** builds. **After disabling UART Download Mode you will not be able to flash other images through UART.*** 257 258*Otherwise, you can switch the UART ROM Download Mode to the Secure Download Mode. It will limit the use of Download Mode functions to simple flash read, write and erase operations.* 259``` 260CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1 261``` 262 263*Once the device makes its first full boot, these configurations cannot be reverted* 264 265--- 266 267Once the **bootloader image** is built, the resulting binary file is required to be signed with `espsecure.py` tool. 268 269First create a signing key: 270```bash 271espsecure.py generate_signing_key --version 2 <BOOTLOADER_SIGNING_KEY.pem> 272``` 273 274Then sign the bootloader image: 275```bash 276espsecure.py sign_data --version 2 --keyfile <BOOTLOADER_SIGNING_KEY.pem> -o <BOOTLOADER_BIN_OUT> <BOOTLOADER_BIN_IN> 277``` 278 279--- 280:warning: ***ATTENTION*** 281 282*Once the bootloader is flashed and the device resets, the **first boot will enable Secure Boot** and the bootloader and key **no longer can be modified**. So **ENSURE** that both bootloader and key are correct and you did not forget anything before flashing.* 283 284--- 285 286Flash the bootloader as following, with `--after no_reset` flag, so you can reset the device only when assured: 287```bash 288esptool.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> 289``` 290 291### [Secure Boot Process](#secure-boot-process) 292 293Secure boot uses a signature block appended to the bootloader image in order to verify the authenticity. The signature block contains the RSA-3072 signature of that image and the RSA-3072 public key. 294 295On its **first boot** the Secure Boot is not enabled on the device eFuses yet, neither the key nor digests. So the first boot will have the following process: 296 2971. On startup, since it is the first boot, the ROM bootloader will not verify the bootloader image (the Secure Boot bit in the eFuse is disabled) yet, so it proceeds to execute it (our MCUboot bootloader port). 2982. Bootloader calculates the SHA-256 hash digest of the public key and writes the result to eFuse. 2993. Bootloader validates the application images and prepare the booting process (MCUboot phase). 3004. Bootloader burns eFuse to enable Secure Boot V2. 3015. Bootloader proceeds to load the Primary image. 302 303After that the Secure Boot feature is permanently enabled and on every next boot the ROM bootloader will verify the MCUboot bootloader image. 304The process of an usual boot: 305 3061. On startup, the ROM bootloader checks the Secure Boot enable bit in the eFuse. If it is enabled, the boot will proceed as following. 3072. ROM bootloader verifies the bootloader's signature block integrity (magic number and CRC). Interrupt boot if it fails. 3083. ROM bootloader verifies the bootloader image, interrupt boot if any step fails.: \ 3093.1. Compare the SHA-256 hash digest of the public key embedded in the bootloader’s signature block with the digest saved in the eFuses. \ 3103.2. Generate the application image digest and match it with the image digest in the signature block. \ 3113.3. Use the public key to verify the signature of the bootloader image, using RSA-PSS with the image digest calculated from previous step for comparison. 3124. ROM bootloader executes the bootloader image. 3135. Bootloader does the usual verification (MCUboot phase). 3146. Proceeds to boot the Primary image. 315 316## [Flash Encryption](#flash-encryption) 317 318The Espressif Flash Encryption is hardware-assisted, transparent to the MCUboot process and is an additional security measure beyond MCUboot existent features. 319The Flash Encryption implementation is also based on [IDF](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/security/flash-encryption.html) and is intended for encrypting off-chip flash memory contents, so it is protected against physical reading. 320 321When enabling the Flash Encryption, the user can encrypt the content either using a **device generated key** (remains unknown and unreadable) or a **host generated key** (owner is responsible for keeping the key private and safe). After the flash encryption gets enabled through eFuse burning on the device, all read and write operations are decrypted/encrypted in runtime. 322 323### [Building bootloader with Flash Encryption](#building-bootloader-with-flash-encryption) 324 325In order to build the bootloader with the feature on, the following configurations must be enabled: 326 327For **release mode**: 328``` 329CONFIG_SECURE_FLASH_ENC_ENABLED=1 330CONFIG_SECURE_FLASH_ENCRYPTION_MODE_RELEASE=1 331``` 332 333For **development mode**: 334``` 335CONFIG_SECURE_FLASH_ENC_ENABLED=1 336CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=1 337``` 338 339--- 340:warning: ***ATTENTION*** 341 342*On development phase is strongly recommended adding the following configuration in order to keep the debugging enabled and also to avoid any unrecoverable/permanent state change:* 343``` 344CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=1 345CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=1 346CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=1 347CONFIG_SECURE_BOOT_ALLOW_JTAG=1 348 349# Options for enabling eFuse emulation in Flash 350CONFIG_EFUSE_VIRTUAL=1 351CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=1 352``` 353--- 354 355--- 356:warning: ***ATTENTION*** 357 358*Unless the recommended flags for **DEVELOPMENT MODE** were enabled, the actions made by Flash Encryption process are **PERMANENT**.* \ 359*Once the bootloader is flashed and the device resets, the **first boot will enable Flash Encryption, encrypt the flash content including bootloader and image slots, burn the eFuses that no longer can be modified** and if device generated the key **it will not be recoverable**.* \ 360*When on **RELEASE MODE**, **ENSURE** that the application with an update agent is flashed before reset the device.* 361 362*In the same way as Secure Boot feature, you can disable UART Download Mode by adding the following configuration:* 363``` 364CONFIG_SECURE_DISABLE_ROM_DL_MODE=1 365``` 366 367*This may be suitable for **production** builds. **After disabling UART Download Mode you will not be able to flash other images through UART.*** 368 369*Otherwise, you can switch the UART Download Mode to the Secure Download Mode. It will limit the use of Download Mode functions to simple flash read, write and erase operations.* 370``` 371CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=1 372``` 373 374*These configurations cannot be reverted after the device's first boot* 375 376--- 377 378### [Signing the image when working with Flash Encryption](#signing-the-image-when-working-with-flash-encryption) 379 380When enabling flash encryption, it is required to signed the image using 32-byte alignment: `--align 32 --max-align 32`. 381 382Command example: 383```bash 384imgtool.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> 385``` 386 387### [Device generated key](#device-generated-key) 388 389First ensure that the application image is able to perform encrypted read and write operations to the SPI Flash. 390Flash the bootloader and application normally: 391```bash 392esptool.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> 393``` 394```bash 395esptool.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> 396``` 397 398On the **first boot**, the bootloader will: 3991. Generate Flash Encryption key and write to eFuse. 4002. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch. 4013. Burn eFuse to enable Flash Encryption. 4024. Reset system to ensure Flash Encryption cache resets properly. 403 404### [Host generated key](#host-generated-key) 405 406First ensure that the application image is able to perform encrypted read and write operations to the SPI Flash. Also ensure that the **UART ROM Download Mode is not disabled** - or that the **Secure Download Mode is enabled**. 407Before flashing, generate the encryption key using `espsecure.py` tool: 408```bash 409espsecure.py generate_flash_encryption_key <FLASH_ENCRYPTION_KEY.bin> 410``` 411 412Burn the key into the device's eFuse (keep a copy on the host), this action can be done **only once**: 413 414--- 415:warning: ***ATTENTION*** 416 417*eFuse emulation in Flash configuration options do not have any effect, so if the key burning command below is used, it will actually burn the physical eFuse.* 418 419--- 420 421- ESP32 422```bash 423espefuse.py --port PORT burn_key flash_encryption <FLASH_ENCRYPTION_KEY.bin> 424``` 425 426- ESP32S2, ESP32C3 and ESP32S3 427```bash 428espefuse.py --port PORT burn_key BLOCK <FLASH_ENCRYPTION_KEY.bin> <KEYPURPOSE> 429``` 430 431BLOCK is a free keyblock between BLOCK_KEY0 and BLOCK_KEY5. And KEYPURPOSE is either XTS_AES_128_KEY, XTS_AES_256_KEY_1, XTS_AES_256_KEY_2 (AES XTS 256 is available only in ESP32S2). 432 433Now, similar as the Device generated key, the bootloader and application can be flashed plaintext. The **first boot** will encrypt the flash content using the host key burned in the eFuse instead of generate a new one. 434 435Flashing the bootloader and application: 436```bash 437esptool.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> 438``` 439```bash 440esptool.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> 441``` 442 443On the **first boot**, the bootloader will: 4441. Encrypt flash in-place including bootloader, image primary/secondary slot and scratch using the written key. 4452. Burn eFuse to enable Flash Encryption. 4463. Reset system to ensure Flash Encryption cache resets properly. 447 448Encrypting data on the host: 449- ESP32 450```bash 451espsecure.py encrypt_flash_data --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA> 452``` 453 454- ESP32-S2, ESP32-C3 and ESP32-S3 455```bash 456espsecure.py encrypt_flash_data --aes_xts --keyfile <FLASH_ENCRYPTION_KEY.bin> --address <FLASH_OFFSET> --output <OUTPUT_DATA> <INPUT_DATA> 457``` 458 459--- 460***Note*** 461 462OTA updates are required to be sent plaintext. The reason is that, as said before, after the Flash Encryption is enabled all read/write operations are decrypted/encrypted in runtime, so as e.g. if pre-encrypted data is sent for an OTA update, it would be wrongly double-encrypted when the update agent writes to the flash. 463 464For updating with an image encrypted on the host, flash it through serial using `esptool.py` as above. **UART ROM Download Mode must not be disabled**. 465 466--- 467 468## [Security Chain scheme](#security-chain-scheme) 469 470Using the 3 features, Secure Boot, Image signature verification and Flash Encryption, a Security Chain can be established so only trusted code is executed, and also the code and content residing in the off-chip flash are protected against undesirable reading. 471 472The overall final process when all features are enabled: 4731. ROM bootloader validates the MCUboot bootloader using RSA signature verification. 4742. MCUboot bootloader validates the image using the chosen algorithm EC256/RSA/ED25519. It also validates an upcoming image when updating. 4753. Flash Encryption guarantees that code and data are not exposed. 476 477### [Size Limitation](#size-limitation) 478 479When all 3 features are enable at same time, the bootloader size may exceed the fixed limit for the ROM bootloader checking on the Espressif chips **depending on which algorithm** was chosen for MCUboot image signing. The issue https://github.com/mcu-tools/mcuboot/issues/1262 was created to track this limitation. 480 481## [Multi image](#multi-image) 482 483The multi image feature (currently limited to 2 images) allows the images to be updated separately (each one has its own primary and secondary slot) by MCUboot. 484 485The Espressif port bootloader handles the boot in two different approaches: 486 487### [Host OS boots second image](#host-os-boots-second-image) 488 489Host OS from the *first image* is responsible for booting the *second image*, therefore the bootloader is aware of the second image regions and can update it, however it does not load neither boots it. 490 491Configuration example (`bootloader.conf`): 492``` 493CONFIG_ESP_BOOTLOADER_SIZE=0xF000 494CONFIG_ESP_MCUBOOT_WDT_ENABLE=y 495 496# Enables multi image, if it is not defined, its assumed 497# only one updatable image 498CONFIG_ESP_IMAGE_NUMBER=2 499 500# Example of values to be used when multi image is enabled 501# Notice that the OS layer and update agent must be aware 502# of these regions 503CONFIG_ESP_APPLICATION_SIZE=0x50000 504CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000 505CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000 506CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000 507CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000 508CONFIG_ESP_SCRATCH_OFFSET=0x150000 509CONFIG_ESP_SCRATCH_SIZE=0x40000 510``` 511 512### [Multi boot](#multi-boot) 513 514In the multi boot approach the bootloader is responsible for booting two different images in two different CPUs, firstly the *second image* on the APP CPU and then the *first image* on the PRO CPU (current CPU), it is also responsible for update both images as well. Thus multi boot will be only supported by Espressif multi core chips - currently only ESP32 is implemented. 515 516--- 517***Note*** 518 519*The host OSes in each CPU must handle how the resources are divided/controlled between then.* 520 521--- 522 523Configuration example: 524``` 525CONFIG_ESP_BOOTLOADER_SIZE=0xF000 526CONFIG_ESP_MCUBOOT_WDT_ENABLE=y 527 528# Enables multi image, if it is not defined, its assumed 529# only one updatable image 530CONFIG_ESP_IMAGE_NUMBER=2 531 532# Enables multi image boot on independent processors 533# (main host OS is not responsible for booting the second image) 534# Use only with CONFIG_ESP_IMAGE_NUMBER=2 535CONFIG_ESP_MULTI_PROCESSOR_BOOT=y 536 537# Example of values to be used when multi image is enabled 538# Notice that the OS layer and update agent must be aware 539# of these regions 540CONFIG_ESP_APPLICATION_SIZE=0x50000 541CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS=0x10000 542CONFIG_ESP_IMAGE0_SECONDARY_START_ADDRESS=0x60000 543CONFIG_ESP_IMAGE1_PRIMARY_START_ADDRESS=0xB0000 544CONFIG_ESP_IMAGE1_SECONDARY_START_ADDRESS=0x100000 545CONFIG_ESP_SCRATCH_OFFSET=0x150000 546CONFIG_ESP_SCRATCH_SIZE=0x40000 547``` 548 549### [Image version dependency](#image-version-dependency) 550 551MCUboot allows version dependency check between the images when updating them. As `imgtool.py` allows a version assigment when signing an image, it is also possible to add the version dependency constraint: 552```bash 553imgtool.py sign --align 4 -v <VERSION> -d "(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)" -H 32 --pad-header -S <SLOT_SIZE> <BIN_IN> <SIGNED_BIN> 554``` 555 556- `<VERSION>` defines the version of the image being signed. 557- `"(<IMAGE_INDEX>, <VERSION_DEPENDENCY>)"` defines the minimum version and from which image is needed to satisfy the dependency. 558 559--- 560Example: 561```bash 562imgtool.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 563``` 564 565Supposing that the image 0 is being signed, its version is 1.0.0 and it depends on image 1 with version at least 0.0.1+0. 566 567--- 568 569## [Serial recovery mode](#serial-recovery-mode) 570 571Serial recovery mode allows management through MCUMGR (more information and how to install it: https://github.com/apache/mynewt-mcumgr-cli) for communicating and uploading a firmware to the device. 572 573Configuration example: 574``` 575# Enables the MCUboot Serial Recovery, that allows the use of 576# MCUMGR to upload a firmware through the serial port 577CONFIG_ESP_MCUBOOT_SERIAL=y 578# GPIO used to boot on Serial Recovery 579CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=32 580# GPIO input type (0 for Pull-down, 1 for Pull-up) 581CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0 582# GPIO signal value 583CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1 584# Delay time for identify the GPIO signal 585CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5 586# UART port used for serial communication 587CONFIG_ESP_SERIAL_BOOT_UART_NUM=1 588# GPIO for Serial RX signal 589CONFIG_ESP_SERIAL_BOOT_GPIO_RX=25 590# GPIO for Serial TX signal 591CONFIG_ESP_SERIAL_BOOT_GPIO_TX=26 592``` 593 594When enabled, the bootloader checks the if the GPIO `<CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT>` configured has the signal value `<CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL>` for approximately `<CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S>` seconds for entering the Serial recovery mode. Example: a button configured on GPIO 32 pressed for 5 seconds. 595 596Serial mode then uses the UART port configured for communication (`<CONFIG_ESP_SERIAL_BOOT_UART_NUM>`, pins `<CONFIG_ESP_SERIAL_BOOT_GPIO_RX>`, `<CONFIG_ESP_SERIAL_BOOT_GPIO_RX>`). 597 598### [Serial Recovery through USB JTAG Serial port](#serial-recovery-through-usb-jtag-serial-port) 599 600Some chips, like ESP32-C3 and ESP32-S3 have an integrated USB JTAG Serial Controller that implements a serial port (CDC) that can also be used for handling MCUboot Serial Recovery. 601More information about the USB pins and hardware configuration: 602- ESP32-C3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32c3/api-guides/usb-serial-jtag-console.html 603- ESP32-S3: https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-guides/usb-serial-jtag-console.html. 604 605Configuration example: 606``` 607# Use Serial through USB JTAG Serial port for Serial Recovery 608CONFIG_ESP_MCUBOOT_SERIAL_USB_SERIAL_JTAG=y 609# Use sector erasing (recommended) instead of entire image size 610# erasing when uploading through Serial Recovery 611CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY=y 612# GPIO used to boot on Serial Recovery 613CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT=5 614# GPIO input type (0 for Pull-down, 1 for Pull-up) 615CONFIG_ESP_SERIAL_BOOT_GPIO_INPUT_TYPE=0 616# GPIO signal value 617CONFIG_ESP_SERIAL_BOOT_GPIO_DETECT_VAL=1 618# Delay time for identify the GPIO signal 619CONFIG_ESP_SERIAL_BOOT_DETECT_DELAY_S=5 620``` 621 622--- 623:warning: ***ATTENTION*** 624 625*When working with Flash Encryption enabled, `CONFIG_ESP_MCUBOOT_ERASE_PROGRESSIVELY` must be ***disabled***, although it is recommended for common Serial Recovery usage* 626 627--- 628 629### [MCUMGR image upload example](#mcumgr-image-upload-example) 630 631After entering the Serial recovery mode on the device, MCUMGR can be used as following: 632 633Configure the connection: 634```bash 635mcumgr conn add esp type="serial" connstring="dev=<PORT>,baud=115200,mtu=256" 636``` 637 638Upload the image (the process may take some time): 639```bash 640mcumgr -c esp image upload <IMAGE_BIN> 641``` 642 643Reset the device: 644```bash 645mcumgr -c esp reset 646``` 647 648--- 649:warning: ***ATTENTION*** 650 651*Serial recovery mode uploads the image to the PRIMARY_SLOT, therefore if the upload process gets interrupted the image may be corrupted and unable to boot* 652 653--- 654