Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR - проблема с секциями в ld
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Сергей Борщ
Мега 8. WinAVR 20070525.
Потребовалось организовать в ОЗУ следующую карту памяти:
0x60-0x71 - зарезервировано
0x71-N - Массив (его размер определяется при объявлении в программе)
N-0x45F - данные программы, стеки, в общем как обычно.

Массив определяю в программе в отдельную секцию:
Код
uint8_t Buffer[5] __attribute__((section("buffer"),used));

Скопировал в каталог проекта скрипт avr4.x, изменил в нем регионы, поставил выходную секцию .bss перед .data, добавил свою секцию в .bss:
Код
MEMORY
{
  text   (rx)   : ORIGIN = 0, LENGTH = 0x17F4
  data   (rw!x) : ORIGIN = 0x800071, LENGTH = 1K
  eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 512
}
....
  .bss :
  {
    *(buffer);    /* reserved for TxBuffer */
    KEEP (*(buffer))
     PROVIDE (__bss_start = .);
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .);
  }  > data

  .data SIZEOF(.bss) + ADDR(.bss)  : AT (ADDR (.text) + SIZEOF (.text) )   /* load from (.text) + sizeof(.text) */
  {
     PROVIDE (__data_start = .);
    *(.data)
    *(.data*)
    *(.rodata)  /* We need to include .rodata here if gcc is used */
    *(.rodata*) /* with -fdata-sections.  */
    *(.gnu.linkonce.d*)
    . = ALIGN(2);
     _edata = .;
     PROVIDE (__data_end = .);
  }  > data
При компиляции получаю предупреждение: ld.exe: Test.elf: warning: allocated section `.data' not in segment
При этом avr-objcopy при создании .hex добавляет в него данные по адресам __data_start (т.е. 0x8000XX). Начал урезать исходники и makefile, чтобы отыскать откуда ноги. Эффект нестабильный - при выкидывании одних кусков исходника пропадает, при выкидывании других - остается. Получил прилагаемый проект, в котором эффект еще повторяется. При дальнейшем уменьшении исходника эффект пропадает. Причем он пропадает даже при изменении той части исходника, код из которой не используется и выкидывается при линковке. Если убрать --gc-sections, эффект также пропадает. Если в линкерном скрипте убрать ". = ALIGN(2);" в .data (кстати, зачем он тут?) - тоже исчезает. Заметил, что одно из условий появления - если в результате сбора мусора линкером сегмент .data получается пустым, однако это не единственное условие, требуется что-то еще.

Пробовал версию 22071221 - поведение идентично. 20060421 - предупреждение не генерится, но в выходной .hex-файл все равно добавляется мусор.

Вопрос первый - что означает это предупреждение? Гугление не помогло.
Вопрос второй - что я делаю не так и как надо правильно добавлять свои секции?
Вопрос третий - пробовал создавать в линкерном скрипте отдельную выходную секцию для массива. В результате avr-objcopy -o ihex -R .eeprom Test.elf Test.hex помещает в .hex нули по VMA адресам этого массива. При указании -R <имя моей секции> она исчезает из выходного файла, но тогда возникет вопрос - почему в выходном файле не появляются секции .noinit, .bss и секции отладочной информации (перечислены в конце скрипта), хотя они и не были перечислены с ключем -R. Где об этом можно почитать? В документации к ld, avr-objcopy, objcopy, gcc ничего на эту тему не нашел.
Сергей Борщ
Провел дополнительные исследования. Выяснил, что появление лишней информации в .hex и это предупреждение не связаны (хотя вчера они появлялись и исчезали одновременно). С появлением лишней информации выяснил, что если мои секции описаны в .bss между строчками PROVIDE (__bss_start = .) и PROVIDE (__bss_end = .), то они не появляются в выходном файле, если же вне этих строчек - то появляются:
Код
  .bss :  /* Так появляется */
  {
    *(buffer);    /* reserved for TxBuffer */
    KEEP (*(buffer))
     PROVIDE (__bss_start = .);
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .);
  }  > data

  .bss :     /* a так - нет */
  {
     PROVIDE (__bss_start = .);
    *(buffer);    /* reserved for TxBuffer */
    KEEP (*(buffer))
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .);
  }  > data
Таким образом обходное решение найдено, но остается третий вопрос - как avr-objcopy по умолчанию определяет, что включать в .hex, а что - нет.
amw
Цитата
При компиляции получаю предупреждение: ld.exe: Test.elf: warning: allocated section `.data' not in segment

Проблема (несоответствие) адресов/размеров переменных и Memory Region.
То есть попытка разместить символ по адресу, не попападающему в соответствующий регион памяти.

Цитата(Сергей Борщ @ Mar 12 2008, 17:02) *
Провел дополнительные исследования. Выяснил, что появление лишней информации в .hex и это предупреждение не связаны (хотя вчера они появлялись и исчезали одновременно). С появлением лишней информации выяснил, что если мои секции описаны в .bss между строчками PROVIDE (__bss_start = .) и PROVIDE (__bss_end = .), то они не появляются в выходном файле, если же вне этих строчек - то появляются:
Код
  .bss :  /* Так появляется */
  {
    *(buffer);    /* reserved for TxBuffer */
    KEEP (*(buffer))
     PROVIDE (__bss_start = .);
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .);
  }  > data

  .bss :     /* a так - нет */
  {
     PROVIDE (__bss_start = .);
    *(buffer);    /* reserved for TxBuffer */
    KEEP (*(buffer))
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .);
  }  > data
Таким образом обходное решение найдено, но остается третий вопрос - как avr-objcopy по умолчанию определяет, что включать в .hex, а что - нет.

