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

104 lines
6.9 KiB
Markdown

# 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_LOGGING``MEMORY_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
(`0x7e``0x7d 0x5e`, `0x7d``0x7d 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 shell``su`
`setprop 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.
## SIDE note — glink rpmsg teardown is broken upstream (applies to CHANNEL open/close, NOT online)
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
- QCSuper: https://github.com/P1sec/QCSuper (docs/The Diag protocol.md)
- pmtools (check for existing diag helper): https://gitlab.com/sdm845-mainline/pmtools