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