Dopler 0 27 февраля, 2010 Опубликовано 27 февраля, 2010 · Жалоба Разбираюсь с документацией на 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 0 1 марта, 2010 Опубликовано 1 марта, 2010 · Жалоба Задам более конкретный вопрос: Можно ли из исходника задать выравнивание для LMA? Для VMA задается следующим образом: .section .data, "aw", @progbits .balign 0x100 Да, и я в первом посте был малость не прав. Правило выравнивания для VMA из исходников на LMA не распространяется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться