Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кросс-компиляция под Xscale/ARM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
samosad
Добрый вечер, прошу совета по кросс-компиляции.

Значит имеем:
хост - PC, OS OpenSUSE 10.3, с компилятором gcc, всевозможными поднятыми серверами,
таргет - Intel IXDP425, соответственно на ней процессор IXP425 архитектуры Xscale, RedBoot 1.94 / 2

Под целевую платформу собрал Linux - Snapgear 3.5 по инструкции с помощью готового toolchain
arm-linux-tools-20061213.tar.gz отсюда: http://snapgear.org/snapgear/downloads.html.

Linux на неё грузится, радостно запускается, видим командную строку.

Далее пытаюсь пишу элементарную программу типа:
file.c :
Код
main()
{
  while(1);
}

Компилирую под хост - gcc file.c - запускаю, работает;
компилирую под таргет - arm-linux-gcc -mbig-endian file.c - загружаю на платформу, запускаю, резутат типа такого: "ошибка libc.so: выполнение бинарного файла остановлено!"
(если не писать параметр -mbig-endian результат еще хуже: "can not execute binary file")
Причем этот же тулчайн (arm-linux-gcc) только что собрал рабочий Snapgear Linux под эту платформу, а элементарная прога типа этой file.c или HelloWorld просто не запускается.

И еще один вопрос - можно ли запускать исполняемые файлы прямо из под RedBoot'a? Упомянутые выше не запускаются, вызывая зависание системы.

Может кто знает, в чем проблема, подскажите, буду очень благодарен!!!
axle
Цитата(samosad @ Mar 2 2008, 02:27) *
И еще один вопрос - можно ли запускать исполняемые файлы прямо из под RedBoot'a? Упомянутые выше не запускаются, вызывая зависание системы.


Можно. Только собраны они должны быть не с arm-linux-gcc, а с arm-elf-gcc. И к линукс это не будет иметь никакого отношения.
amw
Цитата(samosad @ Mar 1 2008, 22:27) *
Добрый вечер, прошу совета по кросс-компиляции.

Значит имеем:
хост - PC, OS OpenSUSE 10.3, с компилятором gcc, всевозможными поднятыми серверами,
таргет - Intel IXDP425, соответственно на ней процессор IXP425 архитектуры Xscale, RedBoot 1.94 / 2

Под целевую платформу собрал Linux - Snapgear 3.5 по инструкции с помощью готового toolchain
arm-linux-tools-20061213.tar.gz отсюда: http://snapgear.org/snapgear/downloads.html.

Linux на неё грузится, радостно запускается, видим командную строку.

Далее пытаюсь пишу элементарную программу типа:
file.c :
Код
main()
{
  while(1);
}

Компилирую под хост - gcc file.c - запускаю, работает;
компилирую под таргет - arm-linux-gcc -mbig-endian file.c - загружаю на платформу, запускаю, резутат типа такого: "ошибка libc.so: выполнение бинарного файла остановлено!"
(если не писать параметр -mbig-endian результат еще хуже: "can not execute binary file")
Причем этот же тулчайн (arm-linux-gcc) только что собрал рабочий Snapgear Linux под эту платформу, а элементарная прога типа этой file.c или HelloWorld просто не запускается.

А на корневой ФС все библиотеки есть? И где они лежат?
Цитата
И еще один вопрос - можно ли запускать исполняемые файлы прямо из под RedBoot'a? Упомянутые выше не запускаются, вызывая зависание системы.

Может кто знает, в чем проблема, подскажите, буду очень благодарен!!!

Исполняемые - нет, бинарники - да. См. пред. пост.
samosad
Цитата
А на корневой ФС все библиотеки есть? И где они лежат?

имеется ввиду ФС которая на целевой платформе? там использую ядро zImage и ФС ramdisk.gz которые генерируются автоматически при сборке Linux (make xconfig - make dep - make)
а корневая ФС основного компа стандартная, тулчайн arm-linux-gcc уставанливается в папку /usr/local/arm-linux, значит и его библиотеки там же должны быть.

и вообще какие библиотеки нужны при компиляции такого файла как file.c (см. первый пост) там же ни одного include'a..
amw
Цитата(samosad @ Mar 3 2008, 22:27) *
имеется ввиду ФС которая на целевой платформе? там использую ядро zImage и ФС ramdisk.gz которые генерируются автоматически при сборке Linux (make xconfig - make dep - make)

