RiPetitor
16 просмотров0 комментариев+1

Как я начал переносить Repka Pi 4 на Armbian и во что это превратилось

Я давно использую одноплатные компьютеры Repka Pi. У меня есть Repka Pi 3 и Repka Pi 4, и обе платы используются не только для экспериментов.

Repka Pi 3 у меня уже работает как небольшой сервер, а Repka Pi 4 я начал рассматривать как более универсальную платформу: сервер, рабочий стол, тестовая машина и стенд для работы с Linux.

В какой-то момент я понял, что хочу не просто установить систему на карту памяти и пользоваться тем, что есть. Мне хотелось получить нормальную воспроизводимую платформу, которую можно собирать самому, обновлять, патчить и получать удовольствие.

Так появилась идея сделать полноценную поддержку Repka Pi 4 в Armbian.

Я учусь на программной инженерии, поэтому этот проект для меня оказался хорошей возможностью выйти за пределы обычной разработки приложений и посмотреть, как на практике устроены загрузчик, Device Tree, ядро Linux, графический стек, ALSA и сборка Linux-дистрибутива.


Почему вообще Armbian #

У Repka есть собственная RepkaOS, и для обычного пользователя это самый простой вариант.

Записал образ, загрузился и работаешь.

Но есть проблемы которые слабо решаются в данной RepkaOS

А именно:

  • Старое ядро
  • Не возможность установить с SD карты на eMMC меньшего размера
  • и другие мелочи

Мне хотелось:

  • использовать современную Debian-based систему
  • самостоятельно собирать Server и Desktop образы
  • контролировать версию ядра
  • обновлять U-Boot
  • иметь воспроизводимый набор патчей
  • отдельно собирать обычное и PREEMPT_RT ядро

Armbian для такой задачи подходит заметно лучше.

Самое важное здесь для меня то, что итоговая система теперь получается из исходников и набора понятных изменений.

Если я через полгода захочу понять, почему была добавлена конкретная настройка, я могу посмотреть Git history, а не вспоминать, какую команду когда-то вводил вручную на уже установленной системе.


U-Boot и память #

Одной из первых интересных проблем стала DRAM.

В разных сборках я увидел отличия в частоте памяти.

RepkaOS использовала более агрессивную конфигурацию, а стандартный U-Boot для H6 работал консервативнее.

В процессе экспериментов появлялась конфигурация:

CONFIG_DRAM_CLK=936

Но выяснилось, что это изменение существовало только внутри рабочего build tree и не было нормально зафиксировано в репозитории.

То есть получалась плохая ситуация:

Git repository != фактически собранный U-Boot

Для проекта, который должен быть воспроизводимым, так оставлять нельзя.

В итоге частоту я решил снизить до более консервативных:

CONFIG_DRAM_CLK=816

Это дает DDR3-1632.

Для нее был сделан отдельный U-Boot patch:

0002-set-repka-pi4-dram-clock-816.patch

Самая сложная проблема: Mali-T720 и Panfrost #

Графика оказалась самым большим приключением.

Repka Pi 4 использует:

Allwinner H6
Mali-T720
Mesa Panfrost

Сам GPU нормально определяется ядром:

Mali-T720 (Panfrost)
direct rendering: Yes
Accelerated: yes

HDMI также способен работать в:

3840x2160@60

Поэтому сначала казалось, что основная часть работы уже закончена.

Но в LXQt начали появляться графические артефакты.

В журнале ядра при этом возникали ошибки:

js=0
INSTR_INVALID_PC

Началось довольно долгое расследование.


Сначала подозревался LightDM #

Проблема была хорошо заметна уже на экране входа.

Поэтому естественной первой гипотезой был LightDM или GTK greeter.

Но затем выяснилось интересное.

Ошибки появлялись практически раз в минуту.

Причиной периодичности оказались часы LightDM:

изменилась минута -> перерисовался текст -> GPU fault

При вводе логина ошибки тоже начинали быстро увеличиваться.

Но сам LightDM оказался только удобным способом воспроизвести проблему.

xft-rgba=none

Очень важный результат появился после отключения RGB subpixel rendering.

При:

xft-rgba=rgb

ошибки стабильно воспроизводились.

При:

xft-rgba=none

они полностью исчезали в обычном desktop workload.

Мы проверили это довольно подробно.

Например:

