From be5563207d82c85134602c47fe2b4159873096a6 Mon Sep 17 00:00:00 2001 From: Sachin Parekh Date: Fri, 31 Jul 2020 12:26:29 +0530 Subject: [PATCH] esp32: Provision to redirect .bss to external ram through linker fragments Include external ram section in the linker template to process it through linker script generation mechanism. This enables redirection of .bss section to external memory using linker fragments libnet80211, libpp, libbt, liblwip: Redirect .bss through fragments --- components/bt/CMakeLists.txt | 3 ++- components/bt/linker.lf | 5 ++++ components/esp32/CMakeLists.txt | 6 ----- components/esp32/component.mk | 5 ---- components/esp32/ld/esp32.extram.bss.ld | 18 -------------- components/esp32/ld/esp32.project.ld.in | 24 +++++++++---------- components/esp32/ld/esp32_fragments.lf | 26 +++++++++++++++++++++ components/esp_common/Kconfig.spiram.common | 9 ++++--- components/esp_wifi/linker.lf | 6 +++++ components/lwip/linker.lf | 3 +++ docs/en/api-guides/external-ram.rst | 2 ++ 11 files changed, 61 insertions(+), 46 deletions(-) create mode 100644 components/bt/linker.lf delete mode 100644 components/esp32/ld/esp32.extram.bss.ld diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 3f87bcce54..307a4e73b5 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -564,7 +564,8 @@ idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "${include_dirs}" PRIV_INCLUDE_DIRS "${priv_include_dirs}" REQUIRES nvs_flash soc esp_timer esp_pm - PRIV_REQUIRES esp_ipc) + PRIV_REQUIRES esp_ipc + LDFRAGMENTS "linker.lf") if(CONFIG_BT_ENABLED) target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-implicit-fallthrough -Wno-unused-const-variable) diff --git a/components/bt/linker.lf b/components/bt/linker.lf new file mode 100644 index 0000000000..f239404450 --- /dev/null +++ b/components/bt/linker.lf @@ -0,0 +1,5 @@ +[mapping:bt] +archive: libbt.a +entries: + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index fb8dad87df..b805a5c539 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -42,12 +42,6 @@ else() target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/esp32_out.ld") - - if(CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY) - # This has to be linked before esp32.project.ld - target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.extram.bss.ld") - endif() - # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" diff --git a/components/esp32/component.mk b/components/esp32/component.mk index b3fc34d33f..8eed73f91e 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -4,11 +4,6 @@ COMPONENT_SRCDIRS := . -ifdef CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - # This linker script must come before esp32.project.ld - LINKER_SCRIPTS += esp32.extram.bss.ld -endif - #Linker scripts used to link the final application. #Warning: These linker scripts are only used when the normal app is compiled; the bootloader #specifies its own scripts. diff --git a/components/esp32/ld/esp32.extram.bss.ld b/components/esp32/ld/esp32.extram.bss.ld deleted file mode 100644 index 582f6eb6ea..0000000000 --- a/components/esp32/ld/esp32.extram.bss.ld +++ /dev/null @@ -1,18 +0,0 @@ -/* This section is only included if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - is set, to link some sections to BSS in PSRAM */ - -SECTIONS -{ - /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ - .ext_ram.bss (NOLOAD) : - { - _ext_ram_bss_start = ABSOLUTE(.); - *(.ext_ram.bss*) - *libnet80211.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) - *libpp.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) - *liblwip.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) - *libbt.a:(EXCLUDE_FILE (libbtdm_app.a) .dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON) - . = ALIGN(4); - _ext_ram_bss_end = ABSOLUTE(.); - } > extern_ram_seg -} diff --git a/components/esp32/ld/esp32.project.ld.in b/components/esp32/ld/esp32.project.ld.in index 7405ec19db..3f8c8165b6 100644 --- a/components/esp32/ld/esp32.project.ld.in +++ b/components/esp32/ld/esp32.project.ld.in @@ -232,12 +232,22 @@ SECTIONS _noinit_end = ABSOLUTE(.); } > dram0_0_seg + /* external memory bss, from any global variable with EXT_RAM_ATTR attribute*/ + .ext_ram.bss (NOLOAD) : + { + _ext_ram_bss_start = ABSOLUTE(.); + + mapping[extern_ram] + + . = ALIGN(4); + _ext_ram_bss_end = ABSOLUTE(.); + } > extern_ram_seg + /* Shared RAM */ .dram0.bss (NOLOAD) : { . = ALIGN (8); _bss_start = ABSOLUTE(.); - *(.ext_ram.bss*) _bt_bss_start = ABSOLUTE(.); *libbt.a:(.bss .bss.* COMMON) . = ALIGN (4); @@ -253,18 +263,6 @@ SECTIONS mapping[dram0_bss] - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.share.mem) - *(.gnu.linkonce.b.*) - . = ALIGN (8); _bss_end = ABSOLUTE(.); } > dram0_0_seg diff --git a/components/esp32/ld/esp32_fragments.lf b/components/esp32/ld/esp32_fragments.lf index 2ab27f1091..feaec8b1ac 100644 --- a/components/esp32/ld/esp32_fragments.lf +++ b/components/esp32/ld/esp32_fragments.lf @@ -15,6 +15,18 @@ entries: entries: COMMON +[sections:legacy_bss] +entries: + .dynsbss + .sbss+ + .gnu.linkonce.sb+ + .scommon + .sbss2+ + .gnu.linkonce.sb2+ + .dynbss + .share.mem + .gnu.linkonce.b+ + [sections:rodata] entries: .rodata+ @@ -64,6 +76,10 @@ entries: entries: .iram.bss+ +[sections:extram_bss] +entries: + .ext_ram.bss+ + [sections:dram] entries: .dram1+ @@ -87,6 +103,11 @@ entries: data -> dram0_data bss -> dram0_bss common -> dram0_bss + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + extram_bss -> extern_ram + else: + extram_bss -> dram0_bss + legacy_bss -> dram0_bss iram -> iram0_text iram_data -> iram0_data iram_bss -> iram0_bss @@ -130,3 +151,8 @@ entries: [scheme:wifi_rx_iram] entries: wifi_rx_iram -> iram0_text + +[scheme:extram_bss] +entries: + bss -> extern_ram + common -> extern_ram diff --git a/components/esp_common/Kconfig.spiram.common b/components/esp_common/Kconfig.spiram.common index f71f6624a4..bf45f1e0e3 100644 --- a/components/esp_common/Kconfig.spiram.common +++ b/components/esp_common/Kconfig.spiram.common @@ -94,6 +94,9 @@ config SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY default n depends on SPIRAM help - If enabled the option,and add EXT_RAM_ATTR defined your variable,then your variable will be placed in - PSRAM instead of internal memory, and placed most of variables of lwip,net802.11,pp,bluedroid library - to external memory defaultly. + If enabled, variables with EXT_RAM_ATTR attribute will be placed in SPIRAM instead of internal DRAM. + BSS section of `lwip`, `net80211`, `pp`, `bt` libraries will be automatically placed + in SPIRAM. BSS sections from other object files and libraries can also be placed in SPIRAM through + linker fragment scheme `extram_bss`. + + Note that the variables placed in SPIRAM using EXT_RAM_ATTR will be zero initialized. diff --git a/components/esp_wifi/linker.lf b/components/esp_wifi/linker.lf index 9e63817e79..9acda0dfc8 100644 --- a/components/esp_wifi/linker.lf +++ b/components/esp_wifi/linker.lf @@ -17,6 +17,9 @@ entries: if ESP32_WIFI_RX_IRAM_OPT = y: * (wifi_rx_iram) + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) + [mapping:net80211] archive: libnet80211.a entries: @@ -25,3 +28,6 @@ entries: if ESP32_WIFI_RX_IRAM_OPT = y: * (wifi_rx_iram) + + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/components/lwip/linker.lf b/components/lwip/linker.lf index 2c722f85e0..6d95da947e 100644 --- a/components/lwip/linker.lf +++ b/components/lwip/linker.lf @@ -85,3 +85,6 @@ entries: else: * (default) + + if SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: + * (extram_bss) diff --git a/docs/en/api-guides/external-ram.rst b/docs/en/api-guides/external-ram.rst index 96d6f9467c..36f2125a4b 100644 --- a/docs/en/api-guides/external-ram.rst +++ b/docs/en/api-guides/external-ram.rst @@ -95,6 +95,8 @@ If enabled, a region of the address space starting from 0x3F800000 will be used Additional data can be moved from the internal BSS segment to external RAM by applying the macro ``EXT_RAM_ATTR`` to any static declaration (which is not initialized to a non-zero value). +It is also possible to place the BSS section of a component or a library to external RAM using linker fragment scheme ``extram_bss``. + This option reduces the internal static memory used by the BSS segment. Remaining external RAM can also be added to the capability heap allocator using the method shown above.