Program arm on linux

Jensd’s I/O buffer

random technotes…

Cross compiling for arm or aarch64 on Debian or Ubuntu

ARM is gaining more and more traction and is growing a lot in popularity. It’s not always possible to build directly on these ARM-based devices, especially when they are limited in resources. The majority of build and developer machines are still on x86 and by using cross compiling, it is possible to build binaries or executables usable on another architecture. For example, to use your standard PC, most likely x86, to build something that is usable on another machine or device that’s on another architecture, like ARM. In this post, I’ll explain how to do cross compiling for 32bit ARM (arm) or 64bit ARM (aarch64) using Debian 10 or Ubuntu 20.04 LTS.

Youtube video

If you are interested, I also created a YouTube video from this blogpost. If you prefer classic text, you can just follow the rest of this article:

Introduction

The ability to cross compile, for me, is most used to build troubleshooting tools that are not installed or available on Linux-based devices. For example a device like a Raspberry Pi, NAS, router or an access point that has a custom Linux build without or limited option to install additional packages.

Sample output of a random embedded device running Linux…:

For the steps below, I will be using Debian 10 (Buster) and I will also test the same steps on Ubuntu 20.04.1 (LTS). All steps are verified to be interchangeable between both. The starting point for both is a minimal installation (standard system utilities + SSH server). This makes sure that, if anyone wants to repeat these steps, all is reproducible and nothing is skipped or missed that would be preinstalled already.

Terminology

In cross compiling, the following (confusing) terminology is used:

  • Build platform: Architecture of the build machine
  • Host platform: The architecture you are building for
  • Target platform: The architecture that will handle the compiled binaries

Build and host are more or less clear but target can be confusing. Simply put, target is only relevant when working on development tools (like the compiler itself).

When you are building for the same architecture as which you are using, build, host and target are the same. This is called a “native” compilation. If build and target platform are the same, but host is different, then we’re talking about cross compilation, which this post is covering. When all three platforms are different, it’s called a “canadian”. This is used to build a cross compiler for another architecture.

Just to be clear, in this post, the build and target platform are x86_64 (standard PC) and the host is the ARM platform. I will cover both 32bit ARM (armv6, armv7 or simply arm) and 64bit ARM (aarch64).

ARM architectures

To find out for which of these (32 bit or 64 bit ARM) you need to compile, the easiest is to look at the output of uname -m.

For x86_64 (standard PC):

64 bit ARM (or aarch64):

Prerequisites

Before we can start compiling, we need to install the necessary packages and tools for cross compiling for ARM. These include the standard tools needed for compiling native:

For 32 bit ARM (arm):

For 64 bit ARM (aarch64):

Of course you can install both the necessary compilers for 32 and 64-bit if you plan to compile for both these architectures.

Compiling a simple C program from source

Once we have installed the prerequisites, we can try and compile a simple C program. Let’s first do a so-called native compile for the PC we’re compiling from, just to make sure that our program does what we want.

Save the source as helloworld.c:

Compile the source “native” and write the binary as helloworld-x86_64

To see what type and for which platform the result of our compilation is, we can check the output with the “file”-tool:

We can execute the binary to check the result:

The next step is to compile the same source for ARM. We simply do this by using a different compiler (arm-linux-gnueabi-gcc instead of gcc for 32 bit ARM or gcc-aarch64-linux-gnu for 64 bit ARM or aarch64).

For 32 bit ARM (arm):

For 64 bit ARM (aarch64):

As you can see, file gives us a different result, which we would expect.
Trying to execute these binaries on the build machine (x86_64), as expected, will result in an error:

To test if this has worked, we need a machine or device running the architecture for which we built:

As you see in the above output, our small program works fine on ARM after cross compiling it!

Cross compiling with configure and make

