我正在尝试在我的ARM MCU中为初始化数据创建一个额外的ram部分(在我的GNU链接器脚本中)。该部分必须放在一个已知的地址,以便我可以在MPU中为它设置特定的属性。 我在使用所有链接器魔法时遇到了一些麻烦。
记忆分为以下几种:
/* Memory Spaces Definitions */
MEMORY
{
rom (rx) : ORIGIN = 0x00420200, LENGTH = 0x001DFE00
ram (rwx) : ORIGIN = 0x20400000, LENGTH = 0x0005e000
ram_nocache_section (rwx) : ORIGIN = 0x2045e000, LENGTH = 0x00002000
sdram(rwx): ORIGIN = 0x70000000, LENGTH = 0x00200000
}
这是我正在尝试处理的“ram_nocache_section”。
我可以按如下方式定义适当的部分:
/* no cache section */
.ram_nocache :
{
. = ALIGN(8);
*(.ram_nocache)
} > ram_nocache_section
这样可行,但生成的二进制文件非常庞大。 0.5 GB。这是因为ram地址空间与闪存地址空间相距0.5 GB。解决这个问题的方法是“重新定位”初始化的ram数据。该脚本执行此操作:
.text :
{
...
} > rom
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
这将在flash和ram中神奇地分配初始化数据(和ram函数)两者。所以这很容易复制,对吗?像这样:
. = ALIGN(4);
_etext = .;
.relocate : AT (_etext)
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram
. = ALIGN(4);
_eramdata = .;
.relocate2 : AT ( _eramdata )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
这将编译,但生成的二进制文件仍然是巨大的。这是因为_eramdata符号以某种方式放在ram中,而不是像_etext那样放在flash中。
那么......根据这个document,我应该可以做这样的事情:
.relocate2 : AT ( _etext + SIZEOF(.data) + SIZEOF(.ramfunc) )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
这不会编译。相反,我可以像这样创建所需的结果:
.relocate2 : AT ( _etext + 10k )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
然而,这是一个相当脆弱和浪费的解决方案。
我该如何正确地做到这一点?我想将'relocate2'部分放在常规'relocate'部分旁边。没有任何多余的浪费或预定义的代码限制。
答案 0 :(得分:2)
我更喜欢这种结构:
. = ALIGN(4);
_etext = .;
.relocate :
{
. = ALIGN(4);
_srelocate = .;
*(.ramfunc .ramfunc.*);
*(.data .data.*);
. = ALIGN(4);
_erelocate = .;
} > ram AT>rom
.relocate2 :
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section AT>rom
两个部分都必须更改为AT> rom。 (没有混合。)
答案 1 :(得分:0)
我可能自己找到了解决方案:
.relocate2 : AT ( _etext + SIZEOF(.relocate) )
{
. = ALIGN(4);
_srelocate2 = .;
. = ALIGN(8);
*(.ram_nocache)
. = ALIGN(4);
_erelocate2 = .;
} > ram_nocache_section
我确信我已经尝试过类似的东西了。但这似乎是我想要的。尽管如此,仍然不是最优雅的解决方案。