From 3444476eb21a71856aeda3478811209813aa7f65 Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Fri, 24 Mar 2023 14:49:45 +0000 Subject: [PATCH 1/2] ESP32 DRAM linker fix The ROM code _data_ section is loaded into the middle of the DRAM address space, unlike the other chips where it is loaded at the end. Therefore subtracting the previously "reserved" section from heap end could actually corrupt the ROM data section. For the ESP32, the DRAM block has been split into two individual segments, with some reserved segments in the middle (addresses taken from esp-idf). At the moment we don't use the second segment at all in esp-hal, but we could utilize it in esp-wifi for placing the internal allocator for example. --- esp32-hal/ld/link-esp32.x | 2 +- esp32-hal/ld/memory.x | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/esp32-hal/ld/link-esp32.x b/esp32-hal/ld/link-esp32.x index fdade4ec3..ca04ab68c 100644 --- a/esp32-hal/ld/link-esp32.x +++ b/esp32-hal/ld/link-esp32.x @@ -28,7 +28,7 @@ INCLUDE "rtc_slow.x" INCLUDE "external.x" /* End of Shared sections */ -_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)-LENGTH(reserved_for_boot_seg) - 2*STACK_SIZE; +_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg) - 2*STACK_SIZE; _stack_start_cpu1 = _heap_end; _stack_end_cpu1 = _stack_start_cpu1 + STACK_SIZE; diff --git a/esp32-hal/ld/memory.x b/esp32-hal/ld/memory.x index 48384f0c0..4bb9747e1 100644 --- a/esp32-hal/ld/memory.x +++ b/esp32-hal/ld/memory.x @@ -19,7 +19,16 @@ MEMORY reserved_for_rom_seg : ORIGIN = 0x3FFAE000, len = 8k /* SRAM2; reserved for usage by the ROM */ dram_seg ( RW ) : ORIGIN = 0x3FFB0000 + RESERVE_DRAM, len = 176k - RESERVE_DRAM /* SRAM2+1; first 64kB used by BT if enable */ - reserved_for_boot_seg : ORIGIN = 0x3FFDC200, len = 144k /* SRAM1; reserved for static ROM usage; can be used for heap */ + + /* + * The following values come from the heap allocator in esp-idf: https://github.com/espressif/esp-idf/blob/ab63aaa4a24a05904da2862d627f3987ecbeafd0/components/heap/port/esp32/memory_layout.c#L137-L157 + * The segment dram2_seg after the rom data space is not mentioned in the esp32 linker scripts in esp-idf, instead the space after is used as heap space. + * It seems not all rom data space is reserved, but only "core"/"important" ROM functions that may be called after booting from ROM. + */ + reserved_rom_data_pro : ORIGIN = 0X3FFE0000, len = 1088 + reserved_rom_data_app : ORIGIN = 0X3FFE3F20, len = 1072 + + dram2_seg : ORIGIN = 0x3FFE4350, len = 111k /* the rest of DRAM after the rom data segments in the middle */ /* external flash The 0x20 offset is a convenience for the app binary image generation. From 192f4678dbc79881abbb3050c19b07c68b7bc70e Mon Sep 17 00:00:00 2001 From: Scott Mabin Date: Fri, 24 Mar 2023 15:50:23 +0000 Subject: [PATCH 2/2] Apply fix to esp32s2 & esp32s3 --- esp32s2-hal/ld/link-esp32s2.x | 2 +- esp32s2-hal/ld/memory.x | 7 ------- esp32s3-hal/ld/link-esp32s3.x | 2 +- esp32s3-hal/ld/memory.x | 2 -- 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/esp32s2-hal/ld/link-esp32s2.x b/esp32s2-hal/ld/link-esp32s2.x index 7e21457c0..a73732e8c 100644 --- a/esp32s2-hal/ld/link-esp32s2.x +++ b/esp32s2-hal/ld/link-esp32s2.x @@ -36,7 +36,7 @@ INCLUDE "rtc_slow.x" INCLUDE "external.x" /* End of Shared sections */ -_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)-LENGTH(reserved_for_boot_seg) - STACK_SIZE; +_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg) - STACK_SIZE; _stack_start_cpu0 = _heap_end; _stack_end_cpu0 = _stack_start_cpu0 + STACK_SIZE; diff --git a/esp32s2-hal/ld/memory.x b/esp32s2-hal/ld/memory.x index 8178af297..550572b78 100644 --- a/esp32s2-hal/ld/memory.x +++ b/esp32s2-hal/ld/memory.x @@ -28,13 +28,6 @@ MEMORY dram_seg ( RW ) : ORIGIN = 0x3FFB0000 + RESERVE_CACHES + VECTORS_SIZE, len = 192k - RESERVE_CACHES - VECTORS_SIZE - /* SRAM1; reserved for static ROM usage; can be used for heap. - Length based on the "_dram0_rtos_reserved_start" symbol from IDF used to delimit the - ROM data reserved region: - https://github.com/espressif/esp-idf/blob/bcb34ca7aef4e8d3b97d75ad069b960fb1c17c16/components/heap/port/esp32s2/memory_layout.c#L121-L122 - */ - reserved_for_boot_seg : ORIGIN = 0x3FFE0000, len = 0x1FA10 - /* external flash The 0x20 offset is a convenience for the app binary image generation. Flash cache has 64KB pages. The .bin file which is flashed to the chip diff --git a/esp32s3-hal/ld/link-esp32s3.x b/esp32s3-hal/ld/link-esp32s3.x index 6bdb39e95..6dc441965 100644 --- a/esp32s3-hal/ld/link-esp32s3.x +++ b/esp32s3-hal/ld/link-esp32s3.x @@ -51,7 +51,7 @@ INCLUDE "rtc_slow.x" INCLUDE "external.x" /* End of Shared sections */ -_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)-LENGTH(reserved_for_boot_seg) - 2*STACK_SIZE; +_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg) - 2*STACK_SIZE; _stack_start_cpu1 = _heap_end; _stack_end_cpu1 = _stack_start_cpu1 + STACK_SIZE; diff --git a/esp32s3-hal/ld/memory.x b/esp32s3-hal/ld/memory.x index 098fae170..c60a1656c 100644 --- a/esp32s3-hal/ld/memory.x +++ b/esp32s3-hal/ld/memory.x @@ -31,8 +31,6 @@ MEMORY iram_seg ( RX ) : ORIGIN = 0x40370000 + RESERVE_ICACHE + VECTORS_SIZE, len = 328k - VECTORS_SIZE - RESERVE_ICACHE dram_seg ( RW ) : ORIGIN = 0x3FC88000 , len = 345856 - reserved_for_boot_seg : ORIGIN = 0x3FCDC700, len = 0xB000 /* reserved for static ROM usage; can be used for heap */ - /* external flash The 0x20 offset is a convenience for the app binary image generation. Flash cache has 64KB pages. The .bin file which is flashed to the chip