Тест Minute faults Typing faults Всего
обычный RGB 20 105 125
xft-rgba=none 0 0 0
RGB без часов 0 63 63
GPU фиксирован на 432 МГц 14 105 119

Это позволило исключить несколько первоначальных гипотез.

Проблема практически точно не связана с:

  • Высокой частотой GPU

  • Переключениями devfreq

  • HDMI 4K60

  • LightDM

  • Часами

  • Самим LXQt


Проверка Mesa #

Следующим подозреваемым стала Mesa.

На системе использовалась Mesa 25.0.7.

Для теста я взял готовый arm64 stack Mesa 26.1.2 из Debian Trixie Backports и запустил его из отдельного prefix, не заменяя системные библиотеки.

Результат оказался практически одинаковым:

Mesa 25.0.7
125 faults

Mesa 26.1.2
121 faults

Значит простое обновление Mesa проблему не решает.


Rendercheck и XRender #

Дальше удалось убрать из уравнения даже GTK и Xft.

Через rendercheck выяснилось, что ошибка воспроизводится обычным:

XRenderComposite(Over)

Даже без ComponentAlpha.

Обычный Composite Over способен вызвать:

js=0 INSTR_INVALID_PC

То есть текущая область поиска уже выглядит примерно так:

XRender -> Xorg glamor -> Mesa Panfrost -> Mali-T720

Это уже гораздо более конкретная проблема.


Временное решение #

Корневой баг пока не исправлен.

Отключать аппаратное ускорение полностью я не хотел.

Например:

AccelMethod "none"

действительно убирает ошибки, но вместе с ними исчезает и нормальное GPU acceleration.

Поэтому пока выбран менее болезненный workaround:

Xft.rgba: none

Для LightDM:

xft-rgba=none

Это не исправление Panfrost.

Это именно временная мера, которая позволяет оставить glamor и аппаратное ускорение, но убрать наблюдаемые артефакты в обычной работе LXQt.

В репозитории это специально отмечено как workaround, чтобы в будущем не забыть удалить его после настоящего исправления драйвера.


3.5 мм Jack #

Еще одна проблема оказалась со звуком.

Сначала казалось, что аналоговый выход Repka Pi 4 вообще не работает в Armbian.

Но ALSA показывала полноценную карту:

card 1: ac200audio

Playback и Capture присутствовали.

После исследования mixer controls обнаружился нужный переключатель:

DAC I2S Playback Switch

Ручное включение:

amixer -c 1 cset name='DAC I2S Playback Switch' on

сразу дало звук через 3.5 мм Jack.

То есть проблема была не в DTS, не в ядре и не в самом AC200.

Не хватало правильной инициализации аудиотракта.


ALSA UCM2 #

Ставить amixer в автозагрузку мне не хотелось.

Это уже был бы настоящий костыль.

Для таких вещей в ALSA существует UCM2.

Проблема была в том, что стандартный:

alsa-ucm-conf

не содержит профиля для ac200-audio.

Поэтому для Repka Pi 4 был сделан собственный минимальный профиль.

Он включает:

DAC I2S Playback Switch

при активации HiFi playback.

После этого звуковой тракт выглядит нормально:

LXQt / audio server -> ALSA UCM -> AC200 -> DAC I2S -> 3.5 mm Line Out

И никаких ручных amixer после загрузки больше не требуется.


lm-sensors #

Казалось бы, добавить lm-sensors в образ должно быть самой простой задачей во всем проекте.

Но даже здесь удалось наступить на изменение Armbian build framework.

Сначала пакет добавлялся через:

PACKAGE_LIST_ADDITIONAL

Образ успешно собирался, но после загрузки:

sensors

не существовал.

Оказалось, что в новой версии Armbian этот способ уже не тот, который нужно использовать для board-specific packages.

В итоге пакет был перенесен в конфигурацию самой платы:

PACKAGE_LIST_BOARD="lm-sensors"

Это намного логичнее.

Теперь пакет относится к Repka Pi 4, а не к конкретному Server или LXQt образу.


MIDI и snd-seq #

Еще одна небольшая доработка появилась из-за MIDI.

В ядре понадобилась поддержка ALSA sequencer:

CONFIG_SND_SEQUENCER=m

Я специально собираю ее как модуль.

Получается:

snd-seq.ko

Он доступен системе, но не обязан постоянно находиться в памяти.

Такой функционал был вынесен в общий kernel profile, который используется:

