- Shell 99.4%
- Batchfile 0.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| blobs | ||
| .gitignore | ||
| build-image.sh | ||
| README.md | ||
Arch Linux ARM для Repka Pi 3
Сборка загрузочного образа Arch Linux ARM (aarch64) для одноплатника
Repka Pi 3 (Allwinner H5, ревизии 1.3–1.6). Проект самодостаточен и
предназначен для git: в репозитории лежат только исходники и маленькие блобы
(~7 МБ), все тяжёлые зависимости (тарбол ALARM ~800 МБ, пакеты) скачиваются
скриптом при сборке в dl/ и в git не попадают.
bash build-image.sh # собрать образ: out/arch-linux-arm-repka-pi3.img
Состав образа
| Компонент | Откуда | Что именно |
|---|---|---|
| Rootfs + ядро | Arch Linux ARM aarch64 | базовый rootfs, ядро linux-aarch64 (мейнлайн), модули |
| Загрузчик | Repka (npo_rbs/repka-os_boot-loader) |
u-boot-sunxi-with-spl.bin (SPL+U-Boot+ATF), пишется на 8 KiB |
| DTB ядра | Repka OS + наш патч | sun50i-h5-repka-pi3.dtb (OPP до 1416 МГц, WiFi mmc1, BT serdev) |
| WiFi прошивка | linux-firmware (в rootfs) | апстрим cyfmac43430-sdio.bin под именами brcmfmac43430-sdio.rbs,repka-pi3.{bin,txt} |
| BT прошивка | blobs/firmware |
bcm43438a1.hcd → BCM43430A1.hcd (+ фолбэк-имена) |
| WiFi/BT userspace | ALARM repo | wpa_supplicant, bluez, bluez-utils (скачиваются и проверяются подписи) |
| Сеть | systemd-networkd + resolved | end0 + wlan0 по DHCP |
Пакеты поверх base регистрируются в /var/lib/pacman/local с полными
списками файлов, так что pacman считает их своими и pacman -Syu работает
штатно (см. «Исправления»).
Исправления, запечённые в образ
Все вошли после реальной отладки на железе (2026-10-10…12):
- Адреса загрузки в boot.cmd: ядро
0x42000000, DTB0x48000000. Старая схема Repka (0x41000000/0x44000000) вешала плату после обновления ядра ALARM ≥ 7.2:Imageвырос с 44 до ~50 МБ и при загрузке накрывал DTB, лежащий на0x44000000(симптом: послеpacman -Syuобрыв по UART сразу после «Starting kernel...»). Новые адреса — стандартные distro-адреса sunxi. - Патч DTB: убран дубль фиксированного клока
ext_osc32kв/clocks. Вендорский DTB объявлял его дважды (один раз с phandle) — второй экземпляр ломал регистрацию часовника RTC/LPO (32 кГц), без которого serdev-BT (brcm,bcm43438-bt) не поднимался. С патчем Bluetooth работает (hci0, патчBCM43430A1.hcdгрузится). Оригинал —blobs/dtb/*.orig.dtb. - Полные списки файлов в pacman-базе для пакетов, распакованных в rootfs
напрямую. Пустая заглушка
%FILES%делала запись «битой»: любоеpacman -Syu, трогающее такие пакеты или их окружение, падало «exists in filesystem». Теперь списки генерируются из исходных.pkg.tar.xz, имя каталога базы — с epoch (wpa_supplicant-2:2.12-1). Внимание: сборщик ALARM в момент сборки отдавал часть пакетов пустыми (size = 0: gcc-libs, libgcc, ca-certificates, linux-firmware) — у них в базе корректно пустой список, а сами файлы в rootfs есть из тарбола. Когда ALARM починит сборщик и эти пакеты обновятся, первый такой-Syuможет попросить--overwrite— это штатно:pacman -Syu --overwrite '*'. - Зеркало pacman в образе:
fl.us.mirror.archlinuxarm.org→ Yandex. Замер с платы (2026-10-13): fl.us — 3-4 МБ/с, Yandex просел до ~0.3 МБ/с (TTFB до 13 с),de.mirror.archlinuxarm.orgотдаёт ошибку на extra.db. Дефолтныйmirror.archlinuxarm.orgпо GeoIP ненадёжен, аos.archlinuxarm.orgотдаёт чужой TLS-сертификат — не использовать. - Статус-LED выключен:
/etc/tmpfiles.d/repka-leds.confставитtrigger=none, brightness=0при каждой загрузке (синяя лампочка не мигает). Вернуть:echo heartbeat > /sys/class/leds/rbs:red:status/trigger. - Root по SSH — только по ключу (
PermitRootLogin prohibit-passwordвsshd_config.d/10-root.conf); стоковый ALARM пускает root по паролюroot. Как получить root по SSH после прошивки — см. «Первый вход». - MTU 1492 на
end0(10-end0.network): за PPPoE-роутером пакеты 1500 без работающего PMTUD душат TCP до КБ/с. - Локаль
en_US.UTF-8(locale.gen+locale.conf+/etc/environment— последняя нужна, чтобы локаль видели SSH-сессии; генерация локали и pacman-ключница — на первой загрузке, юнитfirst-boot-setup.service). - SSH host-ключи генерируются при сборке (sshd готов сразу), suid-биты и владелец root в ФС восстанавливаются (fakeroot/docker) — иначе на плате отваливаются sshd/su/pacman-ключница.
- Pacman-хук контроля размера ядра: после установки/обновления ядра
/usr/local/bin/check-kernel-size.shсверяет размер/boot/Imageс зазором до адреса DTB изboot.cmd(сейчас 96 МиБ при ядре ~50 МБ). Всегда печатает запас; с 80% зазора — ВНИМАНИЕ, при перекрытии — КРИТИЧНО с рецептом лечения (поднять адрес DTB, пересобрать boot.scr), плюс запись в журнал (logger -t kernel-size,journalctl -t kernel-size). poweroff/rebootбез sudo: в образе есть polkit и правило/etc/polkit-1/rules.d/10-poweroff.rules, разрешающее выключение и перезагрузку членам группыwheel(alarmв ней состоит из коробки). Без правила polkit по SSH отвечает «Access denied» — его дефолт пускает выключение только из локальной консоли. Пользователю, созданному после прошивки:usermod -aG wheel <имя>.
Разметка образа
offset 8 KiB u-boot-sunxi-with-spl.bin (SPL Repka)
offset 10 MiB p1: ext4 «rootfs» (метка rootfs), до конца образа
/boot: Image, sun50i-h5-repka-pi3.dtb, boot.cmd, boot.scr
Раздел один — /dev/mmcblk0p1 — и есть корень. boot.scr грузит
/boot/Image + /boot/sun50i-h5-repka-pi3.dtb, root=/dev/mmcblk0p1 rw rootwait, без initramfs (драйверы MMC/EXT4 в ядре ALARM встроены).
При обновлении ядра следите за размером /boot/Image относительно адреса DTB
(см. исправление 1).
Структура репозитория
build-image.sh сборка (bash build-image.sh; IMG_SIZE=8G bash … — другой размер)
README.md этот файл
blobs/
bootloader/ u-boot-sunxi-with-spl.bin — сборка из npo_rbs/repka-os_boot-loader (2024)
dtb/ патченный DTB + оригинал + boot.cmd/boot.scr (адреса 0x42000000/0x48000000)
firmware/ bcm43438a1.hcd (BT-патч AP6212), nvram.txt (запасной nvram, в rootfs есть AP6212.txt)
uboot-variants/ вендорные загрузчики Repka OS: клоки DRAM 672/696/744/768, с UART и «тихие» (nottys0)
dl/ (gitignore) скачанные зависимости: тарбол ALARM + пакеты с подписями
work/ (gitignore) распакованный rootfs, промежуточные файлы
out/ (gitignore) готовый образ, sha256, boot.cmd, uboot-variants/
Прошивки A0 (fw_bcm43438a0.bin, bcm43438a0.hcd) из Repka OS не
используются: на плате чип rev A1 (BCM43430A1), ему нужна апстримная
прошивка. Осторожно: brcmfmac43430-sdio.bin в linux-firmware — симлинк на
cypress/cyfmac43430-sdio.bin, запись «через» симлинк затирает цель.
Зависимости сборки (хост)
- утилиты:
bsdtar(libarchive),e2fsprogs(mkfs.ext4, debugfs),sfdisk,curl,xxd,readelf(binutils) - владелец root в ФС: fakeroot (пакет
fakeroot) или docker — без них образ соберётся от uid 1000 и на плате не поднимется sshd mkimage(u-boot-tools) — для boot.scr; если нет, используется docker (alpine + u-boot-tools), иначе готовыйblobs/dtb/boot.scr
Скачивание идёт с MIRROR (по умолчанию
http://fl.us.mirror.archlinuxarm.org, фолбэк — Yandex);
переопределить: MIRROR=http://… bash build-image.sh.
Прошивка
# заменить sdX на карту (проверить lsblk!)
dd if=out/arch-linux-arm-repka-pi3.img of=/dev/sdX bs=4M conv=fsync status=progress
# или графически: Repka image-writer / balenaEtcher
Образ 6 ГиБ (реально ~2 ГиБ — файл разрежённый). Под карту большего объёма
раздел расширяют после первой загрузки (см. ниже). Заменить загрузчик на
вариант из out/uboot-variants/:
dd if=<bin> of=/dev/sdX bs=1024 seek=8 conv=notrunc.
Первый вход
Учётки по умолчанию ALARM: root / root и alarm / alarm — сменить
пароли сразу. В базе ALARM нет sudo — используй su -.
- UART-консоль: пины 8/10 (UART0 TX/RX), 115200 8N1
- SSH:
ssh alarm@<ip-по-dhcp>(сразу работает)
passwd && passwd alarm # сменить пароли (root, потом alarm)
# свой пользователь вместо/вместе с alarm; wheel даёт poweroff/reboot без sudo
# (правило polkit в образе пускает выключение всем из wheel):
useradd -m -G wheel -s /bin/bash <имя> && passwd <имя>
# расширить раздел на всю карту (под root):
sfdisk --no-reread -N1 /dev/mmcblk0 <<< ',+' && partx -u /dev/mmcblk0
resize2fs /dev/mmcblk0p1 # онлайн, без ребута
# root по SSH (PermitRootLogin prohibit-password — только по ключу):
mkdir -p /root/.ssh && chmod 700 /root/.ssh
echo 'ssh-ed25519 AAAA…' > /root/.ssh/authorized_keys && chmod 600 /root/.ssh/authorized_keys
# на десктопе: ssh-copy-id -i ~/.ssh/<ключ>.pub root@<ip> — но сначала положи ключ по схеме выше
Первые ~минуты после старта платa занята first-boot-setup.service
(pacman-key --init/--populate, locale-gen) — pacman заработает после него.
WiFi и Bluetooth
Bluetooth работает из коробки (serdev + DTB-патч, см. исправление 2):
bluetoothctl power on && bluetoothctl scan on
WiFi (wlan0) может не подняться на ядрах ≥ 7.2 — известная регрессия
pwrseq_simple: для однопинового reset-gpios (PL8) драйвер требует
reset-controller и получает -ENOENT → mmc1 «Failed to initialize a
non-removable card». Обходы (gpio-hog в DTB, userspace-рескан) не помогли.
Варианты: ждать фикс ядра (pacman -Syu), USB-WiFi донгл, откат ядра.
Когда ядро починят, настройка обычная:
wpa_passphrase 'ИМЯ_СЕТИ' 'пароль' >> /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
systemctl restart wpa_supplicant@wlan0
Диагностика: dmesg | grep -E 'brcmf|mmc1'. HT Avail timeout = не подошли
прошивка/nvram.
Сеть
Интерфейс называется end0 (не eth0 — так его называет DTB Repka).
MTU 1492 зашит в 10-end0.network (PPPoE-путь). Если плата внезапно отдаёт
~40 кбит/с на всех WAN-соединениях при нормальном LAN и чистых пингах —
проверьте роутер: Keenetic троттлит устройства по записям с лимитом
(лечится удалением записи устройства или сменой MAC: ip link set end0 address … + закрепить в /etc/systemd/network/*.link).
GPIO (40 pin, распиновка как у Raspberry Pi)
Библиотеки Repka (ставить на самой плате):
- WiringRP — https://gitflic.ru/project/repka_pi/wiring-repka (API в стиле Wiring: PWM, UART, I2C, SPI)
- RepkaPi.GPIO SysFS — https://gitflic.ru/project/repka_pi/repkapigpiofs
Логика 3,3 В, пин ≤ 40 мА (кратковременно). В v1.6 на разъём выведен I2S.
Известные нюансы
- Владение файлами: сборка без fakeroot/docker даёт ФС от uid 1000 — на
плате отвалятся sshd (
/usr/share/empty.sshd must be owned by root), su, pacman-ключница. Лечение после прошивки:chown -R 0:0корня (кроме/home/alarm) + suid-биты. - Обновления:
pacman -Syuобновит и ядро — DTB в/bootне трогается, загрузчик на карте не меняется, адреса в boot.scr уже безопасные (исправление 1). Если после обновления плата не грузится — по UART смотрите, дошёл ли «Starting kernel...», и проверьте размерImage(ls -lh /boot/Image). - DTB собран под ядро 6.1 (Feb 2024), но работает с мейнлайном (проверено
на 6.9, 7.2.9, 7.2.10); таблица OPP до 1416 МГц. Если новое ядро поменяет
биндинги — пересобрать из исходников Repka (
repka-os_boot-loader). - GPU Mali-450 — ускорения OpenGL нет (KMS-консоль и программный рендер). Видео-декодирование — cedrus (V4L2).
- Журнал персистентный:
journalctl -p 3на плате илиjournalctl --directory=<смонтированная карта>/var/log/journal -p 3.