2026-08-20 17:09:43 +00:00
|
|
|
|
# Findings log
|
|
|
|
|
|
|
|
|
|
|
|
One entry per claim. Every claim carries evidence (kernel source reference or
|
|
|
|
|
|
blob offset + observed bytes). Claims that cannot be evidenced are registered
|
|
|
|
|
|
in the Unknowns section instead. Blobs referenced by filename are the
|
|
|
|
|
|
linux-firmware copies listed in `manifest.json` (SHA-256 TBD in fixtures).
|
|
|
|
|
|
|
|
|
|
|
|
Blobs observed: mt7981/mt7915/mt7916/mt7986 × {wm, wa, rom_patch}
|
|
|
|
|
|
(linux-firmware snapshot 2026-04-20, Debian).
|
|
|
|
|
|
|
|
|
|
|
|
## F1 — Connac2 RAM container layout
|
|
|
|
|
|
|
|
|
|
|
|
`[region data, packed from offset 0 in table order][optional hidden trailer
|
|
|
|
|
|
(see F2)][n_region × 40-byte region table][36-byte trailer at EOF]`
|
|
|
|
|
|
|
|
|
|
|
|
Evidence: `mt76_connac_mcu.c` `mt76_connac2_load_ram()` +
|
|
|
|
|
|
`mt76_connac2_send_ram()` (region data streamed sequentially from offset 0;
|
|
|
|
|
|
table and trailer located from EOF); `mt76_connac_mcu.h`
|
|
|
|
|
|
`struct mt76_connac2_fw_region` / `_fw_trailer`. Confirmed by exact layout
|
|
|
|
|
|
match on 8 RAM blobs (sum(region.len) + table + trailer (+ hidden trailer) ==
|
|
|
|
|
|
file size).
|
|
|
|
|
|
|
|
|
|
|
|
Region fields: `decomp_crc/decomp_len/decomp_blk_sz` (MCU-side decompression,
|
|
|
|
|
|
unused when decomp_len==0 — all observed blobs), `addr`, `len`,
|
|
|
|
|
|
`feature_set`, `type`.
|
|
|
|
|
|
|
|
|
|
|
|
## F2 — Hidden second trailer carries the full build string
|
|
|
|
|
|
|
|
|
|
|
|
Between region data and the kernel-parsed table sits a trailer the upstream
|
|
|
|
|
|
loader never reads. WM blobs: 100 bytes; WA blobs: 36 bytes (no string).
|
|
|
|
|
|
Observed family-wide (all 4 chips).
|
|
|
|
|
|
|
|
|
|
|
|
WM hidden trailer = 16×'#' + `40 00 00 00` + 1-byte string length + flags +
|
|
|
|
|
|
full build string + '#'-padding. Recovered strings:
|
|
|
|
|
|
|
|
|
|
|
|
- mt7981_wm: `t-neptune-main-mt7915-1953-MT7981_MP2111_IMP-20240823161204`
|
|
|
|
|
|
- mt7916_wm: `t-neptune-main-mt7915-1953-MT7916_MP2111_IMP-20240823170147`
|
|
|
|
|
|
- mt7986_wm: `t-neptune-main-mt7915-1953-MT7986_MP2111_IMP-20240823160608`
|
|
|
|
|
|
- mt7915_wm: `t-neptune-mp-mt7915-2045-MT7915_MP_7_4_2045-20220929103802`
|
|
|
|
|
|
|
|
|
|
|
|
Significance: the kernel-visible trailer's `fw_ver[10]` is stripped
|
|
|
|
|
|
(`____000000` WM / `DEV_000000` WA); the hidden trailer restores branch
|
|
|
|
|
|
("main"/"mp"), internal build number (1953/2045), MP tag, and build
|
|
|
|
|
|
timestamp. This is the version metadata the changelog tooling keys on.
|
|
|
|
|
|
|
|
|
|
|
|
Evidence: bytes at offset `sum(region.len)` in each blob (see
|
|
|
|
|
|
`manifest.json` → `hidden_trailer.raw_head`).
|
|
|
|
|
|
|
|
|
|
|
|
## F3 — region `type` is a content tag used by some loaders
|
|
|
|
|
|
|
|
|
|
|
|
All parsed mt79-family blobs: `type == 0` (`FW_TYPE_DEFAULT`). It is not
|
|
|
|
|
|
ignored upstream: mt7921's loader selects
|
|
|
|
|
|
`feature_set & FW_FEATURE_NON_DL && type == FW_TYPE_CLC` regions as
|
|
|
|
|
|
country/location-calibration data instead of downloading them to the MCU.
|
|
|
|
|
|
|
|
|
|
|
|
Evidence: `mt7921/mcu.c` CLC handling; `FW_TYPE_CLC` definition in
|
|
|
|
|
|
`mt76_connac_mcu.h`.
|
|
|
|
|
|
|
|
|
|
|
|
## F4 — Patch container format
|
|
|
|
|
|
|
|
|
|
|
|
92-byte big-endian header (16-byte build date, 4-byte platform tag —
|
|
|
|
|
|
"ALPS" on all four — hw_sw_ver, patch_ver, checksum, descriptor), 64-byte BE
|
|
|
|
|
|
section table, plaintext section data at explicit offsets. All observed
|
|
|
|
|
|
patch sections: `enc_type == 0` (plaintext).
|
|
|
|
|
|
|
|
|
|
|
|
Evidence: `mt76_connac2_load_patch()` + `struct mt76_connac2_patch_hdr/_sec`
|
|
|
|
|
|
in `mt76_connac_mcu.h`; exact parse of 4 patch blobs.
|
|
|
|
|
|
|
2026-08-20 17:11:06 +00:00
|
|
|
|
Section counts: mt7915 patch = 2 sections, all others = 1; section `type`
|
|
|
|
|
|
constant `0x30002` on every observed section (loader downloads all sections
|
|
|
|
|
|
regardless; field semantics otherwise unobserved).
|
|
|
|
|
|
|
2026-08-20 17:09:43 +00:00
|
|
|
|
## Unknowns registry
|
|
|
|
|
|
|
|
|
|
|
|
- **U1 — `feature_set` bit 7 (0x80):** observed only on WM regions at
|
|
|
|
|
|
`0xf0xxxxxx` addresses (mt7981 r7–r10, mt7986 equivalents). Upstream
|
|
|
|
|
|
defines bits 0–6 only; vendor-SDK search found no definition (2026-08-20).
|
|
|
|
|
|
Correlation with address family noted; semantics undetermined. May relate
|
|
|
|
|
|
to a second download destination or content class.
|
|
|
|
|
|
- **U2 — hidden-trailer non-string fields:** the `40 00 00 00` and flag
|
|
|
|
|
|
bytes before/around the string (F2) are uninterpreted.
|
|
|
|
|
|
- **U3 — WO container:** `mt7981_wo.bin` uses the mtk_wed loader
|
|
|
|
|
|
(`mtk_wed_mcu.c`), a different format; not yet parsed.
|
|
|
|
|
|
|
|
|
|
|
|
## Related verified facts
|
|
|
|
|
|
|
|
|
|
|
|
- NDS32LE target: `GCC: (2018-10-23_nds32le-elf-mculib-v3) 4.9.4` string in
|
|
|
|
|
|
mt7981_wa region data; FreeRTOS v10.0.0 + `portable/GCC/NDS32/port.c`
|
|
|
|
|
|
strings in mt7981_wo.
|
|
|
|
|
|
- No per-region encryption in any observed blob (`FW_FEATURE_SET_ENCRYPT`
|
|
|
|
|
|
clear; patch `enc_type == 0`). Optional protocol support exists in the
|
|
|
|
|
|
loader (key from EFUSE path) but is not exercised by shipped images.
|