Server
PREEMPT_RT
LXQt

То есть это уже не настройка конкретного desktop-образа, а характеристика самой платформы.


Bluetooth #

С Bluetooth возник уже скорее архитектурный вопрос.

Изначально его пакеты устанавливались только в LXQt.

Но Bluetooth может понадобиться и на Server, и в PREEMPT_RT образе.

Поэтому BlueZ правильнее устанавливать глобально.

При этом постоянно работающий Bluetooth на маленькой ARM-плате тоже не всегда нужен.

bluetoothd в простое потреблял немного:

CPU около 0.2%
RSS около 6 MiB

Это совсем немного.

Но для Server и RT нет смысла держать даже его, если Bluetooth не используется.

Поэтому политика сейчас планируется разная.

Server / RT #

BlueZ установлен
bluetooth.service disabled
Bluetooth radio off

То есть функциональность есть, но никакие ресурсы по умолчанию не расходуются.

LXQt #

Для рабочего стола удобство важнее нескольких мегабайт RAM.

Поэтому:

bluetooth.service active
AutoEnable=false
Bluetooth radio off

Daemon готов к работе, но сам адаптер не включается.

Пользователь открывает Blueman и сразу включает Bluetooth без терминала и systemctl.


Обновление Armbian #

Еще один плюс собственного проекта заключается в том, что upstream Armbian можно обновлять независимо от наших изменений.

Сейчас build framework фиксируется на конкретном Git tag и commit.

Например:

v26.11.0-trunk.22
3da49cffcb8ac58a919d86816fec4659c410ff1e

Это важно для воспроизводимости.

Нельзя просто каждый раз собирать случайный main и надеяться, что результат будет тем же.

Схема получается такая:

Armbian release -> Git commit -> Repka patches -> image

Обновление upstream тоже делается отдельным Git commit.

Если новая версия Armbian что-то ломает, ее можно откатить независимо от поддержки самой Repka.


А что с Repka Pi 3 #

В какой-то момент стало понятно, что проект не ограничится одной Repka Pi 4.

На Repka Pi 3 обнаружились похожие организационные проблемы:

  • нужен lm-sensors

  • нужен общий Bluetooth policy

  • нужен snd-seq.ko

Но прямое копирование патчей с Pi 4 здесь невозможно.

Например, Pi 4 использует AC200, а Pi 3 показывает:

H3 Audio Codec

то есть работает через встроенный H5 codec.

Поэтому общая инфраструктура может быть одинаковой, а board-specific части должны оставаться раздельными.

Это еще одна причина, почему я постепенно ухожу от набора случайных shell-команд к нормальной структуре проекта.


Что уже работает #

На текущем этапе для Repka Pi 4 удалось получить:

  • загрузку современного Armbian

  • Linux 6.18

  • актуальный U-Boot

  • DRAM на 936 МГц

  • Server image

  • LXQt image

  • PREEMPT_RT profile

  • Ethernet

  • Wi-Fi

  • Bluetooth

  • HDMI 4K60

  • Panfrost acceleration

  • временную защиту от desktop-артефактов Panfrost

  • работающий AC200 и 3.5 мм Jack через ALSA UCM

  • lm-sensors

  • ALSA MIDI Sequencer как snd-seq.ko.

Но работа еще далеко не закончена.


Что осталось #

Главная нерешенная техническая проблема сейчас находится в графическом стеке.

Нужно дойти от:

XRenderComposite -> INSTR_INVALID_PC

до конкретного shader binary, GPU address или job descriptor, который ломается на Mali-T720.

То есть следующий уровень расследования оборачивается вокруг Mesa/Panfrost.


Что мне дал этот проект #

Наверное, самая интересная часть работы над Armbian для Repka заключается в том, насколько быстро исчезает граница между "программированием" и "железом".

Для меня как студента программной инженерии это очень полезный проект.

Один commit может изменить частоту DRAM.

Другой добавить модуль ядра.

Третий исправить маршрутизацию физического аудиовыхода.

А ошибка в одной строке Device Tree потенциально может сделать целый аппаратный блок недоступным.

Именно поэтому я хочу продолжать этот проект Repka Pi в Armbian.

Спасибо за внимание!


+1

Комментарии (0)

Для участия в обсуждении Вы должны быть авторизованным пользователем

Еще посты по теме

Наиболее интересные по мнению читателей



Темы

Навигация

ВойтиРегистрация