The above example was pretty simple but when compiling source from larger projects, it’s usually done by generating a makefile with configure and then running the compile and other necessary steps with make. To replace gcc with another, target platform specific compiler would be a lot of work. Fortunately most of the times you can just specify the platform which you are compiling for when running configure.

Читайте также:  Linux для ноутбука acer extensa

As an example, I’ll create a binary for ARM aarch64 of strace. To avoid getting into problems with dependencies on my embedded ARM device, I’ll provide the static option (see below for more explanation).

First step is to get the source of strace from: https://github.com/strace/strace/releases/tag/v5.10 and extract it:

The next step is to run configure. But here we need to specify the build and host platform so that we want to end up with a binary (statically linked) for ARM:

At this point we’re ready to do the actual cross compile by running make:

As you see, I built this one for use on aarch64. If you want to do the same for armv6 or armv7, simply replace –host aarch64-linux-gnu with –host arm-linux-gnueabi when running configure.

Some additional explanation with the flags and arguments I passed to ./configure in order to get this working:

  • checking for library containing timer_create… no
    configure: error: failed to find timer_create
    was fixed by adding LDFLAGS=”-pthread”
  • checking for m32 personality compile support… no
    checking whether to enable m32 personality support… no
    configure: error: Cannot enable m32 personality support
    was fixed by adding –enable-mpers=check

As with the small C-program, it’s time to test the compiled binary on ARM:

This gives us the ability to simply copy and use strace on a random aarch64 machine.

About static linking and dependencies

As I mentioned in the beginning, I mainly use cross compilation to build troubleshooting tools. Often, the platform where you are building for, is limited. This could be due to lack of resources, like an embedded device. But also because pre-built packages are either not available or it’s not possible to install them. In a lot of cases, this also means that installing dependencies for whatever you are building might be a problem. Obviously, these dependencies also have to be built for that same architecture.

If you have this kind of limitation or you simply want your binary to just run on that architecture. Without worrying on dependencies, or conflicting (older) version of those dependencies that might be already installed, you can use static linking. This means that at build time all necessary dependencies will be included in the binary itself.

Static linking has a few drawback as it is potentially unsecure (the included dependencies will not be updated with the system), could cause incompatibility when libraries that do lower level system calls and the resulting binary file will be larger. These are things I can live with when building troubleshooting tools as they are not intended for long-time use.

While static linking might be what you are looking for, it’s not always be easy to accomplish. Especially in combination with cross compilation it can give you a headache. Most tools depend on libc or glibc, which discourages static linking for the good reasons I mentioned in the paragraph above. Fortunately there is a libc implementation that was developed from scratch and that allows proper static linking for libc-dependencies: musl (pronounce as musscle).

Cross compiling with configure and make using the musl libc implementation

To make use of musl, we need to download the correct version for our cross compilation. You can find a full list over here: https://musl.cc/#binaries.

After the download, we can extract the archive and test if this works on our build machine:

Next, I will build a static linked version of TCPdump for aarch64. Always a nice tool to have handy when you need to log, investigate or troubleshoot network connectivity. Unfortunately tcpdump is not always available or in the best case as a limited Busybox-version.

First, we need to install some required tools, these are used by the tcpdump for the build process:

Next, we need to download the source for both tcpdump and libpcap and extract it. You can find the latetst version over here: https://www.tcpdump.org/index.html#latest-releases

After downloading and extracting the source code, we need to run the configure-script for libpcap first. Only this time, we need to set our compiler to the musl-compiler for our cross compilation by setting CC to: aarch64-linux-musl-gcc:

If all went fine, we can do the actual compilation of libpcap by issuing make:

Now, we can repeat the same (./configure and make) for tcpdump itself. By doing the static linking, libpcap will be included and the result is a single binary tcpdump:

As you can see by the last command, we have our statically linked tcpdump binary. If all goes well, we should be able to execute this, without any further dependencies, on an aarch64-based machine.

