强制链接器将相同的代码放在 2 个部分中
Force the linker to put the same code in 2 sections
我试图强制链接器(来自 XC32 的 ld)将相同的可执行代码放置在闪存的两个不同部分中。
该应用程序使得代码可以 运行 作为一个独立的应用程序,并且复位向量可以被引导加载程序覆盖,然后引导加载程序可以分支到伪复位向量。
我的链接描述文件的相关部分是
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 处未放置任何内容。我尝试将选项 --no-gc-sections 传递给链接器,但它似乎没有任何区别。
我的问题是:是否可以强制链接器将相同的代码放入 2 个不同的部分,如何操作?
无论是不是解决这个问题的正确方法,我想出的解决方案是:
通过从 .reset 部分中删除 KEEP(*(.reset)) 块,将启动代码移动到 0x9D1F0000 区域。
在跳转到重新定位的启动代码的复位地址处放置一个 asm 函数。
允许引导加载程序覆盖 asm 函数,因为它会在完成工作后跳转到启动代码。
我通过添加新的内存区域解决了这个问题
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 with/without 引导加载程序
我试图强制链接器(来自 XC32 的 ld)将相同的可执行代码放置在闪存的两个不同部分中。
该应用程序使得代码可以 运行 作为一个独立的应用程序,并且复位向量可以被引导加载程序覆盖,然后引导加载程序可以分支到伪复位向量。
我的链接描述文件的相关部分是
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 处未放置任何内容。我尝试将选项 --no-gc-sections 传递给链接器,但它似乎没有任何区别。
我的问题是:是否可以强制链接器将相同的代码放入 2 个不同的部分,如何操作?
无论是不是解决这个问题的正确方法,我想出的解决方案是:
通过从 .reset 部分中删除 KEEP(*(.reset)) 块,将启动代码移动到 0x9D1F0000 区域。 在跳转到重新定位的启动代码的复位地址处放置一个 asm 函数。 允许引导加载程序覆盖 asm 函数,因为它会在完成工作后跳转到启动代码。
我通过添加新的内存区域解决了这个问题
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 with/without 引导加载程序