Openembedded: Часть 2. Создание и использование SDK для ARM
- сборка toolcahin |
- SDK |
- rootfs |
- openembedded |
- jffs2 |
- cross-toolchain |
- arm9 |
- arm
Для написания программ для платформ отличных от х86 требуется cross-toolchain. Cross-toolchain - это набор кросс-компиляторов, соответствующего окружения и кросс-библиотек, таких как libc под выбранную платформу, в нашем случае это будет ARM, а конкретно ARM926. В прошлой статье мы начали знакомство с OpenEmbedded, этот фреймворк позволяет как построить собственный cross-toolchain, так и использовать прекомпилированные SDK которые можно найти в интернете, например Yagarto или CodeSourcery. Последняя возможность очень скупо описана на официальном сайте, тем интереснее будет исследовать её. Работать мы будем с процессорным модулем PM9263 от Австрийской компании Ronetix. К счастью, эта компания уже интегрировала поддержку своих модулей в OpenEmbedded так что нам остается только установить переменную MACHINE в файле конфигурации Bitbake. Забегая вперед скажу, что Вам надо позаботиться о свободном месте на диске. При строительстве SDK каталог ~/my-distr/tmp стал занимать 21.4Гб, в общем система пересталаа влезать на мой 30 гигабайтный винчестер, пришлось поправить переменную TMPDIR в файле ~/my-distr/build/conf/local.conf и разместить временный каталог на другом диске.
Подготовка
Отредактируем файл ~/my-distr/build/conf/local.conf
Изменим строки:
MACHINE = "ronetix-pm9263" DISTRO = "angstrom-2010.x"
Создание Software Development Kit (SDK)
Software Development Kit (SDK) должен обеспечивать окружение и инструменты для создания приложений которые будут работать на целевой системе. Для этого SDK содержат кросс-компиляторы, библиотеки и подключаемые файлы заголовков, а также сценарии для установки переменных среды окружения. Как мы уже упоминали ранее, OpenEmbedded позволяет строить такие законченные SDK.
В OpenEmbedded SDK разделены на 2 логические части, host и target
Подготовка host-части SDK
host-часть - строит утилиты которые должны будут запускаться на host-PC, такие как cmake или симулятор qemu, а так же различные скрипты и библиотеки. Эти утилиты импортируются наследованием SDK (inherit sdk) и по соглашению имена таких пакетов оканчиваются на -sdk, для примера можете посмотреть файл 'task-sdk-host.bb'.
Части SDK создаются как задачи (task). Создаим файл с именем task-my-toolchain-host.bb в каталоге '~/my-distr/openembedded/recipes/tasks' и запишем в него следующий текст
require task-sdk-host.bb DESCRIPTION = "Host packages for my-distr SDK" LICENSE = "MIT" ALLOW_EMPTY = "1" RDEPENDS_${PN} += ""
Пока мы не планируем использовать какие-либо дополнительные пакеты, по-этому оставим список зависимостей пустым (в дальнейшем мы выясним, что нам надо было включить сюда библиотеку libusb), а базовые пакеты, такие как gcc-cross-sdk, gdb-cross-sdk и другие подключены в файле task-sdk-host.bb.
Подготовка target-части SDK
target-часть - строит заголовочные файлы и библиотеки которые будут использоваться при разработке приложений. В OpenEmbedded имена пакетов для файлов заголовков, символических ссылок на библиотеки, pkg-config файлов и т.п. оканчиваются на -dev. Для инсталляции девелопмент пакетов в SDK создадим файл task-my-toolchain-target.bb в каталоге '~/my-distr/openembedded/recipes/tasks' со следующим содержимым
DESCRIPTION = "Target packages for my-distr SDK" LICENSE = "MIT" ALLOW_EMPTY = "1" PR = "r0" PACKAGES = "${PN}" DEPENDS = "task-sdk-bare" RDEPENDS_${PN} += "\ task-sdk-bare \ "
Здесь минимальный набор пакетов импортируется из файла task-sdk-bare.
Сложим их вместе
В предыдущих двух частях мы подготовили host и target части SDK, теперь нам осталось только сложить их вместе. Создадим meta-toolchain-my.bb в каталоге '~/my-distr/openembedded/recipes/meta' с текстом
PR = "r0" TOOLCHAIN_TARGET_TASK = "task-my-toolchain-target" TOOLCHAIN_HOST_TASK = "task-my-toolchain-host" require meta-toolchain.bb SDK_SUFFIX = "toolchain-my"
Теперь можно запустить сборку SDK коммандой
~/my-distr$ bitbake meta-toolchain-my
Если все прошло успешно, то в конце Вы увидите что-то похожее на
NOTE: Tasks Summary: Attempted 1281 tasks of which 980 didn't need to be rerun and 0 failed.
К сожалению, более внятной информации о завершении процесса сборки чего бы то ни было, bitbake не дает. После удачной сборки SDK в каталоге '~/my-distr/tmp/deploy/eglibc/sdk/' должны появиться файлы 'angstrom-v20110413-i686-linux-armv5te-linux-gnueabi-toolchain-my-extras.tar.bz2' и 'angstrom-v20110413-i686-linux-armv5te-linux-gnueabi-toolchain-my.tar.bz2', в них и находится наш только что созданный SDK. Цифры 20110413 в имени - это дата сборки, у Вас она, естественно, будет другой.
Установка и проверка SDK
Теперь эти файлы нужно распаковать в корневой каталог:
cd / sudo tar xf ~/my-distr/tmp/deploy/eglibc/sdk/angstrom-v20110413-i686-linux-armv5te-linux-gnueabi-toolchain-my.tar.bz2 sudo tar xf ~/my-distr/tmp/deploy/eglibc/sdk/angstrom-v20110413-i686-linux-armv5te-linux-gnueabi-toolchain-my-extras.tar.bz2
Чтобы использовать SDK выполните следующую команду:
$ . /usr/local/angstrom/arm/environment-setup
Ее нужно будет выполнять всякий раз при начале работы, или прописать ее в .bashrc чтобы это выполнялось автоматически. Теперь проверим:
$ arm-angstrom-linux-gnueabi-gcc -v Using built-in specs. COLLECT_GCC=arm-angstrom-linux-gnueabi-gcc Target: arm-angstrom-linux-gnueabi Configured with: /mnt/windows/Dimon/oetmp/work/i686-armv5te-sdk-angstrom-linux-gnueabi/gcc-cross-sdk-4.5-r31.2+svnr168622/gcc-4_5-branch/configure --build=i686-linux --host=i686-linux --target=arm-angstrom-linux-gnueabi --prefix=/usr/local/angstrom/arm --exec_prefix=/usr/local/angstrom/arm --bindir=/usr/local/angstrom/arm/bin --sbindir=/usr/local/angstrom/arm/bin --libexecdir=/usr/local/angstrom/arm/libexec --datadir=/usr/local/angstrom/arm/share --sysconfdir=/usr/local/angstrom/arm/etc --sharedstatedir=/usr/local/angstrom/arm/share/com --localstatedir=/usr/local/angstrom/arm/var --libdir=/usr/local/angstrom/arm/lib --includedir=/usr/local/angstrom/arm/include --oldincludedir=/usr/local/angstrom/arm/include --infodir=/usr/local/angstrom/arm/share/info --mandir=/usr/local/angstrom/arm/share/man --with-libtool-sysroot --enable-largefile --disable-nls --enable-ipv6 --with-gnu-ld --enable-shared --enable-languages=c,c++,objc --enable-threads=posix --disable-multilib --enable-c99 --enable-long-long --enable-symvers=gnu --enable-libstdcxx-pch --program-prefix=arm-angstrom-linux-gnueabi- --enable-target-optspace --enable-lto --enable-libssp --disable-bootstrap --disable-libgomp --disable-libmudflap --with-float=soft --with-sysroot=/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi --with-build-time-tools=/mnt/windows/Dimon/oetmp/sysroots/i686-linux/usr/armv5te/arm-angstrom-linux-gnueabi/bin --with-build-sysroot=/mnt/windows/Dimon/oetmp/sysroots/armv5te-angstrom-linux-gnueabi --disable-libunwind-exceptions --with-mpfr=/mnt/windows/Dimon/oetmp/sysroots/i686-linux/usr --with-system-zlib --enable-__cxa_atexit Thread model: posix gcc version 4.5.3 20110110 (prerelease) (GCC)
Точно таким же образом вы можете установить SDK на любой другой компьютер работающий под управлением ОС Linux.
Решение проблем
ERROR: QA Issue with eglibc-pic: non debug package contains .debug directory: eglibc-pic path /work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/packages-split/eglibc-pic/usr/lib/libc_pic/.debug/sofini.o ERROR: QA Issue with eglibc-pic: non debug package contains .debug directory: eglibc-pic path /work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/packages-split/eglibc-pic/usr/lib/libc_pic/.debug/soinit.o ERROR: QA Issue with eglibc-pic: non debug package contains .debug directory: eglibc-pic path /work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/packages-split/eglibc-pic/usr/lib/libc_pic/.debug/sofini.o ERROR: QA Issue with eglibc-pic: non debug package contains .debug directory: eglibc-pic path /work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/packages-split/eglibc-pic/usr/lib/libc_pic/.debug/soinit.o FATAL: QA run found fatal errors. Please consider fixing them. ERROR: Error in executing python function in: ~/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb ERROR: Exception:<type 'exceptions.SystemExit'> Message:1 ERROR: Printing the environment of the function ERROR: Function do_package_qa failed ERROR: TaskFailed event exception, aborting ERROR: Build of ~/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb do_package failed FATAL: QA run found fatal errors. Please consider fixing them. ERROR: Task 67 (~/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb, do_package) failed with 256 ERROR: TaskFailed event exception, aborting ERROR: Build of ~/my-distr/openembedded/recipes/gcc/gcc-cross_4.5.bb do_compile failed ERROR: TaskFailed event exception, aborting ERROR: Build of ~/my-distr/openembedded/recipes/gcc/gcc-cross-sdk_4.5.bb do_compile failed
Как можно понять из сообщения, в файле '~/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb' есть проблема, а именно, не dbg пакет содержит в себе .debug каталог. Чтобы исправить эту ситуацию надо отредактироватьстроку в файле '/my-distr/openembedded/recipes/eglibc/eglibc-package.inc':
FILES_${PN}-dbg += "${libexecdir}/*/.debug ${libdir}/gconv/.debug"
Заменить на
FILES_${PN}-dbg += "${libexecdir}/*/.debug ${libdir}/gconv/.debug ${libdir}/libc_pic/.debug"
И заново запустить сборку SDK. Если после этого Вы увидите такое сообщение об ошибке
ERROR: TaskFailed event exception, aborting ERROR: Build of /home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb do_configure failed ERROR: Task 64 (/home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb, do_configure) failed with 256 ERROR: '/home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb' failed ERROR: Function do_configure failed NOTE: Task failed: ('function do_configure failed', '/mnt/windows/Dimon/oetmp/work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/temp/log.do_configure.10632') ERROR: Logfile of failure stored in: /mnt/windows/Dimon/oetmp/work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/temp/log.do_configure.10632 Log data follows: | checking build system type... i686-pc-linux-gnu | checking host system type... arm-angstrom-linux-gnueabi | checking for arm-angstrom-linux-gnueabi-gcc... arm-angstrom-linux-gnueabi-gcc -march=armv5te -mtune=arm926ej-s -mthumb-interwork -mno-thumb | checking for suffix of object files... o | checking whether we are using the GNU C compiler... yes | checking whether arm-angstrom-linux-gnueabi-gcc -march=armv5te -mtune=arm926ej-s -mthumb-interwork -mno-thumb accepts -g... yes | checking for arm-angstrom-linux-gnueabi-gcc -march=armv5te -mtune=arm926ej-s -mthumb-interwork -mno-thumb option to accept ISO C89... unsupported | checking for gcc... gcc | checking how to run the C preprocessor... arm-angstrom-linux-gnueabi-gcc -E | configure: error: in `/mnt/windows/Dimon/oetmp/work/armv5te-angstrom-linux-gnueabi/eglibc-2.12-r21.8+svnr12323/build-arm-angstrom-linux-gnueabi': | configure: error: C preprocessor "arm-angstrom-linux-gnueabi-gcc -E" fails sanity check | See `config.log' for more details. | ERROR: Function do_configure failed NOTE: package eglibc-2.12-r21.8+svnr12323: task do_configure: Failed ERROR: TaskFailed event exception, aborting ERROR: Build of /home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb do_configure failed ERROR: Task 64 (/home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb, do_configure) failed with 256 ERROR: '/home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb' failed ERROR: '/home/d400/my-distr/openembedded/recipes/eglibc/eglibc_2.12.bb' failed
то выполните очистку пакетов eglibc-initial и eglibc
~/my-distr$ bitbake -cclean eglibc-initial eglibc
И снова запустите сборку SDK.
Использование прекомпилированного toolchain-а
TODO: You want to use external-toolchain. Setting PREFERRED_PROVIDER for the toolchain to that + environment variables + toolchain layout. Please someone write the documentation for that.
Вот и всё что написано на сайте openembedded.org о возможности использования готовых cross-toolchain-ов. Печально, но не страшно, попробуем разобраться. В интернете нашлось вот такое описание использования прекомпилированного toolchain-а совместно с OE. Вообще, файлы конфигурации OE довольно хорошо откомментированы, так что иногда проще почитать коммантарии, чем рыться в документации.
Итак, как я писал в самом начале статьи, cross-toolchain состоит из:
- binutils, таких как gcc, as, ld и т.д.
- библиотек, таких как libc
- переменных окружения и путей ко всему этому добру.
Всё это мы и должны сконфигурировать.
Binutils
У меня они лежат в каталоге /usr/local/angstrom/arm/bin/, вот список:
arm-angstrom-linux-gnueabi-addr2line arm-angstrom-linux-gnueabi-ar arm-angstrom-linux-gnueabi-as arm-angstrom-linux-gnueabi-c++filt arm-angstrom-linux-gnueabi-cpp arm-angstrom-linux-gnueabi-g++ arm-angstrom-linux-gnueabi-gcc arm-angstrom-linux-gnueabi-gccbug arm-angstrom-linux-gnueabi-gcov arm-angstrom-linux-gnueabi-gdb arm-angstrom-linux-gnueabi-gdbtui arm-angstrom-linux-gnueabi-gprof arm-angstrom-linux-gnueabi-ld arm-angstrom-linux-gnueabi-nm arm-angstrom-linux-gnueabi-objcopy arm-angstrom-linux-gnueabi-objdump arm-angstrom-linux-gnueabi-ranlib arm-angstrom-linux-gnueabi-readelf arm-angstrom-linux-gnueabi-run arm-angstrom-linux-gnueabi-size arm-angstrom-linux-gnueabi-strings arm-angstrom-linux-gnueabi-strip
Бибилиотеки
Кросс-компилированные библиотеки и заголовочные файлы находятся в каталоге /usr/local/angstrom/arm/arm-angstrom-linux-gnueabi, в подкаталогах include и lib
Окружение
Для экспорта переменных создадим такой скрипт и назовем его build_source:
BITBAKE_PATH=~/my-distr/bitbake/bin TOOLCHAIN=/usr/local/angstrom/arm/bin/ export PRE_BUILT=/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi export PATH=$BITBAKE_PATH:$TOOLCHAIN:$PATH export OEDIR=$PWD
Как Вы, наверное, помните, такие скрипты надо запускать строкой:
$ . /путь-к-скрипту/build_source
или
$ source /путь-к-скрипту/build_source
либо вписать содержимое этого скрипта в .bashrc
Настройки OpenEmbedded
Мы определили, где у нас лежат файлы cross-toolchain-а и бибилиотек, теперь надо объяснить всё это OpenEmbedded-у.
Итак, открываем файл ~/my-distr/build/conf/local.conf и находим там такие строки:
# Uncomment this if you want to use a prebuilt toolchain. You will need to # provide packages for toolchain and additional libraries yourself. You also # have to set PATH in your environment to make sure BitBake finds additional binaries. ASSUME_PROVIDED += "virtual/${TARGET_PREFIX}gcc virtual/libc"
Изначально эта строка закомментирована, надо это исправить. Затем, в конец файла надо добавить следующие строки:
export CC = "${CCACHE}arm-angstrom-linux-gnueabi-gcc ${HOST_CC_ARCH}" export CXX = "${CCACHE}arm-angstrom-linux-gnueabi-g++ ${HOST_CC_ARCH}" export CPP = "arm-angstrom-linux-gnueabi-gcc -E" export LD = "arm-angstrom-linux-gnueabi-ld" export AR = "arm-angstrom-linux-gnueabi-ar" export AS = "arm-angstrom-linux-gnueabi-as" export RANLIB = "arm-angstrom-linux-gnueabi-ranlib" export STRIP = "arm-angstrom-linux-gnueabi-strip" export PRE_BUILT=/usr/local/angstrom/arm/arm-angstrom-linux-gnueabi
Если у Вас установлен какой-то другой toolchain, естественно, нужно будет указать его префиксы в названиях.
Следующие строки переопределяют соответствующие переменные из bitbake.conf, так же добавим их в конец нашего local.conf
# # point OE to the lib and include directory # TARGET_CPPFLAGS_append = " -isystem${PRE_BUILT}/include " TARGET_LDFLAGS_prepend = " -L${PRE_BUILT}/lib -Wl,-rpath-link,${PRE_BUILT}/lib "
Если Вы используете другие библиотеки, например Qt, то их надо указать здесь же, а так же добавить их в переменную ASSUME_PROVIDED описанную выше.
Собираем тестовый дистрибутив
~/my-distr$ bitbake micro-image
если в результате мы увидим ошибки, например такие:
| /usr/local/angstrom/arm/lib/gcc/arm-angstrom-linux-gnueabi/4.5.3/../../../../arm-angstrom-linux-gnueabi/bin/ld: cannot find -lusb-1.0 | collect2: ld returned 1 exit status | make[2]: *** [libusb.la] Error 1 | make[2]: Leaving directory `/mnt/windows/Dimon/oetmp/work/armv5te-angstrom-linux-gnueabi/libusb-compat-1_0.1.3-r0/libusb-compat-0.1.3/libusb' | make[1]: *** [all-recursive] Error 1 | make[1]: Leaving directory `/mnt/windows/Dimon/oetmp/work/armv5te-angstrom-linux-gnueabi/libusb-compat-1_0.1.3-r0/libusb-compat-0.1.3' | make: *** [all] Error 2 | FATAL: oe_runmake failed | ERROR: Function do_compile failed NOTE: package libusb-compat-1_0.1.3-r0: task do_compile: Failed ERROR: TaskFailed event exception, aborting ERROR: Build of /home/d400/my-distr/openembedded/recipes/libusb/libusb-compat_0.1.3.bb do_compile failed ERROR: Task 786 (/home/d400/my-distr/openembedded/recipes/libusb/libusb-compat_0.1.3.bb, do_compile) failed with 256
значит отсутствуют какие-либо нужные библиотеки в нашем toolchain-е. В данном примере отсутствует библиотека libusb. Её нужно добавить в host часть SDK и пересобрать его, только перед этим нужно убрать все изменения что мы делали для работы с предустановленным toolchain-ом, иначе новый toolchain будет собираться с использованием старого. Оказывается, создание собственного SDK не такое уж и простое дело.
Добавляем библиотеку в файл '~my-distr/openembedded/recipes/tasks/task-my-toolchain-host.bb'
RDEPENDS_${PN} += "libusb"
Пересобираем и переустанавливаем toolchain как было описано ранее. Теперь можно снова собрать rootfs image.
~/my-distr$ bitbake micro-image
После успешного окончания сборки идем в каталог 'tmp/deploy/eglibc/images/ronetix-pm9263' - там находятся файлы для прошивки
Angstrom-micro-image-eglibc-ipk-v20110705-ronetix-pm9263.rootfs.jffs2 Angstrom-micro-image-eglibc-ipk-v20110705-ronetix-pm9263.rootfs.tar.gz
Файл с расширением jffs2 - это и есть прошивка, которую надо поместить на NAND Flash нашего устройства. Tar-архив - это та же прошивка, только ее можно легко просмотреть на ПК, например для контроля, что нужные файлы попали в прошивку. Это полезно при разработке собственных рецептов.
Заключение
В данной статье мы рассмотрели вопросы создания SDK в среде OpenEmbedded, а так же использование собственноручно созданного SDK в качестве предустановленного toolchain-а при сборке rootfs.
Во время поиска информации по использованию предустановленного toolchain-а, я наткнулся на следующие настройки для работы с CodeSourcery Toolchain
# enable following line to use CodeSourcery Lite TOOLCHAIN_VENDOR := "-none" TOOLCHAIN_TYPE := "external" TOOLCHAIN_BRAND := "csl"
Эти строки нужно добавить в ~/my-distr/build/conf/local.conf. Я не проверял что получится в результате, так что буду рад, если кто-то попробует CodeSourcery и отпишется в комментариях.
- блог пользователя GDI
- 121614 просмотров
Новые записи в блогах
- Устранение дребезга контактов на основе вертикальных счетчиков
- Диагностика Imprecise Bus Faults в микроконтроллерах Cortex-M3/M4/M4F
- Self-powered камера
- Фоновый модулятор: беспроводная связь из ничего (перевод)
- Texas Instruments Analog Applications Journal SLYT612 "Снижение искажений в аналоговых КМОП ключах" (перевод)
- USB MSD. Часть 6. Команды SCSI (перевод)
- USB MSD. Часть 3. USB класс накопителей данных (перевод)
- Texas Instruments Application Report SBAA042 "Кодовые схемы, используемые в аналогово-цифровых преобразователях" (перевод)
- 10 принципов правильного интерфейса
- Релиз SDK на русский микропроцессор КРОЛИК
Комментарии
Отправить комментарий