Да именно целевой платформы.
Проверте, от каких библиотек зависит исполняемый файл. Эти библиотеки должны быть на целевой кортевой ФС вправильных каталогах (/lib, /usr/lib).
Имеются в виду динамические библиотеки, котрые нужны во время выполнения.
Статическая линковка для того и статическая, что бы во время выполнения не нужно было библиотек.
Кроме того, убедитесь, что Вы используете C а не C++ компилятор. В C++ есть libstdc++.so, которая не бывает статической, а только динамической. (По крайней мере я такого не знаю).
Проверить зависимость от динамических библиотек можно примерно так:
Код
amw@fox:~/tmp$ readelf -d file
Dynamic section at offset 0x630 contains 21 entries:
  Tag        Type                         Name/Value
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
0x000000000000000c (INIT)               0x400350
0x000000000000000d (FINI)               0x400534
0x0000000000000004 (HASH)               0x400240
0x000000006ffffef5 (GNU_HASH)           0x400258
0x0000000000000005 (STRTAB)             0x4002c0
0x0000000000000006 (SYMTAB)             0x400278
0x000000000000000a (STRSZ)              56 (bytes)
0x000000000000000b (SYMENT)             24 (bytes)
0x0000000000000015 (DEBUG)              0x0
0x0000000000000003 (PLTGOT)             0x6007d8
0x0000000000000002 (PLTRELSZ)           24 (bytes)
0x0000000000000014 (PLTREL)             RELA
0x0000000000000017 (JMPREL)             0x400338
0x0000000000000007 (RELA)               0x400320
0x0000000000000008 (RELASZ)             24 (bytes)
0x0000000000000009 (RELAENT)            24 (bytes)
0x000000006ffffffe (VERNEED)            0x400300
0x000000006fffffff (VERNEEDNUM)         1
0x000000006ffffff0 (VERSYM)             0x4002f8
0x0000000000000000 (NULL)               0x0

Это приведенный в первом посте исходник скомпилированный на x86_64. Воспользуйтесь соответствующими кросс-тулсами.
Главное в этой строчке:
Код
0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

Цитата
а корневая ФС основного компа стандартная, тулчайн arm-linux-gcc уставанливается в папку /usr/local/arm-linux, значит и его библиотеки там же должны быть.

и вообще какие библиотеки нужны при компиляции такого файла как file.c (см. первый пост) там же ни одного include'a..

include - это не библиотеки. Это всего лиш включаемые файлы.
Запустите компиляцию с ключем -v и внимательно посмотрите, как gcc запускает линкер.
К примеру тот же исходник:
Код
gcc -v -o file file.c
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.3 20071123 (prerelease) (Debian 4.2.2-4)
/usr/lib/gcc/x86_64-linux-gnu/4.2.3/cc1 -quiet -v file.c -quiet -dumpbase file.c -mtune=generic -auxbase file -version -o /tmp/ccYLRllf.s
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../x86_64-linux-gnu/include"
ignoring nonexistent directory "/usr/include/x86_64-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.2.3/include
/usr/include
End of search list.
GNU C version 4.2.3 20071123 (prerelease) (Debian 4.2.2-4) (x86_64-linux-gnu)
        compiled by GNU C version 4.2.3 20071123 (prerelease) (Debian 4.2.2-4).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 7582e76d5636938d7d7e45262761cb70
as -V -Qy -o /tmp/ccqmWqqj.o /tmp/ccYLRllf.s
GNU assembler version 2.18.0 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.18.0.20080103
/usr/lib/gcc/x86_64-linux-gnu/4.2.3/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o file /usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.2.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.2.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.2.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../.. /tmp/ccqmWqqj.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-linux-gnu/4.2.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.2.3/../../../../lib/crtn.o
samosad
amw, благодарю за столь подробный и развёрнутый ответ!
но думаю вопросы еще будут... чуть позже
amw
Цитата(samosad @ Mar 5 2008, 22:08) *
amw, благодарю за столь подробный и развёрнутый ответ!
но думаю вопросы еще будут... чуть позже

Пожалуйста. А помогло?
Будут вопросы - спрашивайте.
samosad
новые вопросы.
компилирую файл так:
Код
arm-elf-gcc -mbig-endian while.c -o while.elf


по команде
Код
#readelf -d while.elf

результат: в файле нет динамических ссылок.

попытка запуска этого файла под РедБутом
Код
RedBoot: load -r -v -b 0x01600000 while.elf
RedBoot: exec 0x01600000


выдаёт кракозябры и вешает платформу.

попытка запуска его же но под линуксом выдает ошибку "Segmentation fault"

