Перейти к содержанию
    

ALIGN в GCC Linker

Разбираюсь с документацией на ld, не совсем мне понятен такой момент.

Вот есть две записи:

.text . : { *(.text) }

.text : { *(.text) }

 

В первой адрес указывается явно через location counter, во второй записи явного указания адреса нет, но он тоже вычисляется через location counter. Для второго случая написано, что при этом учитываются требования к выравниванию, заданные во входных секциях. Не совсем понятно, как эти правила задаются в С программе. Как, например, задать выравнивание для секции .bss или .data?

 

Из этого вопроса следует следующий - где вообще принято устанавливать правила выравнивания для секций - в коде программы или в скриптах линкера?

Вот кусок из дефолтового скрипта для AVR32:

  .text           :
  {
    *(.text)
  } >FLASH AT>FLASH :FLASH =0xd703d703

  .lalign    : { . = ALIGN(8); PROVIDE(_data_lma = .); } >FLASH AT>FLASH :FLASH
  
  . = ORIGIN(INTRAM);

  .data           :
  {
    *(.data)
  } >INTRAM AT>FLASH :INTRAM_AT_FLASH

 

Получается, чтобы выровнять LMA адрес для секции .data создается специальная секция-прослойка .lalign, а затем по команде AT>FLASH секция .data попадает во flash с нужным выравниванием.

Т.е. секция .data во флеш памяти должна быть расположена строго после секции .lalign, только тогда будет гарантировано ее правильное выравнивание.

На мой взгляд, такой подход противоречит идеологии линкера - секции независимы, главное, что функции из одной секции могут обращаться к функциям другой секции по адресам.

Но с другой стороны сохраняется возможность в коде задать выравнивание больше, чем 8 (8 задано в секции lalign ) и секция разместится правильно, так как AT>FLASH привязана к location counter с учетом выравнивания из входных секций.

 

LMA адрес для секции можно задать по другому:

  .text  : 
  { 
    *(.text) 
  } >FLASH :FLASH =0xd703d703
  
  PROVIDE(_data_lma = ALIGN(8));


  . = ORIGIN(INTRAM);

  .data ALIGN(8) :
  AT(_data_lma)
  {
    *(.data)
  } >INTRAM :INTRAM_AT_FLASH

Но насколько я понимаю, в этом случае адрес для размещения _data_lma указывается в явном виде, и все возможные требования по выравниванию, заданные в исходниках, будут проигнорированы.

 

Ну и еще раз повторю вопрос - где обычно задают выравнивание для секций - в исходниках (С и asm) или в скрипте линкера? Если в исходниках, то по хорошему его надо задавать для всех секций, даже для .data и .bss? А то получается, например, что в стартапе .data копируется в RAM двойными словами, т.е. и VMA и LMA для нее должны быть обязательно выровнены на 8 ( в этом случае это задается в скрипте линкера). А есть другие секции, где выравнивание задается в исходниках, и если в линкере указать явный адрес, то выравнивание из исходников будет проигнорировано, причем без всяких warning.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Задам более конкретный вопрос:

Можно ли из исходника задать выравнивание для LMA?

Для VMA задается следующим образом:

 

  .section  .data, "aw", @progbits
    .balign 0x100

 

Да, и я в первом посте был малость не прав. Правило выравнивания для VMA из исходников на LMA не распространяется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...