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.
44 lines
2.5 KiB
Python
44 lines
2.5 KiB
Python
# Independent GPT validator (does not share code with gptedit.py)
|
|
import struct, zlib, sys
|
|
DISK_SECTORS = 7634944
|
|
def check(prim_path, back_path):
|
|
P = open(prim_path, "rb").read(); B = open(back_path, "rb").read()
|
|
ok = True
|
|
def fail(m):
|
|
nonlocal ok; ok = False; print(" FAIL:", m)
|
|
def hdr(buf, label, expect_my, expect_alt):
|
|
h = buf
|
|
sig, rev, hsz, hcrc, _, my, alt, fu, lu = struct.unpack("<8sIII4sQQQQ", h[:56])
|
|
guid = h[56:72]; ent_lba, n, esz, ecrc = struct.unpack("<QIII", h[72:92])
|
|
calc = zlib.crc32(h[:16] + b"\0\0\0\0" + h[20:hsz]) & 0xffffffff
|
|
if sig != b"EFI PART": fail(label + " signature")
|
|
if calc != hcrc: fail("%s header CRC stored %08x calc %08x" % (label, hcrc, calc))
|
|
if my != expect_my: fail("%s my_lba %d != %d" % (label, my, expect_my))
|
|
if alt != expect_alt: fail("%s alternate_lba %d != %d" % (label, alt, expect_alt))
|
|
return dict(fu=fu, lu=lu, guid=guid, ent_lba=ent_lba, n=n, esz=esz, ecrc=ecrc)
|
|
hp = hdr(P[512:1024], "primary", 1, DISK_SECTORS - 1)
|
|
hb = hdr(B[32*512:33*512], "backup", DISK_SECTORS - 1, 1)
|
|
ep = P[hp["ent_lba"]*512: hp["ent_lba"]*512 + hp["n"]*hp["esz"]]
|
|
if hb["ent_lba"] != DISK_SECTORS - 33: fail("backup entries LBA %d" % hb["ent_lba"])
|
|
eb = B[:hb["n"]*hb["esz"]]
|
|
for lab, e, h in (("primary", ep, hp), ("backup", eb, hb)):
|
|
c = zlib.crc32(e) & 0xffffffff
|
|
if c != h["ecrc"]: fail("%s entries CRC stored %08x calc %08x" % (lab, h["ecrc"], c))
|
|
if ep != eb: fail("primary and backup entry arrays differ")
|
|
for k in ("fu", "lu", "guid", "n", "esz"):
|
|
if hp[k] != hb[k]: fail("header field %s differs" % k)
|
|
parts = []
|
|
for i in range(hp["n"]):
|
|
e = ep[i*128:(i+1)*128]
|
|
if e[:16] == b"\0"*16: continue
|
|
s, l = struct.unpack("<QQ", e[32:48]); nm = e[56:128].decode("utf-16le").rstrip("\0")
|
|
if not (hp["fu"] <= s <= l <= hp["lu"]): fail("%s outside usable range" % nm)
|
|
parts.append((s, l, nm))
|
|
parts.sort()
|
|
for a, b in zip(parts, parts[1:]):
|
|
if b[0] <= a[1]: fail("overlap %s / %s" % (a[2], b[2]))
|
|
if P[0x1fe:0x200] != b"\x55\xaa" or P[0x1c2] != 0xee: fail("protective MBR")
|
|
print(" %s: %d partitions, usable %d..%d -> %s" % (prim_path, len(parts), hp["fu"], hp["lu"], "OK" if ok else "INVALID"))
|
|
return ok
|
|
for p, b in (("../gpt/gpt-primary-34sectors.bin", "../gpt/gpt-backup-33sectors.bin"), ("aurora-new-gpt-primary-34sectors.bin", "aurora-new-gpt-backup-33sectors.bin")):
|
|
check(p, b)
|