Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не понимаю окончательно работу GNU линкера
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
haker_fox
Здравствуйте, уважаемые коллеги!
Решил углубить знания по линкеру. Нужно rolleyes.gif Имеется следующий код
CODE
.section     .text
.code 32


    LDR        PC,        =0x40004000


.section    .data
data1:        .word    0x89ABCDEF

.section    .bss
bss1:        .word    0

.section    .fox, "ax"
    NOP
    NOP
    NOP
    NOP
    BX        LR

и скрипт линкера
CODE
MEMORY
{
    RAM(RW)        :    org = 0x40000000, len = 32K
    RAMOV(RW)    :    org = 0x40004000, len = 4K
}

SECTIONS
{
    .text : { *.(text) } > RAM
    .data : { *.( data ) } > RAM
    .bss  : { *.( bss ) } > RAM
    
    .fox  : { *(.fox .fox*) } > RAMOV
    
}

Трансляция кода идет следующим образом
CODE
arm-kgp-elf-as -mcpu=arm7tdmi-s test.s -o test.o
arm-kgp-elf-ld test.o -o test.elf -Ttest.ld

В этом случае все собирается отлично. В эльфе все необходимые секции.
Стоит секцию .fox пометить только флагом "x" в исходнике на языке ассемблера, как она перестает линковаться. Я не понимаю почему это происходит? Документация говорить, что флаг "a" - это перемещаемая (allocatable) секция.
Но нигде не могу найти описания, для чего секции дается такой статус? Почему секцию просто нельзя пометить "xw", например? Да, стандартные секции .text, .data и .bss линкуются всегда...
Буду благодарен за любую информацию!

З.Ы. МК LPC2468.
Спасибо!
am1808
Цитата(haker_fox @ Jan 9 2012, 13:05) *
Стоит секцию .fox пометить только флагом "x" в исходнике на языке ассемблера, как она перестает линковаться. Я не понимаю почему это происходит? Документация говорить, что флаг "a" - это перемещаемая (allocatable) секция.
Но нигде не могу найти описания, для чего секции дается такой статус? Почему секцию просто нельзя пометить "xw", например? Да, стандартные секции .text, .data и .bss линкуются всегда...


вы свою пользовательскую секцию линкуете с адресным пространством on-chip RAM, в таком случае секцию следует обозначить как "allocatable";

попробуйте вашу секцию в скрипте линкера связать с "on-chip non-volatile memory" без использования флага "a" в исходном коде, должно успешно слинковаться
haker_fox
QUOTE (am1808 @ Jan 10 2012, 13:36) *
вы свою пользовательскую секцию линкуете с адресным пространством on-chip RAM, в таком случае секцию следует обозначить как "allocatable";

попробуйте вашу секцию в скрипте линкера связать с "on-chip non-volatile memory" без использования флага "a" в исходном коде, должно успешно слинковаться

К сожалению, ничего не получается без флага "a".
Вот скрипт после изменения
CODE
MEMORY
{
    RAM(RW)        :    org = 0x40000000, len = 512K
    RAMOV(RW)    :    org = 0x80000000, len = 512K
}

SECTIONS
{
    .text : { *.(text) } > RAM
    .data : { *.( data ) } > RAM
    .bss  : { *.( bss ) } > RAM
    
    .fox  : { *(.fox .fox*) } > RAMOV
    
}
, вот фрагмент секции
CODE
.section    .fox, "x"


Не знаю, почему. Оно мне, конечно, не критично, тем более код работает... Просто непонятно...
ReAl
Цитата(haker_fox @ Jan 9 2012, 11:05) *
Документация говорить, что флаг "a" - это перемещаемая (allocatable) секция.
Что-то мне кажется, что это означает не «перемещаемая», а «размещаемая», «занимающая место в бинарнике». В отличие от, скажем, .bss.
am1808
могу ошибаться, но
данная секция в любом случае будет allocatable,
за исключением случаев, когда этот код будет выполняться с ROM

Цитата(ReAl @ Jan 10 2012, 15:34) *
Что-то мне кажется, что это означает не «перемещаемая», а «размещаемая», «занимающая место в бинарнике». В отличие от, скажем, .bss.


Locations represent addresses in memory if a section is allocatable; that is, its
contents are to be placed in memory at program runtime. Symbolic references
to these locations must be changed to addresses by the link editor.

еще может быть полезным:

The linker combines input files into a single output file. The output file and each input file are in a special data format known as an object file format. Each file is called an object file. The output file is often called an executable, but for our purposes we will also call it an object file. Each object file has, among other things, a list of sections. We sometimes refer to a section in an input file as an input section; similarly, a section in the output file is an output section.

