Armbian-compatible U-Boot v2025.01 with eMMC, DTB, and flash fixes for the X96Q TV box. Co-authored-by: Cursor <cursoragent@cursor.com>
X96Q LPDDR3 v1.3 — кастомный U-Boot
Кастомная сборка U-Boot для X96Q TV Box LPDDR3 v1.3 (Allwinner H616/H313, 1 GiB LPDDR3, AXP313A, eMMC boot).
Проверено: UART 115200, загрузка Armbian с eMMC, DRAM: 1 GiB.
Структура репозитория
x96q-uboot/
├── README.md
├── build.sh # сборка (macOS + Homebrew)
├── patches/
│ ├── jernejsk-emmc.patch # фикс eMMC на H616
│ ├── easter-egg.patch # баннер в SPL + Kconfig
│ └── fdtfile-armbian.patch # совместимость DTB с Armbian
├── overlays/
│ ├── configs/x96_q_lpddr3_v1.3_defconfig
│ └── dts/sun50i-h313-x96q-lpddr3-v1.3.dts
├── output/
│ └── u-boot-custom.bin # артефакт сборки (gitignore)
└── scripts/
├── flash-emmc.sh # образ + U-Boot на eMMC
└── flash-uboot-only.sh # только U-Boot поверх существующего образа
Что было сломано и как чинили
1. Неправильный defconfig (DDR3 вместо LPDDR3)
Симптом: DRAM: not supported в UART.
Причина: generic x96q_defconfig настроен на DDR3, а плата — LPDDR3 v1.3 с другими таймингами и AXP313.
Фикс: defconfig x96_q_lpddr3_v1.3_defconfig из Armbian/NickAlilovic + DTS sun50i-h313-x96q-lpddr3-v1.3.dts.
2. eMMC read error в SPL
Симптом: SPL не читает eMMC, BootROM зацикливается или грузит битый bootloader.
Причина: на H616 контроллеру MMC нужен hardware reset карты и FIFO threshold (патч Jernej Skrabec, upstream U-Boot).
Фикс: patches/jernejsk-emmc.patch — backport на v2025.01.
3. Несовпадение имени DTB (главный баг загрузки)
Симптом:
The file allwinner/sun50i-h313-x96q-lpddr3-v1.3.dtb was not found
ERROR: Did not find a cmdline Flattened Device Tree
Причина: U-Boot из SPL выставляет fdtfile по имени своего device tree (…-lpddr3-v1.3.dtb). Armbian в /boot/dtb/allwinner/ кладёт только sun50i-h313-x96q-lpddr3.dtb (без суффикса v1.3). Ядро и initrd грузятся, DTB — нет.
Фикс (три уровня):
- Патч U-Boot
fdtfile-armbian.patch— вmisc_init_r()подменяетfdtfileна Armbian-имя. flash-emmc.sh— после прошивки пишетfdtfile=sun50i-h313-x96q-lpddr3.dtbвarmbianEnv.txtи создаёт symlink…-v1.3.dtb.- Вручную на работающей системе — то же в
/boot/armbianEnv.txt.
U-Boot DT (
v1.3) и kernel DT (lpddr3) — разные файлы с разным назначением. SPL использует свой DTS для DRAM/PMIC; ядро — DTB из образа Armbian.
4. dd: Operation not permitted на boot0/boot1
Симптом: запись в user area проходит, в mmcblk2boot0 — отказ.
Причина: boot-разделы eMMC по умолчанию read-only (force_ro=1).
Фикс: перед dd:
echo 0 > /sys/block/mmcblk2boot0/force_ro
echo 0 > /sys/block/mmcblk2boot1/force_ro
Скрипт flash-emmc.sh делает это автоматически.
5. Card did not respond to voltage select! : -110 на mmc0
Симптом: при фолбэке boot.scr пытается mmc0 и падает.
Причина: в U-Boot mmc0 — SD-слот, при определённых условиях voltage select не проходит; это не блокер, если DTB найден на правильном mmc (SD = mmc1 в нашем случае).
Карта MMC
| Где | Устройство | Назначение |
|---|---|---|
| Linux | mmcblk0 |
SD-карта |
| Linux | mmcblk2 |
eMMC (user area) |
| Linux | mmcblk2boot0/1 |
eMMC boot partitions (по 2 MiB) |
| U-Boot shell | mmc dev 1 |
eMMC |
| U-Boot shell | mmc dev 2 |
то же eMMC (другой индекс) |
| U-Boot autoboot | mmc1 |
откуда грузится boot.scr (SD при вставленной карте) |
SPL/U-Boot пишется в три места:
- user area @ 8 KiB (
dd seek=8) — legacy sunxi offset - boot0 — основная boot-область eMMC
- boot1 — зеркало (резерв)
Сборка
Требования (macOS)
brew install aarch64-elf-gcc gnu-sed openssl@3 swig python3
Команда
./build.sh
Скрипт:
- Клонирует U-Boot
v2025.01и ARM TF-A в.build/ - Накатывает патчи из
patches/ - Копирует defconfig и DTS из
overlays/ - Собирает BL31 + U-Boot
- Кладёт бинарник в
output/u-boot-custom.bin(~822 KiB)
Проверка артефакта
strings output/u-boot-custom.bin | grep -E 'binary build|2025.01|lpddr3'
Ожидаемо:
*** binary build ***U-Boot SPL 2025.01-dirtysun50i-h313-x96q-lpddr3.dtb(fdtfile для Armbian)
Прошивка eMMC
Полная (образ Armbian + U-Boot)
На приставке (под root, лучше загрузившись с SD):
# скопировать на приставку:
# output/u-boot-custom.bin
# scripts/flash-emmc.sh
# Armbian_*.img.xz
cd /home/binary # или куда положили файлы
sudo ./flash-emmc.sh
# или явно:
sudo ./flash-emmc.sh Armbian_community_26.2.0-trunk.904_X96q_trixie_current_6.18.29_minimal.img.xz
Скрипт:
xz -dc образ | dd of=/dev/mmcblk2— запись образа локально (не через SSH pipe)- U-Boot → user @ 8 KiB
- Разблокировка boot0/boot1
- U-Boot → boot0 + boot1
- Правка
armbianEnv.txt+ symlink DTB
После прошивки: вынуть SD, перезагрузка.
Только U-Boot (образ уже на eMMC)
sudo ./flash-uboot-only.sh /path/to/u-boot-custom.bin
Ожидаемый UART при успешной загрузке
*** binary build ***
U-Boot 2025.01-dirty (...) binary build
CPU: Allwinner H616 (SUN50I)
Model: hechuang,x96-q LPDDR3 v1.3
DRAM: 1 GiB
...
U-boot loaded from eMMC
Load fdt: /boot/dtb/allwinner/sun50i-h313-x96q-lpddr3.dtb
Патчи
| Патч | Зачем |
|---|---|
jernejsk-emmc.patch |
reset eMMC + FIFO threshold на H616 |
easter-egg.patch |
CONFIG_X96Q_BINARY_BUILD — маркер в SPL, идентификация сборки |
fdtfile-armbian.patch |
fdtfile → имя DTB из Armbian, иначе boot.scr не находит дерево |
Восстановление (FEL)
Если eMMC bootloader битый и SD не помогает:
- Зажать кнопку FEL, подключить USB (
1f3a:efe8) - FEL + sunxi-tools: wipe boot0/boot1/SPL или прошить свежий
u-boot-custom.bin
Подробности — в родительском репозитории FEL (fel-recover.sh, fel-wipe-emmc.sh).
Версии
| Компонент | Версия |
|---|---|
| U-Boot base | v2025.01 |
| ARM TF-A BL31 | sun50i_h616 |
| Defconfig | Armbian x96_q_lpddr3_v1.3 |
| Плата | X96Q LPDDR3 v1.3 (не путать с DDR3 и не-LPDDR3 ревизиями) |
Лицензия
Патчи и overlay — поверх GPL-2.0+ U-Boot. DTS: GPL-2.0+ OR MIT (см. заголовок файла).