As you can see, tcpdump works fine and does not need any dependencies. This is really helpful if you need to work or troubleshoot on platforms that come with a very limited set of tools and no ability to easily install them. You can simply copy the file and it will work.

6 thoughts on “ Cross compiling for arm or aarch64 on Debian or Ubuntu ”

Very helpful. You’ve provided a clear explanations of how to do it, and why each of the steps is needed. It’s a good tutorial that can be used to extend the concepts to more complicated cross compiling.

Thanks you! Nice to get some positive feedback 🙂
Also working on a small YouTube video covering the same.

Awesome content, thanks! 🙂

I have a question, slightly related, but more about shared libraries: suppose I’m able to cross compile a shared library with a bunch of dependencies (100+), and I’d need to deploy it to aarch64, and it needs to be a shared library (because of how many dependencies there are; otherwise the binary would be huge). Since I’ve never done this, my question is pretty basic: what are my next steps? I can probably makes sure that all those dependencies are of the correct version but they’ll (in general) have a different path.

Читайте также:  Учебники по windows forms

Is there a tutorial and/or tool that you could recommend for automatically linking my library on the aarch64 device?

And thanks for your time!

The aarch64 machine will need those dependencies. Either you could install them through the package manager (if there is any over there) or cross compile these separately. The versions do not need to be an exact match but too far away will probably give you troubles.

About the path they are in, you do not need to worry. At the time of execution, those dependencies/libraries are being searched in LD_LIBRARY_PATH. You check in advance which libs are missing with the ldd command as well.

Источник

Программирование и отладка микроконтроллеров ARM Cortex-M4 фирмы Atmel в среде операционной системы Linux. Часть 1

Представляем электронную версию статьи из номера №2 за 2016 год журнала Компоненты и технологии. Автор Курниц Андрей.

В статье описан процесс развертывания экосистемы разработки приложений для микроконтроллеров Atmel серии SAM4S в среде операционной системы Linux. Читатель познакомится также с оценочной платой SAM4S-EK и семейством ARM Cortex-M4 микроконтроллеров фирмы Atmel. Приведены рекомендации по работе с адаптером отладки SAM-ICE (он же J-LINK) и программой OpenOCD.

Введение

Выбор операционной системы Linux в качестве среды для программирования микроконтроллеров ARM Cortex-M4 фирмы Atmel сложно назвать общепринятой практикой. Напротив, для разработки под свои микроконтроллеры Atmel свободно распространяет среду Atmel Studio 7, предназначенную исключительно для операционных систем Windows. Не будет секретом и тот факт, что разворачивание и настройка среды Atmel Studio 7 для новичка окажется куда проще, чем выбранный автором путь.
Автор предлагает использовать среду разработки Qt Creator в связке с инструментарием для кросс-компиляции GCC и с пакетом OpenOCD для отладки. В качестве операционной системы автор выбрал Linux Lubuntu 14.04 LTS (выполняющуюся на виртуальной машине, но это не существенно). Такой подход позволяет с легкостью переходить на другие ARM (и не только) микроконтроллеры, не меняя при этом привычный комплект инструментов. Например, в [1] приводится пример разработки для микроконтроллеров STM32F4 фирмы ST microelectronics с применением такого же комплекта инструментов.
Несколько слов об используемой терминологии. Аппаратное устройство, которое подключается к целевому микроконтроллеру и к рабочей станции, далее называется отладочным адаптером. Отладчиком же будет называться компьютерная программа, служащая для пошагового выполнения программы, просмотра значений ячеек памяти и т.д.

Аппаратная платформа


Рис. 1. Внешний вид платы SAM4S-EK с подключенным отладочным адаптером.

В основе оценочной платы лежит микроконтроллер SAM4S16C фирмы Atmel, ключевые особенности которого приведены ниже:

  1. Ядро ARM Cortex-M4, максимальная тактовая частота 120МГц
  2. Объемы памяти на кристалле: 1 Мбайт flash-памяти и 128 кбайт ОЗУ
  3. Среди периферийных устройств можно выделить: USB контроллер (работа только в режиме Device), контроллер внешней NAND flash-памяти, контроллер SD карт памяти
  4. Контроллеры интерфейсов UART, I2C, SPI и др.
  5. 100-выводный корпус

