我正在为裸机ARM应用程序编写一个定制的链接器脚本。应用程序存储在闪存中,目前我有一个启动代码在SDRAM中复制整个应用程序,并在SDRAM中继续执行以提高速度。我想修改这个脚本直接从flash运行整个代码,但我有问题的理解某些元素。
在下面的链接器脚本中,.ram_data
段在RAM
中有一个执行地址,在ROM
中有一个加载地址(这两个部分都在SDRAM中)。根据我的理解,执行地址是由链接器用来做所有元素的符号解析,而不是PC相对的,但是加载地址呢?在裸机ARM的上下文中,没有程序加载器这样的东西,链接器也无法对我在flash中编写程序的位置产生任何影响,那么它实际上是用来做什么的呢?
以同样的方式,连接器如何在运行时对SDRAM (rx)或(rw)有任何影响?当我在内存区域修改这些选项时,它实际上改变了什么吗?
MEMORY
{
RAM(rw) : ORIGIN = 0x00001000, LENGTH = 12M-4K
ROM(rx) : ORIGIN = 0x007f1000, LENGTH = 60K
}
SECTIONS
{
.startup :
{ ... } > VECTOR
.rom_text :
{ ... } > ROM
.ram_data :
{
_data_start = .;
*(.data*)
_data_end = .;
} > RAM AT>ROM
.ram_bss :
{ ... } > RAM
}
给定示例链接器脚本,这两个问题是相关的。
根据我的理解,执行地址被链接器用来做所有元素的符号解析,这些元素不是PC相关的,但是加载地址呢?
以同样的方式,连接器如何在运行时对SDRAM (rx)或(rw)有任何影响?当我在内存区域修改这些选项时,它实际上改变了什么吗?
LOAD
地址是有用的,因为一切都必须编程为FLASH。这就是为什么.ram_data
应该有AT>ROM
。它告诉链接器数据将从ROM/Flash中LOAD
。在这种情况下,您必须编写一些汇编引导代码,将其从flash复制到SDRAM。
第二个问题可以通过将>ROM
放在.ram_data
部分来回答。如果这样做,链接器会报错,认为可写部分被放在只读内存中。用读/写信息标记MEMORY
部分是很好的,因为它可以帮助确保部分在正确的位置。也就是说,它是对你提供给链接器的信息进行交叉检查。
将>RAM AT>ROM
替换为>ROM
的错误使概念/问题相似。
根据我的理解,执行地址被链接器用来做所有元素的符号解析,这些元素不是PC相关的,但是加载地址呢?在裸机ARM的上下文中,没有程序加载器这样的东西,链接器也无法对我在flash中编写程序的位置产生任何影响,那么它实际上是用来做什么的呢?
该信息存储在ELF可执行文件中,并由objcopy
等工具使用,以确定二进制文件(例如,.bin
或.hex
)如何布局。最终,它会告诉程序员把程序放在哪里。
以同样的方式,连接器如何在运行时对SDRAM (rx)或(rw)有任何影响?当我在内存区域修改这些选项时,它实际上改变了什么吗?
在这个特殊的用例中,我认为这些标志只是信息。它们主要用于动态加载程序。