Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ALIGN в GCC Linker
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Dopler
Разбираюсь с документацией на 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.
Dopler
Задам более конкретный вопрос:
Можно ли из исходника задать выравнивание для LMA?
Для VMA задается следующим образом:

Код
  .section  .data, "aw", @progbits
    .balign 0x100


Да, и я в первом посте был малость не прав. Правило выравнивания для VMA из исходников на LMA не распространяется.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.