Jump to content

    

TI out file ti bin вылезает большой размер файла

Написал свой загрузчик для C6745, который с SD карты по SPI загружает в SDRAM программы.  Всё блестяще работает на всех моих примерах.

 

Есть  одна проблема - при указании в опциях линкера (CCS v.6, TI Compiler 8.x.x) большого размера кучи (heap) бинарник вырастает до огромных размеров - идёт резервация памяти. Так как куча допускается непроинициализированной, как сделать так, чтобы при построении бинарника он не включал кучу?

 

Из OUT делаю в BIN двумя утилитами (узнал в e2e):

делаем эльфа
1) strip6x.exe -p -o app_elf.bin app.out

делаем бинарник
2) objcopy -I elf32-little -O binary app_elf.bin app.bin

 

Кто что подскажет?

Share this post


Link to post
Share on other sites
6 минут назад, __inline__ сказал:

Есть  одна проблема - при указании в опциях линкера (CCS v.6, TI Compiler 8.x.x) большого размера кучи (heap) бинарник вырастает до огромных размеров - идёт резервация памяти. Так как куча допускается непроинициализированной, как сделать так, чтобы при построении бинарника он не включал кучу?

Куча, хоть  проинициализированная хоть нет, не должна вообще никак влиять на размер образа загрузки.

Цитата

Кто что подскажет?

Видимо что-то у вас не так с атрибутами секций в командном файле компоновщика.

А вообще лучше вообще не использовать кучу. Зачем она вообще нужна? не понимаю...

 

PS: Да - и зачем вам bin? Самый удобный для этого формат - ais. bin не нужен.

Share this post


Link to post
Share on other sites
42 minutes ago, jcxz said:

А вообще лучше вообще не использовать кучу. Зачем она вообще нужна? не понимаю...

Всё хорошо, до тех пор пока программу пишите Вы сами.  Приключения начинаются, когда занимаешься портированием чужих программ.  К примеру декодер H264 - вся работа построена на куче, ибо туча буферов постоянно выделяются-высвобождаются туда-сюда, поверьте если оно б ненужно было, то никто кучу и работу с ней не изобретал,.......

 

 

Quote

Куча, хоть  проинициализированная хоть нет, не должна вообще никак влиять на размер образа загрузки.

Видимо что-то у вас не так с атрибутами секций в командном файле компоновщика.

Мой файл для линковщика - всё как обычно:

Spoiler

-cr
-stack 0x8000
-heap 0x500000

MEMORY
{
    DSPL2ROM     o = 0x00700000  l = 0x00100000     /* 1MB L2 Internal ROM */                
    DSPL2RAM     o = 0x00800000  l = 0x00040000     /* 256kB L2 Internal RAM */              
    DSPL1PRAM    o = 0x00E00000  l = 0x00008000     /* 32kB L1 Internal Program RAM */        
    DSPL1DRAM    o = 0x00F00000  l = 0x00008000     /* 32kB L1 Internal Data RAM */           
    SHDSPL2ROM   o = 0x11700000  l = 0x00100000     /* 1MB L2 Shared Internal ROM */         
    SHDSPL2RAM   o = 0x11800000  l = 0x00040000     /* 256kB L2 Shared Internal RAM */       
    SHDSPL1PRAM  o = 0x11E00000  l = 0x00008000     /* 32kB L1 Shared Internal Program RAM */
    SHDSPL1DRAM  o = 0x11F00000  l = 0x00008000     /* 32kB L1 Shared Internal Data RAM */    
    EMIFACS2     o = 0x60000000  l = 0x02000000     /* 32MB Async Data (CS2) */              
    EMIFACS3     o = 0x62000000  l = 0x02000000     /* 32MB Async Data (CS3) */              
    EMIFACS4     o = 0x64000000  l = 0x02000000     /* 32MB Async Data (CS4) */              
    EMIFACS5     o = 0x66000000  l = 0x02000000     /* 32MB Async Data (CS5) */              
    EMIFBSDRAM   o = 0xC0000000  l = 0x02000000     /* 32MB SDRAM Data */                   
}                                                                       