что я делаю не так?
amw
Цитата(samosad @ Mar 12 2008, 21:45) *
новые вопросы.
компилирую файл так:
Код
arm-elf-gcc -mbig-endian while.c -o while.elf

по команде
Код
#readelf -d while.elf

результат: в файле нет динамических ссылок.

Тут вставить
Код
arm-elf-objcopy -O binary while.elf while.bin

Цитата
попытка запуска этого файла под РедБутом

Заменить это:
Цитата
Код
RedBoot: load -r -v -b 0x01600000 while.elf

На это:
Код
RedBoot: load -r -v -b 0x01600000 while.bin

Цитата
RedBoot: exec 0x01600000[/code]

выдаёт кракозябры и вешает платформу.

попытка запуска его же но под линуксом выдает ошибку "Segmentation fault"

что я делаю не так?

Плюс:
1. Не забыть про big/little endian.
2. Линковать по правильному адресу. См. линкер скрипт в info ld
samosad
значит получил я вот такой файл:
Код
# arm-elf-objdump -h while.elf

while.elf:     file format elf32-bigarm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .init         00000020  00008000  00008000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         000024e4  00008020  00008020  00008020  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  2 .fini         0000001c  0000a504  0000a504  0000a504  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .rodata       0000000c  0000a520  0000a520  0000a520  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .eh_frame     00000004  0000a52c  0000a52c  0000a52c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .ctors        00000008  00012530  00012530  0000a530  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  6 .dtors        00000008  00012538  00012538  0000a538  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  7 .jcr          00000004  00012540  00012540  0000a540  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  8 .data         00000930  00012544  00012544  0000a544  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  9 .bss          00000108  00012e74  00012e74  0000ae74  2**2
                  ALLOC
10 .comment      00000498  00000000  00000000  0000ae74  2**0
                  CONTENTS, READONLY
11 .debug_aranges 00000350  00000000  00000000  0000b310  2**3
                  CONTENTS, READONLY, DEBUGGING
12 .debug_pubnames 0000069c  00000000  00000000  0000b660  2**0
                  CONTENTS, READONLY, DEBUGGING
13 .debug_info   0000e556  00000000  00000000  0000bcfc  2**0
                  CONTENTS, READONLY, DEBUGGING
14 .debug_abbrev 0000295d  00000000  00000000  0001a252  2**0
                  CONTENTS, READONLY, DEBUGGING
15 .debug_line   0000217d  00000000  00000000  0001cbaf  2**0
                  CONTENTS, READONLY, DEBUGGING
16 .debug_frame  000008c8  00000000  00000000  0001ed2c  2**2
                  CONTENTS, READONLY, DEBUGGING
17 .debug_str    000013e9  00000000  00000000  0001f5f4  2**0
                  CONTENTS, READONLY, DEBUGGING
18 .debug_loc    000022ae  00000000  00000000  000209dd  2**0
                  CONTENTS, READONLY, DEBUGGING
19 .debug_ranges 000003d0  00000000  00000000  00022c90  2**3
                  CONTENTS, READONLY, DEBUGGING
20 .ARM.attributes 00000010  00000000  00000000  00023060  2**0
                  CONTENTS, READONLY
#

big-endian при компиляции включил.
дальше делаю
Код
# arm-elf-objcopy -O binary while.elf while.bin

при попытке выполнения while.bin под РедБутом плата ресетицца. это конечно тоже результат (раньше зависала и приходилось руками выкл/вкл делать smile.gif ) но всё же не уверен что это правильный результат... аналогичная история с вторым тестовым файлом hello.bin
полдня убил на чтение info ld но что делать не понял. выходит мне придётся писать Makefile и .ld файл в которых надо будет указывать адреса размещения секций программы в памяти??? это ООчень пугает, и откуда брать эти адреса...

может мне нужен другой тулчейн например xscale-elf-gcc? или это тоже самое что arm-elf-gcc?
amw
Цитата(samosad @ Mar 17 2008, 22:34) *
значит получил я вот такой файл:
Код
# arm-elf-objdump -h while.elf

while.elf:     file format elf32-bigarm

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .init         00000020  00008000  00008000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         000024e4  00008020  00008020  00008020  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

