B7A: QMI DMS time vs VNIIFTRI NTP (DMS = UTC - 0.28 s, sigma 1 ms; NITZ = DMS truncated to 1 s). B7B: a 1970 -> 2026 date -s step is harmless for the modem stack. B7C: aurora-modem probes DMS/NITZ along the start flow and steps CLOCK_REALTIME once at the first valid sample (REG registered/attached), never RTC; background SNTP check (query only) after START OK. 3/3 class-A cold boots PASS (residual +0.04/+0.36/+0.84 s), cache 14fe453a written (B7C_WRITE_VERIFIED) and verified by a normal power-on (V1, +0.26 s). Also publishes the prerequisite R2 (boot-hang / lk eMMC investigation, T4 telnet baseline that B7C builds on) and R3 (autonomous cold boot, NCM loss) material, and extends tools/publish-sanitize.py to r2/, r3/, b7/. Binary images, initramfs, busybox and raw logs stay out (see b7/*/SHA256SUMS).
64 lines
3.2 KiB
Python
64 lines
3.2 KiB
Python
#!/usr/bin/env python3
|
|
# Split UART logs into boots and classify where each boot stopped.
|
|
import sys, re, glob, os, datetime
|
|
STAGES = [
|
|
("sbl_start", r"SBL1, Start"),
|
|
("pm_dev", r"pm_device_init, Start"),
|
|
("flash", r"boot_flash_init, Start"),
|
|
("ddr_params", r"sbl1_ddr_set_params, Start"),
|
|
("preddr_clk", r"Pre_DDR_clock_init, Start"),
|
|
("preddr_done", r"Pre_DDR_clock_init, Delta"),
|
|
("pm_drv", r"pm_driver_init, Start"),
|
|
("batt", r"batt_voltage="),
|
|
("clock_init", r"clock_init, Start"),
|
|
("efs", r"sbl1_efs_handle_cookies"),
|
|
("img_load", r"Image Load, Start"),
|
|
("qsee", r"QSEE Execution"),
|
|
("sbl_end", r"SBL1, End"),
|
|
("lk_uart", r"Android Bootloader - UART_DM"),
|
|
("lk_welcome", r"welcome to lk"),
|
|
("target_init", r"target_init\(\)"),
|
|
("mmc", r"MMC card: "),
|
|
("blkdev", r"block devices:"),
|
|
("fastboot", r"fastboot: processing commands|fastboot_init|USB init ept"),
|
|
("jump", r"Jumping to kernel|booting linux @"),
|
|
("linux", r"Booting Linux on physical CPU"),
|
|
("userspace", r"Run /init|Freeing unused kernel memory"),
|
|
("shell", r"~ # |/ # |aurora-modem"),
|
|
]
|
|
REB = re.compile(r"reboot: Restarting|reboot: Power down|Restarting system|sysrq: |Kernel panic|Internal error|Unable to handle|watchdog|rcu_sched self-detected|BUG:")
|
|
def hts(line):
|
|
m = re.match(r"(\d\d):(\d\d):(\d\d)\.(\d{3}) ", line)
|
|
return (int(m[1])*3600+int(m[2])*60+int(m[3])+int(m[4])/1000) if m else None
|
|
out=[]
|
|
for f in sorted(glob.glob(sys.argv[1]+"/*.log")):
|
|
lines=open(f,errors="replace").read().splitlines()
|
|
boots=[]; cur=None; day=0; last=None
|
|
for i,l in enumerate(lines):
|
|
t=hts(l)
|
|
if t is not None:
|
|
if last is not None and t+day < last-3600: day+=86400
|
|
t+=day; last=t
|
|
if "Format: Log Type" in l or ("SBL1, Start" in l and (cur is None or cur["stage_i"]>0)):
|
|
if cur is None or "Format: Log Type" in l or cur["stage_i"]>0:
|
|
cur={"file":os.path.basename(f),"line":i+1,"t0":t,"stage_i":-1,"stage":"hdr","tlast":t,"batt":None,"events":[],"lastline":l,"ktime":None,"tlinux":None}
|
|
boots.append(cur)
|
|
if cur is None: continue
|
|
for k,(name,rx) in enumerate(STAGES):
|
|
if k>cur["stage_i"] and re.search(rx,l):
|
|
cur["stage_i"]=k; cur["stage"]=name
|
|
if name=="linux": cur["tlinux"]=t
|
|
m=re.search(r"batt_voltage=(\d+)",l)
|
|
if m: cur["batt"]=int(m[1])
|
|
m=re.match(r"\S+ \[\s*(\d+\.\d+)\]",l)
|
|
if m: cur["ktime"]=float(m[1])
|
|
if REB.search(l): cur["events"].append((i+1,l[:140]))
|
|
if t is not None and l[13:].strip(): cur["tlast"]=t; cur["lastline"]=l[:160]; cur["lastno"]=i+1
|
|
for j,b in enumerate(boots):
|
|
b["next_gap"]=(boots[j+1]["t0"]-b["tlast"]) if j+1<len(boots) and boots[j+1]["t0"] and b["tlast"] else None
|
|
b["dur_linux"]=(b["tlast"]-b["tlinux"]) if b["tlinux"] else None
|
|
out+=boots
|
|
for b in out:
|
|
print(f'{b["file"][:34]:34} L{b["line"]:>7} {b["stage"]:11} batt={b["batt"]} ktime={b["ktime"]} linux_dur={None if b["dur_linux"] is None else round(b["dur_linux"],1)} gap_next={None if b["next_gap"] is None else round(b["next_gap"],1)}')
|
|
print(f' last(L{b.get("lastno")}): {b["lastline"]}')
|
|
for e in b["events"][:4]: print(f' ev L{e[0]}: {e[1]}')
|