ورک فلو فلش rootfs
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
name: Transfer, Write and Verify RootFS
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
rootfs_size:
|
||||
description: 'Actual RootFS partition size in bytes (decimal or 0x-prefixed hex)'
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
rootfs-transfer:
|
||||
runs-on: serial-runner
|
||||
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Transfer RootFS, write SPI flash and verify read-back
|
||||
env:
|
||||
ROOTFS_PARTITION_SIZE: ${{ inputs.rootfs_size }}
|
||||
run: |
|
||||
/usr/bin/python3 scripts/serial_command.py transfer-rootfs --rootfs-size "$ROOTFS_PARTITION_SIZE"
|
||||
@@ -19,3 +19,11 @@ For the Kernel workflow, place `zImage` here. It uses maximum size
|
||||
0x500000, RAM address 0x42000000 and flash offset 0x310000. The first
|
||||
64 bytes are checked against the local file; full read-back comparison
|
||||
uses 0x42800000. The same stale-filesize and transfer checks apply.
|
||||
|
||||
For the RootFS workflow, place `rootfs.squashfs` here and supply the actual
|
||||
RootFS partition size in bytes as the required `rootfs_size` workflow input
|
||||
(decimal or 0x-prefixed hex). Determine it from the real board partition map;
|
||||
the workflow does not infer it from flash capacity or a presumed layout.
|
||||
It uses RAM 0x41000000, flash offset 0x810000, a 64-byte header comparison,
|
||||
and read-back RAM 0x42800000. Files must fit the specified partition and
|
||||
the non-overlapping RAM buffers (maximum 0x1800000 bytes).
|
||||
|
||||
@@ -82,15 +82,21 @@ class UBoot:
|
||||
return output
|
||||
|
||||
|
||||
def transfer(cli, firmware, *, dtb=False, kernel=False):
|
||||
address = 0x41000000 if dtb else 0x42000000
|
||||
def transfer(cli, firmware, *, dtb=False, kernel=False, rootfs=False, rootfs_size=None):
|
||||
address = 0x41000000 if (dtb or rootfs) else 0x42000000
|
||||
offset = 0x310000 if kernel else (0x200000 if dtb else 0)
|
||||
limit = 0x500000 if kernel else (0x110000 if dtb else 0x200000)
|
||||
dump_size = 64 if kernel else 32
|
||||
filename = "zImage" if kernel else ("sun8i-v3s-licheepi-zero-dock.dtb" if dtb else "u-boot-sunxi-with-spl.bin")
|
||||
if rootfs:
|
||||
if rootfs_size is None or rootfs_size < 64:
|
||||
raise RuntimeError("Actual RootFS partition size is required (at least 64 bytes)")
|
||||
offset, limit, dump_size, filename = 0x810000, rootfs_size, 64, "rootfs.squashfs"
|
||||
image = firmware.read_bytes()
|
||||
if not dump_size <= len(image) <= limit:
|
||||
raise RuntimeError(f"Firmware size must be between {dump_size} and {limit:#x} bytes")
|
||||
if rootfs and len(image) > 0x1800000:
|
||||
raise RuntimeError("RootFS exceeds the non-overlapping RAM buffer capacity (0x1800000)")
|
||||
# Invalidate any previous transfer length before attempting a new transfer.
|
||||
cli.command("setenv filesize")
|
||||
output = cli.command(
|
||||
@@ -136,14 +142,17 @@ def transfer(cli, firmware, *, dtb=False, kernel=False):
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("mode", choices=("check", "configure", "transfer", "transfer-dtb", "transfer-kernel"), default="check", nargs="?")
|
||||
parser.add_argument("mode", choices=("check", "configure", "transfer", "transfer-dtb", "transfer-kernel", "transfer-rootfs"), 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)")
|
||||
args = parser.parse_args()
|
||||
if args.mode == "transfer-rootfs" and (args.rootfs_size is None or args.rootfs_size < 64):
|
||||
parser.error("--rootfs-size must specify the actual RootFS partition size (at least 64 bytes)")
|
||||
if args.firmware is None:
|
||||
filename = "zImage" if args.mode == "transfer-kernel" else ("sun8i-v3s-licheepi-zero-dock.dtb" if args.mode == "transfer-dtb" else "u-boot-sunxi-with-spl.bin")
|
||||
filename = "rootfs.squashfs" if args.mode == "transfer-rootfs" else "zImage" if args.mode == "transfer-kernel" else ("sun8i-v3s-licheepi-zero-dock.dtb" if args.mode == "transfer-dtb" else "u-boot-sunxi-with-spl.bin")
|
||||
args.firmware = Path(__file__).resolve().parent.parent / "firmware" / filename
|
||||
if args.mode in ("transfer", "transfer-dtb", "transfer-kernel") and not args.firmware.is_file():
|
||||
if args.mode in ("transfer", "transfer-dtb", "transfer-kernel", "transfer-rootfs") and not args.firmware.is_file():
|
||||
raise RuntimeError("Firmware file not found: " + str(args.firmware))
|
||||
# Shared by both workflows: fail rather than interleave serial commands.
|
||||
with open("/tmp/uboot-serial.lock", "w") as lock:
|
||||
@@ -153,8 +162,8 @@ def main():
|
||||
cli.detect()
|
||||
if args.mode == "check":
|
||||
return
|
||||
if args.mode in ("transfer", "transfer-dtb", "transfer-kernel"):
|
||||
transfer(cli, args.firmware, dtb=args.mode == "transfer-dtb", kernel=args.mode == "transfer-kernel")
|
||||
if args.mode in ("transfer", "transfer-dtb", "transfer-kernel", "transfer-rootfs"):
|
||||
transfer(cli, args.firmware, dtb=args.mode == "transfer-dtb", kernel=args.mode == "transfer-kernel", rootfs=args.mode == "transfer-rootfs", rootfs_size=args.rootfs_size)
|
||||
return
|
||||
cli.command("version", r"^U-Boot \d")
|
||||
cli.command(
|
||||
|
||||
مرجع در شماره جدید
مسدود کردن کاربر