VMA == LMA
Похоже на правду.
Смущение вызывает сам адрес. Это область SDRAM? Или Flash? А не занята ли эта область памяти, например RedBoot-ом? Вопросы относятся ко всем секциям.
Если Вы хотите отказаться от ОС, то Вам нужно все делать самому. Абсолютно так-же как и в случае AVR, ARM типа LPC2xxx AT91SAMxxx и др.
Необходимый минимум:
1. Написать скрипт линкера. Описать в нем области памяти (memory region). Распределить секции по этим областям.
2. Написать C-Startup файл. Провести в этом файле инициализацию секций .data и .bss. В случае необходимости (т.е. если RedBoot не делает этого или делает не так как Вам нужно) инициализировать стеки и вектора исключений.
3. Написать простейшую программу на C и помигать светодиодом. printf() не катит, так как неизвестно, куда он будет выводить символы.
4. Покурить ман на предмет отладочных функций RedBoot и попытаться его использовать для отладки.
Цитата
полдня убил на чтение info ld но что делать не понял. выходит мне придётся писать Makefile и .ld файл в которых надо будет указывать адреса размещения секций программы в памяти??? это ООчень пугает, и откуда брать эти адреса...

Либо используйте ОС, либо делайте все самостоятельно.
Цитата
может мне нужен другой тулчейн например xscale-elf-gcc? или это тоже самое что arm-elf-gcc?

Разница только в том (на сколько я успел заметить), что arm-elf-gcc работает всегда и везде, а xscale-elf-gcc мне не удалось заставить работать как надо мне.

Собственно, приведите исходник программы. И начните с "чистого C" а не C++. Проще разбираться.
samosad
Цитата
Смущение вызывает сам адрес. Это область SDRAM? Или Flash? А не занята ли эта область памяти, например RedBoot-ом? Вопросы относятся ко всем секциям.

Адрес секций тут - это как я понимаю смещение относительно базового адреса по которому записана сама программа, не так ли? Если так, то эта память в RAM и она свободная, т.к. при загрузке по этому же адресу 0x01600000 образа ядра zImage оно запускается и работает. да я и другие адреса пробовал, когда залезаешь на флешку РедБут об этом сообщает...

я бы с удовольствием делал всё под ОС но под Linux'ом тоже не получается запустить ничего...
amw
Цитата(samosad @ Mar 18 2008, 18:35) *
Адрес секций тут - это как я понимаю смещение относительно базового адреса по которому записана сама программа, не так ли? Если так, то эта память в RAM и она свободная, т.к. при загрузке по этому же адресу 0x01600000 образа ядра zImage оно запускается и работает. да я и другие адреса пробовал, когда залезаешь на флешку РедБут об этом сообщает...

Позвольте немного базовых замечаний.
Итак смотрим на приведенный фрагмент:
Код
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .init         00000020  00008000  00008000  00008000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .text         000024e4  00008020  00008020  00008020  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

Немного утрировано.
Idx и Name, Size - пропускаем.
VMA - Адрес памяти, по которому производится обращение к этой секции.
LMA - Адрес памяти, по которому данная секция загружается в память перед использованием и инициализацией.
File off - Смещение от начала файла, по которому эта секция храниться на внешнем носителе.

В общем случае VMA != LMA. При наличии ОС, или просто при включенном MMU/Paging.
Будем говорить об ОС. Гипотетической, но большинство реальных ОС делают примерно так-же.

Есть часть ОС, которая "запускает программу на исполнение". Действия:
1. Открыть файл, просмотреть секции, определить размер и адреса LMA для загрузки.
2. Найти свободную память. Отобразить через MMU как непрерывный (по крайней мере для в пределах секции) кусок на адрес LMA.
3. Закрузить секции по адресам LMA в память.
4. Выполнить инициализацию секций.
5. Отобразить память с секциями на адреса VMA.
6. Запустить выполнение программы путем выполнения команды перехода по адресу Entry Point секции .text.

Это весьма утрировано, но пока сгодиться.
При отсутствии ОС и выключеном MMU LMA = VMA.
Память может начинаться с произвольного адреса (допустим начинается 256M = 0x10000000). Пограмма размером 1К. Есть только секция .text. Вопрос на засыпку: Какой размер исполняемого файла? Примерно? Конечно 1K. Это потому, что в файле нет нужды размещать секцию по ее адресу. Секция начинается с начала файла. Это и есть File off. Иначе размер файла будет 0x10000400 байтов.

Цитата
я бы с удовольствием делал всё под ОС но под Linux'ом тоже не получается запустить ничего...

Давайте решим, с чем разбираться. А то создается впечатление, что Вы просто шарахаетесь из стороны в сторону.

PS. Лучше не засорять ветку "основами". Если хотите - пишите в личку.

to moderator: прошу не пинать сильно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.