#!/usr/bin/env python3 """Pack the bundled binaries into the boot capsule (boot/system.img) — the single file the EFI loader reads in one sequential pass, which is the only shape firmware file I/O is fast at (a per-file tree walk measured minutes on real firmware). The format is the v2 initial_ramdisk (system/initial-ramdisk.zig): entries named by full FHS path, so the running system is identical whether the loader read the capsule or walked the tree. Usage: pack-system-image.py [ ]... Layout (little-endian): Header{magic "DNR2", count}, Entry{name[64], offset, len}*N, blobs. """ import struct import sys MAGIC = 0x32524E44 # "DNR2" HEADER = struct.Struct(" int: out_path = sys.argv[1] rest = sys.argv[2:] if len(rest) % 2 != 0: sys.stderr.write("usage: pack-system-image.py [ ]...\n") return 2 items = [(rest[i], rest[i + 1]) for i in range(0, len(rest), 2)] table_end = HEADER.size + len(items) * ENTRY.size entries = b"" blobs = [] offset = table_end for path, source in items: name = path if path.startswith("/") else "/" + path encoded = name.encode("ascii") if len(encoded) > 63: sys.stderr.write(f"pack-system-image: path too long (>63): {name}\n") return 2 with open(source, "rb") as f: data = f.read() entries += ENTRY.pack(encoded, offset, len(data)) blobs.append(data) offset += len(data) with open(out_path, "wb") as f: f.write(HEADER.pack(MAGIC, len(items))) f.write(entries) for blob in blobs: f.write(blob) return 0 if __name__ == "__main__": sys.exit(main())