Quantcast
Channel: Hard-Soft News » soft
Viewing all articles
Browse latest Browse all 10

Программирование для ARM, часть II

$
0
0

Одно из самых существенных отличий разработки для ARM от разработки для обычного ПК заключается в том, что устройства, работающие на ARM, как правило, не могут собирать программы сами для себя. В принципе они, конечно, могут это делать, и если у вас есть компьютер на процессоре ARM с полноценной ОС Linux и средствами разработки, вам беспокоиться не о чем, но большинству устройств просто не хватает ресурсов для самостоятельной сборки чего-либо. Для таких устройств программы собираются на «обычных» интеловских ПК, а затем загружаются в компьютер на процессоре ARM. Одно из таких средств основано на системе Scratchbox и инструментарии сборки CodeSourcery. С помощью этого набора можно создавать и отлаживать программы, предназначенные для различных вариантов ОС Linux, выполняющихся на процессоре ARM.

Scratchbox представляет собой «песочницу», в которой можно выполнять различные действия (в том числе, в режиме эмуляции root), не затрагивая работу остальной системы. Одна из функций Scratchbox – кросс-платформенная сборка, в процессе которой программа связывается не с библиотеками хозяйской системы, а с библиотеками,  установленными в песочнице Scratchbox. Эти библиотеки могут быть предназначены для другой архитектуры процессора, например, для ARM.

Scratchbox позволяет не только собирать программы для архитектуры ARM на машине x86, но и запускать их на выполнение и проводить отладку. Для этого, помимо самой «песочницы» нужно установить средства разработки для ARM (например, CodeSourcery Toolchain, об этом ниже) и эмулятор QEMU. На самом деле программа, собранная под ARM, будет запускаться,   конечно же, в эмуляторе QEMU. Но, благодаря методу CPU-Trancparency, используемому в Scratchbox, выглядит это так, как будто, программы выполняются непосредственно на вашем компьютере.

Помимо прочего, Scratchbox включает в себя насколько наборов разработчика (development kits, devkits), которые содержат компоненты среды (библиотеки, утилиты), предназначенные для сборки программ для различных дистрибутивов Linux.

Для знакомства со Scratchbox проще всего воспользоваться дистрибутивом, который распространяется вместе с MAEMO SDK. Хотя платформа MAEMO выходит из употребления, ее можно использовать для знакомства с процессорами ARM, — принципы кросс-платформенной разработки не меняются так же быстро как решения компании Nokia.

Подробная инструкция по установке MAEMO SDK, в том числе и Scratchbox, доступна по адресу wiki.maemo.org/Documentation/Maemo5_Final_Installation. Вы можете услышать, или, скорее прочитать, что Scratchbox работает только в 32-х битной системе. В настоящее время это уже не так, я ставил Scratchbox на 64-битную Ubuntu. Полезные советы можно найти в специальной теме на форуме поддержки Nokia. MAEMO SDK позволяет эмулировать работу графических приложений с помощью специального графического сервера Xephyr.

Если вы не хотите пользоваться MAEMO SDK, можете установить Scratchbox самостоятельно. С сайта проекта (www.scratchbox.org) можно загрузить исходные тексты Scratchbox и наборов разработчика и готовые пакеты Debian.Сложности могут возникнуть при  настройке Scratchbox. Пакет scratchbox  существует в двух вариантах: старый scratchbox 1.x и новый scratchbox 2, который разрабатывается при поддержке Nokia. Мы рассмотрим настройку scratchbox 2. Перед настройкой scratchbox 2, помимо самого пакета, нужно установить QEMU и систему сборки для ARM. В качестве последней мы используем  инструментарий CodeSourcery для процессоров ARM.

Дистрибутивы инструментария CodeSourcery  доступны по ссылке https://sourcery.mentor.com/sgpp/lite/arm/portal/subscription?@template=lite. Необходимо выбрать дистрибутив, помеченный как  EABI. Помимо, собственно, компилятора и компоновщика, набор CodeSourcery содержит отладчик, профилировщик и вспомогательные утилиты, такие как nm, strip, ld и тому подобное. Этот инструментарий вовсе необязательно использовать вместе со Scratchbox. Если вы установили и настроили Scratchbox, то можно приступать к сборке первой программы для ARM. Пусть это будет стандартная программа helloworld.c (можно, я обойдусь без листинга?).

Зайдите в песочницу Scratchbox с помощью команды scratchbox. Если вы все настроили правильно, вместо обычной строки приглашения вы увидите нечто вроде

[sbox-FREMANTLE_ARMEL: ~] >

Скомандуйте

gcc

В ответ должно быть напечатано нечто наподобие

sbox-arm-none-linux-gnueabi-gcc: no input files

Это означает, что все в порядке, и Scratchbox работает с версией GCC для ARM, а не для хозяйской системы. Теперь можно скомандовать

gcc helloworld.c

Если вы правильно установили и настроили QEMU и указали в настройках Scratchbox QEMU как средство CPU Transparency, то получившийся исполнимый файл можно запускать непосредственно из командной строки. Если запустить из команжной строки не получается, попробуйте запустить файл так:

qemu-arm-sb <имя_файла>

В результате в окне терминала вы увидите на экране строку «Hello World» (или что вы там написали). Даже не верится, что программа собрана для другого процессора. Для того чтобы убедиться, что эмуляция ARM действительно работает, воспользуемся утилитой file. Выдача утилиты должна выглядеть примерно так:

