* Optimize the ESP32-S3 linker script * Incorporate suggestions from review * Extend the size of dram_seg as suggested in the review
177 lines
5.3 KiB
Plaintext
177 lines
5.3 KiB
Plaintext
/* override entry point */
|
|
ENTRY(ESP32Reset)
|
|
|
|
/* reserved for ICACHE */
|
|
RESERVE_ICACHE = 0x8000;
|
|
|
|
/* reserved at the start of the RTC memories for use by the ULP processor */
|
|
RESERVE_RTC_FAST = 0;
|
|
RESERVE_RTC_SLOW = 0;
|
|
|
|
/* define stack size for both cores */
|
|
STACK_SIZE = 8k;
|
|
|
|
VECTORS_SIZE = 0x400;
|
|
|
|
/* Specify main memory areas
|
|
|
|
40370000 <- IRAM/Icache -> 40378000 <- D/IRAM (I) -> 403E0000
|
|
3FC88000 <- D/IRAM (D) -> 3FCF0000 <- DRAM/DCache -> 3FD00000
|
|
|
|
Startup code uses the IRAM from 0x403B9000 to 0x403E0000, which is not available for static
|
|
memory, but can only be used after app starts.
|
|
|
|
D cache use the memory from high address, so when it's configured to 16K/32K, the region
|
|
0x3FCF0000 ~ (3FD00000 - DATA_CACHE_SIZE) should be available. This region is not used as
|
|
static memory, leaving to the heap.
|
|
*/
|
|
MEMORY
|
|
{
|
|
vectors_seg ( RX ) : ORIGIN = 0x40370000 + RESERVE_ICACHE, len = VECTORS_SIZE
|
|
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
|
|
has a 0x18 byte file header, and each segment has a 0x08 byte segment
|
|
header. Setting this offset makes it simple to meet the flash cache MMU's
|
|
constraint that (paddr % 64KB == vaddr % 64KB).)
|
|
*/
|
|
irom_seg ( RX ) : ORIGIN = 0x42000020, len = 4M - 0x20
|
|
drom_seg ( R ) : ORIGIN = 0x3C000020, len = 4M - 0x20
|
|
|
|
|
|
/* RTC fast memory (executable). Persists over deep sleep. Only for core 0 (PRO_CPU) */
|
|
rtc_fast_iram_seg(RWX) : ORIGIN = 0x600fe000, len = 8k
|
|
|
|
/* RTC fast memory (same block as above), viewed from data bus. Only for core 0 (PRO_CPU) */
|
|
rtc_fast_dram_seg(RW) : ORIGIN = 0x600fe000 + RESERVE_RTC_FAST, len = 8k - RESERVE_RTC_FAST
|
|
|
|
/* RTC slow memory (data accessible). Persists over deep sleep. */
|
|
rtc_slow_seg(RW) : ORIGIN = 0x50000000 + RESERVE_RTC_SLOW, len = 8k - RESERVE_RTC_SLOW
|
|
|
|
/* external memory, including data and text */
|
|
psram_seg(RWX) : ORIGIN = 0x3F500000, len = 0xA80000 /* ??? */
|
|
}
|
|
|
|
/* map generic regions to output sections */
|
|
INCLUDE "alias.x"
|
|
|
|
/* esp32 specific regions */
|
|
SECTIONS {
|
|
.rtc_fast.text : {
|
|
. = ALIGN(4);
|
|
*(.rtc_fast.literal .rtc_fast.text .rtc_fast.literal.* .rtc_fast.text.*)
|
|
} > rtc_fast_iram_seg AT > RODATA
|
|
|
|
/*
|
|
This section is required to skip rtc.text area because rtc_iram_seg and
|
|
rtc_data_seg are reflect the same address space on different buses.
|
|
*/
|
|
.rtc_fast.dummy (NOLOAD) :
|
|
{
|
|
_rtc_dummy_start = ABSOLUTE(.); /* needed to make section proper size */
|
|
. = SIZEOF(.rtc_fast.text);
|
|
_rtc_dummy_end = ABSOLUTE(.); /* needed to make section proper size */
|
|
} > rtc_fast_dram_seg
|
|
|
|
|
|
.rtc_fast.data :
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_fast_data_start = ABSOLUTE(.);
|
|
*(.rtc_fast.data .rtc_fast.data.*)
|
|
_rtc_fast_data_end = ABSOLUTE(.);
|
|
} > rtc_fast_dram_seg AT > RODATA
|
|
|
|
.rtc_fast.bss (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_fast_bss_start = ABSOLUTE(.);
|
|
*(.rtc_fast.bss .rtc_fast.bss.*)
|
|
_rtc_fast_bss_end = ABSOLUTE(.);
|
|
} > rtc_fast_dram_seg
|
|
|
|
.rtc_fast.noinit (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
*(.rtc_fast.noinit .rtc_fast.noinit.*)
|
|
} > rtc_fast_dram_seg
|
|
|
|
|
|
.rtc_slow.text : {
|
|
. = ALIGN(4);
|
|
*(.rtc_slow.literal .rtc_slow.text .rtc_slow.literal.* .rtc_slow.text.*)
|
|
} > rtc_slow_seg AT > RODATA
|
|
|
|
.rtc_slow.data :
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_slow_data_start = ABSOLUTE(.);
|
|
*(.rtc_slow.data .rtc_slow.data.*)
|
|
_rtc_slow_data_end = ABSOLUTE(.);
|
|
} > rtc_slow_seg AT > RODATA
|
|
|
|
.rtc_slow.bss (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
_rtc_slow_bss_start = ABSOLUTE(.);
|
|
*(.rtc_slow.bss .rtc_slow.bss.*)
|
|
_rtc_slow_bss_end = ABSOLUTE(.);
|
|
} > rtc_slow_seg
|
|
|
|
.rtc_slow.noinit (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
*(.rtc_slow.noinit .rtc_slow.noinit.*)
|
|
} > rtc_slow_seg
|
|
|
|
.external.data :
|
|
{
|
|
_external_data_start = ABSOLUTE(.);
|
|
. = ALIGN(4);
|
|
*(.external.data .external.data.*)
|
|
_external_data_end = ABSOLUTE(.);
|
|
} > psram_seg AT > RODATA
|
|
|
|
.external.bss (NOLOAD) :
|
|
{
|
|
_external_bss_start = ABSOLUTE(.);
|
|
. = ALIGN(4);
|
|
*(.external.bss .external.bss.*)
|
|
_external_bss_end = ABSOLUTE(.);
|
|
} > psram_seg
|
|
|
|
.external.noinit (NOLOAD) :
|
|
{
|
|
. = ALIGN(4);
|
|
*(.external.noinit .external.noinit.*)
|
|
} > psram_seg
|
|
|
|
/* must be last segment using psram_seg */
|
|
.external_heap_start (NOLOAD) :
|
|
{
|
|
. = ALIGN (4);
|
|
_external_heap_start = ABSOLUTE(.);
|
|
} > psram_seg
|
|
}
|
|
|
|
_external_ram_start = ABSOLUTE(ORIGIN(psram_seg));
|
|
_external_ram_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg));
|
|
|
|
_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)+LENGTH(reserved_for_boot_seg) - 2*STACK_SIZE;
|
|
_text_heap_end = ABSOLUTE(ORIGIN(iram_seg)+LENGTH(iram_seg));
|
|
_external_heap_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg));
|
|
|
|
_stack_start_cpu1 = _heap_end;
|
|
_stack_end_cpu1 = _stack_start_cpu1 + STACK_SIZE;
|
|
_stack_start_cpu0 = _stack_end_cpu1;
|
|
_stack_end_cpu0 = _stack_start_cpu0 + STACK_SIZE;
|
|
|
|
EXTERN(DefaultHandler);
|
|
|
|
INCLUDE "device.x"
|