Собственно __bss_start и __bss_end являются общепринятыми (в мире CGG) именами и должны обрамлять секцию. То-же касается и __data_start и прочих. Я не копал глубоко, но может эти имена анализируются линкером.
PROVIDE () больше предназначено для устранения дублирующих определений и их гарантированного появления чем для собственно определений. Что будет если PROVIDE (__bss_start = .) заменить на __bss_start = .? Сообщение останется?
objcopy по умолчанию копирует в HEX файл (как впрочем и в binary) выходные секции .text .data .rodata (полный список зависит от архитектуры).
Сергей Борщ
Цитата(amw @ Mar 13 2008, 11:08) *
Проблема (несоответствие) адресов/размеров переменных и Memory Region.
То есть попытка разместить символ по адресу, не попападающему в соответствующий регион памяти.
Пппереведи! (с)"Москва слезам не верит". Какое мое действие приводит к возникновению этого предупреждения и почему оно то появляется, то исчезает в зависимости от седержимого кода, удаляемого сборщиком мусора линкера?
Я интуитивно понял, что при какой-то комбинации сборщик мусора линкера выкидывает все из секции .data, но оставляет там байт-заполнитель от инструкции скрипта . = ALIGN(2). Предполагаю, что для этого байта нет соответствующего значения в области AT (ADDR (.text) + SIZEOF (.text), о чем и ругается линкер. Но это только мое предположение.
Цитата(amw @ Mar 13 2008, 11:08) *
Собственно __bss_start и __bss_end являются общепринятыми (в мире CGG) именами и должны обрамлять секцию. То-же касается и __data_start и прочих. Я не копал глубоко, но может эти имена анализируются линкером.
Вот где про это почитать, кроме исходников линкера? В описании линкера эти символы не упоминаются, в примерах скриптов в этом же описании не встречаются, и вдруг выясняется, что они имеют важное значение. Хотелось бы ознакомиться с документами, где это описано, чтобы не двигаться наощупь. И вдруг там описано еще что-то важное и интересное.
Цитата(amw @ Mar 13 2008, 11:08) *
PROVIDE () больше предназначено для устранения дублирующих определений... Что будет если PROVIDE (__bss_start = .) заменить на __bss_start = .? Сообщение останется?
PROVIDE определяет символ, если такой символ не определен в объектных файлах. В данном конкретном случае не изменилось ничего, чего и следовало ожидать.
Цитата(amw @ Mar 13 2008, 11:08) *
objcopy по умолчанию копирует в HEX файл (как впрочем и в binary) выходные секции .text .data .rodata (полный список зависит от архитектуры).
Цитата
- А я Виндовс-2000 так до конца и не прошел sad.gif
- Так это же не игра, а операционная система!
- Откуда инфа?!?!?
Откуда инфа? Где посмотреть этот полный список? .bss, .noinit, .stab, .comment, .debug, .line - тоже выходные секции. Причем как показал мой эксперимент с перемещением __bss_start = . он может копировать выходные секции не целиком, а частями.
Кто-нибудь знает, какой конкретно TFM мне надо R?
singlskv
А почему не сделать просто в Makefile ? :

Код
.....................
## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS +=  -Wl,-Map=Pd105Gcc.map
LDFLAGS += -Wl,-section-start=.data=0x800070
LDFLAGS += -Wl,-section-start=buffer=0x800060

## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R buffer

HEX_EEPROM_FLAGS = -j .eeprom
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0
............................

##Link
$(TARGET): $(OBJECTS)
     $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

%.hex: $(TARGET)
    avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

%.eep: $(TARGET)
    avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@
.......................


в HEX_FLASH_FLAGS просто удаляем секцию buffer при создании hex
amw
Цитата(Сергей Борщ @ Mar 13 2008, 13:29) *
Пппереведи! (с)"Москва слезам не верит". Какое мое действие приводит к возникновению этого предупреждения и почему оно то появляется, то исчезает в зависимости от седержимого кода, удаляемого сборщиком мусора линкера?

Не могу sad.gif. Примерно так же ковыряюсь наугад в скриптах. Более подробной инфы чем info ld не встречал.
Недавно было такое-же, когда я пытался зарезервировать область (читай секцию) в начале ОЗУ под векторы исключений для ARM.
Линкер то выкидывал нафиг эту секцию, то ругался как у Вас.
Методом тыка дошел до того, что в прилагаемом файле.
К стати у меня на Debian Ваш пример компилится/линкуется без ошибок и варнингов.
Есть предположение, что еще что-то добавляется компилятором C++, но на первый взгляд у Вас достаточно полно описаны секции в скрипте.
Цитата
Я интуитивно понял, что при какой-то комбинации сборщик мусора линкера выкидывает все из секции .data, но оставляет там байт-заполнитель от инструкции скрипта . = ALIGN(2). Предполагаю, что для этого байта нет соответствующего значения в области AT (ADDR (.text) + SIZEOF (.text), о чем и ругается линкер. Но это только мое предположение.

Возможно.
Возможно C++ хочет что-то положить в начале памяти. Я собственно с C++ работаю очень редко, потому тут помочь не могу. Как вариант, попробуйте чистый C.
Собственно секции лучше всего располагать по выроненному адресу. Так более универсальнее. Для этого и стоит ALIGN().
Цитата
Вот где про это почитать, кроме исходников линкера? В описании линкера эти символы не упоминаются, в примерах скриптов в этом же описании не встречаются, и вдруг выясняется, что они имеют важное значение. Хотелось бы ознакомиться с документами, где это описано, чтобы не двигаться наощупь. И вдруг там описано еще что-то важное и интересное.
PROVIDE определяет символ, если такой символ не определен в объектных файлах. В данном конкретном случае не изменилось ничего, чего и следовало ожидать.
Откуда инфа? Где посмотреть этот полный список? .bss, .noinit, .stab, .comment, .debug, .line - тоже выходные секции. Причем как показал мой эксперимент с перемещением __bss_start = . он может копировать выходные секции не целиком, а частями.
Кто-нибудь знает, какой конкретно TFM мне надо R?

Боюсь, что авторы binutils не смогут Вам ответить sad.gif .
Список высмотрел когда-то в исходниках. Давно было дело, года 4 назад.

Вот результат компиляции, может поможет.

Код
# avr-gcc -v
Using built-in specs.
Target: avr
Configured with: ../build-tree/gcc-4.1.0/configure -v --enable-languages=c,c++ --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --enable-shared --with-system-zlib --enable-long-long --enable-nls --without-included-gettext --disable-checking --disable-libssp --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=avr
Thread model: single
gcc version 4.1.0
# avr-ld -v
GNU ld (GNU Binutils) 2.18.20071027
Сергей Борщ
Цитата(singlskv @ Mar 13 2008, 15:01) *
А почему не сделать просто в Makefile ?
Потому что буфер находится внутри выходной секции .bss, а ключ -R применяется к выходным, а не входным секциям.
В первом варианте, когда это у меня вылезло, у меня под буфер была выделена отдельная выходная секция и мне ReAl как раз такое решение и посоветовал. Но мое чувство прекрасного воспротивелось этому - если objcopy умеет по умолчанию выкидывать какие-то секции, то пусть и мой буфер выкинет заодно. Для этого я и поместил его в .bss. Вылез подводный камень. Хочу разобраться.

Цитата(amw @ Mar 13 2008, 16:11) *
Методом тыка дошел до того, что в прилагаемом файле.
Спасибо, посмотрю.
Цитата(amw @ Mar 13 2008, 16:11) *
К стати у меня на Debian Ваш пример компилится/линкуется без ошибок и варнингов.
Надо будет проверить. Как раз недавно поставил Кубунту дома, осваиваю.
Цитата(amw @ Mar 13 2008, 16:11) *
Как вариант, попробуйте чистый C.
Нет, уж лучше вы к нам smile.gif
Цитата(amw @ Mar 13 2008, 16:11) *
Собственно секции лучше всего располагать по выроненному адресу. Так более универсальнее. Для этого и стоит ALIGN().
Я понимаю, что это необходимость для ARM. Но для AVR я вижу только расход и так маленькой памяти без необходимости. Поэтому и поднял вопрос - или я чего-то не понимаю, и тогда мне объяснят и я стану умнее, или это просто недоработка и заходящие сюда авторы libc обратят на нее внимание.
Цитата(amw @ Mar 13 2008, 16:11) *
Боюсь, что авторы binutils не смогут Вам ответить sad.gif .
Не уверен. diwil имеет (имел?) к binutils отношение (правда в контексте mspgcc), кое-кто из участников имеет отношение к WinAVR и avr-libc (возможно, при работе с ней приходится и в binutils ковыряться), да и вообще - предполагаю, что многие участники используют gcc в различных видах и, возможно, знают точный ответ на мои глупые вопросы. А может кто-нибудь из спецов покачает головой вот так: sad.gif и скажет: "Э... да это бага!" и тогда мы смело будем писать письмо турецкому султану (баг-репорт).
amw
Цитата(Сергей Борщ @ Mar 13 2008, 18:21) *
Нет, уж лучше вы к нам

smile.gif . Все может быть. Но я имел в виду потестить, а не полностью проект переписывать.
Цитата
Я понимаю, что это необходимость для ARM. Но для AVR я вижу только расход и так маленькой памяти без необходимости. Поэтому и поднял вопрос - или я чего-то не понимаю, и тогда мне объяснят и я стану умнее, или это просто недоработка и заходящие сюда авторы libc обратят на нее внимание.

Я не в курсе AVR архитектуры, однако наводящий вопрос: могут ли быть какие нибудь команды (или ситуации), требующие четного адреса? Возможно. используя эти команды быстрее производится копирование блоков данных (типа копирование секции .data в ОЗУ). Ну или что-то в этом роде.
Цитата
Не уверен. diwil имеет (имел?) к binutils отношение (правда в контексте mspgcc), кое-кто из участников имеет отношение к WinAVR и avr-libc (возможно, при работе с ней приходится и в binutils ковыряться), да и вообще - предполагаю, что многие участники используют gcc в различных видах и, возможно, знают точный ответ на мои глупые вопросы. А может кто-нибудь из спецов покачает головой вот так: sad.gif и скажет: "Э... да это бага!" и тогда мы смело будем писать письмо турецкому султану (баг-репорт).

smile.gif
Сергей Борщ
Цитата(amw @ Mar 13 2008, 20:09) *
я имел в виду потестить, а не полностью проект переписывать.
Боюсь, что мне не удастся повторить этот эффект. Я в этом исходнике его с трудом "удержал" в процессе обрезания. Это я про предупреждение линкера. Про вывод секции в .hex - проверю.
Цитата(amw @ Mar 13 2008, 20:09) *
Я не в курсе AVR архитектуры, однако наводящий вопрос: могут ли быть какие нибудь команды (или ситуации), требующие четного адреса?
В том-то и дело, что нет. 8-битный проц, все чисто байтовое. Точнее есть, но только одно место - заполнение буфера флеш при самопрограммировании производится по 2 байта. Но это никак с .data не связано.

Цитата(amw @ Mar 13 2008, 16:11) *
К стати у меня на Debian Ваш пример компилится/линкуется без ошибок и варнингов.
Но "огрызок" секции .data с моим буфером все равно в хексе присутствует:
Код
:0200000400807A
:0600710000000000000089
Сергей Борщ
amw, спасибо за толчок в новом направлении! Мысли упорядочиваются.

Поймал себя на логическом противоречии. Если мой буфер должен быть заполнен нулями (как и вся секция .bss), то его входная секция должна находиться между __bss_start = . и __bss_end = ., ведь по этим символам crt.s определяет обнуляемую область. Если же он не должен очищаться, то он и не должен находиться в выходной секции .bss. Значит ему место или в .noinit (проверил, эта секция появляется в хексе целиком и на варнинг это не влияет), но поскольку .noinit это скорее внешнее ОЗУ под батарейкой, то моему буферу место в отдельной выходной секции, про которую objcopy ничего заранее знать не может и, значит, про которую ему надо сообщать явно. Выходит, изначально ReAl был прав.

Теперь поймал на противоречии описание avr-libc. Там сказано, что .noinit является частью секции .bss, что противоречит и содержимому скриптов линкера из комплекта avr-libc и духу секции .bss (обнуленные при старте данные). Ведь в описании as ясно сказано:
Цитата
4.5 bss Section
.....When your program starts running, all the contents of the bss section are zeroed bytes.

Кстати, вот где оно все должно было быть! avr-libc-user-manual:
Цитата
9.3 Memory Sections
Remarks:
Need to list all the sections which are available to the avr.
Оно просто не дописано еще!

Тогда несколько изменил бы следующие два выражения оттуда:
Цитата
9.3.2 The .data Section
This section contains static data which was defined in your code.
9.3.3 The .bss Section
Uninitialized global or static variables end up in the .bss section.
Все-таки uninitialized - это про .noinit. Я бы про .data написал This section contains static data which was explicitly initialized in your code. А про .bss: Global or static variables which are not explicitly initialized end up in the .bss section. Those variables are zeroed accordinary with C standart (ISO/IEC 9899:1999 6.7.8.10) И уже не поминал бы .bss в контексте .noinit.

И тут у меня появился следующий вопрос: почему в примерах WinAVR для получения .hex используется команда $(OBJCOPY) -R .eeprom , хотя более логичным было бы использование $(OBJCOPY) -j .text ? Ведь прошиваемой является только выходная секция .text! Рано радовался. Инициализирующие значения .data складываются после .text посредством : AT() в скрипте линкера. Надо подумать, нельзя ли их сложить внутрь .text, рядом с rodata - тогда бы все получилось красиво. А пока эти данные нельзя явно указать objcopy и приходится вместо этого указывать "все, кроме лишнего". И что-то из этого "лишнего" заботливо указано avr-objcopy авторами по-умолчанию (но вот в документации это не отражено или я не нашел). Остаются совсем маленькие вопросы - почему размер "обрезаемой" части .bss определяется по __bss_start и __bss_end, а не по размеру самой секции, ведь эта информация должна быть в объектном файле и objdump ее видит? И почему для avr-objcopy по-умолчанию не указана секция .init? На последнее могу предположить, что .noinit не бывает в больших процессорах, из которых выросли binutils, а список секций живет где-то в непортируемой части. Но это только предположение.

Итого, резюмируя, вопросов осталось три - откуда warning (таки баг сборщика мусора линкера?), почему в .data . = ALIGN(2) и почему в objcopy __bss_start/__bss_end.
amw
Цитата(Сергей Борщ @ Mar 13 2008, 23:19) *
очнее есть, но только одно место - заполнение буфера флеш при самопрограммировании производится по 2 байта. Но это никак с .data не связано.

Как это не связано!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
А как, по вашему производится копирование секции .data из флеш в ОЗУ?
Гляньте в дизассемблер.

Цитата(Сергей Борщ @ Mar 13 2008, 23:19) *
Но "огрызок" секции .data с моим буфером все равно в хексе присутствует:
Код
:0200000400807A
:0600710000000000000089

То есть буффер попал в .data а не в .bss

Цитата(Сергей Борщ @ Mar 14 2008, 03:17) *
amw, спасибо за толчок в новом направлении! Мысли упорядочиваются.

Поймал себя на логическом противоречии. Если мой буфер должен быть заполнен нулями (как и вся секция .bss), то его входная секция должна находиться между __bss_start = . и __bss_end = ., ведь по этим символам crt.s определяет обнуляемую область. Если же он не должен очищаться, то он и не должен находиться в выходной секции .bss. Значит ему место или в .noinit (проверил, эта секция появляется в хексе целиком и на варнинг это не влияет), но поскольку .noinit это скорее внешнее ОЗУ под батарейкой, то моему буферу место в отдельной выходной секции, про которую objcopy ничего заранее знать не может и, значит, про которую ему надо сообщать явно. Выходит, изначально ReAl был прав.

Цитата
Теперь поймал на противоречии описание avr-libc. Там сказано, что .noinit является частью секции .bss, что противоречит и содержимому скриптов линкера из комплекта avr-libc и духу секции .bss (обнуленные при старте данные). Ведь в описании as ясно сказано:
Кстати, вот где оно все должно было быть! avr-libc-user-manual:Оно просто не дописано еще!

Тогда несколько изменил бы следующие два выражения оттуда:
Все-таки uninitialized - это про .noinit. Я бы про .data написал This section contains static data which was explicitly initialized in your code. А про .bss: Global or static variables which are not explicitly initialized end up in the .bss section. Those variables are zeroed accordinary with C standart (ISO/IEC 9899:1999 6.7.8.10) И уже не поминал бы .bss в контексте .noinit.

Инициализируемые переменные - это те, которым Вы в программе явно указали, чему они должны быть равны при старте программы. Точное значение - не важно.Если написано
int a = 0;
Это - инициализируемая переменная.
Если указано
int b;
Это - НЕинициализируемая переменная.
Инициализируемая переменная -> .data.
НЕинициализируемая переменная -> .bss.
Цитата
И тут у меня появился следующий вопрос: почему в примерах WinAVR для получения .hex используется команда $(OBJCOPY) -R .eeprom , хотя более логичным было бы использование $(OBJCOPY) -j .text ? Ведь прошиваемой является только выходная секция .text! Рано радовался. Инициализирующие значения .data складываются после .text посредством : AT() в скрипте линкера. Надо подумать, нельзя ли их сложить внутрь .text, рядом с rodata - тогда бы все получилось красиво. А пока эти данные нельзя явно указать objcopy и приходится вместо этого указывать "все, кроме лишнего". И что-то из этого "лишнего" заботливо указано avr-objcopy авторами по-умолчанию (но вот в документации это не отражено или я не нашел). Остаются совсем маленькие вопросы - почему размер "обрезаемой" части .bss определяется по __bss_start и __bss_end, а не по размеру самой секции, ведь эта информация должна быть в объектном файле и objdump ее видит? И почему для avr-objcopy по-умолчанию не указана секция .init? На последнее могу предположить, что .noinit не бывает в больших процессорах, из которых выросли binutils, а список секций живет где-то в непортируемой части. Но это только предположение.

Инициализацию секции .data и обнуление .bss выполняет сама программа. Во время выполнения. А в crt0.S имеется код типа такого (прифожу C эквивалент)
Код
for (i = __bss_start; i < __bss_end; i++)
    *((char *)i) = 0;

Ваша программа включая crt0.S оперирует символами а не секциями. О секциях знает только компилятор и binutils. __bss_start и _bss_end - это и есть символы, по которым производится очистка.
Цитата
Итого, резюмируя, вопросов осталось три - откуда warning (таки баг сборщика мусора линкера?), почему в .data . = ALIGN(2) и почему в objcopy __bss_start/__bss_end.

1. хз.
2. Посмотрите в исходнике crt0.S или в дизассемблере, как производится копирование .data.
3. Не уверен, что в objcopy, но может зарезервированные имена. .noinit секция (если Вы правильно описали ее суть) вообще не должна трогаться. А .bss должна. Как их отличить если .noinit часть .bss? Похоже что по символам "почему в objcopy __bss_start/__bss_end."

Ваш Test.ld
Код
  /* Global data not cleared after reset.  */
  .noinit  SIZEOF(.data) + ADDR(.data) :
  {
     PROVIDE (__noinit_start = .);
    *(.noinit*)
     PROVIDE (__noinit_end = .);
     _end = .;
     PROVIDE (__heap_start = .);
  }  > data

Информация к размышлению © "17 мгновений весны"

Дизассемблер (фрагмент) Вашего примера
Код
00000032 <__do_copy_data>:
  32:    10 e0           ldi    r17, 0x00; 0
  34:    a7 e7           ldi    r26, 0x77; 119
  36:    b0 e0           ldi    r27, 0x00; 0
  38:    e4 e7           ldi    r30, 0x74; 116
  3a:    f0 e0           ldi    r31, 0x00; 0
  3c:    02 c0           rjmp    .+4      ; 0x42 <.do_copy_data_start>

0000003e <.do_copy_data_loop>:
  3e:    05 90           lpm    r0, Z+
  40:    0d 92           st    X+, r0

00000042 <.do_copy_data_start>:
  42:    a8 37           cpi    r26, 0x78; 120
  44:    b1 07           cpc    r27, r17
  46:    d9 f7           brne    .-10     ; 0x3e <__SP_H__>

Какая из комманд оперирует выровненым адресом?
Сергей Борщ
Цитата(amw @ Mar 14 2008, 11:02) *
Как это не связано!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
А как, по вашему производится копирование секции .data из флеш в ОЗУ?
Нееее smile.gif Из флеш в ОЗУ можно копировать побайтно совершенно безболезненно. Ограничение только при записи в обратном направлении. При записи во флеш (бутлодырь) можно буфер флеша заполнять только по два байта. Но заполняется он из регистров, а читать в регистры можно из любого адреса. И это делается правильно специальными функциями из комплекта avr-libc на инлайн-асме. Так что тут все нормально.
Цитата(amw @ Mar 14 2008, 11:02) *
То есть буффер попал в .data а не в .bss
Звучит правдоподобно, НО КАК? В скрипте-то он был указан быть положенным в .bss
Цитата(amw @ Mar 14 2008, 11:02) *
Инициализируемые переменные - это те, которым Вы в программе явно указали, чему они должны быть равны при старте программы. Точное значение - не важно.Если написано
int a = 0;
Это - инициализируемая переменная.
Если указано
int b;
Это - НЕинициализируемая переменная.
Инициализируемая переменная -> .data.
НЕинициализируемая переменная -> .bss.
То есть вы хотите сказать, что значение b при старте программы не определено? Стандарт утверждает обратное:
Цитата
10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these
rules.
в .bss попадают как раз an object that has static storage duration и которые при этом not initialized explicitly, т.е. не проинициализированны явно. Кстати, где-то встречал упоминание (кажется в каком-то из описаний GCC), что переменные, явно проинициализированные нулем тоже кладутся в .bss а не в .data
Цитата(amw @ Mar 14 2008, 11:02) *
Инициализацию секции .data и обнуление .bss выполняет сама программа.
Ммм... в контексте простой embedded-системы - да. Когда crt0.s является частью программы. Если же в системе живет управляющая ОС, осуществляющая запуск приложений, то ОС, загружая программу, своими средствами выполняет те же действия что и crt0.s перед запуском программы. А именно - копирование секций из LMA в VMA, обнуление .bss, динамическую линковку библиотек, передачу управления на точку указанную через ENTRY() в скрипте линкера. Во всяком случае я пока так себе это представляю.
Цитата(amw @ Mar 14 2008, 11:02) *
Ваша программа включая crt0.S оперирует символами а не секциями. О секциях знает только компилятор и binutils.
Я это понимаю и с этим и не спорил. Я писал об objcopy, которая есть часть binutils и которая оперирует с секциями.
Цитата(amw @ Mar 14 2008, 11:02) *
.noinit секция (если Вы правильно описали ее суть) вообще не должна трогаться. А .bss должна. Как их отличить если .noinit часть .bss?
Вот и я о том же. Значит в описании avr-libc имеется ошибка и ее надо исправить.
Цитата(amw @ Mar 14 2008, 11:02) *
Информация к размышлению © "17 мгновений весны"
Не понял. Эти символы я перемещал - они в моем случае на .hex не влияют.
Цитата(amw @ Mar 14 2008, 11:02) *
Какая из комманд оперирует выровненым адресом?
Никакая. Выровненным во всей системе команд AVR должен быть только аргумент команды перехода или косвенного перехода (ну и упомянутый аргумент команды программирования флеши).
amw
Цитата(Сергей Борщ @ Mar 14 2008, 12:40) *
Нееее smile.gif Из флеш в ОЗУ можно копировать побайтно совершенно безболезненно. Ограничение только при записи в обратном направлении. При записи во флеш (бутлодырь) можно буфер флеша заполнять только по два байта. Но заполняется он из регистров, а читать в регистры можно из любого адреса. И это делается правильно специальными функциями из комплекта avr-libc на инлайн-асме. Так что тут все нормально.

ОК. Убедили, но проверте все же как именно выполняется копирование. Выравние из ниоткуда? Должны же быть причины для такого выравнивания.
Цитата
Звучит правдоподобно, НО КАК? В скрипте-то он был указан быть положенным в .bss То есть вы хотите сказать, что значение b при старте программы не определено? Стандарт утверждает обратное:в .bss попадают как раз an object that has static storage duration и которые при этом not initialized explicitly, т.е. не проинициализированны явно.

Определено. Секция .bss забивается нулями. Естественно я говорю о глобальных и/или статических переменных, а не о тех, что в стеке.
Цитата
Кстати, где-то встречал упоминание (кажется в каком-то из описаний GCC), что переменные, явно проинициализированные нулем тоже кладутся в .bss а не в .data

Гм.. Да. Только что проверил.
Цитата
Ммм... в контексте простой embedded-системы - да. Когда crt0.s является частью программы. Если же в системе живет управляющая ОС, осуществляющая запуск приложений, то ОС, загружая программу, своими средствами выполняет те же действия что и crt0.s перед запуском программы. А именно - копирование секций из LMA в VMA, обнуление .bss, передачу управления на точку указанную через ENTRY() в скрипте линкера.Я это понимаю и с этим и не сприл.

Да. Но! В любом случае, эта часть (копирование и обнуление секций) не есть часть компилятора.
В embedded-мире - это часть libc.
Цитата
Я писал об objcopy, которая есть часть binutils и которая оперирует с секциями.Вот и я о том же. Значит в описании avr-libc имеется ошибка и ее надо исправить.Не понял. Эти символы я перемещал - они в моем случае на .hex не влияют.Никакая. Выровненным во всей системе команд AVR должен быть только аргумент команды перехода или косвенного перехода (ну и упомянутый аргумент команды программирования флеши).

Ага. А где гарантия, что за секция .data (LMA) идет после секции .text? Простейший пример:
Код
text :
{
  (*crt0.o (.text))
}
.data :
{
  *(.data);
}
text :
{
  *(.text);
}

Что будет с переходом, если секция .data - 3 байта?
Думаю, что в виду специфики AVR (и не только) objcopy анализирует что-то, специфичное для конкретной архитектуры.

Щас попробую потасовать секции. Может что-нибудь прояню.
Сергей Борщ
Цитата(Сергей Борщ @ Mar 14 2008, 03:17) *
И тут у меня появился следующий вопрос: почему в примерах WinAVR для получения .hex используется команда $(OBJCOPY) -R .eeprom , хотя более логичным было бы использование $(OBJCOPY) -j .text ? Ведь прошиваемой является только выходная секция .text! Рано радовался. Инициализирующие значения .data складываются после .text посредством : AT() в скрипте линкера. Надо подумать, нельзя ли их сложить внутрь .text, рядом с rodata - тогда бы все получилось красиво.
Развил мысль, все получилось. Надо objcopy указывать не только -j .text, но и -j .data Итого: $(OBJCOPY) -O ihex -j .text -j .data $< $@ копирует в хекс-файл только исполняемый код и инициализирующие значения для .data. Все остальное не копирует.
amw
Цитата(Сергей Борщ @ Mar 14 2008, 13:43) *
Развил мысль, все получилось. Надо objcopy указывать не только -j .text, но и -j .data Итого: $(OBJCOPY) -O ihex -j .text -j .data $< $@ копирует в хекс-файл только исполняемый код и инициализирующие значения для .data. Все остальное не копирует.

А .rodata? Константы нужны? В том числе и те, которые есть в компиляторах и библиотеках.

Цитата
Щас попробую потасовать секции. Может что-нибудь прояню.

Не могу добиться варнинга.
А сравните версии компиляторов. (Я свою приводил выше). Может и в правду какая бага. У Вас есть, а у меня уже (или еще) нет.
Сергей Борщ
Цитата(amw @ Mar 14 2008, 13:27) *
ОК. Убедили, но проверте все же как именно выполняется копирование. Выравние из ниоткуда?
Должны же быть причины для такого выравнивания.
Нормально выполняется. Вот я и надеюсь, что aesok прояснит этот вопрос.
Цитата(amw @ Mar 14 2008, 13:27) *
Да. Но! В любом случае, эта часть (копирование и обнуление секций) не есть часть компилятора.
В embedded-мире - это часть libc.
Да, согласен.

Цитата(amw @ Mar 14 2008, 13:27) *
Ага. А где гарантия, что за секция .data (LMA) идет после секции .text? Простейший пример:
Цитата
Что делает Ричи Блэкмор, когда берет неправильную ноту?
- Вау! Еще и так можно!
smile.gif Вот уж не знал, что выходные секции можно разбивать на части и тасовать. Но в таком случае было бы логично выравнивать начало .text, а не конец предыдущей .data. В общем, пока получается гадание на кофейной гуще.

А вот родилась мысль - может они хотели сделать быстрое копирование, копируя по два байта за каждый проход цикла? Или может так оно и было когда-то, но потом отказались, а это выравнивание - рудимент?
amw
Цитата(Сергей Борщ @ Mar 14 2008, 14:00) *
Нормально выполняется. Вот я и надеюсь, что aesok прояснит этот вопрос.Да, согласен.

smile.gif Вот уж не знал, что выходные секции можно разбивать на части и тасовать. Но в таком случае было бы логично выравнивать начало .text, а не конец предыдущей .data. В общем, пока получается гадание на кофейной гуще.
Цитата

Это был простейший пример.
За секцией .data следуют другие секции, и они могут то-же требовать выравнивания. В общем случае, разумеется. Логично выравнивать каждую секцию, размер которой может быть не кратным.

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

Может и так быть. Однако следует осторожно к этому подходить. И ждать специалиста по binutils smile.gif.
И еще вариант.
Пишем скрипт для одного процессора. Потом появляется новый. Копируем старый скрипт, добавляем нужное (например выравнивание). Потом появляется еще один процессор. Копируем уже модифицированный скрипт и вносим изменения для третьего процессора и т.д.
singlskv
Цитата(Сергей Борщ @ Mar 14 2008, 14:43) *
Развил мысль, все получилось. Надо objcopy указывать не только -j .text, но и -j .data Итого: $(OBJCOPY) -O ihex -j .text -j .data $< $@ копирует в хекс-файл только исполняемый код и инициализирующие значения для .data. Все остальное не копирует.
ИМХО, этот вариант ничем не лучше того что я(и видимо Real) предлагал с удалением
секции -R buffer при производстве hex.

Основная проблемма скорее всего заключается в том, что сегмент определенный
в исходнике как:
Код
uint8_t Buffer[5] __attribute__((section("buffer"),used));
будет иметь все признаки секции .data , те его образ должен появлятся в выходном
hex файле, конечно если мы его "ручками"(-R) не выкинули.
Но при этом для таких секций не будет произведено преобразование адреса VMA в правильный
для сохранения в флеш адрес LMA, те либо это должно делаться в скрипте, либо пользуемся
опцией -R sectname

Покажите минимальный исходник+скрипт в котором есть проблема с лишними
данными в результируещем hex..., будем подумать...
Сергей Борщ
Цитата(singlskv @ Mar 14 2008, 21:08) *
ИМХО, этот вариант ничем не лучше того что я(и видимо Real) предлагал с удалением
секции -R buffer при производстве hex.
Мне он кажется "прямее", потому что надо явно указать что нужно (что я хочу) в выходном файле, а не указанием того, что мне не нужно.

Цитата(singlskv @ Mar 14 2008, 21:08) *
Основная проблемма скорее всего заключается в том, что сегмент определенный
в исходнике как:
Код
uint8_t Buffer[5] __attribute__((section("buffer"),used));
будет иметь все признаки секции .data , те его образ должен появлятся в выходном
hex файле,
Откуда такой вывод? Если я его помещу в выходную секцию .data - появится, если в .bss - нет, и будет обнулен. Если в .noinit (или свою секцию) - и не появится и обнулен не будет.
Цитата(singlskv @ Mar 14 2008, 21:08) *
Покажите минимальный исходник+скрипт в котором есть проблема с лишними данными в результируещем hex..., будем подумать...
Хорошо. Чуть позже.
singlskv
Цитата(Сергей Борщ @ Mar 14 2008, 22:20) *
Мне он кажется "прямее", потому что надо явно указать что нужно (что я хочу) в выходном файле, а не указанием того, что мне не нужно.
Вот в этом мы и пытаемся разобраться... smile.gif как "прямее"
Цитата
Откуда такой вывод? Если я его помещу в выходную секцию .data - появится, если в .bss - нет, и будет обнулен. Если в .noinit (или свою секцию) - и не появится и обнулен не будет.

You may only use the section attribute with a fully initialized global definition
because of the way linkers work. The linker requires each object be defined once,
with the exception that uninitialized variables tentatively go in the common (or
bss) section and can be multiply “defined”. You can force a variable to be
initialized with the ‘-fno-common’ flag or the nocommon attribute.

это из описания gcc.pdf

то есть, ИМХО, по сути обявление своей секции данных, есть объявление алтернаивной
секции .data , но, для нее при этом, без доп телодвижений адрес LMA совпадает с адресом VMA,
и как следствие, мусор в hex тк эта секция не отмапилась на нужные нам адреса в флеш.
Сергей Борщ
Цитата(singlskv @ Mar 14 2008, 21:40) *
то есть, ИМХО, по сути обявление своей секции данных, есть объявление алтернаивной секции .data , но, для нее при этом, без доп телодвижений адрес LMA совпадает с адресом VMA, и как следствие, мусор в hex тк эта секция не отмапилась на нужные нам адреса в флеш.
Это я должен обдумать. Сейчас (пятница smile.gif ) немного не могу въехать. Что-то мне казалось, что все у нас в руках - все секции можно описать в скрипте линкера. Надо указать LMA - указываем, не надо - будет совпадать с VMA. Куда хотим поместить - тот регион и указываем.

Прилагаю обещаный пример. Скрипт - стандартный avr4.x, только добавлена выходная секция .buffer в которую складывается входная buffer. В программе объявлен массив, помещаемый в buffer и массив, помещаемый в .noinit. в .data размещается переменная. По make all создаюся два хекса - Test1.hex создается по примеру WinAVR (objcopy -R .eeprom) - в нем появляются и .buffer и .noinit. Test2 создается по objcopy -j .text -j data - в нем только необходимые для прошивки .text и .data (по адресу LMA). В создаваемом из .elf дизассемблированном Test.lss видно, что все переменные размещаются в нужных адресах ОЗУ.

Извиняюсь, пропустил это письмо:
Цитата(amw @ Mar 14 2008, 13:59) *
А .rodata? Константы нужны? В том числе и те, которые есть в компиляторах и библиотеках.
Конечно. Но они уже сложены в выходную секцию .text в скрипте линкера.
Цитата(amw @ Mar 14 2008, 13:59) *
Не могу добиться варнинга.
А сравните версии компиляторов. (Я свою приводил выше). Может и в правду какая бага. У Вас есть, а у меня уже (или еще) нет.
avr-gcc.exe (GCC) 4.1.2 (WinAVR 20070525)
avr-gcc.exe (GCC) 3.4.6 (WinAVR 20060421)
avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221)
во всех трех случаях варнинг есть.

P.S. родилась еще одна безумная мысль - если у вас нет каких-то особых требований к расположению выходной секции .data в ОЗУ, то в ее начало можно поместить входные секции векторов в ОЗУ и .ramfunc, тогда они будут копироваться crt0.s из флеш в ОЗУ одним заходом вместе с .data
amw
Цитата(Сергей Борщ @ Mar 14 2008, 22:42) *
Конечно. Но они уже сложены в выходную секцию .text в скрипте линкера.avr-gcc.exe (GCC) 4.1.2

Точнее у Вас в .data.
У меня (ARM) отдельная секция для .rodata, и ее не надо копировать в озу.
Цитата
(WinAVR 20070525)
avr-gcc.exe (GCC) 3.4.6 (WinAVR 20060421)
avr-gcc.exe (GCC) 4.2.2 (WinAVR 20071221)
во всех трех случаях варнинг есть.

avr-gcc (GCC) 4.1.0 (Debian/amd64)
Цитата
P.S. родилась еще одна безумная мысль - если у вас нет каких-то особых требований к расположению выходной секции .data в ОЗУ, то в ее начало можно поместить входные секции векторов в ОЗУ и .ramfunc, тогда они будут копироваться crt0.s из флеш в ОЗУ одним заходом вместе с .data

Это Вы про мой пример?
Мысль не безумная, а вполне здравая.
Однако есть причины.
singlskv
Цитата(Сергей Борщ @ Mar 14 2008, 23:42) *
Это я должен обдумать. Сейчас (пятница smile.gif ) немного не могу въехать.

Таки пятница... и Ваш пример сразу не собрался,
собственно интересно что показывает "avr-objdump -h projname.elf"
Сергей Борщ
Цитата(amw @ Mar 14 2008, 23:13) *
Точнее у Вас в .data.
Да, с .rel.rodata попутал.
Цитата(amw @ Mar 14 2008, 23:13) *
У меня (ARM) отдельная секция для .rodata, и ее не надо копировать в озу.
Да, точно. Опять же это распределяется распихиванием входных секций по соответствующим выходным (секциям, а не дням smile.gif ).

Цитата(singlskv @ Mar 14 2008, 23:38) *
Таки пятница... и Ваш пример сразу не собрался,
собственно интересно что показывает "avr-objdump -h projname.elf"
Код
Test.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000074  00000000  00000000  000000b4  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .buffer       00000005  00800060  00800060  00000129  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .data         00000001  00800065  00000074  00000128  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .noinit       00000005  00800066  00800066  0000012e  2**0
                  ALLOC
  4 .stab         00000378  00000000  00000000  00000130  2**2
                  CONTENTS, READONLY, DEBUGGING
  5 .stabstr      00000071  00000000  00000000  000004a8  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_aranges 00000028  00000000  00000000  00000519  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_pubnames 00000038  00000000  00000000  00000541  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_info   0000011d  00000000  00000000  00000579  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_abbrev 00000099  00000000  00000000  00000696  2**0
                  CONTENTS, READONLY, DEBUGGING
10 .debug_line   00000127  00000000  00000000  0000072f  2**0
                  CONTENTS, READONLY, DEBUGGING
11 .debug_frame  00000020  00000000  00000000  00000858  2**2
                  CONTENTS, READONLY, DEBUGGING
12 .debug_str    000000b1  00000000  00000000  00000878  2**0
                  CONTENTS, READONLY, DEBUGGING
Все как и задумано.
singlskv
Цитата(Сергей Борщ @ Mar 15 2008, 01:42) *
Код
Test.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000074  00000000  00000000  000000b4  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .buffer       00000005  00800060  00800060  00000129  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .data         00000001  00800065  00000074  00000128  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .noinit       00000005  00800066  00800066  0000012e  2**0
                  ALLOC
  4 .stab         00000378  00000000  00000000  00000130  2**2
                  CONTENTS, READONLY, DEBUGGING
  5 .stabstr      00000071  00000000  00000000  000004a8  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_aranges 00000028  00000000  00000000  00000519  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_pubnames 00000038  00000000  00000000  00000541  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_info   0000011d  00000000  00000000  00000579  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_abbrev 00000099  00000000  00000000  00000696  2**0
                  CONTENTS, READONLY, DEBUGGING
10 .debug_line   00000127  00000000  00000000  0000072f  2**0
                  CONTENTS, READONLY, DEBUGGING
11 .debug_frame  00000020  00000000  00000000  00000858  2**2
                  CONTENTS, READONLY, DEBUGGING
12 .debug_str    000000b1  00000000  00000000  00000878  2**0
                  CONTENTS, READONLY, DEBUGGING
Все как и задумано.
не понимаю что Вы имеете в виду говоря "как и задуманно"
секции .bss просто нет!
секция .buffer по сути(судя по ее атрибутам CONTENTS, ALLOC, LOAD, DATA) есть суть
вторая секция .data , те будет прописанна в флеш

Вопрос, куда будут попадать переменные которые должны были бы быть в .bss ?

ну и LMA у .buffer указывает на 00800060, те при генерации hex гарантированно будет "мусор"...
amw
Цитата(Сергей Борщ @ Mar 14 2008, 22:42) *
Это я должен обдумать. Сейчас (пятница smile.gif ) немного не могу въехать. Что-то мне казалось, что все у нас в руках - все секции можно описать в скрипте линкера. Надо указать LMA - указываем, не надо - будет совпадать с VMA. Куда хотим поместить - тот регион и указываем.

bb-offtopic.gif На третий день до жирафа дошло, что его ноги сбил паровоз smile.gif .

А вот это не то что Вам надо?
Код
  .buffer (NOLOAD) :
  {
    *(buffer);
    KEEP (*(buffer))
  } > data

  .bss :
  {
     PROVIDE (__bss_start = .);
    *(.bss)
    *(.bss*)
    *(COMMON)
     PROVIDE (__bss_end = .);
  }  > data

Полный пример прилагается. Без -R и -j.
Сергей Борщ
Цитата(singlskv @ Mar 15 2008, 01:14) *
секции .bss просто нет!
Вопрос, куда будут попадать переменные которые должны были бы быть в .bss ?
Ее нет, потому что в данном конкретном случае нет данных для нее. Когда есть - все размещается в те адреса, которые указаны для .bss в скрипте.
Цитата(singlskv @ Mar 15 2008, 01:14) *
секция .buffer по сути(судя по ее атрибутам CONTENTS, ALLOC, LOAD, DATA)
А вот на эту строчку я никогда не обращал внимания, ибо не понимал ее содержание. Теперь все стало на свои места. Спасибо! Теперь понятно, почему objcopy -R .eeprom - потому что если скрипт написан правильно, то все, что кроме .eeprom должно идти во флеш.
Цитата(amw @ Mar 15 2008, 10:59) *
А вот это не то что Вам надо?
А вот это именно оно! И решение лежит-то на поверхности... Видать меня ввело в заблуждение то, что (NOLOAD) в скриптах avr-libc не указан для .bss и .noinit. Спасибо! Вопрос можно считать закрытым.

P.S. WinAVR 20070525 (GNU ld version 2.17 + coff-avr-patch (20050630)) NOLOAD проигнорировал. WinAVR 20060421(GNU ld version 2.16.1 + coff-avr-patch (20050630)) и WinAVR 20071221(GNU ld (GNU Binutils) 2.18) отработали правильно.
amw
Цитата(Сергей Борщ @ Mar 15 2008, 12:58) *
А вот это именно оно! И решение лежит-то на поверхности... Видать меня ввело в заблуждение то, что (NOLOAD) в скриптах avr-libc не указан для .bss и .noinit. Спасибо! Вопрос можно считать закрытым.

.bss по умолчанию (NOLOAD).
Сергей Борщ
Цитата(amw @ Mar 15 2008, 13:59) *
.bss по умолчанию (NOLOAD).
Теперь догадываюсь. Где про это можно прочитать? wink.gif
amw
Цитата(Сергей Борщ @ Mar 15 2008, 16:19) *
Теперь догадываюсь. Где про это можно прочитать? wink.gif

Не помню точно. sad.gif
Где-то в Binutils online documentation кажется.
Тут по GCC http://gcc.gnu.org/onlinedocs/
Тут по binutils http://sources.redhat.com/binutils/
singlskv
Цитата(amw @ Mar 15 2008, 11:59) *
А вот это не то что Вам надо?
Да, так у меня тоже все получилось, спасибо, теперь ясно как делать кошерно...

только ИМХО нужно чуть поменять в MEMORY:
MEMORY
{
text (rx) : ORIGIN = 0, LENGTH = 0x17F4
data (rw!x) : ORIGIN = 0x800071, LENGTH = 1024-17
eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 512
}

для того чтобы при перерасходе секции data линкер нам об этом сообщал.
ReAl
Цитата(Сергей Борщ @ Mar 14 2008, 14:00) *
А вот родилась мысль - может они хотели сделать быстрое копирование, копируя по два байта за каждый проход цикла? Или может так оно и было когда-то, но потом отказались, а это выравнивание - рудимент?
Хм... Как раз на днях макет один начал делать, для серии - зашивает тестовую програму в изделие, дёргает за разные ноги, то-сё, потом зашивает рабочую программу. Это всё без компа работать будет (точнее, прошивки от него получать, на тему серийных номеров общаться оно будет, но там свой контроллер в стенде и он будет шить).
Ну так вот забыл уже, что avreal-то давно уже при неполном слове в .hex для флеша от себя добавляет недостающий байт 0xFF.
А для стенда писал из головы, там не надо сильно много всего, проще было заново. Нарвался на то, что в доп. секции во флеше с серийным номером и калибровочными константами, имеющей нечётное число байт - последний байт не записывается во флеш. Тут-то и вспомнил, что в avreal-е сделано дописывание от себя до полного слова. Ну, для данной задачи было проще в линкерном скрипте для секции .cfg добавить .=ALIGN(2); чем усложнять программу макета wink.gif

А секция .data летит в .hex и при её нечётной длине в хексе какой-то программатор может и обломиться (у AVR по программирования флеша сделано с временным байтовым регистром и если не записать старший байт, то всё слово в буфер страницы не пойдёт, если не писать младший, только старший - то в данном слове продублируется младший из предыдущего слова).
AHTOXA
Цитата(Сергей Борщ @ Mar 12 2008, 18:36) *
Массив определяю в программе в отдельную секцию:
Код
uint8_t Buffer[5] __attribute__((section("buffer"),used));


Хоть проблема уже вроде бы решена smile.gif

Читал мануал, наткнулся на такое:

Цитата
Use the section attribute with an initialized definition of a global variable, as shown in the example. GCC issues a warning and otherwise ignores the section attribute in uninitialized variable declarations.


Это интересно?
Сергей Борщ
Цитата(AHTOXA @ Mar 17 2008, 18:11) *
Это интересно?
Да, это действительно интересно. Только не стыкуется пока с наблюдаемым поведением avr-gcc.
Цитата
билет на трамвае к А стоит дешевле чем на автобусе к В....
обдумать
smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.