Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: назначение startup.s ассемлерных файлов
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
xelax
Вел раньше свои разработки на филипсовых армах lpc использовал при этом IAR. Теперь необходимо перейти на atmel'овские армы и использовать gnu'сный gcc.

Имеется at91sam7x256 evalution kit плата. Скачал и установил Eclipse и YAGARTO gcc. Скачал и скомпилил start example с сайта атмела. Всё получилось, загрузилось и заработало. Но.... Очень много нового и непонятного.

И самое непонятное для меня смысл ассемблеровских стартапных исходников (видел подобное в Keil). wacko.gif
Вот собственно вопросы знатокам gcc:
1. Глубокий смысл этих файлов каков?
2. Можно как-нибудь обойтись без них или переписать на С?

З.Ы. В IARе у меня ничего погдобного не было, всё что нужно я инициализировал сам в коде, использовал настройки проекта и настраивал xcl файлы линкера. Этого хватало.
Stanislav
Цитата(xelax @ Aug 3 2007, 11:22) *
Вот собственно вопросы знатокам gcc:
1. Глубокий смысл этих файлов каков?..
Инициализация С-шной среды (глобальных переменных, стэка, прерываний и т.д.)
Цитата(xelax @ Aug 3 2007, 11:22) *
...2. Можно как-нибудь обойтись без них или переписать на С?
Нельзя. Для запуска процедуры main означенные действия должны быть выполнены. См. стандарты C/C++.
SpiritDance
Цитата(Stanislav @ Aug 3 2007, 14:25) *
Нельзя. Для запуска процедуры main означенные действия должны быть выполнены.

Это совершенно не означает того что нельзя переписать на С smile.gif А потом сишную функцию инициализации вызвать из ассемблерного стартапа. Только сначала нужно sp проинициализировать, я в него например писал адрес "начало рам+100", такого стека хватало, а потом он все равно в crt0 переинициализируется.

Тьфу ты. подумал что это касается инициализации железа. Для остального конечно нужен ассемблер.
Paramon
Цитата(Stanislav @ Aug 3 2007, 14:25) *
Инициализация С-шной среды (глобальных переменных, стэка, прерываний и т.д.)
Нельзя. Для запуска процедуры main означенные действия должны быть выполнены. См. стандарты C/C++.


А если уже давно всё инициализировано, а требутся отдельно (в другом проекте) скомпилить подгружаемый в озу код?
Весь день бьюсь! Всё безрезультатно!
SpiritDance
Хм. Ну а как, по-вашему, exe-файлы делаются и загружаются?
v_shamaev
Цитата(Paramon @ Aug 3 2007, 15:30) *
А если уже давно всё инициализировано, а требутся отдельно (в другом проекте) скомпилить подгружаемый в озу код?
Весь день бьюсь! Всё безрезультатно!

Скомпилить никто не препятствует. Скорее всего вы хотите получить .elf а это уже "собрать" называется, ну в данном случае я бы и посмотрел на правила построения подгружаемых модулей - оверлеи или динамические библиотеки. Там main() не нужен, а сл-но и стартап не прилинковывется. Если хотите грубо вычистить (хаком) - тогда собственный ld-скрипт, убрать в нем стартап, и прописать стартовую процедуру. И ключи линкеру соответствующие.
xelax
Понятно, короче без стартапа на асме не обойтись. Прийдётся серьёзней разбираться с асмом.
Спасибо всем ответившим.

З.Ы. Всё таки у IARа более красивое решение, завуалированное в настройки проекта и настраиваемого pragma'ми.
Paramon
Цитата(xelax @ Aug 6 2007, 09:55) *
Понятно, короче без стартапа на асме не обойтись. Прийдётся серьёзней разбираться с асмом.
Спасибо всем ответившим.

З.Ы. Всё таки у IARа более красивое решение, завуалированное в настройки проекта и настраиваемого pragma'ми.


Да !!! что-то мне КЕЙЛ с каждым разом всё меньнше нравится. 05.gif
Но с IARом совсем незнаком 01.gif
И не только с ИАРом, кроме КЕЙЛА ни с кем laughing.gif
Хомяк
Цитата(xelax @ Aug 6 2007, 08:55) *
Понятно, короче без стартапа на асме не обойтись. Прийдётся серьёзней разбираться с асмом.
Спасибо всем ответившим.

З.Ы. Всё таки у IARа более красивое решение, завуалированное в настройки проекта и настраиваемого pragma'ми.


В IAR-е тоже используются ассмовсий стартуп
Kirill Frolov
[quote name='xelax' date='Aug 3 2007, 11:22' post='279357']
Имеется at91sam7x256 evalution kit плата. Скачал и установил Eclipse и YAGARTO gcc.

Что касается eclipse. Надо просто понимать, что отладчик -- gdb. Остальное -- красивые обёртки. Конфеты в них те же самые.

[quote]
Скачал и скомпилил start example с сайта атмела. Всё получилось, загрузилось и заработало. Но.... Очень много нового и непонятного.

