Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: вопрос по секциям в GNU
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Dopler
Программирую на GCC под AVR32.
В моем процессоре ОЗУ начинается с 0-го адреса, Flash начинается с адреса 0x80000000.
В самом начале ОЗУ (с адреса 0) создаю секцию ".exception", в которой находится таблица векторов прерывания. Эта таблица заполняется в коде, т.е. мне нужно, чтобы секция ".exception" только занимала место, но не была загружаемой.
Помещаю структуру в секцию следующим образом:
Код
EXCEPTION_TABLE __attribute__ ((section (".exception"))) ptrEventTable;


В скрипте линкера секция описана так:
Код
   /*секция exception*/
  .exception :
  {
    _evba = .;
    *(.exception)
  } >INTRAM AT>INTRAM :INTRAM_FROM_CODE

Причем INTRAM_FROM_CODE я объявлял и как PT_LOAD, и как PT_NULL.
В любом случае в .elf файле секция включается с такими атрибутами:
Код
  2 .exception    00000104  00000000  00000000  00000c00  2**2
                  CONTENTS, ALLOC, LOAD, DATA

И соответственно попадает в прошивку (с атрибутом PT_NULL дополнительно выдается warning: "allocated section `.exception' not in segment").
Как сделать так, чтобы секция имела только атрибут ALLOC и не попадала в прошивку? Секция .bss, описанная в скрипте линкера аналогичным образом, имеет только атрибут ALLOC, где это задано мне не понятно.
Сергей Борщ
Цитата(Dopler @ Sep 15 2010, 10:11) *
Секция .bss, описанная в скрипте линкера аналогичным образом, имеет только атрибут ALLOC, где это задано мне не понятно.
Похоже это вбито в компилятор на генетическом уровне. Обзовите секцию как .bss.exception и вставьте ее описание в скрипте до описания остальной части .bss
Dopler
Цитата(Сергей Борщ @ Sep 15 2010, 12:14) *
Похоже это вбито в компилятор на генетическом уровне. Обзовите секцию как .bss.exception и вставьте ее описание в скрипте до описания остальной части .bss


Спасибо за ответ, до такого трюка я уже сам догадался, просто интересно можно ли сделать произвольную секцию незагружаемой? Во всяком случае в gnu ассемблере есть соответствующие директивы, типа
Код
  .section  .exception, "a", @nobits

Но их наличие/отсутствие на тип создаваемой секции не влияет.
AHTOXA
NOLOAD?
Код
    .noinit (NOLOAD) :
    {
        PROVIDE (__noinit_start = .);
        *(.noinit*)
        PROVIDE (__noinit_end = .);
    } > RAM
Dopler
Цитата(AHTOXA @ Sep 15 2010, 12:43) *
NOLOAD?


Да, действительно, спасибо. Надо бы еще раз документацию на ld перечитать.
klen
Цитата(Сергей Борщ @ Sep 15 2010, 12:14) *
Похоже это вбито в компилятор на генетическом уровне. Обзовите секцию как .bss.exception и вставьте ее описание в скрипте до описания остальной части .bss

в том то вся и прелесть GCC что на генетическом уровне вбита идея - "принципиально ничего не прописано - сам прописывай как тебе нада".
Dopler
Цитата(klen @ Sep 16 2010, 14:12) *
в том то вся и прелесть GCC что на генетическом уровне вбита идея - "принципиально ничего не прописано - сам прописывай как тебе нада".

Ну это не совсем так, все же какие-то базовые постулаты в компилятор зашиты (у опытных разработчиков они уже в подкорке, а меня по началу ставили в тупик). Например, та же секция .bss уж точно генерируется автоматически и все параметры ей присваиваются автоматически. Более того ничего с ней сделать компилятор не дает, вылезает варнинг
"ignoring changed section attributes for .bss". Т.е. в GNU есть ряд правил, которые нигде не прописываются, а их надо просто знать.
klen
Цитата(Dopler @ Sep 16 2010, 18:48) *
Ну это не совсем так, все же какие-то базовые постулаты в компилятор зашиты (у опытных разработчиков они уже в подкорке, а меня по началу ставили в тупик). Например, та же секция .bss уж точно генерируется автоматически и все параметры ей присваиваются автоматически. Более того ничего с ней сделать компилятор не дает, вылезает варнинг
"ignoring changed section attributes for .bss". Т.е. в GNU есть ряд правил, которые нигде не прописываются, а их надо просто знать.

