Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

Област с 0x00 в края на генерирания от GCC bin
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=16275
Страница 1 от 2

Автор:  Nikola Kirov [ Вто Дек 25, 2018 2:08 pm ]
Заглавие:  Област с 0x00 в края на генерирания от GCC bin

Направо ме подлуди този път. Вече 7-8 часа се боря. В края на бинарния файл имам голяма област с нули и то извън диапазона за flash който съм задал.
Процесора е Атмелски Cortex M0 и Компилирам с Atml Studio.

Това ми е линкерския скрипт:
Код:
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SEARCH_DIR(.)

__rom_start = 0x00002000;
__rom_size = 0x0001EFC0;

/* Memory Spaces Definitions */
MEMORY
{
  rom      (rx)  : ORIGIN = __rom_start, LENGTH = __rom_size
  ram      (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000;

/* Section Definitions */
SECTIONS
{
    .text :
    {
        . = ALIGN(4);
        _sfixed = .;
        KEEP(*(.vectors .vectors.*))
        *(.text .text.* .gnu.linkonce.t.*)
        *(.glue_7t) *(.glue_7)
        *(.rodata .rodata* .gnu.linkonce.r.*)
        *(.ARM.extab* .gnu.linkonce.armextab.*)

        /* Support C constructors, and C destructors in both user code
           and the C library. This also provides support for C++ code. */
        . = ALIGN(4);
        KEEP(*(.init))
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;

        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;

        . = ALIGN(4);
        KEEP (*crtbegin.o(.ctors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
        KEEP (*(SORT(.ctors.*)))
        KEEP (*crtend.o(.ctors))

        . = ALIGN(4);
        KEEP(*(.fini))

        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;

        KEEP (*crtbegin.o(.dtors))
        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
        KEEP (*(SORT(.dtors.*)))
        KEEP (*crtend.o(.dtors))

        . = ALIGN(4);
        _efixed = .;            /* End of text section */
    } > rom =0xABCDDCBA

    /* .ARM.exidx is sorted, so has to go in its own output section.  */
    PROVIDE_HIDDEN (__exidx_start = .);
    .ARM.exidx :
    {
      *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > rom
    PROVIDE_HIDDEN (__exidx_end = .);

    . = ALIGN(4);
    _etext = .;

      /* must be after _etext */
   /*
   .CRC (__rom_start + __rom_size - 4) : 
   {
      _crc32_ = .;
      LONG(0xCCAACC)
      KEEP(*(.CRC))
   } > rom
   */

    .relocate : AT (_etext)
    {
        . = ALIGN(4);
        _srelocate = .;
        *(.ramfunc .ramfunc.*);
        *(.data .data.*);
        . = ALIGN(4);
        _erelocate = .;
    } > ram

    /* .bss section which is used for uninitialized data */
    .bss (NOLOAD) :
    {
        . = ALIGN(4);
        _sbss = . ;
        _szero = .;
        *(.bss .bss.*)
        *(COMMON)
        . = ALIGN(4);
        _ebss = . ;
        _ezero = .;
    } > ram

   /* .no_init section which is used for uninitialized data */
    .no_init :
    {
        . = ALIGN(4);
    } > ram

    /* stack section */
    .stack (NOLOAD):
    {
        . = ALIGN(8);
        _sstack = .;
        . = . + STACK_SIZE;
        . = ALIGN(8);
        _estack = .;
    } > ram

    . = ALIGN(4);
    _end = . ;
}


Но упорито гадината слага някакви нули отзад. Интересно е като извадя hex файл се получава това в края.
Код:
:1096A400059A0000D5990000C9990000BD990000F1
:1096B4006999000041990000F4010A000100640264
:1096C4008101B32201000000889001008C90010008
:1096D400909001009890010004680100A09001009E
:1096E400A8900100AAAAAAAACDAB000050000020AD
:1096F400000000000896010028960100E89501008A
:109704000000000000000000000000000000000055
:109714000000000000000000000000000000000045
:109724000000000000000000000000000000000035
:109734000000000000000000000000000000000025
:109744000000000000000000000000000000000015
:020000022000DC
:040FBC00CCAACC00EF
:10108400000000000000000000000000000000005C
:10109400000000000000000000000000000000004C
:1010A400000000000000000000000000000000003C
:1010B400000000000000000000000000000000002C
:1010C400000000000000000000000000000000001C
:1010D400000000000000000000000000000000000C
:0810E400000000000000000004
:0400000520007A0459
:00000001FF


Изглежда че отнякъде се слага секция извън диапазона за rom който съм задал. И в бинарния фал между края на програмата и това запълва с нули.

Като откоментирам .CRC секцията си я слага на мястото и след този адрес пак същите нули.
Вече ми писна и пуснах един питонски скрипт изхода да изреже излишното.
Някой да има повече опит и да има идеи. Моите се изчерпаха. Почвам да си мисля че output converter-a който ползва Atmel Studio прави идиотията но не ми е ясно как да изясня случая.

Автор:  Zdrav [ Вто Дек 25, 2018 11:31 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Пробва ли така?
Код:
...
.CRC (__rom_start + __rom_size - 4) (NOLOAD):
{
...
} > rom
...


Друг вариант е да направиш отделен регион за CRC-то:
Код:
MEMORY
{
  rom      (rx)  : ORIGIN = 0x00002000, LENGTH = 0x0001EFBC
  crc      (rx)  : ORIGIN = 0x00020FBC, LENGTH = 4
  ram      (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000
}

...

.CRC (NOLOAD) :
{
      _crc32_ = .;
      LONG(0xCCAACC)
      KEEP(*(.CRC))
} > crc

...

Автор:  Nikola Kirov [ Сря Дек 26, 2018 10:29 am ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Може би не съм обяснил правилно, с CRC то и без него все си имам такъв регион с нули. Просто като го включа за тест го слага на верния адрес и нулите си продължават. Това го писах само като някаква допълнителна зависимост която открих.

Автор:  Zdrav [ Сря Дек 26, 2018 10:46 am ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Да, на някои места ми се губеше нишката на обясненията.
А .map файл имаш ли генериран?
-T mapfile.map при извикването на линкера.
В .map файла би трябвало да видиш какво мапва на тези адреси. Възможно е да имаш входна секция, която не е указано в линкер скрипта, къде в коя изходна секция да отиде.Вероятно имаш секция за която линкера предполага, че трябва да се инициализира и съответно заделя и в rom региона неявно секция с нули която се предполага при стартъп да бъде качена в ram.

Автор:  Nikola Kirov [ Сря Дек 26, 2018 1:25 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Гледам ама нищо не е отбелязано след CRC32 то.
Ето я тази част която гледам:

Код:
.ARM.exidx      0x000197a4        0x8
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
.ARM.exidx     0x000197a4        0x8 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m\libgcc.a(_udivmoddi4.o)
                [!provide]                PROVIDE (__exidx_end, .)

.eh_frame       0x000197ac        0x0
.eh_frame      0x000197ac        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m/crtbegin.o

.rel.dyn        0x000197ac        0x0
.rel.iplt      0x000197ac        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m/crtbegin.o

.jcr            0x000197ac        0x0
.jcr           0x000197ac        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m/crtbegin.o

.igot.plt       0x000197ac        0x0
.igot.plt      0x000197ac        0x0 c:/program files (x86)/atmel/studio/7.0/toolchain/arm/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/6.3.1/thumb/v6-m/crtbegin.o
                0x000197ac                . = ALIGN (0x4)
                0x000197ac                _etext = .

.CRC            0x00020fbc        0x4
                0x00020fbc                _crc32_ = .
                0x00020fbc        0x4 LONG 0xccaacc
*(.CRC)

.relocate       0x20000000       0xb0 load address 0x000197ac
                0x20000000                . = ALIGN (0x4)
                0x20000000                _srelocate = .
*(.ramfunc .ramfunc.*)
*(.data .data.*)
.data.esp_io_functions
                0x20000000       0x18 Library/ESP_comm.o


Ако някъде другаде във файла може да е отбелязано, то не се сещам къде.

Автор:  Nikola Kirov [ Сря Дек 26, 2018 1:34 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Всъщност имам версия която е с орязана функционалност. Тоест генерира по малко код.
При нея генерирания бин е в размера на rom от линкерския скрипт. Но областта с нули е след генерирания код.

Автор:  Zdrav [ Сря Дек 26, 2018 3:11 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Имам смътен спомен че и аз съм срещал този проблем. Останало ми е в главата, че заклинанието (NOLOAD) го решаваше.
Според мен съмнението, че някой Атмелски-Микрочипски output converter прави проблемите може да се провери като ръчно изгенерираш от .elf файла hex файл с objcopy(вероятно при теб е arm-none-eabi-objcopy). И най-вероятно при теб за генерирането на hex файла се ползва точно objcopy, а не някакъв convertor.
Кои версии на gcc и ld се ползват?

Автор:  Nikola Kirov [ Сря Дек 26, 2018 4:10 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Ебаси и лайняната работа.

Код:
   /* .no_init section which is used for uninitialized data */
    .no_init (NOLOAD):
    {
        . = ALIGN(4);
    } > ram


Точно това заклинание оправи работата. Но какъв му е зора? Нали това е секция в рама?
Много благодаря за подсказките :)

Автор:  Zdrav [ Сря Дек 26, 2018 4:32 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Странното е че вероятно има неявно насочени/мапнати входни секции към .no_init
В .map файла виждат ли се някакви секции в .no_init ?
Вероятно там отиват неинициализирани променливи от къстъм входна секция. Т.е. неинициализирани, но не са насочени към .bss
В този случай явно линкера решава да генерира същия по размер блок с 0x00, за да може стартъп кода да "зареди" тези нули и да инициализра с нули къстъм секцията в RAM-a.
Потърси тези къстъм секции или из .map файла или като пуснеш търсене из всички .с сорс файлове на проекта за променливи сложени в къстъм секции.
Търсиш __attribute__
и преглеждаш всички които имат следния вид:
((section(".име на къстъм секция")))
после в линкер скрипта насочваш тези секции към изходни секции и слагаш заклинанието (NOLOAD) на тези изходни секции.
Поне да бъдат явно насочени/мапнати.

Автор:  Nikola Kirov [ Сря Дек 26, 2018 5:10 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Хм , нали идеята на no_init секцията е че тази област не се инициализира?
Тази секция не е някаква моя секция а се ползва за променливите които са __no_init обявени.

Автор:  Nikola Kirov [ Сря Дек 26, 2018 7:37 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Уф GCC то си е ебало майката.
След поправката генерирания бин е неработоспособен.

След още доста блъскане на главата използвах синтаксиса на .bss секцията и стана така
Код:
   /* .no_init section which is used for uninitialized data */
    .no_init (NOLOAD):
   {
      . = ALIGN(4);
        _sno_init = . ;
      *(.no_init .no_init.*)
        *(COMMON)
        . = ALIGN(4);
      _eno_init = . ;
    } > ram


Така си работи и не генерира излишни нули в края.

Автор:  Zdrav [ Сря Дек 26, 2018 9:41 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Да, това имах предвид. В началото имаше просто една празна изходна секция .no_init
Връзката между входна и изходна не става по име. Така както си го направил сега, вътре в блока на изходната секция .no_init имаш мапнати от всички обекти, входните секции .no_init както и секциите чието име започва с този стринг т.е. .no_init.*
Това че имената на входна и изходна секция са същите е съвпадение. За име на изходна секция би трябвало да можеш да сложиш каквото име си избереш.
Обаче как и защо преди това е мапвал точно тези секции в точно тази изходна секция е неясно.

Автор:  Nikola Kirov [ Сря Дек 26, 2018 10:45 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Нямаше нищо в map файла свързано с no_init.
Извратена работа.
Поне някакво предупреждение да изгенерира.
Изобщо колкото пъти съм стигал да правя нещо по линкерски конфигурационен файл на GCC все някакъв главобол е имало.

Автор:  ДедоБоре [ Чет Дек 27, 2018 10:29 am ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

e, то писането на линкер скриптове вече се доближава до стария стил на sendmail конфига...
и (уж за твое добро) в съвременните среди, тя замества естествения интелект и ти го генерира скрипта всеки път. съответно съвсем вече нищо не знаеш какво и къде отива.

ако компилираш чужд сорс, може да има някаква вероятност някоя дефиниция да му се вижда на gcc-то като константа, без да е инициализирана :rolleyes:

с по-сложните кортекси (м7, примерно) е по-комплицирано излюването на пиленцето - копирането на .data в паметта, евентуално функции от .text в TCM и подобни алабализми, ама за кортекс М0... балигу.

Автор:  relsys [ Нед Дек 30, 2018 2:37 pm ]
Заглавие:  Re: Област с 0x00 в края на генерирания от GCC bin

Nikola Kirov написа:
Изобщо колкото пъти съм стигал да правя нещо по линкерски конфигурационен файл на GCC все някакъв главобол е имало.


А имаш ли тогава логично обяснение що го ползваш...?

Страница 1 от 2 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/