Wie zu verstehen, die Beziehung zwischen LMA, VMA und FileOffset?

Unten ist die linker-Skript aus einer ARM-basierte 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*/
}

Es generiert eine ELF-Datei mit Abschnitten wie diesem:

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

Ich habe die linker-Skript unten einfach für das 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*/
}

Es generiert eine ELF-Datei mit Abschnitten wie diesem:

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

Wir können sehen, dass die .text und .rodata Abschnitte LMA ist nicht betroffen. Nur die .data Abschnitt und späteren Abschnitte sind betroffen von der AT() Befehl.

Also es gibt mir ein Gefühl, dass die VMA und LMA-Berechnung während der Verknüpfung ist unabhängig von einander.

Wenn es keine AT() Befehl, der LMA und VMA das gleiche sein wird. Einmal gibt es einen IN () - Befehl, in den Abschnitten, die nach betroffen sein werden.

Ich habe nicht finden eine detaillierte Beschreibung über das Verhalten bei der Verwendung von ld doc. Bin ich richtig?

Und warum die FileOffset geändert durch die AM () - Befehl? Die .text und .Daten, die Abschnitte sind vertauscht und mit Bezug auf FileOffset.