Как понять связь между LMA, VMA и FileOffset? - PullRequest
0 голосов
/ 04 мая 2019

Ниже приведен скрипт компоновщика из ОС на базе 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...