You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Multiple updates and fixes:
- Add memory layouts for AMP scenarios
- Fix typos and errors in diagrams
- Fix typos and errors in text
- Remove unused file
Signed-off-by: Marek Matej <[email protected]>
Co-authored-by: Marek Matej <[email protected]>
The application image loaded by the MCUboot has additional header with information about the SRAM segments.
178
+
The standard MCUboot header is placed at the offset `0x00`. Following structure represent its format:
179
+
```cpp
180
+
/* MCUboot image header. All fields are in little endian byte order. */
181
+
structimage_header {
182
+
uint32_t ih_magic; /* 0x96f3b83d OR 0x96f3b83c (V1) */
183
+
uint32_t ih_load_addr; /* Subsequent ESP header is used to hold application entry address */
184
+
uint16_t ih_hdr_size; /* Size of image header (bytes) */
185
+
uint16_t ih_protect_tlv_size; /* Size of protected TLV area (bytes) */
186
+
uint32_t ih_img_size; /* Does not include header */
187
+
uint32_t ih_flags; /* Image flags */
188
+
struct image_version ih_ver; /* Image version */
189
+
uint32_t _pad1; /* Padding */
190
+
} __packed;
191
+
192
+
```
193
+
194
+
The application image loaded by the MCUboot has an additional header with the information about used SRAM segments, which is placed at the offset `0x20`, just after the standard MCUboot header.
Additional information on the flash and/or SPIRAM regions are provided as a linker symbols and are embedded inside the application image.
193
210
194
-
## Building
195
211
196
-
Following is the description of some basic build steps so you can create the images and scenarios discussed in this article at home.
212
+
## Memory utilization
213
+
214
+
Before we build some example applications, let’s take a moment to discuss how the linking process utilizes SRAM on the ESP32-S3.
215
+
It’s important to note that different Espressif SoCs can have unique memory layouts, which can affect how resources are allocated.
216
+
Therefore each SoC is using slightly different linker script.
217
+
218
+
The images below illustrate the process of application linking, focusing on how the ROM code interacts with SRAM. Key details, such as I-Cache and D-Cache allocations, are highlighted for clarity.
219
+
Important linker symbols, crucial to understanding the memory layout, are shown in green bubbles.
220
+
221
+
- Yellow area is the memory used by the 2nd stage bootloader that can be re-claimed by the application code run-time.
222
+
- Orange area is the memory used by the 1st stage bootloader (or ROM-loader), that can be re-claimed after the application loading is done.
223
+
- Red area is the memory that is not available for the user and should not be used by the linker to spill the code or data.
197
224
198
-
But first lets talk briefly about how the link process utilize the SRAM memory on the ESP32-S3. Note, that different Espressif SoCs have different memory layout.
199
225
200
-
### Memory utilization
226
+
### ESP32-S3 use-case
201
227
202
-
Bellow is the image which illustrates how the application linking is done. Highlighted are details of ROM code usage in SRAM1, and I-Cache, D-Cache placement.
203
-
The illustration is covering an single CPU scenario and does not cover the AMP case.
228
+
Here we are using the ESP32-S3 to illustrate memory utilization, which is **suitable as a reference for most of the newer SoCs**.
204
229
205
-
- Yellow hatched area is the memory that can't be rewritten during the 2nd stage loading (it can be re-claimed during the runtime)
206
-
- Orange hatched area is the memory that can be re-claimed after the application loading is done.
207
-
- Red hatched areas are the memory parts that are not available for the user and should be avoided by the linker.
230
+
The following picture illustrates the memory utilization for an single CPU scenario.
The following picture illustrates memory utilization in a multi-CPU scenario.
241
+
242
+
{{< figure
243
+
default=true
244
+
src="img/esp32s3-zephyr-memory-amp.webp"
245
+
alt=""
246
+
caption="The ESP32-S3 'AMP' memory utilization."
247
+
>}}
248
+
249
+
216
250
***NOTE:***
217
251
*The I-Cache allocation SRAM blocks (0,1) are set by the **`PMS_INTERNAL_SRAM_ICACHE_USAGE`** bits
218
252
and the D-Cache allocation SRAM blocks (9,10) are set by the **`PMS_INTERNAL_SRAM_DCACHE_USAGE`** bits, both in the register `PMC_INTERNAL_SRAM_USAGE_1_REG`*
219
253
254
+
255
+
### ESP32 use-case
256
+
257
+
Here is the memory utilization for the ESP32 platform as its memory model is significantly different from other Espressif SoCs.
258
+
259
+
The following picture illustrates memory utilization in a single CPU scenario.
260
+
261
+
{{< figure
262
+
default=true
263
+
src="img/esp32-zephyr-memory-default.webp"
264
+
alt=""
265
+
caption="The ESP32 'default' memory layout."
266
+
>}}
267
+
268
+
269
+
Following picture illustrates the memory utilization in the multi CPU scenario.
270
+
271
+
{{< figure
272
+
default=true
273
+
src="img/esp32-zephyr-memory-amp.webp"
274
+
alt=""
275
+
caption="The ESP32-S3 'AMP' memory layout."
276
+
>}}
277
+
278
+
220
279
### Tooling - esptool.py
221
280
222
281
The *esptool.py* is the essential tool used to manipulate the binaries for the ESP32 SoCs. Among the other features our focus is on the `--elf2image` command, which is used to convert the `.elf` images to the loadable `.bin` images. This tool is used to create the images loadable by the ROM loader.
@@ -235,13 +294,30 @@ flowchart LR
235
294
236
295
Resulting binary can be loaded to any LMA location (in flash). Its segments will be processed at the location and SRAM will be copied to the corresponding SRAM location, and possible FLASH or SPIRAM segments will be mapped to the virtual address space VMA.
237
296
297
+
298
+
## Building
299
+
300
+
Finally let's build some real life examples that can be flashed into the target board to demonstrate what was discussed in previous chapters.
301
+
Before that it is important to note the image formats used with the Zephyr port of the Espressif SoCs.
302
+
303
+
The table shows the image formats used in various build scenarios:
Single image builds are used as a default build option in the Zephyr RTOS and the CI, unless `--sysbuild` is used.
315
+
Single image builds are used as a default build option in the Zephyr RTOS and the CI (unless `--sysbuild` is used).
241
316
317
+
Building and flashing a WiFi sample application using the Simple Boot:
242
318
```shell
243
319
cd zephyrproject/zephyr
244
-
west build -b esp32s3_devkitm/esp32s3/procpu samples/net/wifi -p
320
+
west build -b esp32s3_devkitm/esp32s3/procpu samples/net/wifi/shell -p
245
321
west flash && west espressif monitor
246
322
```
247
323
@@ -283,18 +359,18 @@ uart:~$
283
359
```
284
360
285
361
286
-
### MCUboot Zephyr RTOS port (ZP)
362
+
### MCUboot Zephyr port (ZP)
287
363
288
364
First lets take a look at how to manually build the MCUboot and the subsequent application. Each `west flash` in the code is using its own flash partition and it is not overwritten by each other.
289
365
290
-
Building MCUboot separately at its location:
366
+
Building and flashing the MCUboot separately at its location:
291
367
```shell
292
368
cd zephyrproject/bootloader/mcuboot
293
369
west build -b esp32s3_devkitm/esp32s3/procpu boot/zephyr -p
294
370
west flash && west espressif monitor
295
371
```
296
372
297
-
Building the sample application that is loadable by the MCUboot created in previous step:
373
+
Building and flashing the sample application that is loadable by the MCUboot created in previous step:
298
374
```shell
299
375
cd zephyrproject/zephyr
300
376
west build -b esp32s3_devkitm/esp32s3/procpu samples/net/wifi -p -DCONFIG_BOOTLOADER_MCUBOOT=y
@@ -303,14 +379,14 @@ west flash && west espressif monitor
303
379
304
380
Now, we can rely on the Sysbuild and build all images at once.
305
381
306
-
Building the application with MCUboot(ZP) using sysbuild:
382
+
Building and flashing the application with MCUboot(ZP) using ***sysbuild***:
307
383
```shell
308
384
cd zephyrproject/zephyr
309
385
west build -b esp32s3_devkitm/esp32s3/procpu samples/new/wifi -p --sysbuild
310
386
west flash && west espressif monitor
311
387
```
312
388
313
-
In both cases (manual & sysbuild) we should see the following console output after the image boots:
389
+
In both cases (manual build & using `--sysbuild` option) we should see the following console output after the image boots:
314
390
```
315
391
ESP-ROM:esp32s3-20210327
316
392
Build:Mar 27 2021
@@ -347,11 +423,88 @@ I (205) heap_runtime: ESP heap runtime init at 0x3fca4f70 size 273 kB.
347
423
uart:~$
348
424
```
349
425
426
+
350
427
### MCUboot Espressif port (EP)
351
428
352
429
To learn how to build the MCUboot Espressif Port, check out this [article](https://docs.mcuboot.com/readme-espressif.html)
353
430
354
-
## Feature table
431
+
432
+
### AMP enabled sample code
433
+
434
+
AMP builds require several images to be built and flashed onto a target SoC. Let's use ESP32-S3 as our test platform and demonstrate the sysbuild capabilities on the sample code provided by the Zephyr RTOS sources.
435
+
The Zephyr sample code (`samples/drivers/ipm/ipm_esp32`) uses IPM (Inter-Processor Mailbox) to demonstrate a simple two-way communication between the `PRO_CPU` core and `APP_CPU` core. Images for both CPU cores must be loaded using the MCUboot.
436
+
Note that there is no support for running AMP if the Simple Boot mechanism is used.
437
+
438
+
Now we can build and flash a complete set of images running the IPM sample:
439
+
```shell
440
+
cd zephyrproject/zephyr
441
+
west build -b esp32s3_devkitm/esp32s3/procpu samples/drivers/ipm/ipm_esp32/ -p --sysbuild
442
+
west flash && west espressif monitor
443
+
```
444
+
445
+
As a result, three images should be created:
446
+
447
+
-`ipm_esp32` - the image for the `PRO_CPU` core
448
+
-`ipm_esp32_remote` - the image for the `APP_CPU` core
449
+
-`mcuboot` - the MCUboot image, which is run by `PRO_CPU`
450
+
451
+
452
+
After flashing and connecting to a target using the serial port, we should be able to see the following output in the console:
453
+
```
454
+
ESP-ROM:esp32s3-20210327
455
+
Build:Mar 27 2021
456
+
rst:0x1 (POWERON),boot:0x8 (SPI_FAST_FLASH_BOOT)
457
+
SPIWP:0xee
458
+
mode:DIO, clock div:2
459
+
load:0x3fcb5400,len:0x2bd8
460
+
load:0x403ba400,len:0xa1fc
461
+
load:0x403c6400,len:0x15c4
462
+
entry 0x403bd044
463
+
I (61) soc_init: MCUboot 2nd stage bootloader
464
+
I (61) soc_init: compile time Dec 12 2024 16:26:23
465
+
W (61) soc_init: Unicore bootloader
466
+
I (61) spi_flash: detected chip: generic
467
+
I (65) spi_flash: flash io: dio
468
+
W (68) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header.
469
+
I (80) soc_init: chip revision: v0.1
470
+
I (83) flash_init: Boot SPI Speed : 40MHz
471
+
I (87) flash_init: SPI Mode : DIO
472
+
I (90) flash_init: SPI Flash Size : 8MB
473
+
I (94) soc_random: Enabling RNG early entropy source
474
+
I (99) soc_random: Disabling RNG early entropy source
475
+
I (103) boot: Disabling glitch detection
476
+
I (107) boot: Jumping to the main image...
477
+
I (145) spi_flash: flash io: dio
478
+
[esp32s3] [INF] Image index: 0, Swap type: none
479
+
[esp32s3] [INF] Loading image 0 - slot 0 from flash, area id: 1
480
+
[esp32s3] [INF] Application start=40378a48h
481
+
[esp32s3] [INF] DRAM segment: paddr=00026ee8h, vaddr=3fc8aec8h, size=010e4h ( 4324) load
0 commit comments