SECTIONS
{
    .text:_c_int00* >  0xC0000000

    .text           >  EMIFBSDRAM
    .stack          >  EMIFBSDRAM
    .bss            >  EMIFBSDRAM
    .cio            >  EMIFBSDRAM
    .const          >  EMIFBSDRAM
    .data           >  EMIFBSDRAM
    .switch         >  EMIFBSDRAM
    .sysmem         >  EMIFBSDRAM
    .far            >  EMIFBSDRAM
    .args           >  EMIFBSDRAM
    .ppinfo         >  EMIFBSDRAM
    .ppdata         >  EMIFBSDRAM

    /* COFF sections */
    .pinit          >  EMIFBSDRAM
    .cinit          >  EMIFBSDRAM
  
    /* EABI sections */
    .binit          >  EMIFBSDRAM
    .init_array     >  EMIFBSDRAM
    .neardata       >  EMIFBSDRAM
    .fardata        >  EMIFBSDRAM
    .rodata         >  EMIFBSDRAM
    .c6xabi.exidx   >  EMIFBSDRAM
    .c6xabi.extab   >  EMIFBSDRAM
}

 

 

 

Quote

PS: Да - и зачем вам bin? Самый удобный для этого формат - ais. bin не нужен.

Так я ж сам загрузчик пишу,  кладу файл бинарника сразу в SDRAM. Для чего мне заморачиваться с AIS?

 

 

Файл разрастается на 2 этапе:

objcopy -I elf32-little -O binary app_elf.bin app.bin

 

.text:_c_int00* >  0xC0000000

Этим мы принудительно заставляем точку входа в программу  быть с адреса начала SDRAM.

 

HINT:

И попутно эта функция ещё сбивает режим округления, так что только в main() его выставлять

Edited by __inline__

Share this post


Link to post
Share on other sites
41 минуту назад, __inline__ сказал:

Мой файл для линковщика - всё как обычно:

А где атрибуты у выходных секций? Не вижу ни одного. Разве это обычно? Обычно нужные атрибуты явно задают.

Вот как у меня. Общая память (для всего SoC):

SECTIONS
{
  .SOCBshare:             load = RAM_SDRAM_SOC_BEGIN
  .SOCshare:              load = RAM_SHARED_SOC_BEGIN
  .bssRawData           > RAM_SHARED_SOC, type = NOLOAD
  .bssPlotData          > RAM_SHARED_SOC, type = NOLOAD
  .bssSpectrData        > RAM_SHARED_SOC, type = NOLOAD
  .mmrSyscfgRegs        > MMR_SYSCFG,  PAGE 2
  .mmrPsc0Regs          > MMR_PSC0,    PAGE 2
...
}

память ARM:

Спойлер

-stack 0x00000000  //!<stack size
-heap  0x00000040  //!<heap size

SECTIONS
{
  .exceptions:            load = 0xFFFF0000
  .bootStart:             load = RAM_SDRAM_ARM_RX_BEGIN
  .sysvecs              > RAM_ARM, type = NOINIT
  .stkSVC               > RAM_ARM, type = NOINIT
  .stkABT               > RAM_ARM, type = NOINIT
  .stkUND               > RAM_ARM, type = NOINIT
  .stkSYS               > RAM_ARM, type = NOINIT
  .stkFIQ               > RAM_ARM, type = NOINIT
  .stkIRQ               > RAM_ARM, type = NOINIT
  .stkIRQnest           > RAM_ARM, type = NOINIT
  .bssTrapData          > RAM_ARM, type = NOINIT
  .bss0: { *(.bssDMA) } > RAM_SHARED_ARM_RW, type = NOINIT
  .bss                  > RAM_SDRAM_ARM_RW, type = NOINIT
  .bssStk               > RAM_SDRAM_ARM_RW, type = NOINIT
  .bssInternal          > RAM_SHARED_ARM_RW
  .noinit               > RAM_SDRAM_ARM_RW, type = NOINIT
  .noinitLarge          > RAM_SDRAM_ARM_RW, type = NOINIT
  .cinit                > RAM_SDRAM_ARM_RX
  .pinit                > RAM_SDRAM_ARM_RX
  .cio                  > RAM_SDRAM_ARM_RW
  .const                > RAM_SDRAM_ARM_RX
  .sysmem               > RAM_SDRAM_ARM_RW
  .text                 > RAM_SDRAM_ARM_RX
  .textFast             > RAM_SDRAM_ARM_RX
  .textInternal         > RAM_SHARED_ARM_RX //!<must be placed in the internal memory
  .textPrintfiStkSw     > RAM_SDRAM_ARM_RW
  .far                  > RAM_SDRAM_ARM_RW
  .switch               > RAM_SDRAM_ARM_RX
  .mmuTTable            > RAM_SDRAM_ARM_NC_RW, type = NOINIT
  .bssLargeDMA          > RAM_SDRAM_ARM_NC_RW, type = NOINIT
  .bssUsbData           > RAM_SDRAM_ARM_RW, type = NOINIT
  .bssSlow              > RAM_SDRAM_ARM_RW

  .fram:                > MEM_FRAM, type = DSECT, PAGE = 1
}

