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:
2026-06-05 05:22:22 +03:00
commit 359c107d36
11 changed files with 839 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
#!/usr/bin/env bash
# Прошивка eMMC на X96Q — запускать на приставке под root
# Usage: sudo ./flash-emmc.sh [образ.img.xz]
set -euo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
UBOOT="${UBOOT:-${DIR}/../output/u-boot-custom.bin}"
IMG_XZ="${1:-}"
if [[ $EUID -ne 0 ]]; then
echo "Запустите: sudo $0 [образ.img.xz]"
exit 1
fi
if [[ -z "$IMG_XZ" ]]; then
shopt -s nullglob
imgs=( "$DIR"/*.img.xz )
if [[ ${#imgs[@]} -eq 0 ]]; then
echo "Нет .img.xz в $DIR"
exit 1
elif [[ ${#imgs[@]} -eq 1 ]]; then
IMG_XZ="${imgs[0]}"
else
echo "Несколько образов — укажите явно:"
ls -lh "${imgs[@]}"
exit 1
fi
fi
[[ -f "$IMG_XZ" ]] || { echo "Нет файла: $IMG_XZ"; exit 1; }
[[ -f "$UBOOT" ]] || { echo "Нет $UBOOT"; exit 1; }
EMMC=/dev/mmcblk2
BOOT0=/dev/mmcblk2boot0
BOOT1=/dev/mmcblk2boot1
[[ -b "$EMMC" ]] || { echo "eMMC не найден: $EMMC"; exit 1; }
unlock_boot() {
local ro
for part in boot0 boot1; do
ro="/sys/block/mmcblk2${part}/force_ro"
[[ -w "$ro" ]] || continue
echo 0 >"$ro"
echo "mmcblk2${part}: force_ro=$(cat "$ro")"
done
}
echo "=== eMMC flash (X96Q) ==="
echo "Образ: $IMG_XZ ($(du -h "$IMG_XZ" | cut -f1))"
echo "U-Boot: $UBOOT"
echo "Цель: $EMMC + $BOOT0 + $BOOT1"
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT 2>/dev/null | grep -E 'mmcblk|NAME' || lsblk
echo "[1/4] Запись образа на $EMMC ..."
xz -dc "$IMG_XZ" | dd of="$EMMC" bs=4M status=progress conv=fsync
sync
echo "[2/4] U-Boot → user area @ 8 KiB ..."
dd if="$UBOOT" of="$EMMC" bs=1024 seek=8 conv=fsync
echo "Разблокировка boot0/boot1 (force_ro) ..."
unlock_boot
echo "[3/4] U-Boot → boot0 ..."
dd if="$UBOOT" of="$BOOT0" bs=1024 conv=fsync
echo "[4/4] U-Boot → boot1 ..."
dd if="$UBOOT" of="$BOOT1" bs=1024 conv=fsync
sync
# Armbian DTB: в образе sun50i-h313-x96q-lpddr3.dtb, не v1.3
MNT="/tmp/emmc-fix"
mkdir -p "$MNT"
if mount "${EMMC}p1" "$MNT"; then
ENV="${MNT}/boot/armbianEnv.txt"
DTB="${MNT}/boot/dtb/allwinner"
if [[ -f "$ENV" ]]; then
if grep -q '^fdtfile=' "$ENV"; then
sed -i 's/^fdtfile=.*/fdtfile=sun50i-h313-x96q-lpddr3.dtb/' "$ENV"
else
echo 'fdtfile=sun50i-h313-x96q-lpddr3.dtb' >>"$ENV"
fi
fi
if [[ -d "$DTB" && -f "${DTB}/sun50i-h313-x96q-lpddr3.dtb" ]]; then
ln -sf sun50i-h313-x96q-lpddr3.dtb "${DTB}/sun50i-h313-x96q-lpddr3-v1.3.dtb"
fi
sync
umount "$MNT"
fi
rmdir "$MNT" 2>/dev/null || true
echo "Готово. Выключите, выньте SD, включите — загрузка с eMMC."
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
# Только U-Boot на eMMC (без перезаписи образа) — запускать на приставке под root
set -euo pipefail
DIR="$(cd "$(dirname "$0")" && pwd)"
UBOOT="${1:-${DIR}/../output/u-boot-custom.bin}"
if [[ $EUID -ne 0 ]]; then
echo "Запустите: sudo $0 [u-boot-custom.bin]"
exit 1
fi
[[ -f "$UBOOT" ]] || { echo "Нет файла: $UBOOT"; exit 1; }
EMMC=/dev/mmcblk2
BOOT0=/dev/mmcblk2boot0
BOOT1=/dev/mmcblk2boot1
echo "=== U-Boot only → $EMMC ==="
echo "Бинарник: $UBOOT"
echo 0 >/sys/block/mmcblk2boot0/force_ro
echo 0 >/sys/block/mmcblk2boot1/force_ro
dd if="$UBOOT" of="$EMMC" bs=1024 seek=8 conv=fsync
dd if="$UBOOT" of="$BOOT0" bs=1024 conv=fsync
dd if="$UBOOT" of="$BOOT1" bs=1024 conv=fsync
sync
echo "Готово."