#!/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+17} {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]}')