ESP32-S3汇编代码编译烧录失败问题排查求助
ESP32-S3 汇编代码无法启动问题排查
操作步骤
- 汇编代码
pin15.S:
.section .text .global _start _start: movi a2, 0x3FF44000 movi a3, 1 << 15 s32i a3, a2, 0x4 # Set output bit for GPIO 15 loop: movi a2, 0x3FF44000 movi a3, 1 << 15 s32i a3, a2, 0x4 call0 delay movi a2, 0x3FF44000 # GPIO base address movi a3, 1 << 15 # Mask for GPIO 15 s32i a3, a2, 0x8 # Clear output bit for GPIO 15 call0 delay j loop delay: movi a1, 0x3FFFFF delay_loop: addi a1, a1, -1 bnez a1, delay_loop ret
- 编译命令:
xtensa-esp32s3-elf-as -o pin15.o pin15.S xtensa-esp32s3-elf-ld -T linkerscript2.ld -o pin15.elf pin15.o
- 链接脚本
linkerscript2.ld:
ENTRY(_start) MEMORY { iram0_0_seg : ORIGIN = 0x40100000, LENGTH = 0x20000 /* Instruction RAM */ dram0_0_seg : ORIGIN = 0x3FFB0000, LENGTH = 0x20000 /* Data RAM */ } SECTIONS { .literal : { *(.literal) } > iram0_0_seg .text : { *(.text) *(.text.*) } > iram0_0_seg .data : { *(.data) *(.data.*) } > dram0_0_seg .bss : { *(.bss) *(.bss.*) } > dram0_0_seg }
- 镜像生成与烧录命令:
esptool.py --chip esp32s3 elf2image pin15.elf esptool.py --chip esp32s3 --port /dev/ttyACM0 --baud 115200 write_flash 0x10000 pin15.bin
报错信息
ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0x3 (RTC_SW_SYS_RST),boot:0x8 (SPI_FAST_FLASH_BOOT) Saved PC:0x403cdd11 SPIWP:0xee mode:DIO, clock div:1 load:0x3fce3810,len:0x1798 load:0x403c9700,len:0x4 load:0x403c9704,len:0xcbc load:0x403cc700,len:0x2d98 entry 0x403c9914 I (31) boot: ESP-IDF v5.2-dirty 2nd stage bootloader I (31) boot: compile time Aug 5 2024 03:46:49 I (31) boot: Multicore bootloader I (35) boot: chip revision: v0.2 I (38) boot.esp32s3: Boot SPI Speed : 80MHz I (43) boot.esp32s3: SPI Mode : DIO I (48) boot.esp32s3: SPI Flash Size : 2MB I (53) boot: Enabling RNG early entropy source... I (58) boot: Partition Table: I (62) boot: ## Label Usage Type ST Offset Length I (69) boot: 0 nvs WiFi data 01 02 00009000 00005000 I (76) boot: 1 otadata OTA data 01 00 0000e000 00002000 I (84) boot: 2 app0 factory app 00 00 00010000 00140000 I (91) boot: 3 spiffs Unknown data 01 82 00150000 000a0000 I (99) boot: End of partition table I (103) boot: Defaulting to factory image I (108) esp_image: segment 0: paddr=00010020 vaddr=40080000 size=00044h ( 68) load E (116) esp_image: Segment 0 0x40080000-0x40080044 invalid: bad load address range E (124) boot: Factory app partition is not bootable E (130) boot: No bootable app partitions in the partition table
排查分析与结论
核心问题根源
报错中的*E (116) esp_image: Segment 0 0x40080000-0x40080044 invalid: bad load address range*是关键。ESP32-S3的二级bootloader尝试将程序加载到0x40080000,但该地址属于MMIO区域,并非合法的IRAM地址。
问题出在镜像生成流程:手动用xtensa-esp32s3-elf-ld链接的ELF文件,没有包含ESP32-S3镜像要求的段元信息,导致esptool.py elf2image无法识别你在链接脚本中指定的0x40100000执行地址,反而默认使用了旧ESP32系列的非法加载地址。
是否需要更换分区表?
不需要。当前分区表的factory分区起始地址0x10000、长度0x140000完全符合规范,问题与分区表无关。
修复方案
修改链接脚本,添加Flash加载地址属性
给代码段和数据段指定Flash中的存储地址,让elf2image能正确生成镜像。修改后的链接脚本示例:ENTRY(_start) MEMORY { iram0_0_seg : ORIGIN = 0x40100000, LENGTH = 0x20000 /* Instruction RAM */ dram0_0_seg : ORIGIN = 0x3FFB0000, LENGTH = 0x20000 /* Data RAM */ flash_code : ORIGIN = 0x00010020, LENGTH = 0x13FFE0 /* Factory分区起始+镜像头偏移 */ } SECTIONS { .iram0.text : AT(flash_code) { _iram_text_start = .; *(.text) *(.text.*) *(.literal) _iram_text_end = .; } > iram0_0_seg .data : AT(flash_code + (_iram_text_end - _iram_text_start)) { _data_start = .; *(.data) *(.data.*) _data_end = .; } > dram0_0_seg .bss : { *(.bss) *(.bss.*) } > dram0_0_seg }其中
AT(flash_code)指定了段在Flash中的存储位置,与烧录地址对应。用ESP-IDF工具链编译(更可靠)
手动链接容易踩格式坑,推荐将汇编代码放入ESP-IDF工程:- 在工程
main目录下添加pin15.S - 修改
CMakeLists.txt,添加target_sources(app PRIVATE pin15.S) - 用
idf.py build编译,自动生成符合规范的镜像,再用idf.py flash烧录
- 在工程
验证ELF段信息
生成ELF后,执行xtensa-esp32s3-elf-readelf -l pin15.elf查看段信息,确认LOAD段的虚拟地址(VirtAddr)是你指定的IRAM地址,物理地址(PhysAddr)是Flash中的正确偏移。
内容的提问来源于stack exchange,提问作者blurrpp314
相关产品推荐
相关产品推荐

