diff --git a/components/bootloader/subproject/CMakeLists.txt b/components/bootloader/subproject/CMakeLists.txt index 48746c522f5..4fba9e1ce55 100644 --- a/components/bootloader/subproject/CMakeLists.txt +++ b/components/bootloader/subproject/CMakeLists.txt @@ -74,11 +74,8 @@ idf_build_set_property(__OUTPUT_SDKCONFIG 0) # Define a property for the default linker script set(LD_DEFAULT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/main/ld/${IDF_TARGET}") project(bootloader) -if(CONFIG_ESP32P4_SELECTS_REV_LESS_V3) - target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.rev0_2.ld.in") -else() - target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.ld.in") -endif() +target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.memory.ld.in") +target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.sections.ld.in") idf_build_set_property(COMPILE_DEFINITIONS "BOOTLOADER_BUILD=1" APPEND) idf_build_set_property(COMPILE_DEFINITIONS "NON_OS_BUILD=1" APPEND) diff --git a/components/bootloader/subproject/CMakeLists_v2.txt b/components/bootloader/subproject/CMakeLists_v2.txt index 3dd1f516841..549dbd50775 100644 --- a/components/bootloader/subproject/CMakeLists_v2.txt +++ b/components/bootloader/subproject/CMakeLists_v2.txt @@ -114,11 +114,8 @@ idf_build_set_property(COMPILE_OPTIONS "-fno-stack-protector" APPEND) # Bootloader Linker script # --------------------------------------------------------------------------- set(LD_DEFAULT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/main/ld/${IDF_TARGET}") -if(CONFIG_ESP32P4_SELECTS_REV_LESS_V3) - idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.rev0_2.ld.in" APPEND) -else() - idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.ld.in" APPEND) -endif() +idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.memory.ld.in" APPEND) +idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.sections.ld.in" APPEND) # --------------------------------------------------------------------------- # Build the bootloader ELF diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld.in b/components/bootloader/subproject/main/ld/bootloader.sections.common.ld similarity index 54% rename from components/bootloader/subproject/main/ld/esp32s2/bootloader.ld.in rename to components/bootloader/subproject/main/ld/bootloader.sections.common.ld index ee61741d6e9..5c4345ba1c4 100644 --- a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld.in +++ b/components/bootloader/subproject/main/ld/bootloader.sections.common.ld @@ -1,27 +1,14 @@ /* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" -/* Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - */ - - -MEMORY -{ - iram_seg (RWX) : org = 0x4004A000, len = 0x4000 /* SRAM part of block 12 and 13 */ - iram_loader_seg (RWX) : org = 0x4004E000, len = 0x7000 /* SRAM part of block 13, Block 14 & part of 15 */ - dram_seg (RW) : org = 0x3FFE5000, len = 0x5B00 /* Part SRAM Blocks 15 & 16, ROM static buffer starts at end of this region (reclaimed after app runs) */ -} - -/* Default entry point: */ +/* Default entry point: */ ENTRY(call_start_cpu0); - SECTIONS { @@ -30,42 +17,8 @@ SECTIONS . = ALIGN (16); _loader_text_start = ABSOLUTE(.); *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libesp_rom.a:esp_rom_regi2c.*(.literal .text .literal.* .text.*) + *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ + IRAM_LOADER_TEXT_INPUTS *(.fini.literal) *(.fini) *(.gnu.version) @@ -102,7 +55,7 @@ SECTIONS *(COMMON) . = ALIGN (8); _bss_end = ABSOLUTE(.); - } >dram_seg + } > dram_seg .dram0.bootdesc : ALIGN(0x10) { @@ -110,7 +63,7 @@ SECTIONS *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ } > dram_seg - .dram0.data : + .dram0.data : ALIGN(0x10) { *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ *(.data) @@ -123,7 +76,7 @@ SECTIONS *(.gnu.linkonce.s2.*) *(.jcr) _data_end = ABSOLUTE(.); - } >dram_seg + } > dram_seg .dram0.rodata : { @@ -132,7 +85,7 @@ SECTIONS *(.rodata.*) *(.gnu.linkonce.r.*) *(.rodata1) - *(.sdata2 .sdata2.*) + *(.sdata2 .sdata2.* .srodata .srodata.*) __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); *(.xt_except_table) *(.gcc_except_table) @@ -141,7 +94,7 @@ SECTIONS *(.eh_frame_hdr) *(.eh_frame) . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ + /* C++ constructor and destructor tables, properly ordered: */ __init_array_start = ABSOLUTE(.); KEEP (*crtbegin.*(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) @@ -161,7 +114,7 @@ SECTIONS *(.dynamic) *(.gnu.version_d) _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ + /* Literals are also RO data. */ _lit4_start = ABSOLUTE(.); *(*.lit4) *(.lit4.*) @@ -169,7 +122,7 @@ SECTIONS _lit4_end = ABSOLUTE(.); . = ALIGN(4); _dram_end = ABSOLUTE(.); - } >dram_seg + } > dram_seg .iram.text : { @@ -192,68 +145,13 @@ SECTIONS _etext = .; } > iram_seg - /** This section will be used by the debugger and disassembler to get more information - * about raw data present in the code. - * Indeed, it may be required to add some padding at some points in the code - * in order to align a branch/jump destination on a particular bound. - * Padding these instructions will generate null bytes that shall be - * interpreted as data, and not code by the debugger or disassembler. - * This section will only be present in the ELF file, not in the final binary - * For more details, check GCC-212 + /** + * Discarding .rela.* sections results in the following mapping: + * .rela.text.* -> .text.* + * .rela.data.* -> .data.* + * And so forth... */ - .xt.prop 0 : - { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) - } - - .xt.lit 0 : - { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) - } - - .xtensa.info 0: { *(.xtensa.info) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } + /DISCARD/ : { *(.rela.*) } /** * This section is not included in the binary image; it is only present in the ELF file. @@ -268,4 +166,74 @@ SECTIONS KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) _noload_keep_in_elf_end = ABSOLUTE(.); } + + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + .debug_pubtypes 0 : { *(.debug_pubtypes) } + + /* DWARF 3 */ + .debug_ranges 0 : { *(.debug_ranges) } + + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + + /* GNU DWARF 2 extensions */ + .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } + .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } + + /* DWARF 4 */ + .debug_types 0 : { *(.debug_types) } + + /* DWARF 5 */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + + /** + * Miscellaneous sections + */ + .comment 0 : { *(.comment) } + .note.GNU-stack 0 : { *(.note.GNU-stack) } + + .riscv.attributes 0 : { *(.riscv.attributes) } + +/** + * .xt.prop and .xt.lit sections will be used by the debugger and disassembler + * to get more information about raw data present in the code. + * Indeed, it may be required to add some padding at some points in the code + * in order to align a branch/jump destination on a particular bound. + * Padding these instructions will generate null bytes that shall be + * interpreted as data, and not code by the debugger or disassembler. + * This section will only be present in the ELF file, not in the final binary + * For more details, check GCC-212 + */ + .xtensa.info 0 : { *(.xtensa.info) } + .xt.prop 0 : { *(.xt.prop .xt.prop.* .gnu.linkonce.prop.*) } + .xt.lit 0 : { *(.xt.lit .xt.lit.* .gnu.linkonce.p.*) } + } diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32/bootloader.ld.in deleted file mode 100644 index d45a7ad0c29..00000000000 --- a/components/bootloader/subproject/main/ld/esp32/bootloader.ld.in +++ /dev/null @@ -1,281 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/* -Linker file used to link the bootloader. -*/ - - -/* Simplified memory map for the bootloader - - The main purpose is to make sure the bootloader can load into main memory - without overwriting itself. -*/ - -MEMORY -{ - /* IRAM POOL1, used for APP CPU cache. Bootloader runs from here during the final stage of loading the app because APP CPU is still held in reset, the main app enables APP CPU cache */ - iram_loader_seg (RWX) : org = 0x40078000, len = 0x8000 /* 32KB, APP CPU cache */ - /* 63kB, IRAM. We skip the first 1k to prevent the entry point being - placed into the same range as exception vectors in the app. - This leads to idf_monitor decoding ROM bootloader "entry 0x40080xxx" - message as one of the exception vectors, which looks scary to users. - */ - iram_seg (RWX) : org = 0x40080400, len = 0xfc00 - /* 64k at the end of DRAM, after ROM bootloader stack */ - dram_seg (RW) : org = 0x3FFF0000, len = 0x6000 -} - -/* Default entry point: */ -ENTRY(call_start_cpu0); - - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libesp_rom.a:*.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } >dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : ALIGN(0x10) - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } >dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } >dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - /** This section will be used by the debugger and disassembler to get more information - * about raw data present in the code. - * Indeed, it may be required to add some padding at some points in the code - * in order to align a branch/jump destination on a particular bound. - * Padding these instructions will generate null bytes that shall be - * interpreted as data, and not code by the debugger or disassembler. - * This section will only be present in the ELF file, not in the final binary - * For more details, check GCC-212 - */ - .xt.prop 0 : - { - KEEP (*(.xt.prop .xt.prop.* .gnu.linkonce.prop.*)) - } - - .xt.lit 0 : - { - KEEP (*(.xt.lit .xt.lit.* .gnu.linkonce.p.*)) - } - - .xtensa.info 0: { *(.xtensa.info) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32/bootloader.memory.ld.in new file mode 100644 index 00000000000..0f22110658a --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32/bootloader.memory.ld.in @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/* +Linker file used to link the bootloader. +*/ + + +/* Simplified memory map for the bootloader + + The main purpose is to make sure the bootloader can load into main memory + without overwriting itself. +*/ + +MEMORY +{ + /* IRAM POOL1, used for APP CPU cache. Bootloader runs from here during the final stage of loading the app because APP CPU is still held in reset, the main app enables APP CPU cache */ + iram_loader_seg (RWX) : org = 0x40078000, len = 0x8000 /* 32KB, APP CPU cache */ + /* 63kB, IRAM. We skip the first 1k to prevent the entry point being + placed into the same range as exception vectors in the app. + This leads to idf_monitor decoding ROM bootloader "entry 0x40080xxx" + message as one of the exception vectors, which looks scary to users. + */ + iram_seg (RWX) : org = 0x40080400, len = 0xfc00 + /* 64k at the end of DRAM, after ROM bootloader stack */ + dram_seg (RW) : org = 0x3FFF0000, len = 0x6000 +} + +/* Default entry point: */ diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in new file mode 100644 index 00000000000..3a332943eed --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32/bootloader.sections.ld.in @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libesp_rom.a:*.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld.in deleted file mode 100644 index a181c16ca3d..00000000000 --- a/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld.in +++ /dev/null @@ -1,327 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-C2 ROM static data usage is as follows: - * - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only - * - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x3fcdeb70 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x3fcdcb70). - */ - -/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ -iram_dram_offset = 0x6e0000; - -/* We consider 0x3fcdcb70 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x3fcdcb70; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2800; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x403aeb70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x3fccb264 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x3fcdcb70 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x3fcdeb70 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x3fcdf4bc ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x3fcdfa70 ------------------> _dram0_rtos_reserved_end - * | | - * 0x3fcdfa74 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x3fce0000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32c2/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32c2/bootloader.memory.ld.in new file mode 100644 index 00000000000..66ee16ae8b3 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c2/bootloader.memory.ld.in @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C2 ROM static data usage is as follows: + * - 0x3fccb264 - 0x3fcdcb70: Shared buffers, used in UART/USB/SPI download mode only + * - 0x3fcdcb70 - 0x3fcdeb70: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fcdeb70 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x3fcdcb70). + */ + +/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ +iram_dram_offset = 0x6e0000; + +/* We consider 0x3fcdcb70 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x3fcdcb70; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2800; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c2/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x403aeb70, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x3fccb264 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x3fcdcb70 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x3fcdeb70 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x3fcdf4bc ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x3fcdfa70 ------------------> _dram0_rtos_reserved_end + * | | + * 0x3fcdfa74 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x3fce0000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in new file mode 100644 index 00000000000..69d70bc7d6a --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c2/bootloader.sections.ld.in @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld.in deleted file mode 100644 index 8c8d136dfb5..00000000000 --- a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld.in +++ /dev/null @@ -1,328 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-C3 ROM static data usage is as follows: - * - 0x3fccae00 - 0x3fcdc710: Shared buffers, used in UART/USB/SPI download mode only - * - 0x3fcdc710 - 0x3fcde710: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x3fcde710 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x3fcdc710). - */ - -/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ -iram_dram_offset = 0x700000; - -/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x3fcdc710; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2800; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c3/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x403ce710, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x3fccae00 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x3fcdc710 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x3fcde710 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x3fcdf060 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x3fcdf664 ------------------> _dram0_rtos_reserved_end - * | | - * 0x3fcdf830 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x3fce0000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32c3/bootloader.memory.ld.in new file mode 100644 index 00000000000..e8f3e4e5417 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c3/bootloader.memory.ld.in @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C3 ROM static data usage is as follows: + * - 0x3fccae00 - 0x3fcdc710: Shared buffers, used in UART/USB/SPI download mode only + * - 0x3fcdc710 - 0x3fcde710: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fcde710 - 0x3fce0000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x3fcdc710). + */ + +/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ +iram_dram_offset = 0x700000; + +/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x3fcdc710; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2800; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update (SRAM_DRAM_END + I_D_SRAM_OFFSET) in components/esp_system/ld/esp32c3/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x403ce710, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x3fccae00 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x3fcdc710 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x3fcde710 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x3fcdf060 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x3fcdf664 ------------------> _dram0_rtos_reserved_end + * | | + * 0x3fcdf830 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x3fce0000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in new file mode 100644 index 00000000000..3b5f2177af3 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c3/bootloader.sections.ld.in @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld.in deleted file mode 100644 index a5c932295a1..00000000000 --- a/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld.in +++ /dev/null @@ -1,332 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-C5 ROM static data usage is as follows: - * - 0x4084e5a0 - 0x4085c5a0: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4085c5a0 - 0x4085e5a0: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x4085e5a0 - 0x40860000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4085c5a0). - */ - -/* We consider 0x4085c5a0 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4085c5a0; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2A00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c5/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4084e5a0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4084e5a0 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4085c5a0 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4085e5a0 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4085f4f8 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4085fbb4 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4085fc60 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x40860000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32c5/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32c5/bootloader.memory.ld.in new file mode 100644 index 00000000000..975a12019ef --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c5/bootloader.memory.ld.in @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C5 ROM static data usage is as follows: + * - 0x4084e5a0 - 0x4085c5a0: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4085c5a0 - 0x4085e5a0: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4085e5a0 - 0x40860000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4085c5a0). + */ + +/* We consider 0x4085c5a0 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x4085c5a0; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2A00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c5/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x4084e5a0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x4084e5a0 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4085c5a0 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4085e5a0 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4085f4f8 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4085fbb4 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4085fc60 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x40860000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in new file mode 100644 index 00000000000..4b2e639c228 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c5/bootloader.sections.ld.in @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld.in deleted file mode 100644 index a0a799bed3e..00000000000 --- a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld.in +++ /dev/null @@ -1,328 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-C6 ROM static data usage is as follows: - * - 0x4086ad08 - 0x4087c610: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4087c610 - 0x4087e610: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x4087e610 - 0x40880000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4087c610). - */ - -/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4087c610; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c6/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4086E610, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility_tee.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4086ad08 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4087c610 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4087e610 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4087f564 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4087fab0 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4087fce8 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x40880000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32c6/bootloader.memory.ld.in new file mode 100644 index 00000000000..cf5950d215d --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.memory.ld.in @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C6 ROM static data usage is as follows: + * - 0x4086ad08 - 0x4087c610: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4087c610 - 0x4087e610: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4087e610 - 0x40880000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4087c610). + */ + +/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x4087c610; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c6/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x4086E610, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x4086ad08 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4087c610 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4087e610 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4087f564 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4087fab0 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4087fce8 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x40880000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in new file mode 100644 index 00000000000..970d5811ed3 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.sections.ld.in @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility_tee.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld.in deleted file mode 100644 index ccca076db96..00000000000 --- a/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld.in +++ /dev/null @@ -1,327 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-C61 ROM static data usage is as follows: - * - 0x4083e670 - 0x4084c670: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4084c670 - 0x4084e670: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x4084e670 - 0x40850000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4084c670). - */ - -/* We consider 0x4084c670 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4084c670; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c61/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4083e670, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4083e670 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4084c670 ------------------> _stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4084e670 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4084f5c8 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4084fba0 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4084fc5a ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x40850000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32c61/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32c61/bootloader.memory.ld.in new file mode 100644 index 00000000000..81cfa71c55d --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c61/bootloader.memory.ld.in @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-C61 ROM static data usage is as follows: + * - 0x4083e670 - 0x4084c670: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4084c670 - 0x4084e670: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4084e670 - 0x40850000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4084c670). + */ + +/* We consider 0x4084c670 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x4084c670; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32c61/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x4083e670, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x4083e670 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4084c670 ------------------> _stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4084e670 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4084f5c8 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4084fba0 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4084fc5a ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x40850000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in new file mode 100644 index 00000000000..235e680bb9a --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32c61/bootloader.sections.ld.in @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld.in deleted file mode 100644 index bd26b238f9e..00000000000 --- a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld.in +++ /dev/null @@ -1,326 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-H2 ROM static data usage is as follows: - * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs) - * - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4084d380). - */ - -/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4084cfd0; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h2/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4083EFD0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4083ba78 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4084d380 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4084f380 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4084fee0 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4084ffc0 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4084ffc8 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x40850000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32h2/bootloader.memory.ld.in new file mode 100644 index 00000000000..50c2f54bbd2 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.memory.ld.in @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-H2 ROM static data usage is as follows: + * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs) + * - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4084d380). + */ + +/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x4084cfd0; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h2/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x4083EFD0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x4083ba78 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4084d380 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4084f380 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4084fee0 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4084ffc0 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4084ffc8 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x40850000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in new file mode 100644 index 00000000000..2eb1cd0e221 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.sections.ld.in @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld.in deleted file mode 100644 index 6f94636ed6e..00000000000 --- a/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld.in +++ /dev/null @@ -1,326 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-H21 ROM static data usage is as follows: - * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs) - * - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4084d380). - */ - -/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x40849a78; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h21/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4083ba78, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4083ba78 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4084d380 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4084f380 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4084fee0 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4084ffc0 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4084ffc8 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x40850000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32h21/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32h21/bootloader.memory.ld.in new file mode 100644 index 00000000000..cdd6c0725c4 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h21/bootloader.memory.ld.in @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-H21 ROM static data usage is as follows: + * - 0x4083ba78 - 0x4084d380: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4084d380 - 0x4084f380: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4084f380 - 0x4084fee0: ROM .bss and .data used in startup code or nonos/early boot (can be freed when IDF runs) + * - 0x4084fee0 - 0x40850000: ROM .bss and .data used in startup code and when IDF runs (cannot be freed) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4084d380). + */ + +/* We consider 0x3fcdc710 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x40849a78; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32h21/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x4083ba78, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x4083ba78 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4084d380 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4084f380 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4084fee0 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4084ffc0 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4084ffc8 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x40850000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in new file mode 100644 index 00000000000..2eb1cd0e221 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h21/bootloader.sections.ld.in @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld.in deleted file mode 100644 index 1f8441c6a51..00000000000 --- a/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld.in +++ /dev/null @@ -1,325 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-H4 ROM static data usage is as follows: - * - 0x4084d350 - 0x4085b350: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4085b350 - 0x4085d350: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x4085d350 - 0x40860000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4085b350). - */ - -/* We consider 0x4085b350 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4085d350; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2200; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_SEG_END in components/esp_system/ld/esp32h4/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4084f350, "bootloader_iram_loader_seg_start inconsistent with SRAM_SEG_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4084d350 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4085b350 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4085d350 ------------------> __stack (pro cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4085fea8 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4085ffb4 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4085ffc4 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x40860000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32h4/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32h4/bootloader.memory.ld.in new file mode 100644 index 00000000000..602a727b8ae --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h4/bootloader.memory.ld.in @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-H4 ROM static data usage is as follows: + * - 0x4084d350 - 0x4085b350: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4085b350 - 0x4085d350: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x4085d350 - 0x40860000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4085b350). + */ + +/* We consider 0x4085b350 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x4085d350; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2200; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_SEG_END in components/esp_system/ld/esp32h4/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x4084f350, "bootloader_iram_loader_seg_start inconsistent with SRAM_SEG_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x4084d350 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4085b350 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4085d350 ------------------> __stack (pro cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4085fea8 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4085ffb4 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4085ffc4 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x40860000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in new file mode 100644 index 00000000000..235e680bb9a --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32h4/bootloader.sections.ld.in @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld.in deleted file mode 100644 index ce6ae140796..00000000000 --- a/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld.in +++ /dev/null @@ -1,332 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** - * Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-P4 ROM static data usage is as follows: - * - 0x4ff296b8 - 0x4ff3afc0: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4ff3afc0 - 0x4ff3fba4: CPU1 stack, can be reclaimed as heap after RTOS startup - * - 0x4ff3fba4 - 0x4ff40000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4087c610). - */ - -/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4ffbcfc0; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32p4/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4FFAEFC0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - *libgcc.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4ffa96b8 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4ffbafc0 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4ffbcfc0 ------------------> __stack (pro cpu) - * | | - * | | Startup app cpu stack - * | | - * 0x4ffbefc0 ------------------> __stack_app (app cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4ffbfbb0 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4ffbffa4 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4ffbffc8 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x4ffc0000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32p4/bootloader.memory.ld.in new file mode 100644 index 00000000000..e7b0611af49 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32p4/bootloader.memory.ld.in @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** + * Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-P4 ROM static data usage is as follows: + * - 0x4ff296b8 - 0x4ff3afc0: Shared buffers, used in UART/USB/SPI download mode only + * - 0x4ff3afc0 - 0x4ff3fba4: CPU1 stack, can be reclaimed as heap after RTOS startup + * - 0x4ff3fba4 - 0x4ff40000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x4087c610). + */ + +/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 + bootloader_usable_dram_end = 0x4ffbcfc0; +#else + bootloader_usable_dram_end = 0x4ff3abd0; +#endif +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32p4/memory.ld.in to the same value. + */ +#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 +#define BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED 0x4FFAEFC0 +#else +#define BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED 0x4FF2CBD0 +#endif +ASSERT(bootloader_iram_loader_seg_start == BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED, + "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * Addresses are valid for chip revision (r): + * r <= ECO4 / r > ECO4 + * 0x4ff296b8 / 0x4ffa96b8 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x4ff3afc0 / 0x4ffbafc0 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x4ff3cfc0 / 0x4ffbcfc0 ------------------> __stack (pro cpu) + * | | + * | | Startup app cpu stack + * | | + * 0x4ff3efc0 / 0x4ffbefc0 ------------------> __stack_app (app cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x4ff3fba4 / 0x4ffbfbb0 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x4ff3ff94 / 0x4ffbffa4 ------------------> _dram0_rtos_reserved_end + * | | + * 0x4ff3ffc8 / 0x4ffbffc8 ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x4ff40000 / 0x4ffc0000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev0_2.ld.in b/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev0_2.ld.in deleted file mode 100644 index 7837346e9d5..00000000000 --- a/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev0_2.ld.in +++ /dev/null @@ -1,332 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** - * Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-P4 ROM static data usage is as follows: - * - 0x4ff296b8 - 0x4ff3afc0: Shared buffers, used in UART/USB/SPI download mode only - * - 0x4ff3afc0 - 0x4ff3fba4: CPU1 stack, can be reclaimed as heap after RTOS startup - * - 0x4ff3fba4 - 0x4ff40000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x4087c610). - */ - -/* We consider 0x4087c610 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x4ff3abd0; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32p4/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x4FF2CBD0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - *libgcc.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x4ff296b8 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x4ff3afc0 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x4ff3cfc0 ------------------> __stack (pro cpu) - * | | - * | | Startup app cpu stack - * | | - * 0x4ff3efc0 ------------------> __stack_app (app cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x4ff3fba4 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x4ff3ff94 ------------------> _dram0_rtos_reserved_end - * | | - * 0x4ff3ffc8 ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x4ff40000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in new file mode 100644 index 00000000000..f54803a1894 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32p4/bootloader.sections.ld.in @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if !CONFIG_ESP32P4_SELECTS_REV_LESS_V3 +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) +#else +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) +#endif + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32s2/bootloader.memory.ld.in new file mode 100644 index 00000000000..1e8aa0c71ef --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s2/bootloader.memory.ld.in @@ -0,0 +1,21 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/* Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + */ + + +MEMORY +{ + iram_seg (RWX) : org = 0x4004A000, len = 0x4000 /* SRAM part of block 12 and 13 */ + iram_loader_seg (RWX) : org = 0x4004E000, len = 0x7000 /* SRAM part of block 13, Block 14 & part of 15 */ + dram_seg (RW) : org = 0x3FFE5000, len = 0x5B00 /* Part SRAM Blocks 15 & 16, ROM static buffer starts at end of this region (reclaimed after app runs) */ +} + +/* Default entry point: */ diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in new file mode 100644 index 00000000000..f38f53823da --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s2/bootloader.sections.ld.in @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libesp_rom.a:esp_rom_regi2c.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld.in deleted file mode 100644 index b0b31113c12..00000000000 --- a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld.in +++ /dev/null @@ -1,343 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "sdkconfig.h" - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-S3 ROM static data usage is as follows: - * - 0x3fcd7e00 - 0x3fce9704: Shared buffers, used in UART/USB/SPI download mode only - * - 0x3fce9710 - 0x3fceb710: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x3fceb710 - 0x3fced710: APP CPU stack, can be reclaimed as heap after RTOS startup - * - 0x3fced710 - 0x3fcf0000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x3fce9704). For alignment purpose we shall use value (0x3fce9700). - */ - -/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ -iram_dram_offset = 0x6f0000; - -/* We consider 0x3fce9700 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x3fce9700; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x3000; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_IRAM_END in components/esp_system/ld/esp32s3/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x403CB700, "bootloader_iram_loader_seg_start inconsistent with SRAM_IRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - /** This section will be used by the debugger and disassembler to get more information - * about raw data present in the code. - * Indeed, it may be required to add some padding at some points in the code - * in order to align a branch/jump destination on a particular bound. - * Padding these instructions will generate null bytes that shall be - * interpreted as data, and not code by the debugger or disassembler. - * This section will only be present in the ELF file, not in the final binary - * For more details, check GCC-212 - */ - .xt.prop 0 : - { - KEEP (*(.xt.prop .gnu.linkonce.prop.*)) - } - - .xt.lit 0 : - { - KEEP (*(.xt.lit .gnu.linkonce.p.*)) - } - - .xtensa.info 0: { *(.xtensa.info) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x3fcd7e00 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x3fce9710 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x3fceb710 ------------------> __stack (pro cpu) - * | | - * | | Startup app cpu stack - * | | - * 0x3fced710 ------------------> __stack_app (app cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x3fceee34 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x3fcef770 ------------------> _dram0_rtos_reserved_end - * | | - * 0x3fcef81c ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x3fcf0000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32s3/bootloader.memory.ld.in new file mode 100644 index 00000000000..a96952424b1 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s3/bootloader.memory.ld.in @@ -0,0 +1,94 @@ +/* + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-S3 ROM static data usage is as follows: + * - 0x3fcd7e00 - 0x3fce9704: Shared buffers, used in UART/USB/SPI download mode only + * - 0x3fce9710 - 0x3fceb710: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fceb710 - 0x3fced710: APP CPU stack, can be reclaimed as heap after RTOS startup + * - 0x3fced710 - 0x3fcf0000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x3fce9704). For alignment purpose we shall use value (0x3fce9700). + */ + +/* The offset between Dbus and Ibus. Used to convert between 0x403xxxxx and 0x3fcxxxxx addresses. */ +iram_dram_offset = 0x6f0000; + +/* We consider 0x3fce9700 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x3fce9700; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x3000; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len + iram_dram_offset; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_IRAM_END in components/esp_system/ld/esp32s3/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x403CB700, "bootloader_iram_loader_seg_start inconsistent with SRAM_IRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x3fcd7e00 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x3fce9710 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x3fceb710 ------------------> __stack (pro cpu) + * | | + * | | Startup app cpu stack + * | | + * 0x3fced710 ------------------> __stack_app (app cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x3fceee34 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x3fcef770 ------------------> _dram0_rtos_reserved_end + * | | + * 0x3fcef81c ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x3fcf0000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in new file mode 100644 index 00000000000..be0e97427fa --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s3/bootloader.sections.ld.in @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libesp_common.a:fpga_overrides.*(.literal.bootloader_fill_random .text.bootloader_fill_random) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in b/components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in deleted file mode 100644 index 4abb21dce74..00000000000 --- a/components/bootloader/subproject/main/ld/esp32s31/bootloader.ld.in +++ /dev/null @@ -1,335 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** Simplified memory map for the bootloader. - * Make sure the bootloader can load into main memory without overwriting itself. - * - * ESP32-S31 ROM static data usage is as follows: - * - 0x2f0696b0 - 0x2f07afb0: Shared buffers, used in UART/USB/SPI download mode only - * - 0x2f07afb0 - 0x2f07cfb0: PRO CPU stack, can be reclaimed as heap after RTOS startup - * - 0x2f07cfb0 - 0x2f080000: ROM .bss and .data (not easily reclaimable) - * - * The 2nd stage bootloader can take space up to the end of ROM shared - * buffers area (0x2f07afb0). - */ - -/* We consider 0x2f07afb0 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, - * and work out iram_seg and iram_loader_seg addresses from there, backwards. - */ - - -/* These lengths can be adjusted, if necessary: */ -bootloader_usable_dram_end = 0x2f07afb0; -bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ -bootloader_dram_seg_len = 0x5000; -bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2D00; - -/* Start of the lower region is determined by region size and the end of the higher region */ -bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; -bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; -bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; -bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; - -MEMORY -{ - iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len - iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len - dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len -} - -/* The app may use RAM for static allocations up to the start of iram_loader_seg. - * If you have changed something above and this assert fails: - * 1. Check what the new value of bootloader_iram_loader_seg start is. - * 2. Update the value in this assert. - * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32s31/memory.ld.in to the same value. - */ -ASSERT(bootloader_iram_loader_seg_start == 0x2f06cfb0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); - -/* Default entry point: */ -ENTRY(call_start_cpu0); - -SECTIONS -{ - - .iram_loader.text : - { - . = ALIGN (16); - _loader_text_start = ABSOLUTE(.); - *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram1 .iram1.*) /* catch stray IRAM_ATTR */ - *liblog.a:(.literal .text .literal.* .text.*) - /* we use either libgcc or compiler-rt, so put similar entries for them here */ - *libgcc.a:(.literal .text .literal.* .text.*) - *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) - *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) - *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) - *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) - *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) - *libspi_flash.a:*.*(.literal .text .literal.* .text.*) - *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) - *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) - *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) - *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) - *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) - *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) - *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) - *libefuse.a:*.*(.literal .text .literal.* .text.*) - *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) - *(.fini.literal) - *(.fini) - *(.gnu.version) - _loader_text_end = ABSOLUTE(.); - } > iram_loader_seg - - .iram.text : - { - . = ALIGN (16); - *(.entry.text) - *(.init.literal) - *(.init) - } > iram_seg - - - /* Shared RAM */ - .dram0.bss (NOLOAD) : - { - . = ALIGN (8); - _dram_start = ABSOLUTE(.); - _bss_start = ABSOLUTE(.); - *(.dynsbss) - *(.sbss) - *(.sbss.*) - *(.gnu.linkonce.sb.*) - *(.scommon) - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - *(.dynbss) - *(.bss) - *(.bss.*) - *(.gnu.linkonce.b.*) - *(COMMON) - . = ALIGN (8); - _bss_end = ABSOLUTE(.); - } > dram_seg - - .dram0.bootdesc : ALIGN(0x10) - { - _data_start = ABSOLUTE(.); - *(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */ - } > dram_seg - - .dram0.data : - { - *(.dram1 .dram1.*) /* catch stray DRAM_ATTR */ - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - *(.data1) - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - *(.gnu.linkonce.s2.*) - *(.jcr) - _data_end = ABSOLUTE(.); - } > dram_seg - - .dram0.rodata : - { - _rodata_start = ABSOLUTE(.); - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - *(.rodata1) - *(.sdata2 .sdata2.* .srodata .srodata.*) - __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); - *(.xt_except_table) - *(.gcc_except_table) - *(.gnu.linkonce.e.*) - *(.gnu.version_r) - *(.eh_frame_hdr) - *(.eh_frame) - . = (. + 3) & ~ 3; - /* C++ constructor and destructor tables, properly ordered: */ - __init_array_start = ABSOLUTE(.); - KEEP (*crtbegin.*(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - __init_array_end = ABSOLUTE(.); - KEEP (*crtbegin.*(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) - 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) - _rodata_end = ABSOLUTE(.); - /* Literals are also RO data. */ - _lit4_start = ABSOLUTE(.); - *(*.lit4) - *(.lit4.*) - *(.gnu.linkonce.lit4.*) - _lit4_end = ABSOLUTE(.); - . = ALIGN(4); - _dram_end = ABSOLUTE(.); - } > dram_seg - - .iram.text : - { - _stext = .; - _text_start = ABSOLUTE(.); - *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) - *(.iram .iram.*) /* catch stray IRAM_ATTR */ - *(.fini.literal) - *(.fini) - *(.gnu.version) - - /** CPU will try to prefetch up to 16 bytes of - * of instructions. This means that any configuration (e.g. MMU, PMS) must allow - * safe access to up to 16 bytes after the last real instruction, add - * dummy bytes to ensure this - */ - . += 16; - - _text_end = ABSOLUTE(.); - _etext = .; - } > iram_seg - - .riscv.attributes 0: { *(.riscv.attributes) } - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_pubtypes 0 : { *(.debug_pubtypes) } - /* DWARF 3 */ - .debug_ranges 0 : { *(.debug_ranges) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - /* GNU DWARF 2 extensions */ - .debug_gnu_pubnames 0 : { *(.debug_gnu_pubnames) } - .debug_gnu_pubtypes 0 : { *(.debug_gnu_pubtypes) } - /* DWARF 4 */ - .debug_types 0 : { *(.debug_types) } - /* DWARF 5 */ - .debug_addr 0 : { *(.debug_addr) } - .debug_line_str 0 : { *(.debug_line_str) } - .debug_loclists 0 : { *(.debug_loclists) } - .debug_macro 0 : { *(.debug_macro) } - .debug_names 0 : { *(.debug_names) } - .debug_rnglists 0 : { *(.debug_rnglists) } - .debug_str_offsets 0 : { *(.debug_str_offsets) } - - .comment 0 : { *(.comment) } - .note.GNU-stack 0: { *(.note.GNU-stack) } - - /** - * Discarding .rela.* sections results in the following mapping: - * .rela.text.* -> .text.* - * .rela.data.* -> .data.* - * And so forth... - */ - /DISCARD/ : { *(.rela.*) } - - /** - * This section is not included in the binary image; it is only present in the ELF file. - * It is used to keep certain symbols in the ELF file. - */ - .noload 0 (INFO) : - { - /* Reserve first 4 bytes as zero for vars pointed to NULL */ - . = 0; - LONG(0); - _noload_keep_in_elf_start = ABSOLUTE(.); - KEEP(*(.noload_keep_in_elf .noload_keep_in_elf.*)) - _noload_keep_in_elf_end = ABSOLUTE(.); - } -} - - -/** - * Appendix: Memory Usage of ROM bootloader - * - * 0x2f0696b0 ------------------> _dram0_0_start - * | | - * | | - * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h - * | | - * | | - * 0x2f07afb0 ------------------> __stack_sentry - * | | - * | | 2. Startup pro cpu stack (freed when IDF app is running) - * | | - * 0x2f07cfb0 ------------------> __stack (pro cpu) - * | | - * | | Startup app cpu stack - * | | - * 0x2f07efb0 ------------------> __stack_app (app cpu) - * | | - * | | - * | | 3. Shared memory only used in startup code or nonos/early boot* - * | | (can be freed when IDF runs) - * | | - * | | - * 0x2f07fb20 ------------------> _dram0_rtos_reserved_start - * | | - * | | - * | | 4. Shared memory used in startup code and when IDF runs - * | | - * | | - * 0x2f07ff24 ------------------> _dram0_rtos_reserved_end - * | | - * 0x2f07ffac ------------------> _data_start_interface - * | | - * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) - * | | - * 0x2f080000 ------------------> _data_end_interface - */ diff --git a/components/bootloader/subproject/main/ld/esp32s31/bootloader.memory.ld.in b/components/bootloader/subproject/main/ld/esp32s31/bootloader.memory.ld.in new file mode 100644 index 00000000000..dab0d419e1e --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s31/bootloader.memory.ld.in @@ -0,0 +1,91 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "sdkconfig.h" + +/** Simplified memory map for the bootloader. + * Make sure the bootloader can load into main memory without overwriting itself. + * + * ESP32-S31 ROM static data usage is as follows: + * - 0x2f0696b0 - 0x2f07afb0: Shared buffers, used in UART/USB/SPI download mode only + * - 0x2f07afb0 - 0x2f07cfb0: PRO CPU stack, can be reclaimed as heap after RTOS startup + * - 0x2f07cfb0 - 0x2f080000: ROM .bss and .data (not easily reclaimable) + * + * The 2nd stage bootloader can take space up to the end of ROM shared + * buffers area (0x2f07afb0). + */ + +/* We consider 0x2f07afb0 to be the last usable address for 2nd stage bootloader stack overhead, dram_seg, + * and work out iram_seg and iram_loader_seg addresses from there, backwards. + */ + + +/* These lengths can be adjusted, if necessary: */ +bootloader_usable_dram_end = 0x2f07afb0; +bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ +bootloader_dram_seg_len = 0x5000; +bootloader_iram_loader_seg_len = 0x7000; +bootloader_iram_seg_len = 0x2D00; + +/* Start of the lower region is determined by region size and the end of the higher region */ +bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; +bootloader_dram_seg_start = bootloader_dram_seg_end - bootloader_dram_seg_len; +bootloader_iram_loader_seg_start = bootloader_dram_seg_start - bootloader_iram_loader_seg_len; +bootloader_iram_seg_start = bootloader_iram_loader_seg_start - bootloader_iram_seg_len; + +MEMORY +{ + iram_seg (RWX) : org = bootloader_iram_seg_start, len = bootloader_iram_seg_len + iram_loader_seg (RWX) : org = bootloader_iram_loader_seg_start, len = bootloader_iram_loader_seg_len + dram_seg (RW) : org = bootloader_dram_seg_start, len = bootloader_dram_seg_len +} + +/* The app may use RAM for static allocations up to the start of iram_loader_seg. + * If you have changed something above and this assert fails: + * 1. Check what the new value of bootloader_iram_loader_seg start is. + * 2. Update the value in this assert. + * 3. Update SRAM_DRAM_END in components/esp_system/ld/esp32s31/memory.ld.in to the same value. + */ +ASSERT(bootloader_iram_loader_seg_start == 0x2f06cfb0, "bootloader_iram_loader_seg_start inconsistent with SRAM_DRAM_END"); + +/** + * Appendix: Memory Usage of ROM bootloader + * + * 0x2f0696b0 ------------------> _dram0_0_start + * | | + * | | + * | | 1. Large buffers that are only used in certain boot modes, see shared_buffers.h + * | | + * | | + * 0x2f07afb0 ------------------> __stack_sentry + * | | + * | | 2. Startup pro cpu stack (freed when IDF app is running) + * | | + * 0x2f07cfb0 ------------------> __stack (pro cpu) + * | | + * | | Startup app cpu stack + * | | + * 0x2f07efb0 ------------------> __stack_app (app cpu) + * | | + * | | + * | | 3. Shared memory only used in startup code or nonos/early boot* + * | | (can be freed when IDF runs) + * | | + * | | + * 0x2f07fb20 ------------------> _dram0_rtos_reserved_start + * | | + * | | + * | | 4. Shared memory used in startup code and when IDF runs + * | | + * | | + * 0x2f07ff24 ------------------> _dram0_rtos_reserved_end + * | | + * 0x2f07ffac ------------------> _data_start_interface + * | | + * | | 5. End of DRAM is the 'interface' data with constant addresses (ECO compatible) + * | | + * 0x2f080000 ------------------> _data_end_interface + */ diff --git a/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in b/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in new file mode 100644 index 00000000000..4b2e639c228 --- /dev/null +++ b/components/bootloader/subproject/main/ld/esp32s31/bootloader.sections.ld.in @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define IRAM_LOADER_TEXT_INPUTS \ + *liblog.a:(.literal .text .literal.* .text.*) \ + /* we use either libgcc or compiler-rt, so put similar entries for them here */ \ + *libgcc.a:(.literal .text .literal.* .text.*) \ + *libclang_rt.builtins.a:(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_clock_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_common_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_disable .text.bootloader_random_disable) \ + *libbootloader_support.a:bootloader_random*.*(.literal.bootloader_random_enable .text.bootloader_random_enable) \ + *libbootloader_support.a:bootloader_efuse.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_console_loader.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_panic.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:bootloader_soc.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_encryption_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_secure_features.*(.literal .text .literal.* .text.*) \ + *libbootloader_support.a:secure_boot_signatures_bootloader.*(.literal .text .literal.* .text.*) \ + *libmicro-ecc.a:*.*(.literal .text .literal.* .text.*) \ + *libspi_flash.a:*.*(.literal .text .literal.* .text.*) \ + *libhal.a:mmu_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:cache_hal.*(.literal .text .literal.* .text.*) \ + *libhal.a:efuse_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_wdt.a:wdt_hal_iram.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:huk_hal.*(.literal .text .literal.* .text.*) \ + *libesp_hal_security.a:key_mgr_hal.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_key_mgr.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_periph_clk.*(.literal .text .literal.* .text.*) \ + *libesp_security.a:esp_crypto_lock.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_clk.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:rtc_time.*(.literal .text .literal.* .text.*) \ + *libesp_hw_support.a:regi2c_ctrl.*(.literal .text .literal.* .text.*) \ + *libesp_hal_regi2c.a:regi2c_impl.*(.literal .text .literal.* .text.*) \ + *libefuse.a:*.*(.literal .text .literal.* .text.*) \ + *libriscv.a:rv_utils.*(.literal .text .literal.* .text.*) + +#include "bootloader.sections.common.ld" diff --git a/components/bootloader_support/private_include/bootloader_init.h b/components/bootloader_support/private_include/bootloader_init.h index 54f5eb48513..09938891e58 100644 --- a/components/bootloader_support/private_include/bootloader_init.h +++ b/components/bootloader_support/private_include/bootloader_init.h @@ -14,7 +14,7 @@ extern "C" { /**@{*/ /** - * @brief labels from bootloader linker script: bootloader.ld.in + * @brief labels from bootloader linker script: bootloader.sections.common.ld.in * */ extern int _bss_start;