ARM STR7xx的加载程序脚本

时间:2008-10-22 06:15:48

标签: gcc arm ld linker-scripts

我正在尝试使用Eclipse + CDT + yagarto(gnu toolchain)+ OpenOCD对ARM进行编程。在几个示例项目中(例如,来自yagarto站点),我找到了链接器脚本(* .ld),其中指定了许多链接信息(以及节定义)。实际上我之前没有遇到过这些文件(IAR不需要它们),我发现从初看起来有点难以理解。所以我的问题是我可以为我的目标处理器(STR710FZ2T6)使用一个这样的脚本文件和我的所有项目,或者我必须熟悉编写这些脚本并为每个项目编写它们。如果我可以为特定目标处理器的所有项目使用单个文件,请咨询我可以在哪里找到这样的通用处理器。

2 个答案:

答案 0 :(得分:3)

我的猜测是每个第三人都有不同的脚本或解决方案。有许多问题需要解决,不同的连接器将以不同的方式解决这些问题。我认为如果不是黑魔法,GNU就会变得太难了。

对于嵌入式系统,您通常会使用闪存或eeprom或其他形式的只读内存来启动。与其他处理器一样,ARM有一个向量表来告诉它基本上复位代码的位置和中断等。因此该表必须位于特定的位置,您必须告诉链接器将它放在特定的位置(第一个)

我喜欢使用的一个脚本是:

MEMORY
{
    bob (RX) : ORIGIN = 0x0000000, LENGTH = 32K
    joe (WAIL) : ORIGIN = 0x2000000, LENGTH = 256K
}

SECTIONS
{
    JANE : { startup.o } >bob
}

我通常使用ram和rom作为名字而不是bob和joe,但在这里证明了它们只是标签的名称并不重要。

主题的另一个变体:

MEMORY
{
    rom(RX)   : ORIGIN = 0x00000000, LENGTH = 0x8000
    ram(WAIL) : ORIGIN = 0x20000000, LENGTH = 0x2000
}

SECTIONS
{
    .text : { *(.text*) } > rom
}

第一个允许您以任何顺序将文件放在链接器命令行上,但您必须在startup.o文件中包含向量表。后者允许您使用任何文件名,但链接器脚本上的第一个文件需要具有向量表。

arm-thumb-elf-gcc -Wall $(COPS) vectors.o putget.o blinker2.c -T memmap -o blinker2.elf

或直接使用ld

arm-thumb-elf-ld vectors.o putget.o blinker2.o -T memmap -o blinker2.elf

RX告诉链接器将读取和执行内容放在该内存部分中,而WAIL基本上是其他所有内容。例如,如果你只有一个ram,你可以将所有标志RXWAIL放在告诉ram所在位置的行上。在这种情况下,根据您的加载程序,您可以依赖elf文件告诉加载程序从哪里开始分支,或者您可以简单地将入口点作为二进制文件的开头,并且加载程序可以更简单。臂(不是cortex-m3)有一个分支指令作为复位向量的第一个向量,所以你可以假装为ram解决方案构建一个向量表,并且只能工作。

这个解决方案的许多问题都不会让我感到困扰。我在代码中初始化变量,而不是在声明期间。

int rx;

int main ( void )
{
  rx = 7;

而不是

int rx=7;

int main ( void )
{

我也从不认为代码启动时变量为零我在开始之前总是把它初始化为某个东西。您的启动代码和链接器脚本作为一个团队可以一起工作,以便更容易自动重置bss代码并在启动时将非零初始化数据从rom复制到ram。 (int rx = 7;上面需要一些代码从rom中的某处复制值7并将其写入ram中为变量rx分配的内存位置,这样当main()启动时,7就在那里。

由于这种方法,我的启动代码也非常简单:

.globl _start
_start:
    b reset
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang
    b hang

hang : b hang

reset:
    ldr sp,=0x10004000
    bl main
    b hang

您将看到或阅读有关允许启动代码和链接器脚本协同工作的解决方案,而无需对堆栈指针,堆空间等进行硬编码,再次将大量工作投入到复杂的启动中代码和链接器脚本可以获得一些自动化,也许可以节省一些工作,也许不是。自动化,如果/何时工作可以并且将减少人为错误并且这可能是一件好事,如果您经常切换芯片或尝试编写一系列在一系列芯片中工作的代码,您可能也希望这种自动化

我的底线是YES,您只能使用一个链接器脚本来执行所有ARM工作。但你必须根据该脚本定制你的工作。您可能不会找到一个适用于每个人的示例代码的脚本。脚本越复杂,借用就越难。是的,我上面的脚本很可能是在ld命令行上完成的,但回过头来的时候(gcc 2.95)我无法让它工作,所以开发了上面的最小脚本并且从那时起就一直在使用它们。不得不出于某种原因修改到第二个脚本,但是使用4.x.x,肯定是4.4.x我可以使用其中任何一个。

答案 1 :(得分:0)

没有通用链接描述文件。这些脚本非常重要,因为它们定义了内存(RAM或ROM)中各种数据和程序部分的放置位置。在IAR编译器中有一些等价物(如果我没记错的话,是xcl文件)。你显然直到现在才使用默认的。

有一篇关于STR7xx的文章称为“使用STR7xx Cross的开源工具” 开发“。您可以在yagarto主页中找到一个链接。我建议您查看它并尝试了解链接器文件的工作原理。还有一些其他配置文件需要您对它们有所了解。