Each section in an object file has a name and a size. Most sections also have an associated block of data, known as the section contents. A section may be marked as loadable, which mean that the contents should be loaded into memory when the output file is run. A section with no contents may be allocatable, which means that an area in memory should be set aside, but nothing in particular should be loaded there (in some cases this memory must be zeroed out). A section which is neither loadable nor allocatable typically contains some sort of debugging information.

Every loadable or allocatable output section has two addresses. The first is the VMA, or virtual memory address. This is the address the section will have when the output file is run. The second is the LMA, or load memory address. This is the address at which the section will be loaded. In most cases the two addresses will be the same. An example of when they might be different is when a data section is loaded into ROM, and then copied into RAM when the program starts up (this technique is often used to initialize global variables in a ROM based system). In this case the ROM address would be the LMA, and the RAM address would be the VMA.
haker_fox
Похоже, линкер так строг, поскольку для него "темный лес" за стандарнтыми секциями .text, .data и .bss. Поскольку моя секция .fox не лежит в .text, он (линкер) не знает, что с ней делать, т.к. не понятно, каким образом она попадет в указанное адресное пространство. Следовательно, ему необходимо "намекнуть", что мы сами решим проблему, и скопируем секцию туда , куда надо. На это и указывает флаг "а".

Господа, большое спасибо за помощь!!!
am1808
Цитата(haker_fox @ Jan 10 2012, 19:37) *
Похоже, линкер так строг, поскольку для него "темный лес" за стандарнтыми секциями .text, .data и .bss. Поскольку моя секция .fox не лежит в .text, он (линкер) не знает, что с ней делать, т.к. не понятно, каким образом она попадет в указанное адресное пространство. Следовательно, ему необходимо "намекнуть", что мы сами решим проблему, и скопируем секцию туда , куда надо. На это и указывает флаг "а".

Господа, большое спасибо за помощь!!!

о чем и речь, и дело даже не в том, знает линкер про секции .text, .data, .bss, а в том, по каким адресам аллокировать секции в runtime

можете еще почитать ресурс вот тут http://bravegnu.org/gnu-eprog/lds.html
haker_fox
Еще вопрос. Может быть ответы на него есть, но не знаю, как правильно его сформулировать поисковику.
В общем, в крипте для линкера определены сегмены памяти (озу, флеш и т.д.) в разделе MEMORY. Можно ли их значения получить в программе на Си? Либо определить эти сегменты (имена) где-то в другом файле (Makefile?), а затем оттуда уже цеплять к скрипту и программе на си?
В общем программа на Си должна знать почти все об определенных секциях памяти. Лишний раз объявлять их через #define чревато ошибками...

Заранее спасибо!!!
ReAl
Посмотрите в скрипте линкера имена bss_start и подобное.
Наставьте своего, например, my_section_start
В С-файле:
Код
extern unsigned char my_section_start;
void *my_section_start_p = &my_section_start; // это и будет адрес начала секции


Тут немного про это. Только на украинсокм (если бы ждал наличия времени на переводы, то вообще не выложил бы). Но код говорит сам за себя.
http://real.kiev.ua/2011/05/01/vykorystannya-sektsij-v-gcc/
am1808
Цитата(haker_fox @ Jan 15 2012, 06:47) *
Еще вопрос. Может быть ответы на него есть, но не знаю, как правильно его сформулировать поисковику.
В общем, в крипте для линкера определены сегмены памяти (озу, флеш и т.д.) в разделе MEMORY. Можно ли их значения получить в программе на Си? Либо определить эти сегменты (имена) где-то в другом файле (Makefile?), а затем оттуда уже цеплять к скрипту и программе на си?
В общем программа на Си должна знать почти все об определенных секциях памяти. Лишний раз объявлять их через #define чревато ошибками...

Заранее спасибо!!!

конечно можно, объявляете указатель как extern в Сишном модуле как адрес начала секции, затем в линкере даете этому указателю адрес интересующей вас секции, и компилируете, подцепляя ваш линкер скрипт.
почитайте:
Код
info ld


хороший и наглядный пример можно посмотреть тут:
http://www.compsoc.man.ac.uk/~moz/kernelne...all/kernel.html
Сергей Борщ
QUOTE (ReAl @ Jan 15 2012, 09:59) *
CODE
extern unsigned char my_section_start;
void *my_section_start_p = &my_section_start; // это и будет адрес начала секции
Я в последнее время стал писать
CODE
extern uint8_t my_section_start[];
extern uint8_t my_section_end[];

for(uint8_t * ptr = my_section_start; ptr < my_section_end; ++ptr)
{

}

ReAl
Хм, что-то в этом есть. И с точки зрения удобства использования (без & на каждый чих), и с точки «зрения в корень», ибо секция как таковая представляет собой массив :-)
Спасибо.
haker_fox
Сколько ответов! :-) Спасибо большое!!! Буду пробывать...)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.