И самое непонятное для меня смысл ассемблеровских стартапных исходников (видел подобное в Keil). wacko.gif
[/quote]

А как ты представляешь C-шный стартап? Я вот /в общем случае/
не представляю. В частном -- может быть... далеко не всегда.
Понятное, дело, он может быть не полностью ассемблерный.
Ассемблера там на самом деле-то всего ничего нужно.
Смысл простой. C(++)-компилятор расчитывает на то, что к моменту
вызова main() будет обнулёна секция bss, будут скопированы из ROM в RAM
данные из .data -- это как минимум. Потом в main() могут передаваться какие-то аргументы (например, от монитора-загрузчика). Обработка преываний опять же -- C не имеет для этого средств.
Настойка какой-то критичной части аппаратуры, что требуется, возможно, сразу
после старта CPU.

[quote]
Вот собственно вопросы знатокам gcc:
1. Глубокий смысл этих файлов каков?
2. Можно как-нибудь обойтись без них или переписать на С?
[/quote]

1. См. выше.

2. Можно в части случаев на части архитектур. В части случаев нельзя.

[quote]
З.Ы. В IARе у меня ничего погдобного не было, всё что нужно я инициализировал сам в коде, использовал настройки проекта и настраивал xcl файлы линкера. Этого хватало.
[/quote]

Там стартап был положен в комплект компилятора. Как это делается, например, для avr-gcc (winavr). Но опять же, в ряде случаев такой стартап чем-то не устраивает и его приходится менять. Keil для чего, например, даёт исходники и подробно разъясняет в документации как это делается.

Совет: напиши собственный стартап и собственные скрипты для линкера. ОЧЕНЬ ПОМОЖЕТ в понимании КАК ЭТО РАБОТАЕТ. И, возможно, во многих других вопросах. Только времени придётся сколько-то затратить.


[quote name='Stanislav' post='279437' date='Aug 3 2007, 14:25']
Инициализация С-шной среды (глобальных переменных, стэка, прерываний и т.д.)
Нельзя. Для запуска процедуры main означенные действия должны быть выполнены. См. стандарты C/C++.
[/quote]

А main не нужно (забыл, написал я выше или нет, но типовой же стартап содержит смешанный на C и ассемблере код). Ничто не мешает написать что-то вроде следующего:

int main(int argc, char *argv[]);
void _start(void) __attribute__((naked));

void _start(void)
{
while (1) {
memset(__bss_start__, 0, __bss_end__ - __bss_start__);
memcpy(_data, _etext, _edata - _data);
main(0, NULL);
}
}

Но во-первых режимы ARM'а без хотя бы asm("blablabla CPSR") уже не
получится. Во-вторых сложно настроить стек (а без этого сишная программа
сразу же свалится) -- можно использовать опять же asm() и полагаться
на оптимизатор который не додумается что-то разместить в стеке.
Потом сложности с обработкой прерывываний того же порядка, плюс
чрезвычайно неэффективный код, если это вообще возможно, не уверен.
И, наконец, нужно как-то сформировать вектор прерываний. Думаю
можно как-то выкрутиться, но уже сложно (и, видимо, опять asm()).

Реально проще написать на ассемблере. Там всего-то строк 200.
По крайней мере там где проще. Там где не проще в примерах и у меня есть C-шная функция, вызываемая непосредственно из стартапа, до вызова main() (и до всяких там обнулений bss, но уже с настроенным стеком). В ней я, например, генератор завожу и биты в портах в безопасное состояние устанавливаю.

Приложу к письму пример своего стартапа (crt0.S) и C-функции из него вызываемой (main.c).
Alex03
Ну и ещё crt инициализирует кучу, для С++ вызывает конструкторы глобальных объектов, а после main соответствующие деструкторы. Видимо тамже может быть вызов функций по списку сгенерённому вызовами atexit(). и т.д.
Kirill Frolov
Цитата(Alex03 @ Aug 8 2007, 12:29) *
Ну и ещё crt инициализирует кучу, для С++ вызывает конструкторы глобальных объектов,


Что касается "кучи", то тут как и во многих других случаях используется тот грязный трюк, что
всё попавшее в bss изначально обнулено. И используется "ленивая" инициализация по первому вызову
соответствующей функции. Это для варианта с newlibc, у IAR не знаю. Вообще "куча" для работы C[++]
программ не обязательна...

Цитата
а после main соответствующие деструкторы.


Какой, к чёрту, выход из встраеваемой программы...

Цитата
Видимо тамже может быть вызов функций по списку сгенерённому вызовами atexit(). и т.д.


Это из exit() должно вызывается (входит в состав lic), в который следует попадать в т.ч. после выхода из main(),
после чего положено звать _exit(). Но -- см. выше.
Alex03
Кучи бывают всякие, и не факт что в bss-е.
Выход из main() тоже может понадобиться.

Ну а в общем случае содержимое startup/crt (как впрочем и линкерного скрипта) довольно опционально и сильно зависит (может зависеть) от платформы/железа/библиотек/ОС/нужд проги и т.д.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.