统一hex文件超100KB时,Bootloader作为应用可加载项失效问题咨询
问题描述
- 小应用(如16KB的blinkLED)与Bootloader组成的统一Hex文件可正常运行:开关为高时停留在Bootloader,开关为低时跳转至应用实现LED闪烁;20KB/32KB以内的应用通过
btl_host.py刷写后也能正常运行。 - 127KB的应用与Bootloader组成统一Hex文件后,刷写脚本执行成功、Bootloader可正常访问,但应用无法运行;该应用单独运行时功能正常。
- 所有应用使用相同的链接脚本:
PROVIDE(_vector_spacing = 0x0001); PROVIDE(_ebase_address = 0x9D001000); _RESET_ADDR = 0xBD000000; _GEN_EXCPT_ADDR = _ebase_address + 0x180; MEMORY { kseg0_program_mem (rx) : ORIGIN = 0x9D001000, LENGTH = 0x80000 - 0x1000 kseg1_boot_mem : ORIGIN = 0xBD000000, LENGTH = 0x490 /* Bootloader Trigger Pattern 16 Bytes */ kseg1_data_mem (w!x) : ORIGIN = 0xA0000000 + 16, LENGTH = 0x20000 - 16 sfrs : ORIGIN = 0xBF800000, LENGTH = 0x100000 configsfrs : ORIGIN = 0xBFC02FF0, LENGTH = 0x10 }
可能的原因及排查方向
Bootloader跳转逻辑与地址映射问题
检查Bootloader跳转至应用的入口地址是否正确指向kseg0_program_mem的起始地址0x9D001000,确认跳转指令是否完成kseg1到kseg0的内存空间切换。同时验证统一Hex文件中Bootloader区域(0xBD000000~0xBD00048F)与应用区域(0x9D001000起)是否存在地址重叠,避免应用代码被Bootloader覆盖。中断向量表(EBASE)配置冲突
链接脚本中_ebase_address设为应用程序的起始地址0x9D001000,但Bootloader运行时可能将EBASE指向自身的异常向量区域。若跳转至应用后未重新初始化EBASE,应用触发中断时会跳回Bootloader的异常处理逻辑,导致崩溃。需确认应用启动代码中是否主动更新EBASE寄存器至0x9D001000。数据段初始化与内存范围问题
127KB应用的全局/静态变量占用的数据段可能更大,需检查其是否超出链接脚本中kseg1_data_mem的范围(0xA0000010~0xA001FFFF)。同时确认统一Hex生成时,Bootloader的数据区未覆盖应用的.data/.bss段,且Bootloader跳转前未破坏应用的数据初始化状态。Bootloader的内存/缓存配置限制
部分Bootloader对跳转后的应用内存访问有隐性限制,比如未正确配置MMU或缓存,导致大应用超出缓存范围后无法正常取指执行。检查Bootloader的跳转代码,确认是否禁用了自身的缓存,或为应用程序区域配置了正确的内存属性(如可执行、可读取)。Hex文件合并工具的兼容性问题
对比单独应用的Hex文件与统一Hex中应用段的内容,检查是否存在代码缺失、地址偏移错误。部分Hex合并工具对大尺寸文件的处理存在bug,可能导致大应用的部分代码未被正确写入Flash。
内容的提问来源于stack exchange,提问作者Saad Naeem

