uzbek-plus/tools/verify.py
q 105bef466a Project Aurora: mainline ARM64 Linux on JZ08AU (MSM8916) LTE modem
Sanitized research log, build/reproducibility docs, DTS, kernel configs,
patches, initramfs sources, bootchain migration plans and test logs.
B5 direct boot PASS; B6 modem lifecycle in progress.
No dumps, NV/EFS, vendor firmware or device identifiers included.
2026-09-30 17:23:18 +03:00

47 lines
2.8 KiB
Python

#!/usr/bin/env python3
# Parse primary+backup GPT from full image, verify every partition dump against it,
# write MANIFEST.md / manifest.tsv, extract GPT blobs.
import struct, hashlib, zlib, os, sys
W = os.path.expanduser("~/doc/modem/jz08-aurora")
full = f"{W}/dumps/full-emmc.bin"
f = open(full, "rb"); S = 512
size = os.path.getsize(full); nsec = size // S
def rd(lba, n=1): f.seek(lba*S); return f.read(n*S)
def hdr(lba):
h = rd(lba)
sig, rev, hs, crc, _, cur, bak, first, last, guid, elba, n, esz, ecrc = struct.unpack_from("<8sIII4sQQQQ16sQIII", h)
hh = bytearray(h[:hs]); hh[16:20] = b"\0"*4
ents = rd(elba, (n*esz+S-1)//S)[:n*esz]
return dict(sig=sig, cur=cur, bak=bak, first=first, last=last, elba=elba, n=n, esz=esz,
hcrc_ok=zlib.crc32(hh) == crc, ecrc_ok=zlib.crc32(ents) == ecrc, ents=ents)
p = hdr(1); b = hdr(p["bak"])
out = [f"full image: {size} bytes, {nsec} sectors, sha256 {hashlib.sha256(open(full,'rb').read()).hexdigest()}"]
for nm, h in (("primary", p), ("backup", b)):
out.append(f"{nm}: sig={h['sig']} cur={h['cur']} bak={h['bak']} first={h['first']} last={h['last']} entries@{h['elba']} n={h['n']} hdrCRC={'OK' if h['hcrc_ok'] else 'BAD'} entCRC={'OK' if h['ecrc_ok'] else 'BAD'}")
out.append(f"primary entries == backup entries: {p['ents'] == b['ents']}; backup hdr at last LBA: {p['bak'] == nsec-1}")
open(f"{W}/gpt/gpt-primary-34sectors.bin", "wb").write(rd(0, 34))
open(f"{W}/gpt/gpt-backup-33sectors.bin", "wb").write(rd(nsec-33, 33))
rows = []; ok = True
for i in range(p["n"]):
e = p["ents"][i*p["esz"]:(i+1)*p["esz"]]
if e[:16] == b"\0"*16: continue
first, last, attr = struct.unpack_from("<QQQ", e, 32)
name = e[56:128].decode("utf-16le").rstrip("\0")
cnt = last-first+1; bsz = cnt*S
fh = hashlib.sha256(rd(first, cnt)).hexdigest()
pf = f"{W}/partitions/{name}.bin"
if os.path.exists(pf):
psz = os.path.getsize(pf); ph = hashlib.sha256(open(pf, "rb").read()).hexdigest()
st = "MATCH" if (psz == bsz and ph == fh) else f"DIFF(size {psz} vs {bsz})"
else: st = "MISSING"
if st != "MATCH": ok = False
rows.append((i+1, name, first, cnt, bsz, f"{attr:#018x}", fh, st))
with open(f"{W}/manifest.tsv", "w") as m:
m.write("idx\tname\tstart_lba\tsectors\tbytes\tattrs\tsha256\trl_vs_rf\n")
for r in rows: m.write("\t".join(map(str, r)) + "\n")
with open(f"{W}/MANIFEST.md", "w") as m:
m.write("# Aurora eMMC manifest (from full-emmc.bin GPT)\n\n```\n" + "\n".join(out) + "\n```\n\n")
m.write("| # | name | start LBA | sectors | bytes | attrs | SHA256 | rl vs rf |\n|---|---|---|---|---|---|---|---|\n")
for r in rows: m.write("| " + " | ".join(map(str, r)) + " |\n")
m.write(f"\nALL PARTITIONS VERIFIED: {ok}\n")
print("\n".join(out)); print("ALL OK" if ok else "PROBLEMS"); [print(*r[:5], r[7]) for r in rows]