# 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 — нет. **Фикс (три уровня):** 1. **Патч U-Boot** `fdtfile-armbian.patch` — в `misc_init_r()` подменяет `fdtfile` на Armbian-имя. 2. **`flash-emmc.sh`** — после прошивки пишет `fdtfile=sun50i-h313-x96q-lpddr3.dtb` в `armbianEnv.txt` и создаёт symlink `…-v1.3.dtb`. 3. Вручную на работающей системе — то же в `/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`: ```bash 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) ```bash brew install aarch64-elf-gcc gnu-sed openssl@3 swig python3 ``` ### Команда ```bash ./build.sh ``` Скрипт: 1. Клонирует U-Boot `v2025.01` и ARM TF-A в `.build/` 2. Накатывает патчи из `patches/` 3. Копирует defconfig и DTS из `overlays/` 4. Собирает BL31 + U-Boot 5. Кладёт бинарник в `output/u-boot-custom.bin` (~822 KiB) ### Проверка артефакта ```bash strings output/u-boot-custom.bin | grep -E 'binary build|2025.01|lpddr3' ``` Ожидаемо: - `*** binary build ***` - `U-Boot SPL 2025.01-dirty` - `sun50i-h313-x96q-lpddr3.dtb` (fdtfile для Armbian) ## Прошивка eMMC ### Полная (образ Armbian + U-Boot) На приставке (под root, лучше загрузившись с SD): ```bash # скопировать на приставку: # 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 ``` Скрипт: 1. `xz -dc образ | dd of=/dev/mmcblk2` — запись образа локально (не через SSH pipe) 2. U-Boot → user @ 8 KiB 3. Разблокировка boot0/boot1 4. U-Boot → boot0 + boot1 5. Правка `armbianEnv.txt` + symlink DTB После прошивки: **вынуть SD**, перезагрузка. ### Только U-Boot (образ уже на eMMC) ```bash 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 не помогает: 1. Зажать кнопку **FEL**, подключить USB (`1f3a:efe8`) 2. 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 (см. заголовок файла).