Архитектура ARM давно вышла за пределы встраиваемых систем и смартфонов. Сегодня она питает серверы Ampere, ноутбуки Apple Silicon, одноплатные компьютеры Raspberry Pi и промышленные контроллеры. Переход с x86 на ARM меняет привычные правила игры: другой набор инструкций, иная модель загрузки, особенности работы с плавающей точкой и необходимость кросс-компиляции. Понимание этих различий позволяет не просто запустить систему, а построить предсказуемое окружение для разработки и эксплуатации.
Отличия архитектуры ARM от привычного x86
Главное различие - набор инструкций RISC против CISC. ARM использует фиксированную длину инструкций (32 бита в ARMv7, 32 бита в AArch64), что упрощает конвейер процессора, но требует больше инструкций для сложных операций. В x86 инструкции переменной длины, сложные адресации и микрокодная трансляция - это гибкость ценой большей площади кристалла и тепловыделения.
Регистровый файл ARMv7 содержит 16 регистров общего назначения (r0-r15), где r13 - указатель стека, r14 - регистр связи, r15 - счётчик команд. В AArch64 (ARMv8-A) их 31 (x0-x30) плюс нулевой регистр xzr. Вызов функций происходит через регистры: первые аргументы в x0-x7 (AArch64) или r0-r3 (ARMv7), остальные - в стек. Это быстрее, чем передача всего через стек как в 32-битном x86, но требует соблюдения ABI при смешивании ассемблерных вставок и C-кода.
Порядок байтов - little-endian по умолчанию, хотя архитектура поддерживает и big-endian. В Debian arm64 и armhf используют little-endian, что совпадает с x86_64 и упрощает перенос кода. Однако структуры данных с явным указанием порядка байтов (сетевые пакеты, файловые форматы) требуют внимания - htonl/ntohl остаются актуальны.
Загрузка системы кардинально отличается. Нет единого BIOS/UEFI для всех платформ. Каждая SoC загружается по-своему: Raspberry Pi - через GPU firmware (start.elf, bootcode.bin), Allwinner - через SPL и U-Boot на SD-карте, Rockchip - через idbloader и U-Boot, серверные платформы Ampere - через UEFI на SPI-флеш. Ядро должно знать аппаратную платформу через Device Tree (DTB), который передаёт загрузчик. На x86 ядро само обнаруживает железо через ACPI и PCI; на ARM без корректного DTB система не загрузится или не увидит периферию.
Архитектуры armhf и arm64 и критерии выбора
Debian поддерживает две основные 32-битные ABI: armel (soft-float, EABI) и armhf (hard-float, VFPv3-D16). Разница в соглашении вызова функций с плавающей точкой. armel передаёт float/double в целочисленных регистрах или через стек - совместимо с процессорами без FPU, но медленно. armhf использует регистры VFP (s0-s15 для float, d0-d7 для double) - ускорение в 5-10 раз на задачах с математикой. Минимальный процессор для armhf - ARMv7-A с VFPv3-D16 (Cortex-A7, A8, A9, A15). Raspberry Pi 2/3/4, все современные смартфоны и SBC на Allwinner, Rockchip, Amlogic подходят.
arm64 (aarch64) - 64-битная архитектура ARMv8-A. Регистры 64-битные, адресное пространство 48 бит (256 ТБ), NEON и VFPv4 обязательны. GNU triplet - aarch64-linux-gnu, в Debian архитектура называется arm64. Это выбор для нового железа: Raspberry Pi 3/4/5, Rockchip RK3588, Ampere Altra, Apple M-серии. Преимущества - доступ к памяти больше 4 ГБ, лучшая производительность 64-битной арифметики, современные инструкции CRC32, AES, SHA.
Выбор между armhf и arm64 зависит от железа и задач. На 32-битных платах (Pi 2, старые Allwinner A20) - только armhf. На 64-битных - arm64 даёт прирост 15-30% в компиляции, шифровании, работе с базами данных. Но если нужны проприетарные 32-битные бинарники (некоторые драйверы GPU, старые коммерческие приложения), armhf остаётся актуален. Multiarch в Debian позволяет ставить armhf-пакеты на arm64-систему: dpkg --add-architecture armhf && apt update && apt install libc6:armhf.
Обзор дистрибутивов Debian, Fedora и Arch Linux ARM
Debian - эталонная база для ARM. Порт arm64 стал официальным релизным архитектурой с Debian 8 Jessie (2015). В Debian 12 Bookworm собрано более 98% пакетов основного архива (около 12200 исходных пакетов под архитектуру). armhf поддерживается с Debian 7 Wheezy, armel - с 5.0 Lenny. Установщик debian-installer работает на широком спектре платформ: Raspberry Pi (через официальные образы), 96boards (HiKey, DragonBoard), Odroid, Pine64, серверы Ampere. Для экзотических платформ нужен ручной debootstrap и настройка U-Boot.
Fedora официально поддерживает aarch64 (arm64) как primary architecture. Поддержка 32-битного armhfp (armhf) прекращена начиная с Fedora 37 (ноябрь 2022). Образы Fedora Server, Workstation, IoT, CoreOS есть для Raspberry Pi 3/4/5, Pine64, Rock64, Odroid N2, а также generic UEFI-образа для серверного железа. Особенность Fedora - актуальные версии пакетов (GCC 14, glibc 2.39, kernel 6.x) и быстрая интеграция патчей upstream. Для сборки пакетов под aarch64 в Fedora используют koji с билдерами aarch64. Кросс-компиляция под arm64: dnf install cross-gcc-arm64.
Arch Linux ARM - сообщественный порт, неофициальный, но с максимальным покрытием платформ. Поддерживает armv7h (hard-float ARMv7) и aarch64. Уникальная особенность - отдельные репозитории для каждой SoC: allwinner, amlogic, broadcom (Pi), freescale, marvell, rockchip, samsung, ti, xilinx. Установка - через архив rootfs (tar.gz) и запись загрузчика на SD-карту. Нет инсталлятора, но есть скрипты pacstrap для chroot. Rolling-release модель даёт новейшие ядра и пакеты, но требует внимания при обновлении загрузчика (U-Boot, extlinux) - сбой делает систему не загружаемой.
Для встраиваемых систем и контейнеров актуальны Alpine Linux (musl libc, минимальный размер, образы под armhf/aarch64), Ubuntu Core (snap-based, transactional updates), OpenWrt (маршрутизаторы, IoT), Buildroot/Yocto (сборка кастомных дистрибутивов).
Проблема отсутствия нужного пакета в репозитории
Главная боль на ARM - проприетарное ПО и пакеты, собранные только под x86_64. Примеры: драйверы NVIDIA (нет нативных ARM-бинарников, только через виртуализацию), Zoom, Microsoft Teams, Steam клиент, многие коммерческие IDE. Решения разнятся по сложности.
Flatpak и AppImage частично решают проблему: многие приложения распространяются в этих форматах с архитектурой aarch64. Flathub собирает ARM-сборки для LibreOffice, GIMP, Firefox, VS Code (code-oss), OBS Studio. Но не все мейнтейнеры включают ARM в CI.
Компиляция из исходников - стандартный путь в Arch и Gentoo. В Debian/Fedora можно пересобрать пакет: apt source пакет && cd пакет-* && dpkg-buildpackage -b -aarm64 (нативно) или через кросс-инструментарий. Если пакет не собирается - часто виноваты устаревшие config.guess/config.sub (не знают aarch64), жёстко заданные флаги компилятора для x86, inline-ассемблер без ARM-варианта. Лечится патчами или обновлением autotools/cmake.
QEMU user-mode эмуляция (qemu-aarch64-static) позволяет запускать ARM-бинарники на x86_64 хосте. В Docker: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes. Это даёт возможность собирать ARM-образы на мощном x86-сервере. Но производительность падает в 3-10 раз, многопоточные приложения (Java, Go, Rust) часто падают из-за неполной эмуляции futex/pthreads.
Кросс-компиляция, инструменты и практика
Кросс-компиляция - сборка кода под целевую архитектуру на хосте другой архитектуры. Для ARM из x86_64 нужен кросс-тулчейн: binutils, gcc, glibc, заголовки ядра для целевого тройника (target triplet).
В Debian/Ubuntu установка для arm64:
dpkg --add-architecture arm64
apt update
apt install crossbuild-essential-arm64
Это тянет gcc-aarch64-linux-gnu, g++-aarch64-linux-gnu, libc6-dev-arm64-cross, linux-libc-dev-arm64-cross, dpkg-cross. Компилятор вызывается как aarch64-linux-gnu-gcc. Проверка: aarch64-linux-gnu-gcc -v покажет Target: aarch64-linux-gnu.
Для armhf:
dpkg --add-architecture armhf
apt update
apt install crossbuild-essential-armhf
Компилятор - arm-linux-gnueabihf-gcc.
Сборка простого проекта с CMake:
mkdir build-arm64 && cd build-arm64
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/dpkg/cross-compile/aarch64-linux-gnu.cmake ..
make -j$(nproc)
Файл тулчейна задаёт CMAKE_C_COMPILER=aarch64-linux-gnu-gcc, CMAKE_SYSTEM_NAME=Linux, CMAKE_SYSTEM_PROCESSOR=aarch64, пути к sysroot. Для Meson:
cat > cross-arm64.meson << 'EOF'
[binaries]
c = 'aarch64-linux-gnu-gcc'
cpp = 'aarch64-linux-gnu-g++'
ar = 'aarch64-linux-gnu-ar'
strip = 'aarch64-linux-gnu-strip'
pkgconfig = 'aarch64-linux-gnu-pkg-config'
[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'aarch64'
endian = 'little'
EOF
meson setup build-arm64 --cross-file cross-arm64.meson
ninja -C build-arm64
Проблемы кросс-сборки: configure-скрипты не могут запускать тестовые бинарники (они под ARM). Решение - кэш configure (config.cache) с заранее известными ответами, или DEB_BUILD_OPTIONS=nocheck чтобы пропустить тесты. pkg-config ищет .pc файлы в хостовом префиксе - нужно экспортировать PKG_CONFIG_LIBDIR=/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/share/pkgconfig и использовать aarch64-linux-gnu-pkg-config.
Rust: rustup target add aarch64-unknown-linux-gnu и cargo build --target aarch64-unknown-linux-gnu. Нужен линкер aarch64-linux-gnu-ld и libc6-dev-arm64-cross. Go: GOOS=linux GOARCH=arm64 go build (кросс-компиляция нативно, без внешнего тулчейна, но CGO требует кросс-gcc).
Сборка ядра под ARM:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image dtbs modules
Для 32-битного ARM: ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- и выбор конфига (например, bcm2711_defconfig для Pi 4).
Опыт работы на компактных энергоэффективных устройствах
Raspberry Pi 4 Model B (4 ГБ) потребляет 3.4 Вт в простое и до 7.6 Вт под нагрузкой (Linpack, 4 ядра Cortex-A72 @ 1.5 ГГц). Pi 5 - 4.1 Вт в простое, 12 Вт пик (Cortex-A76 @ 2.4 ГГц). Питание через USB-C 5В/3А (Pi 4) или 5В/5А (Pi 5). Нет вентилятора - троттлинг при 80°C. Пассивный радиатор снижает пик на 3-4°C.
Rockchip RK3588 (8 ядер: 4×Cortex-A76 + 4×Cortex-A55, Mali-G610) в Orange Pi 5 / Radxa Rock 5B: 5-6 Вт в простое, 14-18 Вт под нагрузкой. Производительность многопоточная - уровень Ryzen 3 3200U / Core i5-7200U. Поддержка VPU (кодирование/декодирование 8K H.265/VP9/AV1) в mainline kernel 6.6+ через hantro/vpu драйверы.
Ampere Altra (80 ядер Neoverse N1 @ 3.0 ГГц) в сервере: 150-200 Вт под полной нагрузкой, 40-50 Вт в простое. SPEC CPU 2017 rate - около 400 (int) и 380 (fp), сравнимо с EPYC 7763 (64 ядра) при двойном TDP. Это уже не SBC, а полноценные серверы для облачных нагрузок, контейнеров, CI/CD.
На практике: Pi 4 4ГБ тянет Home Assistant + Zigbee2MQTT + Mosquitto + PostgreSQL + Grafana + 5-10 контейнеров Docker. Память - узкое место, zram (systemd-zram-generator) спасает. Pi 5 8ГБ позволяет запускать полноценный CI-раннер (GitHub Actions self-hosted, GitLab Runner) и собирать небольшие проекты нативно за приемлемое время.
Охлаждение - критично для стабильности. Пассивный корпус-алюминий (Flirc, Argon One) даёт -10°C. Активный вентилятор 30×30×10 мм (PWM, 5В) удерживает 55-60°C под нагрузкой. Без охлаждения Pi 5 троттлит через 2-3 минуты компиляции ядра.
Хранилище: microSD - слабое звено. Скорость 50-90 МБ/с (UHS-I), ресурс записи ограничен. Для 24/7 систем - USB-SSD (Pi 4/5 загружаются с USB) или NVMe через PCIe HAT (Pi 5, RK3588). f2fs или ext4 с noatime,commit=60 продлевает жизнь флешке. Zram swap на RAM быстрее и безопаснее SD-карты.
Сетевые нагрузки: Pi 4/5 имеют настоящий гигабит (не через USB). iperf3 - 940 Мбит/с в обе стороны. RK3588 - 2.5GbE (Realtek RTL8125), Ampere - 10/25/100GbE. Это позволяет использовать ARM-устройства как роутеры, файловые серверы (Samba, NFS), сетевые шлюзы с защищёнными туннелями (до 1 Гбит/с на Pi 4 одной нити).
Особенности отладки и профилирования на ARM
perf работает нативно: perf record -g ./program && perf report. Для кросс-профилирования - perf record на целевом устройстве, perf report на хосте с переносом perf.data и символов (/usr/lib/debug/.build-id/).
GDB: нативная отладка gdb ./program на ARM-устройстве. Кросс-отладка: aarch64-linux-gnu-gdb ./program на хосте + gdbserver :1234 ./program на цели, затем target remote IP:1234. Для отладки ядра - KGDB через последовательный порт или QEMU с -s -S.
Valgrind на ARM64 поддерживается полностью (memcheck, helgrind, callgrind). На armhf - с ограничениями (нет поддержки NEON в старых версиях). Запуск под valgrind замедляет в 20-50 раз.
Трассировка: bpftrace, bcc-tools работают на ARM с kernel 5.10+. trace-cmd и kernelshark для анализа загрузки и латентностей.
Linux на ARM перестал быть экзотикой. Debian, Fedora, Arch Linux ARM дают зрелые пользовательские пространства с почти полным покрытием пакетов. Кросс-компиляция стала рутиной благодаря multiarch и crossbuild-essential. Компактные платы RK3588 и Pi 5 закрывают нишу десктопов и билд-серверов, серверные Ampere - нишу облака. Главные вызовы остаются теми же: проприетарные бинарники только под x86, разнообразие загрузчиков и Device Tree, необходимость охлаждения при нагрузке. Но для открытого ПО, контейнеров, сетевых сервисов, встраиваемых систем и CI/CD - ARM сегодня часто выгоднее x86 по соотношению производительность/ватт/рубль.