3

我有以下链接器脚本,它应该链接代码以在基于闪存的微控制器上运行。uC 在地址 0x0 处有闪存,在 0x40000000 处有 RAM。我想将数据部分放入闪存,但链接程序以便在 RAM 中完成对数据部分的访问。关键是,当控制器启动时,我将手动将其从闪存复制到正确的 RAM 位置。

MEMORY 
{
    flash   : ORIGIN = 0x00000000, LENGTH = 512K
    ram : ORIGIN = 0x40000000, LENGTH = 32K
    usbram   : ORIGIN = 0x7FD00000, LENGTH = 8K
    ethram   : ORIGIN = 0x7FE00000, LENGTH = 16K
}

SECTIONS
{
    .text : { *(.text) } >flash
    __end_of_text__ = .;
    .data : 
    {
        __data_beg__ = .;
        __data_beg_src__ = __end_of_text__;
        *(.data)
        __data_end__ = .;
    } >ram AT>flash
    .bss : 
    {
        __bss_beg__ = .;
        *(.bss)
    } >ram
}

如上所示的代码生成以下输出:

40000000 <__data_beg__>:
40000000:   00000001    andeq   r0, r0, r1
40000004:   00000002    andeq   r0, r0, r2
40000008:   00000003    andeq   r0, r0, r3
4000000c:   00000004    andeq   r0, r0, r4
40000010:   00000005    andeq   r0, r0, r5
40000014:   00000006    andeq   r0, r0, r6

它表示形式的数组

int foo[] = {1,2,3,4,5,6};

问题是它链接到 0x40000000,而不是我想要的闪存区域。我希望链接器脚本的 AT>flash 部分指定链接到闪存,如 LD 手册中所述。

http://sourceware.org/binutils/docs/ld/Output-Section-Attributes.html#Output-Section-Attributes

这是我的 ld 调用:

arm-elf-ld  -T ./lpc2368.ld entry.o main.o -o binary.elf

谢谢。

4

2 回答 2

1

您的链接描述文件将 .data 链接到 RAM 并将 .data 加载到 FLASH。这是由于 AT 命令。

为什么要将易失性数据链接到闪存?数据和 Bss 必须始终链接到 RAM。您的链接描述文件非常正确。您只会将文本和常量数据链接到闪存中。

请查看您的地图文件。它必然会为数据变量分配一个 RAM 地址。

然后程序加载器代码将 (data_end - data_beg) 字节从 data_beg_src 复制到 data_beg。

因此,数组的第一个数据被复制到 SRAM 的开头。

如果您需要将数据链接到闪存:

 Data :
  {
   *(.data);
  } > flash

链接器现在将链接和加载 .data 到闪存中。但如果我是你,我不会那样做。

于 2012-12-08T03:55:38.520 回答
0

您的 .data 虚拟地址 = 0x40000000

您的 .data 逻辑地址 = 0x00000000

这可以通过命令看到 objdump -h file.elf

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  8 .data         00000014  40000000  00000000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
于 2015-11-19T14:57:00.843 回答