In aarch64 baremetal program build, some array in the C program is given section attirubtes so that they are placed at .axpudata_args0, .axpudata_args1, ... sections and This is the linkadd.h file that is included at the start of the linker script.
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;
And this is the linker script (showing parts).
INCLUDE linkadd.h
...
. = AXPUDATA_START;
_axpudata_start = .;
.axpudata : {
. = ARGBUF0;
*(.axpudata_args0)
. = ARGBUF1;
*(.axpudata_args1)
. = ARGBUF2;
*(.axpudata_args2)
. = ARGBUF3;
*(.axpudata_args3)
. = ARGBUF4;
I thought the arrays would be placed at 0xa0000000, 0xa0100000, 0xa0200000, ... But the resulting map files shows they were allocated at 0xa0000000, 0x14000000, 0x14010000, like below.
.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
Why does the args_buffer0 start from 0x14000000 not 0xa0000000? The actual buffer size is 0x2000, 0x2000, 0x40000, .. I don't know why after the program count is set to 0xa0000000, another 0xa0000000 is filled so that the args_buffer_0 starts at 0x14000000 not 0xa0000000. I have worked with linker script many times in the past but I can't figure out what is wrong in this case. I would apprecated it if any could shed some light to me here.
This is from Michael Petch's comment which is the correct answer I wanted.
When you set . (current location counter) within an output section it is an offset relative to the virtual memory address at the beginning of the current output section (in your case 0xa0000000 since you set . to 0xa0000000 outside the section). When you do . = ARGBUF0;` you are setting the location counter to 0xa0000000 + 0xa0000000 which is 0x140000000. . = ARGBUF1; inside the section sets the location counter to 0xa0000000 + 0xa0000000 + 0x100000 which is 0x140100000 and so on
So I changed linkadd.h like this :
AXPUDATA_START = 0xa0000000;
AXPUDATA_SPACE = 0x100000;
ARGBUF0 = 0;
ARGBUF1 = 1*AXPUDATA_SPACE;
ARGBUF2 = 2*AXPUDATA_SPACE;
ARGBUF3 = 3*AXPUDATA_SPACE;
and the output becomes what I wanted.
.axpudata 0x00000000a0000000 0xd00800
0x0000000000000000 . = ARGBUF0
*(.axpudata_args0)
.axpudata_args0
0x00000000a0000000 0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
0x00000000a0000000 args_buffer_0
0x0000000000100000 . = ARGBUF1
*fill* 0x00000000a0002000 0xfe000
*(.axpudata_args1)
.axpudata_args1
0x00000000a0100000 0x2000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
0x00000000a0100000 args_buffer_1
0x0000000000200000 . = ARGBUF2
*fill* 0x00000000a0102000 0xfe000
*(.axpudata_args2)
.axpudata_args2
0x00000000a0200000 0x40000 aarch64/cvp_earth/comp1_baremetal/baremetal_bm.o
0x00000000a0200000 args_buffer_2
0x0000000000300000 . = ARGBUF3
*fill* 0x00000000a0240000 0xc0000