Aller au contenu

Contenu d'un fichier binaire

Les fichiers binaires .elf

Les fichiers binaires .elf sont standardisés. Ils contiennent des informations permettant de ré-adresser en mémoire leur contenu, mais également permettent d’obtenir des indications complémentaires lors du debug du programme.

La répartition des différents blocs de code et des données est résumée dans le fichier .pio/build/DISCO_F/STM32F412xG.ld.link_script.ld après compilation de votre projet.

Vous trouvez ci-après un exemple de ce fichier dans lequel nous pouvons retrouver:

  • les adresses mémoires par défaut (lines [4] et [5]),
  • les sections destinées à la mémoire Flash (> FLASH) et RAM (> RAM),
  • les différents blocs (.txt, .ARM.*, .ssb, .Heap, etc.)
STM32F412xG.ld.link_script.ld
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
M_CRASH_DATA_RAM_SIZE = 0x100;
MEMORY
{
    FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 0x100000
    RAM (rwx) : ORIGIN = 0x20000000 + (((113 * 4) + 7) & 0xFFFFFFF8), LENGTH = 0x40000 - (((113 * 4) + 7) & 0xFFFFFFF8)
}
ENTRY(Reset_Handler)
SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)
        KEEP(*(.init))
        KEEP(*(.fini))
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)
        *(.rodata*)
        KEEP(*(.eh_frame*))
    } > FLASH
    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH
    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;
    __etext = .;
    _sidata = .;
    .crash_data_ram :
    {
        . = ALIGN(8);
        __CRASH_DATA_RAM__ = .;
        __CRASH_DATA_RAM_START__ = .;
        KEEP(*(.keep.crash_data_ram))
        *(.m_crash_data_ram)
        . += M_CRASH_DATA_RAM_SIZE;
        . = ALIGN(8);
        __CRASH_DATA_RAM_END__ = .;
    } > RAM
    .data : AT (__etext)
    {
        __data_start__ = .;
        _sdata = .;
        *(vtable)
        *(.data*)
        . = ALIGN(8);
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);
        . = ALIGN(8);
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);
        . = ALIGN(8);
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);
        KEEP(*(.jcr*))
        . = ALIGN(8);
        __data_end__ = .;
        _edata = .;
    } > RAM
    .uninitialized (NOLOAD):
    {
        . = ALIGN(32);
        __uninitialized_start = .;
        *(.uninitialized)
        KEEP(*(.keep.uninitialized))
        . = ALIGN(32);
        __uninitialized_end = .;
    } > RAM
    .bss :
    {
        . = ALIGN(8);
        __bss_start__ = .;
        _sbss = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(8);
        __bss_end__ = .;
        _ebss = .;
    } > RAM
    .heap (COPY):
    {
        __end__ = .;
        PROVIDE(end = .);
        *(.heap*)
        . = ORIGIN(RAM) + LENGTH(RAM) - 0x400;
        __HeapLimit = .;
    } > RAM
    .stack_dummy (COPY):
    {
        *(.stack*)
    } > RAM
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    _estack = __StackTop;
    __StackLimit = __StackTop - 0x400;
    PROVIDE(__stack = __StackTop);
    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}

Exercice Contenu d’un fichier binaire/1

Après compilation de votre programme, vous trouvez dans le répertoire .pio/build/DISCO_F le fichier texte STM32F412xG.ld.link_script.ld.

  • D’où provient ce fichier ?
  • Observez le contenu de ce fichier et mettez en relation son contenu avec l’organisation mémoire du STM32F412 et les composants de votre programme.
  • Comparez également son contenu avec les informations données sous allocation de la mémoire dynamiquement en relation avec l’édition des liens de votre programme.
  • Dans le répertoire de l’installation de platformio .platformio/packages/toolchain-gccarmnoneeabi/bin, vous trouvez toute une série d’outils dont arm-none-eabi-readelf qui permet d’extraire de l’information de votre fichier binaire firmware.elf. Explorez celui-ci à la recherche des liens symboliques et comparez avec la définition proposée dans le fichier STM32F412xG.ld.link_script.ld.