Add X96Q LPDDR3 v1.3 custom U-Boot build and eMMC flash tooling.
Armbian-compatible U-Boot v2025.01 with eMMC, DTB, and flash fixes for the X96Q TV box. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
# 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 (см. заголовок файла).
|
||||
Reference in New Issue
Block a user