#!/bin/bash # R2/T3C watcher: READ-ONLY UART (CH340 TX disconnected) - never sends anything to the board. # R2/T2 watcher (480s; board side read-only). Usage: t2-watch.sh # For each SBL1 start: class A/B/C from pm_device_init, furthest stage, PASS/FAIL; Linux -> PON dump over UART (md5-checked); # hang -> wait for auto-reset (max 120 s from start), next start is recorded as a follow-up of the same attempt. L=$1; TAG=$2; TTY=/dev/null # T3C: never write to the board OUT=~/doc/modem/jz08-aurora/logs/r2/t3c; mkdir -p $OUT; RES=$OUT/results.tsv [ -f $RES ] || printf 'attempt\tstart#\tstart\tclass\tsblS\tpm_device\tcdt\tpm_driver\tsbl_end\tsbl_delta\tbatt\tsbl1End\tlk\tlinux\tstage\tresult\tautoreset\trtc\t807\t808\t80a\t80c\t80d\tlk_first\tlk_last\tmmc\tpanic\tnote\n' > $RES lg() { tr -d '\000' < $L; } dumpcmd() { printf '%s\r' "grep -q ' /sys/kernel/debug ' /proc/mounts || mount -t debugfs debugfs /sys/kernel/debug; R=/sys/kernel/debug/regmap/0-00/registers; { dd if=\$R bs=9 skip=2048 count=256 2>/dev/null; dd if=\$R bs=9 skip=2304 count=256 2>/dev/null | grep -v ': 00\$'; } > /tmp/t2.txt; echo T2-BEGIN-$1; sed 's/^/T2R /' /tmp/t2.txt; echo T2-SUM-$1 \$(md5sum < /tmp/t2.txt) up=\$(cut -d' ' -f1 /proc/uptime); echo T2-END-$1" > $TTY } capture() { # id startline for try in 1 2 3; do echo "capture disabled in T3C" >/dev/null; return 1 # for i in $(seq 1 25); do sleep 1; lg | tail -n +$2 | grep -a -q "T2-END-$1-$try" && break; done seg=$(lg | tail -n +$2 | sed -n "/T2-BEGIN-$1-$try/,/T2-END-$1-$try/p") body=$(echo "$seg" | grep -a -o "T2R [0-9a-f]\{4\}: [0-9a-f]\{2\}" | cut -c5-) want=$(echo "$seg" | grep -a -o "T2-SUM-$1-$try [0-9a-f]\{32\}" | awk '{print $2}' | tail -1) got=$(printf '%s\n' "$body" | md5sum | awk '{print $1}') [ -n "$want" ] && [ "$want" = "$got" ] && { printf '%s\n' "$body" > $OUT/$1-regs.txt; return 0; } echo "try $try md5 mismatch want=$want got=$got" >> $OUT/$1-meta.txt done; return 1 } stage_of() { # text on stdin local t; t=$(cat); local s=sbl_start echo "$t" | grep -a -q "Pre_DDR_clock_init, Start" && s=ddr_init echo "$t" | grep -a -q "pm_driver_init" && s=pm_driver echo "$t" | grep -a -q "SBL1, End" && s=sbl1_end echo "$t" | grep -a -q "welcome to lk" && s=lk echo "$t" | grep -a -q "target_init()" && s=lk_target_init echo "$t" | grep -a -q "MMC card:" && s=lk_mmc echo "$t" | grep -a -q -E "Jumping to kernel|booting linux @" && s=lk_jump echo "$t" | grep -a -q "Booting Linux on physical" && s=linux echo "$t" | grep -a -q "EMMC-RO-SUMMARY" && s=linux_init echo $s } pos=$(lg | wc -l); pos=$((pos+1)); k=0 echo "$(date +%T) $TAG: watching $L from line $pos" while true; do n=$(lg | tail -n +$pos | grep -a -n "SBL1, Start" | head -1 | cut -d: -f1) [ -z "$n" ] && { sleep 1; continue; } s=$((pos+n-1)); k=$((k+1)); ts=$(lg | sed -n "${s}p" | cut -c1-8 | tr -d :) sleep 3 sbl=$(lg | sed -n "${s},$((s+40))p") v() { echo "$sbl" | grep -a -o "$1 - *[0-9]* - $2" | awk '{print $3}' | head -1; } sblS=$(v B "SBL1, Start"); pmd=$(v D pm_device_init); cdt=$(v D boot_config_data_table_init); pmdrv=$(v D pm_driver_init) sbld=$(v D "SBL1, Delta"); batt=$(echo "$sbl" | grep -a -o "batt_voltage=[0-9]*" | cut -d= -f2 | head -1) cls=U; [ -n "$pmd" ] && { if [ "$pmd" -lt 11500 ]; then cls=A; elif [ "$pmd" -gt 15000 ]; then cls=C; else cls=B; fi; } id=$TAG-$k-$ts-$cls alive=$(lg | head -n $((s-1)) | tail -n 3000 | awk '{x=substr($0,14); gsub(/\\x[0-9a-f][0-9a-f]/,"",x); if (x ~ /[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]/ && $0 !~ /Format: Log|Log type: B/) p=$0} END{print substr(p,1,12)}') stt=$(lg | sed -n "${s}p" | cut -c1-12) maxoff=$(awk -v a="$alive" -v b="$stt" 'BEGIN{if(a==""){print "?";exit} split(a,x,":");split(b,y,":");printf "%.1f",(y[1]*3600+y[2]*60+y[3])-(x[1]*3600+x[2]*60+x[3])}') echo "start line $s time $ts sblS=$sblS pm_device_init=$pmd cdt=$cdt pm_driver=$pmdrv sbl_delta=$sbld batt=$batt class=$cls" > $OUT/$id-meta.txt echo "$(date +%T) start #$k $id" ok=0; restarted=0 for i in $(seq 1 120); do sleep 1 seg=$(lg | tail -n +$((s+1))) echo "$seg" | grep -a -q "SBL1, Start" && { restarted=1; break; } echo "$seg" | grep -a -q "EMMC-RO-SUMMARY" && { ok=1; break; } done segend=$(lg | tail -n +$s | awk 'NR>1 && /SBL1, Start/{exit} {print}') stage=$(echo "$segend" | stage_of); last=$(echo "$segend" | grep -a -v "^.\{13\} *$" | tail -1 | cut -c1-12) pos=$((s+1)) sblE=$(v B "SBL1, End") f_end=no; f_lk=no; f_lx=no echo "$segend" | grep -a -q "SBL1, End" && f_end=yes echo "$segend" | grep -a -q "welcome to lk" && f_lk=yes echo "$segend" | grep -a -q "Booting Linux on physical" && f_lx=yes rtc=-; r7=-; r8=-; ra=-; rc=-; rd=-; ar=no lkseg=$(echo "$segend" | awk '/Android Bootloader - UART_DM|welcome to lk/{on=1} /Booting Linux on physical|Format: Log Type|Log type: B/{on=0} on') echo "$lkseg" > $OUT/$id-lk.txt lkfirst=$(echo "$lkseg" | grep -a -v "^.\{13\} *$" | head -1 | cut -c14-80) lklast=$(echo "$lkseg" | grep -a -v "^.\{13\} *$" | grep -a -v -e " r[0-9][0-9]* *0x" -e "usp 0x" -e "spsr 0x" -e " fiq r13" -e " irq r13" -e " svc r13" -e " und r13" -e " abt r13" -e " sys r13" | tail -1 | cut -c14-100) mmc=$(echo "$lkseg" | grep -a -i -E "mmc|sdc|sdhc|card|cid|ocr|cmd8" | cut -c14- | sed 's/^\[[0-9]*\] *//' | tr '\t' ' ' | paste -sd'|' | cut -c1-400) pan=$(echo "$lkseg" | grep -a -i -E "panic|assert|abort|fault" | head -2 | cut -c14- | tr '\t' ' ' | paste -sd'|' | cut -c1-200) [ -n "$pan" ] && echo "$stage" | grep -q "^lk" && stage=lk_panic [ -z "$lkfirst" ] && lkfirst=-; [ -z "$lklast" ] && lklast=-; [ -z "$mmc" ] && mmc=-; [ -z "$pan" ] && pan=- if [ $ok = 1 ]; then sleep 12 if lg | tail -n +$((s+1)) | grep -a -q "SBL1, Start"; then res=FAIL; note="restart after Linux init" else res=PASS; note="read-only: no PON capture (TX disconnected)"; fi rtc=$(lg | tail -n +$s | grep -a -o "setting system clock to [^(]*([0-9]*)" | head -1 | grep -o "([0-9]*)" | tr -d "()") junk=$(lg | tail -n +$s | grep -a -c -E "sh: .*(not found|syntax error|Permission denied)") [ "$junk" -gt 0 ] && note="$note; WARNING: $junk junk-input shell errors on console" elif [ $restarted = 1 ]; then lastt=$(echo "$segend" | grep -a -E "^.{13}.*[A-Za-z0-9]{3}" | grep -a -v -E "Format: Log Type|Log type: B" | tail -1 | cut -c1-12) nt=$(lg | tail -n +$((s+1)) | grep -a -m1 "SBL1, Start" | cut -c1-12) lat=$(awk -v a="$lastt" -v b="$nt" 'BEGIN{split(a,x,":");split(b,y,":");printf "%.1f",(y[1]*3600+y[2]*60+y[3])-(x[1]*3600+x[2]*60+x[3])}') ar="yes ${lat}s"; res=FAIL; note="hang at $stage (last output $lastt), auto-reset -> next start #$((k+1))" else res=FAIL; note="hang at $stage, no reset within 120 s (last output $last)"; fi [ $k -gt 1 ] && note="FOLLOW-UP start after auto-reset; $note" [ $k = 1 ] && note="last-alive->start ${maxoff}s (off-time upper bound incl. 5 s batt->USB); $note" printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' $TAG $k $ts $cls "$sblS" "$pmd" "$cdt" "$pmdrv" "$sblE" "$sbld" "$batt" $f_end $f_lk $f_lx $stage $res "$ar" "$rtc" "$r7" "$r8" "$ra" "$rc" "$rd" "$lkfirst" "$lklast" "$mmc" "$pan" "$note" >> $RES echo "$(date +%T) #$k $id -> $stage $res autoreset=$ar rtc=$rtc ($note)" [ $res = PASS ] && { echo "$(date +%T) $TAG DONE"; exit 0; } [ $restarted = 0 ] && { echo "$(date +%T) $TAG STUCK (needs power cycle)"; exit 0; } done