Среди особенностей оценочной платы SAM4S-EK можно выделить следующие:

  1. Микросхема NAND flash-памяти Micron MT29F2G08ABAEA объемом 2 Гбит
  2. Цветной дисплейный модуль FTM280C34D разрешением 320×240 точек, с диагональю 2,8 дюйма и с резистивной сенсорной панелью. Дисплей содержит встроенный контроллер Ilitek ILI9320, подключенный к микроконтроллеру по параллельному интерфейсу.
  3. Контроллер резистивной сенсорной панели Texas Instruments ADS7843E
  4. Распаяны два DB9 разъема для двух портов RS-232 (один из них — с сигналами RTS, CTS), выведен также интерфейс RS-485
  5. Элементы сенсорного управления по технологии Atmel QTouch, расположены прямо на печатной плате (сенсорные кнопки 5 шт. и слайдер)
  6. Электретный микрофон и операционный усилитель TS922 для него
  7. Усилитель звуковой частоты для подключения наушников TPA022, а также 3,5мм гнездо типа «джек».
  8. Два коаксиальных BNC разъема, которые подключены к встроенным АЦП и ЦАП блокам микроконтроллера.
  9. Держатель micro-SD карты памяти
  10. 63 вывода общего назначения (GPIO) выведены на IDC разъемы с шагом 2,54 мм

Более подробно как о плате SAM4S-EK, так и о микроконтроллере SAM4S16C можно ознакомиться на сайте Atmel [12].

Комплект инструментов

Когда аппаратная (плата SAM4S-EK) и программная (операционная система Linux Lubuntu) платформы определены, можно построить систему аппаратных и программных инструментов для программирования и отладки целевого микроконтроллера (рис. 2)

Рис. 2. Структурная схема процесса отладки микроконтроллера

Микроконтроллер по интерфейсу JTAG подключен к отладочному адаптеру SAM-ICE, который в свою очередь подключен к рабочей станции по интерфейсу USB. Питание отладочного адаптера подается также по интерфейсу USB, а питание платы разработчика вместе с микроконтроллером должно осуществляться отдельно (на рис. 2 не показано).
На рабочей станции должна выполняться некая программа, которая будет взаимодействовать с адаптером отладки SAM-ICE с одной стороны и отладчиком GDB, входящим в инструментарий GCC, с другой. На эту роль идеально подходит свободно распространяемая программа OpenOCD 5, которая помимо отладки может использоваться для загрузки прошивки во flash-память микроконтроллера и для внутрисхемного тестирования.
Программа OpenOCD поддерживает как адаптер отладки SAM-ICE (в действительности это аналог популярного J-LINK), так и оценочную плату SAM4S-EK (соответственно и микроконтроллеры Atmel SAM4). Кроме этого OpenOCD доступна в виде исходных кодов и может быть собрана для операционной системы Linux.
Интегрированная среда разработки Qt Creator (рис. 2) получает отладочную информацию через отладчик GDB и предоставляет в удобном для разработчика виде (точки останова, значения переменных, пошаговое выполнение программы и др.)
Программа OpenOCD работает в режиме сервера и допускает подключение других клиентов-программ, например, telnet-клиента (рис. 2). Это может быть удобно для серийного программирования микроконтроллеров на производстве.

Установка OpenOCD

Установить OpenOCD можно наименее трудоемким способом — из репозиториев Ubuntu, для чего следует выполнить команду:

