diff --git a/.gitea/workflows/flash-aminpa-V1.5.yml b/.gitea/workflows/flash-aminpa-V1.5.yml new file mode 100644 index 0000000..eb8a758 --- /dev/null +++ b/.gitea/workflows/flash-aminpa-V1.5.yml @@ -0,0 +1,65 @@ +name: flash-aminpa-V1.5 +# Production flash for Amin Pardaz Asia device v1.5 + +on: + push: + branches: + - main + +concurrency: + group: aminpa-serial-flash + cancel-in-progress: false + +jobs: + flash-aminpa: + name: Production flash - Amin Pardaz Asia v1.5 + runs-on: serial-runner + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Validate all firmware files before erasing flash + run: | + /usr/bin/python3 - <<'PY' + from pathlib import Path + + required = { + "u-boot-sunxi-with-spl.bin": 32, + "sun8i-v3s-licheepi-zero-dock.dtb": 32, + "zImage": 64, + "rootfs.squashfs": 64, + } + for filename, minimum in required.items(): + path = Path("firmware") / filename + if not path.is_file() or path.stat().st_size < minimum: + raise SystemExit(f"Missing or invalid firmware: {path}") + print(f"Found {path}: {path.stat().st_size} bytes") + PY + + - name: Check current U-Boot CLI + run: /usr/bin/python3 scripts/serial_command.py check + + - name: Configure and verify network + run: /usr/bin/python3 scripts/serial_command.py configure + + - name: Check all firmware sizes against detected flash layout + run: /usr/bin/python3 scripts/serial_command.py preflight + + - name: Erase detected SPI flash and verify sample + run: /usr/bin/python3 scripts/serial_command.py erase + + - name: Transfer, write and verify U-Boot + run: /usr/bin/python3 scripts/serial_command.py transfer + + - name: Transfer, write and verify DTB + run: /usr/bin/python3 scripts/serial_command.py transfer-dtb + + - name: Transfer, write and verify Kernel + run: /usr/bin/python3 scripts/serial_command.py transfer-kernel + + - name: Transfer, write and verify RootFS + run: /usr/bin/python3 scripts/serial_command.py transfer-rootfs + + - name: Inspect boot configuration + run: /usr/bin/python3 scripts/serial_command.py boot-config diff --git a/scripts/serial_command.py b/scripts/serial_command.py index c948af8..22f5cd6 100644 --- a/scripts/serial_command.py +++ b/scripts/serial_command.py @@ -199,7 +199,7 @@ def boot_config(cli, confirmed=False): def main(): parser = argparse.ArgumentParser() - parser.add_argument("mode", choices=("check", "configure", "transfer", "transfer-dtb", "transfer-kernel", "transfer-rootfs", "erase", "boot-config"), default="check", nargs="?") + parser.add_argument("mode", choices=("check", "configure", "transfer", "transfer-dtb", "transfer-kernel", "transfer-rootfs", "erase", "boot-config", "preflight"), default="check", nargs="?") parser.add_argument("--port", default="/dev/ttyUSB0") parser.add_argument("--firmware", type=Path, default=None) parser.add_argument("--rootfs-size", type=lambda value: int(value, 0), help="Actual RootFS partition size in bytes (decimal or 0x-prefixed hex)") @@ -218,6 +218,18 @@ def main(): cli.detect() if args.mode == "check": return + if args.mode == "preflight": + capacity = detect_flash(cli) + files = {"uboot": "u-boot-sunxi-with-spl.bin", "dtb": "sun8i-v3s-licheepi-zero-dock.dtb", + "kernel": "zImage", "rootfs": "rootfs.squashfs"} + for part, filename in files.items(): + path = Path(__file__).resolve().parent.parent / "firmware" / filename + minimum = 64 if part in ("kernel", "rootfs") else 32 + limit = LAYOUTS[capacity][part][1] + if not path.is_file() or not minimum <= path.stat().st_size <= limit: + raise RuntimeError(f"Firmware missing or outside selected partition size: {path} (maximum {limit:#x})") + print("All firmware sizes fit the detected flash layout.") + return if args.mode == "erase": erase_flash(cli) return