STM32F072 Flash应用重定位失败:ENTRY指令作用及启动地址疑问
STM32链接脚本ENTRY指令作用及Flash偏移启动问题解答
一、ENTRY(Reset_Handler)的真实作用
ENTRY指令是链接器与加载器的逻辑入口标记,核心作用有两点:
- 告诉链接器,将
Reset_Handler标记为程序的逻辑起始点,供调试器启动程序时定位执行入口,或给操作系统等加载器指明程序启动位置。 - 避免链接器因
Reset_Handler未被其他代码直接引用而将其优化(不过你的脚本中已经用KEEP(*(.isr_vector))保护了向量表,这个作用在此场景下不突出)。
关键要明确:它完全不影响STM32的硬件启动流程。STM32上电是硬件硬逻辑,必须先从0x00000000取栈顶地址加载到MSP,再从0x00000004(映射到Flash默认起始地址0x08000004)取第一条指令执行,这个过程和链接脚本的ENTRY指令没有任何关联。
二、仅靠链接脚本能否让MCU从0x08000800启动?
不行,因为STM32的启动地址是硬件固化的,必须从0x08000004取第一条指令。仅修改链接脚本将代码放到0x08000800,MCU仍会去默认地址查找指令,必然无法正常运行。
要实现从0x08000800启动,有两种可行方案:
方案1:在默认Flash起始地址放置跳转代码
在0x08000000开始的前2KB区域,编写极简汇编启动代码:
.section .isr_vector_default,"x" .global __Vectors_default __Vectors_default: .word 0x20004000 ; 与链接脚本中_estack一致的栈顶地址 .word Reset_Handler_default Reset_Handler_default: LDR R0, =0x08000804 BX R0 ; 直接跳转到偏移后的Reset_Handler
之后在链接脚本中配置这段代码到默认Flash区域,保留原有偏移区域的配置即可。
方案2:配置NVIC向量表偏移寄存器(SCB->VTOR)
先从默认地址执行一段初始化代码,修改SCB->VTOR寄存器,将向量表偏移指向0x08000800,后续所有中断与复位都会使用新向量表:
- 在0x08000000区域放置临时Reset_Handler:
Reset_Handler_temp: LDR R0, =0xE000ED08 ; SCB->VTOR寄存器地址 LDR R1, =0x08000800 ; 新向量表起始地址 STR R1, [R0] LDR R0, =0x08000804 ; 跳转到偏移后的Reset_Handler BX R0
- 主程序代码与向量表仍放在0x08000800区域,链接脚本保持你当前的配置即可。
注意:临时Reset_Handler要足够精简,确保放在前2KB区域内,不覆盖主程序的偏移区域。
补充:你的链接脚本说明
你修改了FLASH的ORIGIN到0x08000800,这会将.isr_vector与.text都放到该偏移地址,这部分配置是正确的,但必须配合上述两种方案之一,才能绕开硬件启动的固定地址限制,让程序正常运行。
内容的提问来源于stack exchange,提问作者Evox402
相关产品推荐
相关产品推荐

