在 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开始。我过去曾多次使用链接描述文件,但我无法弄清楚这种情况下出了什么问题。如果有人可以在这里给我一些启发,我将不胜感激。
这是来自 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