Размещение раздела .data в отдельном сегменте (шапке программы)

У меня была сложная проблема: мне нужно было получить доступ к данным инициализации .data как к отдельному сегменту для приложения Arm без операционной системы.

Я смог добиться этого, используя Регион раздела вывода.

Мой исходный скрипт компоновщика выглядел примерно так:

SECTIONS
{
    /*
     * For Cortex-M devices, the beginning of the startup code is stored in
     * the .interrupt_vector section, which goes to FLASH
     */
    .text :
    {
        . = ALIGN(4);
        KEEP(*(.interrupt_vector))
        KEEP(*(.reset))

        *(.text .text.*)            /* all remaining code */
        *(.rodata .rodata.*)        /* read-only data (constants) */
        . = ALIGN(4);
    } >FLASH
   /*
     * This address is used by the startup code to
     * initialize the .data section.
     */
    . = ALIGN(4);
    __data_init__ = .;

    .data  : AT ( __data_init__ )
    {
        . = ALIGN(4);

        /* This is used by the startup code to initialize the .data section */
        __data_start__ = . ;
        *(.data_begin .data_begin.*)
        *(.data .data.*)
        *(.data_end .data_end.*)
        . = ALIGN(4);

        /* This is used by the startup code to initialize the .data section */
        __data_end__ = . ;
    } >RAM

    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        __bss_start__ = .;
        *(.bss_begin .bss_begin.*)

        *(.bss .bss.*)
        *(COMMON)

        *(.bss_end .bss_end.*)
        . = ALIGN(4);
        __bss_end__ = .;
    } >RAM

И моя функция запуска имеет:

    /* Copy .data from FLASH to RAM */
    src = &__data_init__;
    dest = &__data_start__;
    end = &__data_end__;

    while(dest < end) {
      *dest++ = *src++;
    }

Я изменил свой скрипт компоновщика на:

SECTIONS
{
    /*
     * For Cortex-M devices, the beginning of the startup code is stored in
     * the .interrupt_vector section, which goes to FLASH
     */
    .text :
    {
        . = ALIGN(4);
        KEEP(*(.interrupt_vector))
        KEEP(*(.reset))

        *(.text .text.*)            /* all remaining code */
        *(.rodata .rodata.*)        /* read-only data (constants) */
        . = ALIGN(4);
    } >FLASH
    .data :
    {
        . = ALIGN(4);
        __data_init__ = LOADADDR (.data);

        /* This is used by the startup code to initialize the .data section */
        __data_start__ = . ;
        *(.data_begin .data_begin.*)
        *(.data .data.*)
        *(.data_end .data_end.*)
        . = ALIGN(4);

        /* This is used by the startup code to initialize the .data section */
        __data_end__ = . ;
    } >RAM AT > FLASH

    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        __bss_start__ = .;
        *(.bss_begin .bss_begin.*)

        *(.bss .bss.*)
        *(COMMON)

        *(.bss_end .bss_end.*)
        . = ALIGN(4);
        __bss_end__ = .;
    } >RAM AT > RAM

И теперь у меня есть .data как совершенно отдельный сегмент ELF:

arm-none-eabi-readelf.exe -l ../../../firmware/Cortex-M3/cm3-bootloader/Release/cm3-bootloader.elf

Elf file type is EXEC (Executable file)
Entry point 0x601b9
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x010000 0x00060000 0x00060000 0x067fc 0x067fc R E 0x10000
  LOAD           0x019b30 0x20019b30 0x000667fc 0x00064 0x00064 RW  0x10000
  LOAD           0x029b2c 0x20019b2c 0x20019b2c 0x00000 0x060e8 RW  0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text .ARM.exidx.reset
   01     .data
   02     .systemclock .bss ._stack

Кроме того, __data_init__ по-прежнему указывает именно на то место, где находится .data LMA:

.data           0x20019b30       0x64 load address 0x000680f4
                0x20019b30                . = ALIGN (0x4)
                0x000680f4                __data_init__ = LOADADDR (.data)
                0x20019b30                __data_start__ = .

Это не вопрос, это просто для регистрации, как я это сделал, на случай, если это будет полезно кому-то еще.


person Leonardo    schedule 03.03.2021    source источник
comment
Разве вы не должны опубликовать это как самостоятельный ответ? Было бы полезно, если бы часть вопроса могла более полно объяснить, чего вы стремились достичь и почему, потому что это может помочь другим людям с той же проблемой найти это. Вы хотели сделать .data отдельным сегментом — отдельно от чего?   -  person Nate Eldredge    schedule 03.03.2021
comment
Это глупый вопрос, правильный ответ Как поместить 2 раздела в 1 сегмент (Используя ld скрипты)   -  person Leonardo    schedule 03.03.2021