我试图迫使链接器(从XC32)将相同的可执行代码放置在闪存的两个不同部分。
该应用程序使代码可以作为独立的应用程序运行,并且使复位向量可以被引导加载程序覆盖,然后引导加载器可以分支到伪复位向量。
我的链接器脚本的相关部分包括
MEMORY
{
  kseg1_boot_mem     : ORIGIN = 0xBFC00000, LENGTH = 0x480
  bootload_boot_mem  : ORIGIN = 0x9D1F0000, LENGTH = 0x480
}
SECTIONS
{
  .reset 0xBFC00000 :
  {
    KEEP(*(.reset))
  } > kseg1_boot_mem
  .bootloadreset 0x9D1F0000 :
  {
    KEEP(*(.reset))
  } > bootload_boot_mem
}使用此方法,0xBFC00000处的区域将按预期填充,但在0x9D1F0000时不会出现任何情况。我尝试过将选项--非gc-段--传递给链接器,但这似乎没有什么区别。
我的问题是:是否有可能强迫链接器将相同的代码放入两个不同的部分,以及如何这样做?
发布于 2015-12-15 12:20:12
无论这是否是解决这个问题的正确方法,我想出的解决办法是:
将启动代码移到0x9D1F0000处的区域,方法是从.reset部分中移除.reset(*(.reset))块。将asm函数放置在重置地址处,该地址跳转到重新定位的启动代码。允许引导加载程序覆盖asm函数,因为它在完成工作后将分支到启动代码。
发布于 2017-08-16 15:24:22
我通过添加新的内存区域来解决这个问题
MEMORY
{
  virtual_boot               : ORIGIN = 0xBFC00000, LENGTH = 0x200
  .
  .
  .
} 然后在第一节中添加
SECTIONS
{
  .virtualboot :
  {
    /*KEEP(*(.virtualboot))*/
    LONG(0x08000000 | ((_RESET_ADDR & 0x1FFFFFFF) >> 2));
    LONG(0x00);
  } > virtual_boot
  .
  .
  .
}_RESET_ADDR应该在前面定义,在我的代码中是
_RESET_ADDR = (0x9D006000 + 0x1000);这样,我的代码就可以在带有/不带引导加载器的MCU上运行。
https://stackoverflow.com/questions/33937887
复制相似问题