GCC, ARMboot - создание автономного приложения без какой-либо библиотеки и какой-либо ОС

У меня есть встроенная аппаратная система, которая содержит загрузчик на основе ARMboot (который очень похож на Uboot и PPCboot) .

Этот загрузчик обычно служит для загрузки образа uClinux с флэш-памяти. Однако теперь я пытаюсь использовать этот загрузчик для запуска автономного приложения helloworld, которое не требует какой-либо связанной библиотеки. Фактически, он содержит только while(1){} код в основной функции.

Моя проблема в том, что я не могу узнать, какие настройки GCC мне следует использовать для создания автономного правильно отформатированного двоичного файла.

Я использую следующую команду сборки:

cr16-elf-gcc -o helloworld helloworld.c -nostdlib

выводит предупреждающее сообщение:
предупреждение: не удается найти символ записи _start; по умолчанию 00000004

После этого в загрузчике я загружаю созданное приложение и запускаю его по некоторому адресу:

tftpboot 0xa00000 helloworld
go 0xa00004

Но не работает :( Система перезагружается.

Обычно он должен просто зависнуть (из-за while(1)).


person psihodelia    schedule 08.01.2010    source источник


Ответы (4)


Я не знаю этого загрузчика, но я думаю, вам следует использовать objcopy, подобный этому, чтобы выгрузить свои исполняемые данные в необработанный двоичный файл. Не переходите к заголовкам ELF, народ :)

objcopy -O binary ./a.out o.bin

Также попробуйте скомпилировать независимый от позиции код и прочитать руководства по ld и gcc.

person Community    schedule 08.01.2010
comment
АГА! Спасибо! Это именно то, что я закомментировал в Makefile и с тех пор полностью забыл об этом. Теперь все работает! - person psihodelia; 08.01.2010
comment
Хм, с одной стороны, звучит хорошо, что вы зашли так далеко. Но мне интересно, получаете ли вы какой-либо стартовый код для инициализации среды C - инициализации глобальных переменных, инициализации указателя стека и т. Д. - person Craig McQueen; 09.01.2010
comment
Вы правы, он не получает ничего, что не устанавливал. Хотя стек, вероятно, оставлен где-то для использования, а привет-мир может быть доступен для записи, значения для глобальных переменных остаются в ELF с помощью objcopy, и функции по-прежнему ожидают запуска везде, где их загружает Linux. Вот почему ему нужно читать руководства по ld и gcc, уделяя особое внимание разделу процессора, если он еще не прочитал. - person ; 09.01.2010

Компоновщик жалуется на отсутствие кода запуска.

Вам необходимо предоставить две вещи: код запуска и командный файл компоновщика, который определяет карту адресов вашего целевого процессора.

В вашем случае код запуска выглядит как «bl main», но обычно код запуска инициализирует указатель стека, по крайней мере, перед переходом к main.

Если вы знаете, что загружаете свой пример в ОЗУ, вы можете запустить свою программу напрямую из main. Вам нужно будет определить адрес main () и использовать его для вашей команды «go».

person Richard Pennington    schedule 08.01.2010
comment
Команда tftpboot загружает приложение в оперативную память. Как я могу определить адрес main ()? - person psihodelia; 08.01.2010
comment
Вы можете сбрасывать символы с помощью nm helloworld. - person Richard Pennington; 08.01.2010
comment
Это дает мне 00000004 T _main. Я загружаю приложение в ОЗУ по адресу 0xa00000 и запускаю приложение по адресу 0xa00004 (как в исходном сообщении). Я что-то не так делаю? - person psihodelia; 08.01.2010
comment
Можете ли вы разобрать код на 0xa00004? Выглядит правильно? - person Richard Pennington; 08.01.2010
comment
Я не уверен, что это правильно: 'Дизассемблирование раздела .text: 00000004 ‹_main›: 4: 1d 01 push $ 0x2, r13 6: fd 55 movd (sp), (r13) 00000008 ‹.L2›: 8: e0 10 br * + 0x8 ‹.L2›: s Демонтаж раздела .heap: 00400000 ‹__BSS_END›: ... 'Моя основная функция: int main (void) {while (1) {} return 255; } - person psihodelia; 08.01.2010
comment
Спасибо, проблема решена благодаря jbcreix (см. Выше). - person psihodelia; 08.01.2010

Я работаю на ARM non-os non-lib весь день каждый день. Это мои текущие параметры gcc:

рука-все-gcc -Wall -O2 -nostdlib -nostartfiles -ffreestanding -c hello.c -o hello.o

затем я использую компоновщик, чтобы объединить код C с векторными таблицами и т. д., даже если это не изображение, которому нужна векторная таблица, с помощью векторной таблицы можно легко поместить точку входа в первую инструкцию.

person old_timer    schedule 08.01.2010

По какой причине вы не можете статически связать хотя бы стандартные библиотеки? У вас должна быть рабочая программа и преимущества стандартных библиотек без внешних зависимостей.

Кроме того, позволяет ли ваша цепочка инструментов / IDE различать «автономное приложение» и «приложение Linux»? IDE для AVR32 имеет это отличие и может генерировать либо программу, которая работает во встроенной среде Linux, либо автономную программу, которая в основном становится ОС.

person Ioan    schedule 08.01.2010