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
Executable
+129
View File
@@ -0,0 +1,129 @@
#!/usr/bin/env bash
# Сборка U-Boot для X96Q LPDDR3 v1.3 (Allwinner H616)
set -euo pipefail
ROOT="$(cd "$(dirname "$0")" && pwd)"
UBOOT_DIR="$ROOT/.build/u-boot"
ATF_DIR="$ROOT/.build/arm-trusted-firmware"
PATCH_DIR="$ROOT/patches"
OVERLAY_DIR="$ROOT/overlays"
CROSS_BIN="$ROOT/.build/cross-bin"
OUT_DIR="$ROOT/output"
CROSS_COMPILE=aarch64-elf-
UBOOT_TAG=v2025.01
DEFCONFIG=x96_q_lpddr3_v1.3_defconfig
BL31="$ATF_DIR/build/sun50i_h616/debug/bl31.bin"
OUTPUT="$UBOOT_DIR/u-boot-sunxi-with-spl.bin"
NCPU="$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)"
export PATH="$CROSS_BIN:/opt/homebrew/opt/gnu-sed/libexec/gnubin:/opt/homebrew/bin:$PATH"
need_cmd() {
command -v "$1" >/dev/null 2>&1 || { echo "Missing: $1" >&2; exit 1; }
}
setup_venv() {
if [[ ! -x "$ROOT/.venv/bin/python3" ]]; then
python3 -m venv "$ROOT/.venv"
"$ROOT/.venv/bin/pip" install -q 'setuptools==69.5.1'
fi
export PATH="$ROOT/.venv/bin:$PATH"
}
setup_cross_shims() {
mkdir -p "$CROSS_BIN"
for t in objcopy ar ranlib ld nm strip; do
ln -sf "/opt/homebrew/bin/${CROSS_COMPILE}${t}" "$CROSS_BIN/$t"
done
}
clone_repos() {
mkdir -p "$ROOT/.build"
if [[ ! -d "$UBOOT_DIR/.git" ]]; then
git clone --filter=blob:none --tags https://github.com/u-boot/u-boot.git "$UBOOT_DIR"
fi
if [[ ! -d "$ATF_DIR/.git" ]]; then
git clone --depth=1 https://github.com/ARM-software/arm-trusted-firmware.git "$ATF_DIR"
fi
}
prepare_uboot_tree() {
local patch applied=0
(
cd "$UBOOT_DIR"
git fetch --depth 1 origin tag "$UBOOT_TAG" 2>/dev/null || true
git checkout -f "$UBOOT_TAG"
git clean -fdx
)
for patch in \
"$PATCH_DIR"/jernejsk-emmc.patch \
"$PATCH_DIR"/easter-egg.patch \
"$PATCH_DIR"/fdtfile-armbian.patch; do
[[ -f "$patch" ]] || continue
if (cd "$UBOOT_DIR" && git apply --check "$patch" 2>/dev/null); then
(cd "$UBOOT_DIR" && git apply "$patch")
applied=$((applied + 1))
elif (cd "$UBOOT_DIR" && git apply --reverse --check "$patch" 2>/dev/null); then
echo "Already applied: $(basename "$patch")"
else
echo "Failed to apply: $patch" >&2
exit 1
fi
done
mkdir -p "$UBOOT_DIR/configs" \
"$UBOOT_DIR/dts/upstream/src/arm64/allwinner"
cp -f "$OVERLAY_DIR/configs/$DEFCONFIG" \
"$UBOOT_DIR/configs/$DEFCONFIG"
cp -f "$OVERLAY_DIR/dts/sun50i-h313-x96q-lpddr3-v1.3.dts" \
"$UBOOT_DIR/dts/upstream/src/arm64/allwinner/sun50i-h313-x96q-lpddr3-v1.3.dts"
echo "U-Boot $UBOOT_TAG + $applied patches + overlay"
}
build_bl31() {
(
cd "$ATF_DIR"
gmake CROSS_COMPILE="$CROSS_COMPILE" AR="${CROSS_COMPILE}ar" RANLIB="${CROSS_COMPILE}ranlib" \
PLAT=sun50i_h616 DEBUG=1 bl31
)
}
build_uboot() {
local openssl_prefix py_ldflags py_cflags
openssl_prefix="$(brew --prefix openssl@3)"
py_ldflags="$(python3-config --ldflags --embed 2>/dev/null || python3-config --ldflags)"
py_cflags="$(python3-config --includes)"
(
cd "$UBOOT_DIR"
export PATH="$ROOT/.venv/bin:$PATH"
gmake CROSS_COMPILE="$CROSS_COMPILE" BL31="$BL31" "$DEFCONFIG"
gmake CROSS_COMPILE="$CROSS_COMPILE" BL31="$BL31" \
BINMAN_ALLOW_MISSING=1 \
HOSTCFLAGS="$py_cflags -I$openssl_prefix/include" \
HOSTLDFLAGS="$py_ldflags -L$openssl_prefix/lib -lcrypto" \
-j"$NCPU"
)
}
main() {
need_cmd git
need_cmd gmake
need_cmd "${CROSS_COMPILE}gcc"
need_cmd python3
need_cmd swig
need_cmd brew
setup_cross_shims
setup_venv
clone_repos
prepare_uboot_tree
build_bl31
build_uboot
mkdir -p "$OUT_DIR"
cp -f "$OUTPUT" "$OUT_DIR/u-boot-custom.bin"
echo "U-Boot: $(git -C "$UBOOT_DIR" describe --tags --always)"
echo "Output: $OUT_DIR/u-boot-custom.bin"
ls -la "$OUT_DIR/u-boot-custom.bin"
}
main "$@"