Однако в этом случае будет установлена устаревшая версия 0.7.0 (проверить версию установленной программы OpenOCD можно выполнив команду openocd —version).
Для получения актуальной версии (на момент написания статьи — 0.9.0), необходимо собрать OpenOCD из исходных кодов. Для этого надо выполнить следующие действия:
1. Загрузить исходные коды OpenOCD с сайта [2], выполнив команду:

В результате в домашнем каталоге должен появиться файл-архив openocd-0.9.0.tar.bz2.

2. Далее следует разархивировать OpenOCD, выполнив команду:

В результате, в домашнем каталоге должен появиться каталог с исходным кодом openocd-0.9.0

3. Проверить, установлена ли библиотека libusb-dev, которая необходима для взаимодействия рабочей станции и адаптера SAM-ICE по USB интерфейсу. Чтобы проверить наличие библиотеки libusb-dev, следует выполнить команду:

Читайте также:  Zip file linux download

Если библиотека установлена, то вывод должен быть примерно такой:

Если библиотека не установлена, то ее установить ее можно, выполнив команду:

4. Для сборки OpenOCD также потребуются следующие пакеты:

  • make,
  • libtool,
  • pkg-config версии 0.23 и выше,
  • autoconf версии 2.64 и выше,
  • automake версии 1.9 и выше,
  • texinfo

Проверить их наличие можно тем же способом, что и библиотеки libusb-dev, как описано выше.

5. Теперь можно собрать пакет OpenOCD с поддержкой адаптера SAM-ICE, для чего следует последовательно выполнить следующие команды:

Ключ —enable-jlink предписывает включить поддержку адаптера J-LINK. Дело в том, что адаптер SAM-ICE представляет собой модифицированный J-LINK BASE от фирмы Segger так, что он может работать только с микроконтроллерами фирмы Atmel. Однако программный интерфейс для работы с J-LINK полностью совместим с адаптером SAM-ICE.

Подключение адаптера SAM-ICE

Далее следует подключить адаптер SAM-ICE к рабочей станции и проверить список подключенных по USB устройств командой:
lsusb
Если адаптер SAM-ICE подключен, то вывод команды должен содержать следующую строку:

Где 1366 — VID-номер (код производителя USB-устройства), 0101 — PID-номер (код изделия). Эти номера потребуются в дальнейшем для настройки менеджера устройств udev.
Чтобы обеспечить взаимодействие сервера отладки OpenOCD с адаптером SAM-ICE по интерфейсу USB необходимо создать файл-правило для менеджера устройств udev, например, так:

В окне редактора Nano ввести следующий текст:

Где поля idVendor и idProduct соответствуют полученным ранее номерам VID и PID.
Далее следует перезагрузить рабочую станцию.
Если же сконфигурировать udev, как описано в [3], то запуск сервера отладки OpenOCD будет возможен только с правами суперпользователя, что в дальнейшем создаст проблемы с отладкой из среды QtCreator.

Совместная работа адаптера SAM-ICE и сервера отладки OpenOCD

/sam/) создать файл конфигурации openocd.cfg со следующим содержимым:

Файл openocd.cfg содержит предписания для сервера OpenOCD, а именно:

  • разрешить подключение к серверу по протоколу telnet через порт 4444,
  • установить порт 3333 для подключения отладчика GDB,
  • соединяться с адаптером J-LINK (SAM-ICE),
  • целевая платформа — оценочная плата Atmel SAM4S_EK,
  • разрешить программирование flash-памяти.

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

/sam/), запустить сервер OpenOCD командой

Если все сделано правильно, в терминал будет выведено:

При этом приглашение командной строки выведено не будет, что свидетельствует о том, что сервер успешно запущен и установлено соединение с целевым микроконтроллером через отладочный адаптер SAM-ICE.
Теперь можно подключиться к серверу отладки по протоколу telnet, для чего надо открыть второй терминал и выполнить команду:

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

Когда соединение с сервером установлено, можно выполнить любую из команд OpenOCD (полный список — в [7]), например, просмотреть содержимое регистров ядра микроконтроллера. Для этого следует остановить выполнение программы в микроконтроллере командой halt:

