Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/saf/device/evidence/diag_capture.md
Fimeg bde961c6f2 saf: one spine — device, state, and work under the index
PAF becomes saf/device (history kept), STATE.md dissolves
into saf/state.md with the dated era archived, the substrate
SAF moves up from souveraine, and every agreement points at
saf/INDEX.md and nowhere else. one map, nothing to remember
2026-08-18 09:47:30 -04:00

6.9 KiB

PAF · DIAG capture runbook (Route B instrument)

Goal: get the modem's OWN view of RF-init — why it never self-completes, parks offline, and refuses online (DeviceNotReady 52). Everything so far is QMI reporting a refusal code; DIAG (QCDM/DM) gives the modem's internal F3 debug messages, radio frames, and NV/EFS state. This is the byte-for-byte trace every prior frontier (#5/#7/#8) named as the missing piece.

Why DIAG (vs the coredump path)

  • F3/DM debug messages = the modem narrating its RF/NAS/MCFG init in its own words. Richer than a remoteproc coredump/SSR reason.
  • NV item + EFS read/write over DIAG = Route B's EFS/NV diff (GLM thread #2) at the authoritative source, and the write path for mcfg_autoselect_by_uim / power-up operating mode.
  • The decisive comparison: run the SAME tool on BOTH OSes against the SAME modem silicon and diff.

Channel facts (confirmed)

  • DIAG is exposed on Android via /dev/diag, created by the diagchar kernel module (root).
  • Enable frame capture: DIAG_IOCTL_SWITCH_LOGGINGMEMORY_DEVICE_MODE = 2; check DIAG_IOCTL_REMOTE_DEV for the extra device_type byte.
  • Packet framing: cmd_code(1B) + payload + CRC16-CCITT(2B) + 0x7e, HDLC escaping (0x7e0x7d 0x5e, 0x7d0x7d 0x5d).
  • Message classes: DIAG_LOG_F (binary log packets / radio frames), DIAG_MSG_F / DIAG_EXT_MSG_F (F3 debug strings — the narration we want). NV/EFS/L1-3 commands supported.
  • Tool: QCSuper (P1sec, open source) for frame + F3 capture → pcap/GSMTAP. For arbitrary NV item read/write, a raw DIAG client (libqcdm-style framer, or QCSuper's diag layer directly).
  • CHECK FIRST: sdm845-mainline/pmtools may already ship a diag/modem helper — look before reinventing the framer.

Side A — Android (slot B, rooted): the WORKING reference [HIGH VALUE — never captured]

diagchar + /dev/diag are present on the downstream Android kernel. Two ways in:

  • USB-DIAG (exposes a serial/COM port): adb root; adb shellsusetprop sys.usb.config diag,serial_cdev,rmnet_gsi,adb (XDA-confirmed on Pixel 3). Our ledger saw this HAL-revert to adb-only on this LineageOS build — RETRY it; if it reverts, use local.
  • Local /dev/diag (reliable fallback): run the client on-device over adb, not USB-DIAG.
  1. adb root; adb shell ls -l /dev/diag — confirm node exists.
  2. Push/run QCSuper on-device (or proxy /dev/diag over adb). Start F3 + frame capture.
  3. Trigger a clean offline→online: airplane mode OFF→ON (we already have this at QCRIL-function granularity in android-capture-20260620/; DIAG gets it at message/F3 granularity).
  4. Save: F3 stream + radio frames spanning the transition. This is the modem self-onlining at its own RF-init — the thing pmOS never reaches.
  5. While here, DIAG-read the NV/EFS state the working modem holds:
    • power-up operating mode NV
    • mcfg_autoselect_by_uim
    • RF-calibration NV / QCN region (Confirm exact NV item indices from the modem's NV table / QCSuper — do NOT guess indices.)

Output → android-capture-YYYYMMDD/diag/.

Side B — pmOS (slot A, mainline): the FAILURE side [verify availability first]

diagchar is a downstream module; mainline SDM845 does NOT ship it. So /dev/diag may be absent. Determine the transport before assuming symmetry:

  1. ls -l /dev/diag* ; dmesg | grep -i diag ; zcat /proc/config.gz | grep -i diag (or check the built kernel config) ; look for a glink/rpmsg channel named DIAG.
  2. If a DIAG transport exists → run QCSuper, attempt --dms-set-operating-mode=online, capture the F3 stream of the FAILED RF-init. Diff F3 against Side A around the offline→online point — the first divergence is the answer.
  3. If NO DIAG transport on mainline → fall back to GLM thread #1: remoteproc coredump/SSR reason + tqftpserv/rmtfs request trace during the failed online. Diff that against Side A's DIAG F3. (Retry-safe: online attempts do NOT poison the modem — the old "one-shot per boot" rule is disproven. A QMI Set Operating Mode = RESET (4) cleanly reinitializes it without reboot. Retry freely. See HANDOFF.md CORRECTIONS.)

What we're diffing for

KEY: a static NV/QCN diff between the two OSes will be NULL. modemst1/2 + fsg/fsc + persist are on UNSLOTTED partitions → the modem reads BYTE-IDENTICAL persisted EFS/NV/cal on both Android and pmOS (ledger L83: Android-primed EFS → still fails). The modem has no separate flash; its NV lives in that shared EFS. So a QPST QCN backup / NV-item dump will read the same bytes on both sides — it will NOT reveal the delta. The difference is necessarily RUNTIME behavior, which is exactly why the F3 stream (not a static snapshot) is the instrument:

  • The F3 line(s) where Android's modem advances RF-init past the point pmOS's stalls.
  • Whether the working modem boots into LPM and flips LPM→online, vs pmOS sitting in offline (mode 3) — and what in the F3 stream gates that state.
  • Whether the working modem's online even TOUCHES NV/PDC (frontier #4 says steady-state Android is verify-only) — if it doesn't, the gate is pure firmware-state/timing the AP can't feed.

(NV reads in Side A step 5 are still worth doing ONCE — to confirm the shared-EFS assumption and record the working values — but expect them equal to pmOS. Don't build a Route B fix around a static NV diff until F3 shows the modem actually consuming that item at init.)

Tools reality (we're on Arch, not Windows)

  • QPST / QXDM are Windows-only proprietary. QPST = QCN backup/restore; QXDM = deep F3 logging. Given the shared-EFS point above, QPST's QCN backup buys little here.
  • QCSuper (Linux, open) is the path for F3 + frame capture. For raw NV item read/write, a libqcdm-style framer or QCSuper's diag layer. Check pmtools first.

Dynamically opening/closing glink rpmsg channels is documented as broken on the upstreaming list (the wwan_remove_port/rpmsg_wwan_ctrl 614s hung_task seen on op6t). This is a real risk when creating/tearing down a glink channel (e.g. opening a raw DIAG rpmsg endpoint). It is NOT the "one failed online poisons the modem" rule that used to be here — that rule is disproven: a plain --dms-set-operating-mode=online is an ordinary QMI message on the existing IPCRTR transport, it does not open a glink channel, and it is retry-safe (RESET reinitializes). Keep the caution for raw glink channel-open probes only. An AT read of the modem's own reason (+CEER, +CFUN?) has no free path anyway: QMI service 8 is AT-forwarding, not AT-execution (see qrtr_tools_reference 2026-07-02), and a raw glink AT port is exactly the channel-open that this note warns about.

Refs