From 49941733c62b58b45bca4f8e4a4a15170b111866 Mon Sep 17 00:00:00 2001 From: Shubham Kulkarni Date: Tue, 18 Aug 2020 14:59:13 +0530 Subject: [PATCH] boards: esp32: linker: move libraries and reserve DRAM regions Fix issues with restoring symbols from common ld templates Workaround esptool linker sections limit Move kernel library into IRAM Improve UDP throughput Signed-off-by: Shubham Kulkarni --- soc/xtensa/esp32/linker.ld | 207 ++++++++++++++++++++++++------------- 1 file changed, 133 insertions(+), 74 deletions(-) diff --git a/soc/xtensa/esp32/linker.ld b/soc/xtensa/esp32/linker.ld index 0b983544f60..8aedc5af866 100644 --- a/soc/xtensa/esp32/linker.ld +++ b/soc/xtensa/esp32/linker.ld @@ -1,6 +1,7 @@ /* * Copyright (c) 2016 Cadence Design Systems, Inc. * Copyright (c) 2017 Intel Corporation + * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd. * SPDX-License-Identifier: Apache-2.0 */ @@ -18,9 +19,10 @@ #include #define RAMABLE_REGION dram0_0_seg :dram0_0_phdr -#define ROMABLE_REGION iram0_0_seg :iram0_0_phdr +#define RAMABLE_REGION_1 dram0_1_seg :dram0_1_phdr +#define ROMABLE_REGION drom0_0_seg :drom0_0_phdr +#define IRAM_REGION iram0_0_seg :iram0_0_phdr #define FLASH_CODE_REGION irom0_0_seg :irom0_0_phdr -#define FLASH_DATA_REGION drom0_0_seg :drom0_0_phdr PROVIDE ( __stack = 0x3ffe3f20 ); @@ -30,6 +32,10 @@ PROVIDE ( intr_matrix_set = 0x4000681c ); PROVIDE ( g_ticks_per_us_app = 0x3ffe40f0 ); PROVIDE ( g_ticks_per_us_pro = 0x3ffe01e0 ); PROVIDE ( ets_delay_us = 0x40008534 ); +PROVIDE ( gpio_output_set = 0x40009b24 ); +PROVIDE ( gpio_output_set_high = 0x40009b5c ); +PROVIDE ( roundup2 = 0x4000ab7c ); +PROVIDE ( crc32_le = 0x4005cfec ); PROVIDE ( esp32_rom_uart_tx_one_char = 0x40009200 ); PROVIDE ( esp32_rom_uart_rx_one_char = 0x400092d0 ); @@ -52,7 +58,21 @@ MEMORY { iram0_0_seg(RX): org = 0x40080000, len = 0x20000 irom0_0_seg(RX): org = 0x400D0020, len = 0x330000-0x20 - dram0_0_seg(RW): org = 0x3FFB0000, len = 0x50000 + /* + * Following is DRAM memory split with reserved address ranges in ESP32: + * + * 0x3FFA_E000 - 0x3FFB_0000 (Reserved: data memory for ROM functions) + * 0x3FFB_0000 - 0x3FFE_0000 (RAM bank 1 for application usage) + * 0x3FFE_0000 - 0x3FFE_0440 (Reserved: data memory for ROM PRO CPU) + * 0x3FFE_3F20 - 0x3FFE_4350 (Reserved: data memory for ROM APP CPU) + * 0x3FFE_4350 - 0x3F10_0000 (RAM bank 2 for application usage) + * + * FIXME: + * - Utilize available memory regions to full capacity + * - Reserve memory region for BT controller library from ROM + */ + dram0_0_seg(RW): org = 0x3FFB0000, len = 0x30000 + dram0_1_seg(RW): org = 0x3FFE4350, len = 0x1BCB0 drom0_0_seg(R): org = 0x3F400020, len = 0x400000-0x20 rtc_iram_seg(RWX): org = 0x400C0000, len = 0x2000 rtc_slow_seg(RW): org = 0x50000000, len = 0x1000 @@ -65,6 +85,7 @@ PHDRS { drom0_0_phdr PT_LOAD; dram0_0_phdr PT_LOAD; + dram0_1_phdr PT_LOAD; iram0_0_phdr PT_LOAD; irom0_0_phdr PT_LOAD; } @@ -155,36 +176,36 @@ SECTIONS /* This goes here, not at top of linker script, so addr2line finds it last, and uses it in preference to the first symbol in IRAM */ _iram_start = ABSOLUTE(0); - } GROUP_LINK_IN(ROMABLE_REGION) + } GROUP_LINK_IN(IRAM_REGION) SECTION_DATA_PROLOGUE(k_objects,, ALIGN(4)) { - Z_LINK_ITERABLE(k_timer); + Z_LINK_ITERABLE_GC_ALLOWED(k_timer); . = ALIGN(4); - Z_LINK_ITERABLE(k_mem_slab); + Z_LINK_ITERABLE_GC_ALLOWED(k_mem_slab); . = ALIGN(4); - Z_LINK_ITERABLE(k_mem_pool); + Z_LINK_ITERABLE_GC_ALLOWED(k_mem_pool); . = ALIGN(4); - Z_LINK_ITERABLE(k_heap); + Z_LINK_ITERABLE_GC_ALLOWED(k_heap); . = ALIGN(4); - Z_LINK_ITERABLE(k_mutex); + Z_LINK_ITERABLE_GC_ALLOWED(k_mutex); . = ALIGN(4); - Z_LINK_ITERABLE(k_stack); + Z_LINK_ITERABLE_GC_ALLOWED(k_stack); . = ALIGN(4); - Z_LINK_ITERABLE(k_msgq); + Z_LINK_ITERABLE_GC_ALLOWED(k_msgq); . = ALIGN(4); - Z_LINK_ITERABLE(k_mbox); + Z_LINK_ITERABLE_GC_ALLOWED(k_mbox); . = ALIGN(4); - Z_LINK_ITERABLE(k_pipe); + Z_LINK_ITERABLE_GC_ALLOWED(k_pipe); . = ALIGN(4); - Z_LINK_ITERABLE(k_sem); + Z_LINK_ITERABLE_GC_ALLOWED(k_sem); . = ALIGN(4); - Z_LINK_ITERABLE(k_queue); + Z_LINK_ITERABLE_GC_ALLOWED(k_queue); } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) SECTION_DATA_PROLOGUE(net,, ALIGN(4)) { - _net_buf_pool_list = .; + _esp_net_buf_pool_list = .; KEEP(*(SORT_BY_NAME("._net_buf_pool.static.*"))) #if defined(CONFIG_NETWORKING) @@ -201,78 +222,52 @@ SECTIONS Z_ITERABLE_SECTION_RAM(_static_thread_data, 4) #pragma push_macro("Z_ITERABLE_SECTION_RAM") +#pragma push_macro("Z_ITERABLE_SECTION_RAM_GC_ALLOWED") +#undef Z_ITERABLE_SECTION_RAM_GC_ALLOWED +#define Z_ITERABLE_SECTION_RAM_GC_ALLOWED(x, y) #undef Z_ITERABLE_SECTION_RAM #define Z_ITERABLE_SECTION_RAM(x, y) #include +/* Restore original value for symbols referenced by `common-ram.ld` */ +_net_buf_pool_list = _esp_net_buf_pool_list; +#pragma pop_macro("Z_ITERABLE_SECTION_RAM_GC_ALLOWED") #pragma pop_macro("Z_ITERABLE_SECTION_RAM") - SECTION_DATA_PROLOGUE(log_static_section,,) + SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(20)) { - __log_const_start = .; + _rodata_start = ABSOLUTE(.); + +#if defined(CONFIG_NET_SOCKETS) + . = ALIGN(4); + Z_LINK_ITERABLE(net_socket_register); + . = ALIGN(4); +#endif + +#if defined(CONFIG_SETTINGS) + . = ALIGN(4); + Z_LINK_ITERABLE(settings_handler_static); + . = ALIGN(4); +#endif + + . = ALIGN(4); + __esp_log_const_start = .; KEEP(*(SORT(.log_const_*))); - __log_const_end = .; + __esp_log_const_end = .; - __log_backends_start = .; + . = ALIGN(4); + __esp_log_backends_start = .; KEEP(*("._log_backend.*")); - __log_backends_end = .; - } GROUP_LINK_IN(ROMABLE_REGION) + __esp_log_backends_end = .; - SECTION_DATA_PROLOGUE(shell_static_section,,) - { . = ALIGN(4); Z_LINK_ITERABLE(shell); . = ALIGN(4); - __shell_root_cmds_start = .; + __esp_shell_root_cmds_start = .; KEEP(*(SORT(.shell_root_cmd_*))); - __shell_root_cmds_end = .; - } GROUP_LINK_IN(ROMABLE_REGION) + __esp_shell_root_cmds_end = .; -#include - - SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4)) - { - /* Code marked as running out of IRAM */ - _iram_text_start = ABSOLUTE(.); - *(.iram1 .iram1.*) - *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) - *libesp32.a:panic.*(.literal .text .literal.* .text.*) - *librtc.a:(.literal .text .literal.* .text.*) - *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) - *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) - *libhal.a:(.literal .text .literal.* .text.*) - *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) - *libspi_flash.a:spi_flash_rom_patch.*(.literal .text .literal.* .text.*) - *libgcov.a:(.literal .text .literal.* .text.*) - *libnet80211.a:( .wifi0iram .wifi0iram.*) - *libpp.a:( .wifi0iram .wifi0iram.*) - *libnet80211.a:( .wifirxiram .wifirxiram.*) - *libpp.a:( .wifirxiram .wifirxiram.*) - _iram_text_end = ABSOLUTE(.); - } GROUP_LINK_IN(ROMABLE_REGION) - - .dram0.data : - { - _data_start = ABSOLUTE(.); - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - KEEP(*(.jcr)) - *(.dram1 .dram1.*) - _data_end = ABSOLUTE(.); . = ALIGN(4); - } GROUP_LINK_IN(RAMABLE_REGION) - - SECTION_PROLOGUE(_RODATA_SECTION_NAME,,ALIGN(16)) - { - _rodata_start = ABSOLUTE(.); *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) @@ -302,7 +297,72 @@ SECTIONS *(.gnu.version_d) . = ALIGN(4); /* this table MUST be 4-byte aligned */ _rodata_end = ABSOLUTE(.); - } GROUP_LINK_IN(FLASH_DATA_REGION) + } GROUP_LINK_IN(ROMABLE_REGION) + +#pragma push_macro("Z_ITERABLE_SECTION_ROM") +#pragma push_macro("ROMABLE_REGION") +#undef Z_ITERABLE_SECTION_ROM +#define Z_ITERABLE_SECTION_ROM(x,y) +#undef ROMABLE_REGION +/* This is to workaround limitation of `esptool` which needs single `FLASH` data segment + * which is already defined above. In case, `common-rom.ld` creates additional segments + * they will be placed in DRAM instead. */ +#define ROMABLE_REGION RAMABLE_REGION +#include +/* Restore original value for symbols referenced by `common-rom.ld` */ +__log_const_start = __esp_log_const_start; +__log_const_end = __esp_log_const_end; +__log_backends_start = __esp_log_backends_start; +__log_backends_end = __esp_log_backends_end; +__shell_root_cmds_start = __esp_shell_root_cmds_start; +__shell_root_cmds_end = __esp_shell_root_cmds_end; +#pragma pop_macro("ROMABLE_REGION") +#pragma pop_macro("Z_ITERABLE_SECTION_ROM") + + SECTION_PROLOGUE(_TEXT_SECTION_NAME, , ALIGN(4)) + { + /* Code marked as running out of IRAM */ + _iram_text_start = ABSOLUTE(.); + *(.iram1 .iram1.*) + *(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text) + *libesp32.a:panic.*(.literal .text .literal.* .text.*) + *librtc.a:(.literal .text .literal.* .text.*) + *libsubsys__net__l2__ethernet.a:(.literal .text .literal.* .text.*) + *libsubsys__net__lib__config.a:(.literal .text .literal.* .text.*) + *libsubsys__net__ip.a:(.literal .text .literal.* .text.*) + *libsubsys__net.a:(.literal .text .literal.* .text.*) + *libkernel.a:(.literal .text .literal.* .text.*) + *libsoc.a:rtc_*.*(.literal .text .literal.* .text.*) + *libsoc.a:cpu_util.*(.literal .text .literal.* .text.*) + *libhal.a:(.literal .text .literal.* .text.*) + *libgcc.a:lib2funcs.*(.literal .text .literal.* .text.*) + *libspi_flash.a:spi_flash_rom_patch.*(.literal .text .literal.* .text.*) + *libgcov.a:(.literal .text .literal.* .text.*) + *libnet80211.a:( .wifi0iram .wifi0iram.*) + *libpp.a:( .wifi0iram .wifi0iram.*) + *libnet80211.a:( .wifirxiram .wifirxiram.*) + *libpp.a:( .wifirxiram .wifirxiram.*) + _iram_text_end = ABSOLUTE(.); + } GROUP_LINK_IN(IRAM_REGION) + + .dram0.data : + { + _data_start = ABSOLUTE(.); + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + *(.data1) + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + _data_end = ABSOLUTE(.); + . = ALIGN(4); + } GROUP_LINK_IN(RAMABLE_REGION) .flash.text : { @@ -343,7 +403,6 @@ SECTIONS _bss_end = ABSOLUTE(.); } GROUP_LINK_IN(RAMABLE_REGION) - SECTION_DATA_PROLOGUE(_NOINIT_SECTION_NAME, (NOLOAD),) { . = ALIGN (8); @@ -351,7 +410,7 @@ SECTIONS *(".noinit.*") . = ALIGN (8); _heap_start = ABSOLUTE(.); - } GROUP_LINK_IN(RAMABLE_REGION) + } GROUP_LINK_IN(RAMABLE_REGION_1) #ifdef CONFIG_GEN_ISR_TABLES #include