Для DSP-ядра - сделано аналогично.

 

41 минуту назад, __inline__ сказал:

Так я ж сам загрузчик пишу,  кладу файл бинарника сразу в SDRAM. Для чего мне заморачиваться с AIS?

Я тоже сам писал. И что?

 

PS: Ещё можно убедиться по map-файлу, что нет каких-то ещё выходных секций в несмежных с EMIFBSDRAM областях памяти. Может какие-то регистры периферии при старте прописываются. Тогда дырка между ними и EMIFBSDRAM будет заполнена.

Share this post


Link to post
Share on other sites
Quote

А где атрибуты у выходных секций? Не вижу ни одного. Разве это обычно? Обычно нужные атрибуты явно задают.

Я взял тот файл для  линковщика, который мне CCS для C6745 предложил - называется он C6745.cmd.  Это его содержимое.  Хотите сказать что он неверный? Моя отсебятина там только - загон функции c_int00 в начало SDRAM.

 

Quote

Вот как у меня. Общая память (для всего SoC):

Атрибуты это что ? Можете выделить жирным в ваших скриптах линковщика? NOINIT  - оно?

 

 

PS: Ещё можно убедиться по map-файлу, что нет каких-то ещё выходных секций в несмежных с EMIFBSDRAM областях памяти. Может какие-то регистры периферии при старте прописываются. Тогда дырка между ними и EMIFBSDRAM будет заполнена.

а вот  это уже интересно!

 

Я тоже сам писал. И что?

нафига мне AIS в самописанном загрузчике?

Edited by __inline__

Share this post


Link to post
Share on other sites
13 минут назад, __inline__ сказал:

Я взял тот файл для  линковщика, который мне CCS для C6745 предложил - называется он C6745.cmd.  Это его содержимое.  Хотите сказать что он неверный? Моя отсебятина там только - загон функции c_int00 в начало SDRAM.

Хочу сказать, что он простейший, базовый. Если хотите лучшего тюнинга, то следует прочитать про назначение атрибутов.

Цитата

Атрибуты это что ? Можете выделить жирным в ваших скриптах линковщика? NOINIT  - оно?

И NOINIT и LOAD и NOLOAD и многие другие. Читайте их описание в мануале на линковщик.

Цитата

нафига мне AIS в самописанном загрузчике?

Ну иначе тогда (если есть несмежные области) - смиритесь с огромным bin.  :unknw:

ais позволяет оставить маленький размер при любом раскидывании секций по памяти.

Share this post


Link to post
Share on other sites
1 hour ago, jcxz said:

Ну иначе тогда (если есть несмежные области) - смиритесь с огромным bin.  :unknw:

ais позволяет оставить маленький размер при любом раскидывании секций по памяти.

Проблема из-за вот этого:

.text:_c_int00* >  0xC0000000

Если убрать, то бинарник становится маленьким, но entry point плавает.  И в map-файле почему-то куча со стеком на младших адресах, ниже идёт код, данные......

Как можно принудительно заставить линковщик засовывать секции .stack и .sysmem в самый конец? (по старшим адресам)

Пока ничего кроме как указать стартовый адрес стека, вычислив его дефайнами не приходит в голову.

 

Share this post


Link to post
Share on other sites

Решил проблему, поделив все секции на Read-Only и Read-Write.  Ввёл границу раздела памяти (между RO и RW).

Скрипт для линкера такой:

#define SDRAM_BASE 0xC0000000
#define SDRAM_SIZE 0x02000000 // 32 MB
#define RO_SIZE    0x0004B000 //300 kB

-c
-stack 0x00008000 //32 kB
-heap  0x01E00000 //30 MB

MEMORY
{
 RO o = SDRAM_BASE         l = RO_SIZE
 RW o = SDRAM_BASE+RO_SIZE l = SDRAM_SIZE-RO_SIZE
}

SECTIONS
{
 .text:_c_int00* > SDRAM_BASE

 .text           > RO
 .const          > RO
 .switch         > RO
 .cinit          > RO
 .rodata         > RO

 .sysmem         > RW
 .far            > RW
 .stack          > RW
 .bss            > RW
 .neardata       > RW
 .fardata        > RW
}

Тут только те секции, что использую. Остальные выкинул за ненадобностью.

В случае Страуструпа (C++) надо добавить другие секции.

 

Проверил - всё пашет как надо!  Обширный попкорн теперь не создаётся (файл не раздувается)!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this