359c107d36
Armbian-compatible U-Boot v2025.01 with eMMC, DTB, and flash fixes for the X96Q TV box. Co-authored-by: Cursor <cursoragent@cursor.com>
204 lines
7.7 KiB
Markdown
204 lines
7.7 KiB
Markdown
# 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 (см. заголовок файла).
|