Below is the linker script from an ARM-based OS.
ENTRY(__entry) /*kernel entry (kernel/asm/boot.S)*/
/*kernel will be loaded at this address after boot*/
INCLUDE linker.ld
SECTIONS
{
/*kernel will be compiled with virtual address base at 2GB*/
. = 0x80000000 + start_address; /*2GB + start_address = (0x80010000)*/
PROVIDE(_kernel_start = .); /*defined at kernel/include/kernel.h, set to 0x80010000*/
.text : AT(start_address)
{
*(.text)
}
.data :
{
*(.data)
}
.bss :
{
*(.bss COMMON)
}
. = ALIGN(8);
PROVIDE(_fb_start = .);
. += framebuffer_size;
PROVIDE(_kernel_end = .); /*defined at kernel/include/kernel.h*/
}
It will generate an ELF file with sections like this:
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000c610 80010000 00010000 00010000 2**2 <=== LMA and FileOffset are affected starting from this section.
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rodata 0000037d 8001c610 0001c610 0001c610 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .data 00004000 80020000 00020000 00020000 2**14
CONTENTS, ALLOC, LOAD, DATA
3 .got 00000024 80024000 00024000 00024000 2**2
CONTENTS, ALLOC, LOAD, DATA
I changed the linker script to below just for experiment:
ENTRY(__entry) /*kernel entry (kernel/asm/boot.S)*/
/*kernel will be loaded at this address after boot*/
INCLUDE linker.ld
SECTIONS
{
/*kernel will be compiled with virtual address base at 2GB*/
. = 0x80000000 + start_address; /*2GB + start_address = (0x80010000)*/
PROVIDE(_kernel_start = .); /*defined at kernel/include/kernel.h, set to 0x80010000*/
.text : /*AT(start_address) */ <--------------- Here Commented!
{
*(.text)
}
.data : AT(start_address) <--------------- Move it to here!
{
*(.data)
}
.bss :
{
*(.bss COMMON)
}
. = ALIGN(8);
PROVIDE(_fb_start = .);
. += framebuffer_size;
PROVIDE(_kernel_end = .); /*defined at kernel/include/kernel.h*/
}
It will generate an ELF file with sections like this:
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000c610 80010000 80010000 00020000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rodata 0000037d 8001c610 8001c610 0002c610 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .data 00004000 80020000 00010000 00010000 2**14 <=== LMA and FileOffset are affected starting from this section.
CONTENTS, ALLOC, LOAD, DATA
3 .got 00000024 80024000 00014000 00014000 2**2
CONTENTS, ALLOC, LOAD, DATA
We can see the .text
and .rodata
sections LMA is not affected. Only the .data
section and later sections are affected by the AT()
command.
So it gives me a feeling that the VMA and LMA calculation during linking is independent of each other.
If there's no AT()
command, the LMA and VMA will be the same. Once there's a AT() command, the sections that after it will be affected.
I didn't find detailed description about this behavior in the Using ld doc. Am I correct?
And why the FileOffset is also changed by the AT() command? The .text and .data sections are swapped with regard to FileOffset.
User contributions licensed under CC BY-SA 3.0