ld - 链接描述文件中的节加载地址和执行地址

标签 ld linker-scripts bare-metal

我正在为裸机 ARM 应用程序编写自定义链接器脚本。该应用程序存储在闪存中,目前我有一个启动代码将整个应用程序复制到 SDRAM 中,并继续在 SDRAM 中执行以提高速度。我想修改此脚本以直接从闪存运行整个代码,但我在理解某些元素时遇到问题。

在下面的链接描述文件中,.ram_data 部分在 RAM 中具有执行地址,在 ROM 中具有加载地址(这两个部分都位于SDRAM)。据我了解,链接器使用执行地址来对与 PC 无关的所有元素进行符号解析,但是加载地址呢?在裸机 ARM 的环境中,不存在程序加载器之类的东西,链接器也不可能对我在闪存中编写程序的位置产生任何影响,那么它实际上是用来做什么的?

同样,链接器如何在运行时对 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
}

最佳答案

鉴于您的示例链接器脚本,这两个问题是相关的。

From what I understand the execution address is used by the linker to do the symbol resolution of all elements which are not PC relative, but what about the load address?

In the same way, how can the linker have any influence on the SDRAM being (rx) or (rw) at run-time? Does it actually change anything when I modify those options in the memory regions?

LOAD 地址非常有用,因为所有内容都必须编程到FLASH。这就是为什么 .ram_data 应该有 AT>ROM。它告诉链接器数据将从 ROM/Flash 加载。在这种情况下,您必须编写一些汇编程序引导代码,将其从闪存复制到SDRAM

第二个问题可以通过将>ROM放入.ram_data部分来回答。如果您这样做,链接器将提示<​​em>可写部分被放置在只读内存中。最好用读/写信息标记 MEMORY 部分,因为它有助于确保部分位于正确的位置。即,它是对您提供给链接器的信息的交叉检查。

>RAM AT>ROM 改为 >ROM 的错误使概念/问题相似。

关于ld - 链接描述文件中的节加载地址和执行地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15912057/

相关文章:

c++ - 如何允许并正确加载.so 文件的修改?

linux - 指定符号放置的绝对地址

c - 链接描述文件,初始化 C 变量

gcc - 如何正确使用简单的链接描述文件?可执行文件在运行时获取SIGKILL

c - bss段结束地址小于起始地址

c - ARMv7-A 裸机调用堆栈的问题

c - FatFS f_write 不工作

linux - 执行glibc的ld-2.6.1.so时收到 "Illegal Instruction"

multithreading - 裸机嵌入式设备上的线程

c - 防止 GCC LTO 删除函数