Затем просмотреть непосредственно содержимое регистров командой reg:

Завершить работу сервера OpenOCD можно командой shutdown, при этом автоматически закроется и telnet соединение:

Связку «адаптер SAM-ICE – программа OpenOCD» можно использовать для серийного производства для загрузки готовой прошивки во flash-память микроконтроллера. Например, чтобы очистить всю flash-память микроконтроллера Atmel SAM4S16C, необходимо выполнить команду:

Где 0x00400000 — адрес начала flash-памяти в адресном пространстве, 0x100000 — размер flash-памяти в шестнадцатеричной системе счисления, для микроконтроллера SAM4S16C составляет 1 Мбайт = 2^20 байт = 0x100000(16) байт. Адрес начала flash-памяти и ее размер получен из документации на данный микроконтроллер [12].
В случае успешного стирания вывод программы OpenOCD должен содержать строку:

Для непосредственно записи прошивки во flash-память надо выполнить команду:

Где sam.hex — имя файла с прошивкой в формате Intel HEX. OpenOCD принимает также другие форматы файлов с прошивкой, например binary и ELF.
В случае успешной загрузки прошивки во flash-память вывод должен содержать строки:

То есть в данном случае очищается лишь те сектора flash-памяти, в которые будет размещена прошивка.

Создание комплекта в Qt Creator

Теперь, когда связка «адаптер отладки — сервер отладки» настроена и готова к работе, можно приступать к настройке интегрированной среды разработки, в нашем случае — Qt Creator.
При этом предполагается, что на рабочую станцию уже установлен инструментарий GCC для сборки для микроконтроллеров ARM, а также установлена и настроена сама среда Qt Creator, процесс установки и настройки которых подробно описан в [1].
Прежде всего, необходимо добавить сервер отладки, для этого в Qt Creator следует вызвать настройки (пункт главного меню «Инструменты –> Параметры…»), выбрать вкладку «BareMetal» («Голое устройство»), нажать «Добавить» и выбрать пункт «OpenOCD». Появится окно, где можно указать параметры запуска сервера (рис. 3). Следует отметить, что поддержка OpenOCD добавляется в среду Qt Creator при включении модуля «BareMetal», как это сделать — описано в [1].

Рис. 3. Добавление сервера отладки OpenOCD в Qt Creator.

Имя сервера отладки можно задать «OpenOCD + SAM-ICE» (рис. 3), «Режим запуска» следует установить в «Запуск в режиме TCP/IP», так как сервер OpenOCD будет выполняться на рабочей станции, то поле «Хост» должно содержать имя компьютера «localhost» и порт 3333, указанный ранее в конфигурационном файле openocd.cfg.
В поле «Исполняемый файл» следует вписать имя исполняемого файла openocd (или полный путь к нему, если необходимо). Поле «Файл конфигурации» должно содержать путь к файлу конфигурации OpenOCD, созданному ранее, в данном случае это

sam/openocd.cfg. Поля «Команды инициализации» и «Команды сброса» по умолчанию содержат команды управления сервером, менять их содержимое не требуется.
Далее можно добавить новое устройство, для которого будет производиться сборка и отладка — микроконтроллер семейства Atmel SAM4S. Для этого в настройках Qt Creator следует выбрать вкладку «Устройства» и нажать «Добавить…».
После чего ввести имя устройства, например «Atmel SAM» и выбрать настроенный ранее сервер отладки «OpenOCD + SAM-ICE».
Когда устройство добавлено, можно окончательно настроить комплект для сборки так, как показано на рис. 4.

Рис. 4. Добавление комплекта для микроконтроллеров Atmel SAM4S в Qt Creator.

Компилятор GCC и отладчик GDB заданы из состава инструментария GCC для микроконтроллеров ARM так, как описано в [1].

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

Источник

Оцените статью