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
104 lines
6.9 KiB
Markdown
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
|