OVMS3-idf/components/esp32/ld/esp32.project.ld.in

410 lines
11 KiB
Text
Raw Normal View History

2016-08-17 15:08:22 +00:00
/* Default entry point: */
ENTRY(call_start_cpu0);
2016-08-17 15:08:22 +00:00
SECTIONS
{
/* RTC fast memory holds RTC wake stub code,
including from any source file named rtc_wake_stub*.c
*/
.rtc.text :
{
. = ALIGN(4);
mapping[rtc_text]
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
_rtc_text_end = ABSOLUTE(.);
2018-02-26 17:32:58 +00:00
} > rtc_iram_seg
2019-06-25 01:03:58 +00:00
/*
2019-06-25 01:03:58 +00:00
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.dummy :
{
_rtc_dummy_start = ABSOLUTE(.);
_rtc_fast_start = ABSOLUTE(.);
. = SIZEOF(.rtc.text);
_rtc_dummy_end = ABSOLUTE(.);
} > rtc_data_seg
2019-06-25 01:03:58 +00:00
/* This section located in RTC FAST Memory area.
It holds data marked with RTC_FAST_ATTR attribute.
See the file "esp_attr.h" for more information.
*/
.rtc.force_fast :
{
. = ALIGN(4);
_rtc_force_fast_start = ABSOLUTE(.);
_coredump_rtc_fast_start = ABSOLUTE(.);
mapping[rtc_fast_coredump]
_coredump_rtc_fast_end = ABSOLUTE(.);
*(.rtc.force_fast .rtc.force_fast.*)
. = ALIGN(4) ;
_rtc_force_fast_end = ABSOLUTE(.);
} > rtc_data_seg
/* RTC data section holds RTC wake stub
data/rodata, including from any source file
named rtc_wake_stub*.c and the data marked with
RTC_DATA_ATTR, RTC_RODATA_ATTR attributes.
2019-06-25 01:03:58 +00:00
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
*/
.rtc.data :
{
_rtc_data_start = ABSOLUTE(.);
/* coredump mapping */
_coredump_rtc_start = ABSOLUTE(.);
mapping[rtc_coredump]
_coredump_rtc_end = ABSOLUTE(.);
/* should be placed after coredump mapping */
mapping[rtc_data]
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
_rtc_data_end = ABSOLUTE(.);
} > rtc_data_location
/* RTC bss, from any source file named rtc_wake_stub*.c */
.rtc.bss (NOLOAD) :
{
_rtc_bss_start = ABSOLUTE(.);
*rtc_wake_stub*.*(.bss .bss.*)
*rtc_wake_stub*.*(COMMON)
mapping[rtc_bss]
_rtc_bss_end = ABSOLUTE(.);
} > rtc_data_location
2019-06-25 01:03:58 +00:00
/* This section holds data that should not be initialized at power up
and will be retained during deep sleep.
User data marked with RTC_NOINIT_ATTR will be placed
2019-06-25 01:03:58 +00:00
into this section. See the file "esp_attr.h" for more information.
The memory location of the data is dependent on
CONFIG_ESP32_RTCDATA_IN_FAST_MEM option.
*/
.rtc_noinit (NOLOAD):
{
. = ALIGN(4);
_rtc_noinit_start = ABSOLUTE(.);
*(.rtc_noinit .rtc_noinit.*)
. = ALIGN(4) ;
_rtc_noinit_end = ABSOLUTE(.);
} > rtc_data_location
2019-06-25 01:03:58 +00:00
/* This section located in RTC SLOW Memory area.
It holds data marked with RTC_SLOW_ATTR attribute.
See the file "esp_attr.h" for more information.
*/
.rtc.force_slow :
{
. = ALIGN(4);
_rtc_force_slow_start = ABSOLUTE(.);
*(.rtc.force_slow .rtc.force_slow.*)
. = ALIGN(4) ;
_rtc_force_slow_end = ABSOLUTE(.);
} > rtc_slow_seg
/* Get size of rtc slow data based on rtc_data_location alias */
2019-06-25 01:03:58 +00:00
_rtc_slow_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_slow_end - _rtc_data_start)
: (_rtc_force_slow_end - _rtc_force_slow_start);
2019-06-25 01:03:58 +00:00
_rtc_fast_length = (ORIGIN(rtc_slow_seg) == ORIGIN(rtc_data_location))
? (_rtc_force_fast_end - _rtc_fast_start)
: (_rtc_noinit_end - _rtc_fast_start);
2019-06-25 01:03:58 +00:00
ASSERT((_rtc_slow_length <= LENGTH(rtc_slow_seg)),
"RTC_SLOW segment data does not fit.")
2019-06-25 01:03:58 +00:00
ASSERT((_rtc_fast_length <= LENGTH(rtc_data_seg)),
"RTC_FAST segment data does not fit.")
2016-08-17 15:08:22 +00:00
/* Send .iram0 code to iram */
.iram0.vectors :
2016-08-17 15:08:22 +00:00
{
_iram_start = ABSOLUTE(.);
2016-08-17 15:08:22 +00:00
/* Vectors go to IRAM */
_init_start = ABSOLUTE(.);
/* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */
. = 0x0;
KEEP(*(.WindowVectors.text));
. = 0x180;
KEEP(*(.Level2InterruptVector.text));
. = 0x1c0;
KEEP(*(.Level3InterruptVector.text));
. = 0x200;
KEEP(*(.Level4InterruptVector.text));
. = 0x240;
KEEP(*(.Level5InterruptVector.text));
. = 0x280;
KEEP(*(.DebugExceptionVector.text));
. = 0x2c0;
KEEP(*(.NMIExceptionVector.text));
. = 0x300;
KEEP(*(.KernelExceptionVector.text));
. = 0x340;
KEEP(*(.UserExceptionVector.text));
. = 0x3C0;
KEEP(*(.DoubleExceptionVector.text));
. = 0x400;
_invalid_pc_placeholder = ABSOLUTE(.);
2016-08-17 15:08:22 +00:00
*(.*Vector.literal)
*(.UserEnter.literal);
*(.UserEnter.text);
. = ALIGN (16);
*(.entry.text)
*(.init.literal)
*(.init)
2016-08-17 15:08:22 +00:00
_init_end = ABSOLUTE(.);
} > iram0_0_seg
2016-08-17 15:08:22 +00:00
.iram0.text :
{
/* Code marked as runnning out of IRAM */
_iram_text_start = ABSOLUTE(.);
mapping[iram0_text]
2016-08-17 15:08:22 +00:00
} > iram0_0_seg
.dram0.data :
{
_data_start = ABSOLUTE(.);
Reclaim BT/BTDM BSS and Data in bluetooth memory release function 1. Modify esp_bt_controller_mem_release() to release BTDM BSS and Data to heap if ESP_BT_MODE_BTDM mode is passed to it 2. Add a new API esp_bt_mem_release() which internally calls esp_bt_controller_mem_release() with the provided mode and then if mode is ESP_BT_MODE_BTDM, releases BT BSS and Data to heap. Background: For Wi-Fi and BT/BLE applications, for e.g. the usecase is like when Bluetooth is used for provisioning and once the device is connected to the Wi-Fi AP, we can turn off Bluetooth completely. In such scenarios, it should be possible to reclaim all the memory of Bluetooth. Although, currently this does not happen. Experiment: Made the following modifications to examples/bluetooth/gatt_server : 1. Added support of simple_wifi to it 2. Moved all the bluetooth related code under CONFIG_BT_ENABLED config option 3. Calculated the free heap in 2 similar scenarios: i. Disabled BT (CONFIG_BT_ENABLED undefined) and checked the free heap after STA connected ii. Kept BT enabled and disabled it after STA connected and checked the free heap Ideally, the numbers for i., ii. above should have been similar. But there was a delta of almost 30-31K. (i. > ii.) 4. Through make size-components checked the common BSS for libbta.a and libbtdm_app.a and found it to be almost 30K. Data is around 1K Solution: 1. Modified the linker script to mark the BSS and Data for these libraries and free it when ESP_BT_MODE_BTDM mode is passed to mem release APIs. 2. Verified that the free heap is comparable for i. and ii. above. Note: It is known that once this is done, Bluetooth can only be used again post reboot. Signed-off-by: Hrishikesh Dhayagude <hrishi@espressif.com>
2018-07-11 06:22:32 +00:00
_bt_data_start = ABSOLUTE(.);
*libbt.a:(.data .data.*)
. = ALIGN (4);
_bt_data_end = ABSOLUTE(.);
_btdm_data_start = ABSOLUTE(.);
*libbtdm_app.a:(.data .data.*)
. = ALIGN (4);
_btdm_data_end = ABSOLUTE(.);
2019-06-25 01:03:58 +00:00
_nimble_data_start = ABSOLUTE(.);
*libnimble.a:(.data .data.*)
. = ALIGN (4);
_nimble_data_end = ABSOLUTE(.);
*(.gnu.linkonce.d.*)
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
*(.jcr)
/* coredump mapping */
_coredump_dram_start = ABSOLUTE(.);
mapping[dram_coredump]
_coredump_dram_end = ABSOLUTE(.);
/* should be placed after coredump mapping */
_esp_system_init_fn_array_start = ABSOLUTE(.);
KEEP (*(SORT(.esp_system_init_fn) SORT(.esp_system_init_fn.*)))
_esp_system_init_fn_array_end = ABSOLUTE(.);
mapping[dram0_data]
_data_end = ABSOLUTE(.);
. = ALIGN(4);
2018-02-26 17:32:58 +00:00
} > dram0_0_seg
/*This section holds data that should not be initialized at power up.
The section located in Internal SRAM memory region. The macro _NOINIT
can be used as attribute to place data into this section.
See the esp_attr.h file for more information.
*/
.noinit (NOLOAD):
{
. = ALIGN(4);
_noinit_start = ABSOLUTE(.);
2019-06-25 01:03:58 +00:00
*(.noinit .noinit.*)
2018-02-26 17:32:58 +00:00
. = ALIGN(4) ;
_noinit_end = ABSOLUTE(.);
} > dram0_0_seg
2016-08-17 15:08:22 +00:00
/* Shared RAM */
.dram0.bss (NOLOAD) :
{
. = ALIGN (8);
_bss_start = ABSOLUTE(.);
*(.ext_ram.bss*)
Reclaim BT/BTDM BSS and Data in bluetooth memory release function 1. Modify esp_bt_controller_mem_release() to release BTDM BSS and Data to heap if ESP_BT_MODE_BTDM mode is passed to it 2. Add a new API esp_bt_mem_release() which internally calls esp_bt_controller_mem_release() with the provided mode and then if mode is ESP_BT_MODE_BTDM, releases BT BSS and Data to heap. Background: For Wi-Fi and BT/BLE applications, for e.g. the usecase is like when Bluetooth is used for provisioning and once the device is connected to the Wi-Fi AP, we can turn off Bluetooth completely. In such scenarios, it should be possible to reclaim all the memory of Bluetooth. Although, currently this does not happen. Experiment: Made the following modifications to examples/bluetooth/gatt_server : 1. Added support of simple_wifi to it 2. Moved all the bluetooth related code under CONFIG_BT_ENABLED config option 3. Calculated the free heap in 2 similar scenarios: i. Disabled BT (CONFIG_BT_ENABLED undefined) and checked the free heap after STA connected ii. Kept BT enabled and disabled it after STA connected and checked the free heap Ideally, the numbers for i., ii. above should have been similar. But there was a delta of almost 30-31K. (i. > ii.) 4. Through make size-components checked the common BSS for libbta.a and libbtdm_app.a and found it to be almost 30K. Data is around 1K Solution: 1. Modified the linker script to mark the BSS and Data for these libraries and free it when ESP_BT_MODE_BTDM mode is passed to mem release APIs. 2. Verified that the free heap is comparable for i. and ii. above. Note: It is known that once this is done, Bluetooth can only be used again post reboot. Signed-off-by: Hrishikesh Dhayagude <hrishi@espressif.com>
2018-07-11 06:22:32 +00:00
_bt_bss_start = ABSOLUTE(.);
*libbt.a:(.bss .bss.* COMMON)
. = ALIGN (4);
_bt_bss_end = ABSOLUTE(.);
_btdm_bss_start = ABSOLUTE(.);
*libbtdm_app.a:(.bss .bss.* COMMON)
. = ALIGN (4);
_btdm_bss_end = ABSOLUTE(.);
2019-06-25 01:03:58 +00:00
_nimble_bss_start = ABSOLUTE(.);
*libnimble.a:(.bss .bss.* COMMON)
. = ALIGN (4);
_nimble_bss_end = ABSOLUTE(.);
mapping[dram0_bss]
2016-08-17 15:08:22 +00:00
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.share.mem)
*(.gnu.linkonce.b.*)
2016-08-17 15:08:22 +00:00
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
2018-02-26 17:32:58 +00:00
} > dram0_0_seg
2016-08-17 15:08:22 +00:00
ASSERT(((_bss_end - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")
2019-06-25 01:03:58 +00:00
esp32s2: fix THREADPTR calculation, re-enable FreeRTOS TLS tests 1. Clarify THREADPTR calculation in FreeRTOS code, explaining where the constant 0x10 offset comes from. 2. On the ESP32-S2, .flash.rodata section had different default alignment (8 bytes instead of 16), which resulted in different offset of the TLS sections. Unfortunately I haven’t found a way to query section alignment from C code, or to use a constant value to define section alignment in the linker script. The linker scripts are modified to force a fixed 16 byte alignment for .flash.rodata on the ESP32 and ESP32-S2beta. Note that the base address of .flash.rodata was already 16 byte aligned, so this has not changed the actual memory layout of the application. Full explanation of the calculation below. Assume we have the TLS template section base address (tls_section_vma), the address of a TLS variable in the template (address), and the final relocation value (offset). The linker calculates: offset = address - tls_section_vma + align_up(TCB_SIZE, alignment). At run time, the TLS section gets copied from _thread_local_start (in .rodata) to task_thread_local_start. Let’s assume that an address of a variable in the runtime TLS section is runtime_address. Access to this address will happen by calculating THREADPTR + offset. So, by a series of substitutions: THREADPTR + offset = runtime_address THREADPTR = runtime_address - offset THREADPTR = runtime_address - (address - tls_section_vma + align_up(TCB_SIZE, alignment)) THREADPTR = (runtime_address - address) + tls_section_vma - align_up(TCB_SIZE, alignment) The difference between runtime_address and address is same as the difference between task_thread_local_start and _thread_local_start. And tls_section_vma is the address of .rodata section, i.e. _rodata_start. So we arrive to THREADPTR = task_thread_local_start - _thread_local_start + _rodata_start - align_up(TCB_SIZE, alignment). The idea with TCB_SIZE being added to the THREADPTR when computing the relocation was to let the OS save TCB pointer in the TREADPTR register. The location of the run-time TLS section was assumed to be immediately after the TCB, aligned to whatever the section alignment was. However in our case the problem is that the run-time TLS section is stored not next to the TCB, but at the top of the stack. Plus, even if it was stored next to the TCB, the size of a FreeRTOS TCB is not equal to 8 bytes (TCB_SIZE hardcoded in the linker). So we have to calculate THREADPTR in a slightly obscure way, to compensate for these differences. Closes IDF-1239
2020-01-20 13:20:02 +00:00
/* When modifying the alignment, update tls_section_alignment in pxPortInitialiseStack */
.flash.rodata : ALIGN(0x10)
2016-08-17 15:08:22 +00:00
{
_rodata_start = ABSOLUTE(.);
*(.rodata_desc .rodata_desc.*) /* Should be the first. App version info. DO NOT PUT ANYTHING BEFORE IT! */
*(.rodata_custom_desc .rodata_custom_desc.*) /* Should be the second. Custom app version info. DO NOT PUT ANYTHING BEFORE IT! */
mapping[flash_rodata]
*(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */
2016-08-17 15:08:22 +00:00
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE_ = ABSOLUTE(.);
*(.xt_except_table)
*(.gcc_except_table .gcc_except_table.*)
2016-08-17 15:08:22 +00:00
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
. = (. + 3) & ~ 3;
__eh_frame = ABSOLUTE(.);
KEEP(*(.eh_frame))
. = (. + 7) & ~ 3;
/* C++ constructor and destructor tables
Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt
*/
2016-08-17 15:08:22 +00:00
__init_array_start = ABSOLUTE(.);
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors SORT(.ctors.*)))
2016-08-17 15:08:22 +00:00
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))
2016-08-17 15:08:22 +00:00
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
/* C++ exception handlers table: */
__XT_EXCEPTION_DESCS_ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
/* Addresses of memory regions reserved via
SOC_RESERVE_MEMORY_REGION() */
soc_reserved_memory_region_start = ABSOLUTE(.);
KEEP (*(.reserved_memory_address))
soc_reserved_memory_region_end = ABSOLUTE(.);
2016-08-17 15:08:22 +00:00
_rodata_end = ABSOLUTE(.);
/* Literals are also RO data. */
2016-08-17 15:08:22 +00:00
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
. = ALIGN(4);
2018-02-04 22:06:45 +00:00
_thread_local_start = ABSOLUTE(.);
*(.tdata)
*(.tdata.*)
*(.tbss)
*(.tbss.*)
_thread_local_end = ABSOLUTE(.);
. = ALIGN(4);
2019-07-22 14:04:03 +00:00
} >default_rodata_seg
2016-08-17 15:08:22 +00:00
.flash.text :
{
_stext = .;
_text_start = ABSOLUTE(.);
mapping[flash_text]
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
2016-08-17 15:08:22 +00:00
*(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */
*(.fini.literal)
*(.fini)
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
/* Similar to _iram_start, this symbol goes here so it is
resolved by addr2line in preference to the first symbol in
the flash.text segment.
*/
_flash_cache_start = ABSOLUTE(0);
2019-07-22 14:04:03 +00:00
} >default_code_seg
/* Marks the end of IRAM code segment */
.iram0.text_end (NOLOAD) :
{
. = ALIGN (4);
_iram_text_end = ABSOLUTE(.);
} > iram0_0_seg
.iram0.data :
{
. = ALIGN(4);
_iram_data_start = ABSOLUTE(.);
/* coredump mapping */
_coredump_iram_start = ABSOLUTE(.);
mapping[iram_coredump]
_coredump_iram_end = ABSOLUTE(.);
/* should be placed after coredump mapping */
mapping[iram0_data]
_iram_data_end = ABSOLUTE(.);
2019-07-22 14:04:03 +00:00
} > iram0_0_seg
.iram0.bss (NOLOAD) :
{
. = ALIGN(4);
_iram_bss_start = ABSOLUTE(.);
mapping[iram0_bss]
_iram_bss_end = ABSOLUTE(.);
. = ALIGN(4);
_iram_end = ABSOLUTE(.);
} > iram0_0_seg
2019-07-22 14:04:03 +00:00
/* Marks the end of data, bss and possibly rodata */
.dram0.heap_start (NOLOAD) :
{
. = ALIGN (8);
_heap_start = ABSOLUTE(.);
} > dram0_0_seg
2016-08-17 15:08:22 +00:00
}
2019-07-22 14:04:03 +00:00
ASSERT(((_iram_end - ORIGIN(iram0_0_seg)) <= LENGTH(iram0_0_seg)),
2019-07-22 14:04:03 +00:00
"IRAM0 segment data does not fit.")
ASSERT(((_heap_start - ORIGIN(dram0_0_seg)) <= LENGTH(dram0_0_seg)),
"DRAM segment data does not fit.")