в этом случае Вы правы, но этот же компиллер не запрещает вообще не использовать секции .text .data .bss - используйте свои.
я посмотрю детально на счет "ignoring changed section attributes for .bss", мож ключик есть для кастомного восприятия стандартных секций
Konkere
Гм, вопрос по секциям elfa. Есть в исполняемом файле след секции:
Код
.text
.init
.fini
.text.__do_global_dtors_aux
.text.frame_dummy
.text.__do_global_ctors_aux


Из них только первая является моим кодом, остальное компилятор сам создает. Можно ли удалить эти секции из исполняемого файла и как это сделать?
demiurg_spb
Из стандартного makefile от WinAVR:
Код
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
    @echo
    @echo $(MSG_FLASH) $@
    $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@

Делаем умозрительное заключение, что -R означает удалить секцию.
Сергей Борщ
QUOTE (Konkere @ Nov 26 2010, 12:19) *
Можно ли удалить эти секции из исполняемого файла и как это сделать?
Удалить-то можно, но будет ли программа после этого работать? .init - скорее всего используется стартап-кодом. .text.__do_global_ctors_aux - видимо вызов конструкторов глобальных объектов. Если используете C++ - то она нужна. .text.__do_global_dtors_aux - видимо вызов деструкторов глобальных объектов. Если нет выхода из main() - то она точно не нужна.
Konkere
Цитата(demiurg_spb @ Nov 26 2010, 17:19) *
Делаем умозрительное заключение, что -R означает удалить секцию.


Спасибо, будем пробывать.

Цитата(Сергей Борщ @ Nov 26 2010, 18:41) *
Удалить-то можно, но будет ли программа после этого работать? .init - скорее всего используется стартап-кодом.

Инициализация жестко прописана в моем коде, поэтому я не уверен, что .init, созданный компилятором не будет нарушать работу программы.
Сергей Борщ
QUOTE (Konkere @ Nov 28 2010, 22:46) *
Инициализация жестко прописана в моем коде, поэтому я не уверен, что .init, созданный компилятором не будет нарушать работу программы.
Подход оригинальный, но ненаказуемый. И все же хотелось бы услышать, чем плоха стандартная инициализация переменных? Как минимум два ее плюса я знаю - она занимает минимальное место в памяти программ и выполняется достаточно быстро (быстрее разве что пересылка DMA). А вот недостатки?
Konkere
Цитата(Сергей Борщ @ Nov 29 2010, 03:14) *
Подход оригинальный, но ненаказуемый. И все же хотелось бы услышать, чем плоха стандартная инициализация переменных? Как минимум два ее плюса я знаю - она занимает минимальное место в памяти программ и выполняется достаточно быстро (быстрее разве что пересылка DMA). А вот недостатки?


В данном случае речь идет об инициализации регистров процессорра mips. И любой лишний код может вызвать исключение и прекращение работы процессора, что нехорошо smile3009.gif
demiurg_spb
Сергей Вам говорит не о "инициализации регистров процессора", а о инициализации "С, С++ контекста" - это совершенно разные понятия.
Konkere
Цитата(demiurg_spb @ Nov 29 2010, 16:00) *
Сергей Вам говорит не о "инициализации регистров процессора", а о инициализации "С, С++ контекста" - это совершенно разные понятия.


C++ контекст в моем случае не используется, С контекст - будем прописывать сами. Как я уже говорил, этот дополнительный код компилятора может вызвать необрабатываемое прерывание, поэтому он мне не нужен. Насколько я понял, он берется из файла "crt0.o". Как запретить компилятору или линкеру его использовать? К сожелению, вышеуказанный способ избавления от секций ("-R ._init -R .fini", например) у меня почему-то не работает.

P.S. Компилятор mips-kgp-elf, спасибо Klen-у
AHTOXA
Цитата(Konkere @ Nov 30 2010, 10:20) *
Насколько я понял, он берется из файла "crt0.o". Как запретить компилятору или линкеру его использовать?


Ключ линкера -nostartfiles.
Сергей Борщ
QUOTE (Konkere @ Nov 30 2010, 07:20) *
С контекст - будем прописывать сами. Как я уже говорил, этот дополнительный код компилятора может вызвать необрабатываемое прерывание, поэтому он мне не нужен.
В таких случаях обычно пишется функция с названием типа low_level_init() и вызывается из стартапа до инициализации. Она настраивает нужуную вам периферию, после чего возвращает управление в стартап. И уже он родным для компилятора образом подготавливает контекст и вызывает main(). Если в crt0.o не предусмотрен вызов подобной функции - никто не заставляет линковать crt0.o. Достаточно добавить его исходник в проект и в него вписать вызов нужной функции. Прописывать контекст самостоятельно - неэстетично smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.