Ниже приведен скрипт компоновщика из ОС на базе ARM .
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*/
}
. Он создаст файл ELF с такими разделами:
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
Я изменил скрипт компоновщика на приведенный ниже просто для эксперимента:
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*/
}
Он сгенерирует файл ELF с такими разделами:
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
Мы можем видеть .text
и .rodata
разделы LMA не затрагиваются.Команда AT()
влияет только на раздел .data
и более поздние.
Так что у меня возникает ощущение, что расчеты VMA и LMA во время соединения не зависят друг от друга.
Если нет команды AT()
, LMA и VMA будут одинаковыми.Как только появится команда AT (), разделы, которые после нее будут затронуты.
Я не нашел подробного описания этого поведения в Использование ld doc .Я прав?
И почему FileOffset также изменяется командой AT ()?Разделы .text и .data меняются местами в отношении FileOffset.