a.out: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.14, dynamically linked (uses shared libs), not stripped

Теперь можно вздохнуть с облегчением. Скомпилировав программу helloworld.c с ключом –S, мы получим код программы на ассемблере для ARM.

Вам, конечно, хочется проверить работу программы на настоящем железе. Если у вас есть устройство под управлением Android, сделать это будет нетрудно. Прежде всего, программу Hello World придется собрать статически, то есть с библиотекой времени выполнения:

gcc helloworld.c -static-libgcc

Теперь скопируем полученный  файл (например, a.out) на устройство Android и в программе «Эмулятор терминала» выполним следующие команды:

chmod +x a.out
./a.out

Наша программа на устройстве Android

Наша программа на устройстве Android


Можно поступить и иначе: вообще отказаться от библиотеки glibc при сборке программы. При этом, правда, придется заменить вызовы функций типа printf() на системные вызовы и заменить функцию main() на функцию _start():
void _start()
{
char * s = "Hello\n";
__asm__ ("mov r0, #0; mov r1, %[sptr]; mov r2, #7; swi 0x900004" // _write(0, s, 7)
:
: [sptr] "r" (s)
: "r0", "r1", "r2");
__asm__ ("mov r0, #0; swi 0x900001"); // _exit(0)
}

Программу нужно собирать с ключом -nostdlib. В результате получится исполнимый файл маленького размера (около 500 байтов), который будет выполняться на всех совместимых системах так же, как и статически скомпонованный файл. Обратите внимание, что системные вызовы на платформе ARM выполняются с помощью инструкции swi (Software Interrupt). Более подробно о системных вызовах ARM Linux будет сказано в следующей части.

Отладка в Scratchbox

Работая в Scratchbox с программами, предназначенными для ARM, нетрудно забыть о том, что на самом деле у нас процессор x86. Однако, когда мы приступаем к отладке приложения, ограничения эмуляции напоминают нам об этом: мы не можем отлаживать программу, предназначенную для ARM, из командной строки. Нам придется сначала запустить сервер Qemu в режиме отладки (напомню, что Qemu обладает встроенным отладчиком), а затем подключиться к этому серверу с помощью программы gdb, как к удаленной машине. Допустим, у нас есть программа hello, скомпилированная для платформы ARM с флагом –g (то есть, с отладочной информацией). В этом случае сервер запускается из командной строки Scratchbox с помощью команды

qemu-arm-sb -g 1212 a.out

Здесь 1212 – номер порта, по которому клиент отладки соединяется с сервером, а a.out – имя исполнимого файла отлаживаемой программы. Теперь в окне терминала Scratchbox мы запускаем программу gdb (или gdbtui). В командной строке отладчика вводим команды

(gdb) file hello
(gdb) target remote :1212

Поскольку сервер отладки выполняется на той же машине, что и клиент, мы указываем только порт, но не адрес. В результате программа загружена и готова к дальнейшей отладке, которая аналогична процессу отладки локального файла.

Отладка программы для ARM на обычном ПК

Отладка программы для ARM на обычном ПК

Особенности кросс-платформенной сборки

На какую бы платформу не был рассчитан Scratchbox во время сборки, это точно не та платформа, которую использует ваше устройство Android. Почему же программа смогла запуститься и какие тут есть ограничения? Для того чтобы ответить на этот вопрос, нудно понять, что делает программу и некоторую систему совместимыми. Для того чтобы программа работала в системе, она должна быть совместима с системой на нескольких уровнях. Первый уровень – это машинные команды. На этом уровне совместимость нами обеспечена. Если вы ничего не меняли в настройках Scratchbox, созданная программа использует набор инструкций ARM7, а его поддерживают все современные устройства на ARM. Второй уровень – это формат файла программы (он должен быть понятен операционной системе, чтобы она могла загрузить программу), форматы передачи параметров при выполнении системных вызовов и тому подобное. Поскольку  мы создали программу для Linux и выполняем ее тоже под Linux, хотя и другой версии и сборки, этот уровень совместимости нам тоже обеспечен. Наша программа использует тот же стандарт исполнимого файла ELF, что и операционная система. ELF – не единственный стандарт, с которым нам придется иметь дело. В мире встраиваемых систем существует еще один стандарт – EABI. Стандарт EABI (эта аббревиатура часто упоминается в названиях программ, предназначенных для сборки под ARM) определяет единые правила для библиотек и исполнимых файлов на встраиваемых системах независимо от ос и средства сборки. Это означает, что библиотека и программа, собранные согласно стандарту EABI, смогут взаимодействовать друг с другом, даже если они были собраны в разных системах и с использованием разных инструментов. Между прочим, стандарт EABI сам по себе не касается машинного кода и реализован не только для ARM, но и для других процессоров встраиваемых систем.

Третий уровень совместимости – совместимость программы с используемыми в системе библиотеками. Программа должна использовать библиотеки тех версий, которые доступны в системе, и знать, где их искать. Собирая программу с помощью, например, MAEMO SDK, нельзя обеспечить ее совместимость с Android на этом уровне. Хотя в основе Android лежит Linux, это другая версия Linux. Вот почему для запуска программы под Android, она была скомпилирована статически со средой времени выполнения. Разумеется, такая программа не может сделать многого, но увидеть, как программа ARM выполняется на настоящем железе все равно должно быть приятно.

Продолжение следует.

 


Viewing all articles
Browse latest Browse all 10

Trending Articles