下面是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*/
}
它将生成带有以下部分的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
我们可以看到LMA的.text
和.rodata
部分不受影响。 .data
命令仅影响AT()
部分和后面的部分。
因此,我感觉链接期间的VMA和LMA计算彼此独立。
如果没有AT()
命令,则LMA和VMA将相同。一旦有了AT()命令,它后面的部分将受到影响。
我没有在Using ld doc中找到有关此行为的详细描述。我说得对吗?
为什么AT()命令也更改FileOffset? .text和.data部分相对于FileOffset进行了交换。