From fa2d2b88983ee6ac4f2f487178ac0be95a5e53c8 Mon Sep 17 00:00:00 2001 From: nuttxs Date: Mon, 26 Jan 2026 14:49:48 +0800 Subject: [PATCH] boards/xtensa: fixes for compilation and start-up issues when legacy boot mode is configured 1. Explicitly define the .rtc_reserved section to ensure RTC data that requires fixed address is correctly placed and does not conflict with other sections 2. When legacy boot is configured, vecbase must also be set and clear the BSS section 3. Cache must be disabled during Flash operations, so all Flash-operation-related functions must be placed in IRAM (internal RAM). Update the linker script for legacy boot mode Signed-off-by: nuttxs --- arch/xtensa/src/esp32s3/esp32s3_start.c | 32 ++++++------- .../esp32/common/scripts/legacy_sections.ld | 31 +++++++++++++ .../esp32s3/common/scripts/legacy_sections.ld | 46 +++++++++++++++++++ 3 files changed, 92 insertions(+), 17 deletions(-) diff --git a/arch/xtensa/src/esp32s3/esp32s3_start.c b/arch/xtensa/src/esp32s3/esp32s3_start.c index 1f7fb2e9311..eccd7dc2711 100644 --- a/arch/xtensa/src/esp32s3/esp32s3_start.c +++ b/arch/xtensa/src/esp32s3/esp32s3_start.c @@ -471,6 +471,10 @@ noinstrument_function void IRAM_ATTR __start(void) { const esp_app_desc_t *app_desc; + /* Move CPU0 exception vectors to IRAM */ + + __asm__ __volatile__ ("wsr %0, vecbase\n"::"r" (_init_start)); + #if defined(CONFIG_ESP32S3_APP_FORMAT_MCUBOOT) || \ defined(CONFIG_ESPRESSIF_SIMPLE_BOOT) size_t partition_offset = PRIMARY_SLOT_OFFSET; @@ -482,8 +486,6 @@ noinstrument_function void IRAM_ATTR __start(void) uint32_t app_drom_vaddr = (uint32_t)_image_drom_vma; #ifdef CONFIG_ESPRESSIF_SIMPLE_BOOT - __asm__ __volatile__ ("wsr %0, vecbase\n"::"r" (_init_start)); - if (bootloader_init() != 0) { ets_printf("Hardware init failed, aborting\n"); @@ -491,21 +493,6 @@ noinstrument_function void IRAM_ATTR __start(void) } #endif -#ifndef CONFIG_ESPRESSIF_SIMPLE_BOOT - /* Move CPU0 exception vectors to IRAM */ - - __asm__ __volatile__ ("wsr %0, vecbase\n"::"r" (_init_start)); - - /* Clear .bss. We'll do this inline (vs. calling memset) just to be - * certain that there are no issues with the state of global variables. - */ - - for (uint32_t *dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) - { - *dest++ = 0; - } -#endif - if (map_rom_segments(app_drom_start, app_drom_vaddr, app_drom_size, app_irom_start, app_irom_vaddr, app_irom_size) != 0) { @@ -514,6 +501,17 @@ noinstrument_function void IRAM_ATTR __start(void) } #endif +#ifndef CONFIG_ESPRESSIF_SIMPLE_BOOT + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (uint32_t *dest = (uint32_t *)_sbss; dest < (uint32_t *)_ebss; ) + { + *dest++ = 0; + } +#endif + app_desc = esp_app_get_description(); if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) { diff --git a/boards/xtensa/esp32/common/scripts/legacy_sections.ld b/boards/xtensa/esp32/common/scripts/legacy_sections.ld index 1442432f664..af254b44b41 100644 --- a/boards/xtensa/esp32/common/scripts/legacy_sections.ld +++ b/boards/xtensa/esp32/common/scripts/legacy_sections.ld @@ -111,6 +111,22 @@ SECTIONS *libsched.a:sched_unlock.*(.literal .text .literal.* .text.*) *libsched.a:spinlock.*(.literal .text .literal.* .text.*) + *libarch.a:esp_spiflash.*(.literal .text .literal.* .text.*) + *libarch.a:esp_flash_api.*(.text .text.* .literal .literal.*) + *libarch.a:esp_flash_spi_init.*(.text .text.* .literal .literal.*) + *libarch.a:spi_flash_hal_iram.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_encrypt_hal_iram.*(.text .text.* .literal .literal.*) + *libarch.a:spi_flash_hal_gpspi.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_chip*.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_wrap.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_os_func_noos.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_os_func_app.*(.literal .literal.* .text .text.*) + *libarch.a:flash_brownout_hook.*(.literal .literal.* .text .text.*) + *libarch.a:esp_cache.*(.literal .literal.* .text .text.*) + *libarch.a:cache_hal_esp32.*(.literal .literal.* .text .text.*) + *libarch.a:cache_utils.*(.literal .literal.* .text .text.*) + *libarch.a:memspi_host_driver.*(.literal .literal.* .text .text.*) + *(.wifirxiram .wifirxiram.*) *(.wifi0iram .wifi0iram.*) *(.wifiorslpiram .wifiorslpiram.*) @@ -242,6 +258,21 @@ SECTIONS *libc.a:lib_stackchk.*(.rodata .rodata.*) #endif *libarch.a:esp32_spiflash.*(.rodata .rodata.*) + *libarch.a:esp_flash_api.*(.rodata .rodata.*) + *libarch.a:esp_flash_spi_init.*(.rodata .rodata.*) + *libarch.a:spi_flash_hal_iram.*(.rodata .rodata.*) + *libarch.a:spi_flash_encrypt_hal_iram.*(.rodata .rodata.*) + *libarch.a:spi_flash_hal_gpspi.*(.rodata .rodata.*) + *libarch.a:spi_flash_chip*.*(.rodata .rodata.*) + *libarch.a:spi_flash_wrap.*(.rodata .rodata.*) + *libarch.a:spi_flash_os_func_noos.*(.rodata .rodata.*) + *libarch.a:spi_flash_os_func_app.*(.rodata .rodata.*) + *libarch.a:flash_brownout_hook.*(.rodata .rodata.*) + *libarch.a:esp_cache.*(.rodata .rodata.*) + *libarch.a:cache_utils.*(.rodata .rodata.*) + *libarch.a:cache_hal_esp32.*(.rodata .rodata.*) + *libarch.a:memspi_host_driver.*(.rodata .rodata.*) + *libarch.a:xtensa_context.*(.rodata .rodata.*) *libarch.a:xtensa_copystate.*(.rodata .rodata.*) *libarch.a:xtensa_cpupause.*(.rodata .rodata.*) diff --git a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld index 3bedd957fa0..5ed2b6532af 100644 --- a/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld +++ b/boards/xtensa/esp32s3/common/scripts/legacy_sections.ld @@ -147,6 +147,19 @@ SECTIONS #endif *libarch.a:*cache_hal.*(.text .text.* .literal .literal.*) *libarch.a:*esp_rom_cache_esp32s2_esp32s3.*(.literal .text .literal.* .text.*) + *libarch.a:esp_cache.*(.literal .literal.* .text .text.*) + *libarch.a:cache_utils.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_hal_iram.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_hal_gpspi.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_encrypt_hal_iram.*(.text .text.* .literal .literal.*) + *libarch.a:spi_flash_chip*.*(.literal .literal.* .text .text.*) + *libarch.a:spi_flash_wrap.*(.literal .literal.* .text .text.*) + *libarch.a:esp_spiflash.*(.literal .text .literal.* .text.*) + *libarch.a:esp_flash_spi_init.*(.text .text.* .literal .literal.*) + *libarch.a:esp_flash_api.*(.text .text.* .literal .literal.*) + *libarch.a:spi_flash_os_func*.*(.literal .literal.* .text .text.*) + *libarch.a:*flash_brownout_hook.*(.literal .literal.* .text .text.*) + *libarch.a:memspi_host_driver.*(.literal .literal.* .text .text.*) *(.wifirxiram .wifirxiram.*) *(.wifi0iram .wifi0iram.*) @@ -238,6 +251,20 @@ SECTIONS *libc.a:lib_stackchk.*(.rodata .rodata.*) #endif + *libarch.a:esp_cache.*(.rodata .rodata.*) + *libarch.a:cache_utils.*(.rodata .rodata.*) + *libarch.a:spi_flash_hal_iram.*(.rodata .rodata.*) + *libarch.a:spi_flash_hal_gpspi.*(.rodata .rodata.*) + *libarch.a:spi_flash_encrypt_hal_iram.*(.rodata .rodata.*) + *libarch.a:spi_flash_chip*.*(.rodata .rodata.*) + *libarch.a:spi_flash_wrap.*(.rodata .rodata.*) + *libarch.a:esp_spiflash.*(.rodata .rodata.*) + *libarch.a:esp_flash_spi_init.*(.rodata .rodata.*) + *libarch.a:esp_flash_api.*(.rodata .rodata.*) + *libarch.a:spi_flash_os_func*.*(.rodata .rodata.*) + *libarch.a:flash_brownout_hook.*(.rodata .rodata.*) + *libarch.a:memspi_host_driver.*(.rodata .rodata.*) + _edata = ABSOLUTE(.); . = ALIGN(4); @@ -423,4 +450,23 @@ SECTIONS . = ALIGN (4); _srtcheap = ABSOLUTE(.); } > rtc_slow_seg + + /* This section holds RTC data that should have fixed addresses. + * The data are not initialized at power-up and are retained during deep sleep. + */ + + .rtc_reserved (NOLOAD): + { + . = ALIGN(4); + _rtc_reserved_start = ABSOLUTE(.); + + /* New data can only be added here to ensure existing data are not moved. + * Because data have adhered to the end of the segment and code is relied on it. + * >> put new data here << + */ + + *(.rtc_timer_data_in_rtc_mem .rtc_timer_data_in_rtc_mem.*) + KEEP(*(.bootloader_data_rtc_mem .bootloader_data_rtc_mem.*)) + _rtc_reserved_end = ABSOLUTE(.); + } > rtc_reserved_seg }