数组放置在与链接器脚本不同的奇怪地址(arm64 裸机)

问题描述 投票:0回答:1

在 aarch64 裸机程序构建中,C 程序中的某些数组被赋予节属性,以便将它们放置在 .axpudata_args0、.axpudata_args1、... 节中,这是链接器开头包含的 linkadd.h 文件脚本。

AXPUDATA_START = 0xa0000000;
AXPUDATA_SPACE = 0x100000;
ARGBUF0 = AXPUDATA_START;
ARGBUF1 = AXPUDATA_START + AXPUDATA_SPACE;
ARGBUF2 = AXPUDATA_START + 2*AXPUDATA_SPACE;
ARGBUF3 = AXPUDATA_START + 3*AXPUDATA_SPACE;

这是链接器脚本(显示部分)。

INCLUDE linkadd.h
...
  . = AXPUDATA_START;
    _axpudata_start = .;
  .axpudata : {
        . = ARGBUF0;
        *(.axpudata_args0)
        . = ARGBUF1;
        *(.axpudata_args1)
        . = ARGBUF2;
        *(.axpudata_args2)
        . = ARGBUF3;
        *(.axpudata_args3)
        . = ARGBUF4;

我以为数组会被放置在 0xa0000000、0xa0100000、0xa0200000,...但是生成的映射文件显示它们被分配在 0xa0000000、0x14000000、0x14010000,如下所示。

.axpudata       0x00000000a0000000 0xa0d00800
                0x00000000a0000000                . = ARGBUF0
 *fill*         0x00000000a0000000 0xa0000000
 *(.axpudata_args0)
 .axpudata_args0
                0x0000000140000000     0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x0000000140000000                args_buffer_0
                0x00000000a0100000                . = ARGBUF1
 *fill*         0x0000000140002000    0xfe000
 *(.axpudata_args1)
 .axpudata_args1
                0x0000000140100000     0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x0000000140100000                args_buffer_1
                0x00000000a0200000                . = ARGBUF2
 *fill*         0x0000000140102000    0xfe000
 *(.axpudata_args2)
 .axpudata_args2
                0x0000000140200000    0x40000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
                0x0000000140200000                args_buffer_2
                0x00000000a0300000                . = ARGBUF3
 *fill*         0x0000000140240000    0xc0000

为什么args_buffer0从0x14000000开始而不是从0xa0000000开始?实际的缓冲区大小是0x2000,0x2000,0x40000,..我不知道为什么在程序计数设置为0xa0000000之后,又填充了另一个0xa0000000,以便args_buffer_0从0x14000000而不是0xa0000000开始。我过去曾多次使用链接描述文件,但我无法弄清楚这种情况下出了什么问题。如果有人可以在这里给我一些启发,我将不胜感激。

c gcc linker arm64 bare-metal
1个回答
1
投票

这是来自 Michael Petch 的评论,这是我想要的正确答案。

当您设置 . (当前位置计数器)在输出部分内 是相对于虚拟内存开头地址的偏移量 当前输出部分的(在您的情况下为 0xa0000000,因为您设置了 . 到该部分之外的 0xa0000000)。当你这样做时。 = ARGBUF0;`你是 将位置计数器设置为 0xa0000000 + 0xa0000000,即 0x140000000。 。 = ARGBUF1;该部分内设置位置计数器 到 0xa0000000 + 0xa0000000 + 0x100000 即 0x140100000 等等

所以我像这样更改了 linkadd.h :

AXPUDATA_START = 0xa0000000;
AXPUDATA_SPACE = 0x100000;
ARGBUF0 = 0;
ARGBUF1 = 1*AXPUDATA_SPACE;
ARGBUF2 = 2*AXPUDATA_SPACE;
ARGBUF3 = 3*AXPUDATA_SPACE;

输出就变成了我想要的。

.axpudata       0x00000000a0000000   0xd00800
                0x0000000000000000                . = ARGBUF0
 *(.axpudata_args0)
 .axpudata_args0
                0x00000000a0000000     0x2000 aarch64/cvp_earth/telechips_baremetal/baremetal_bm.o
                0x00000000a0000000                args_buffer_0
                0x0000000000100000                . = ARGBUF1
 *fill*         0x00000000a0002000    0xfe000
 *(.axpudata_args1)
 .axpudata_args1
                0x00000000a0100000     0x2000 aarch64/cvp_earth/telechips_baremetal/baremetal_bm.o
                0x00000000a0100000                args_buffer_1
                0x0000000000200000                . = ARGBUF2
 *fill*         0x00000000a0102000    0xfe000
 *(.axpudata_args2)
 .axpudata_args2
                0x00000000a0200000    0x40000 aarch64/cvp_earth/telechips_baremetal/baremetal_bm.o
                0x00000000a0200000                args_buffer_2
                0x0000000000300000                . = ARGBUF3
 *fill*         0x00000000a0240000    0xc0000
© www.soinside.com 2019 - 2024. All rights reserved.