11.1. ADSP and CDSP firmware

modem_a and dsp_a hold the non-HLOS Hexagon-DSP firmware. Both partitions are filesystems, not bare ELFs — the partition format is FAT16/ext4 (below), not the first embedded ELF at modem_a 0x4b000:

  • modem_a (195 MB) is a FAT16 filesystem (MSDOS5.0 / FAT16 boot sector at offset 0, 0x55aa at 0x1fe) — the Qualcomm ``/firmware`` peripheral-image repository. It holds the split-loaded MBN images (image/<subsys>.mdt = ELF header + program table + type-2 HASH segment, with the payload in sibling .bNN files) for modem/MPSS, adsp, cdsp, npu, venus (video), plus WLAN (wlanmdsp.mbn), a set of QSEE trustlets (qwes, soter64, smplap32/64, gptest, featenabler, rtic, and ``widevine.mbn`` — the DRM TA; cross-ref Secure world and coprocessors (TZ, HYP, trustlets)), and the modem_pr/ carrier tree (139 mcfg_sw + 4 mcfg_hw + 12 QMI .so). verinfo/ver_info.txt records the meta-build ``Bitra.LA.3.2.1-00040-STD.PROD-2`` (2024-08-20).

  • dsp_a (64 MB) is an ext4 filesystem (magic 0xef53 at 0x438, volume label dsp) — the ``/dsp`` mount. It holds FastRPC user-PD dynamic libraries (adsp/ audio codecs + fluence + sensor skels; cdsp/ compute/VPP/HTA skels + libc++), not DSP boot firmware. So the CDSP/ADSP boot images live in modem_a; dsp_a only carries their loadable user-space libraries.

  • core_nhlos_a (170 MB) is a second FAT16 image/``+``verinfo/ pack, byte-identical boot sector to modem_a, carrying the production modem (MPSS.HI.2.5.1-01188-BITRA_GEN_PACK-1) and the WLAN firmware — whereas modem_a embeds a test modem variant (MPSS.HI.2.5.1-01197-BITRA_GENNM_TEST-1); the two partitions carry different MPSS builds.

No separate SLPI subsystem exists — there is no slpi.* image in modem_a and no slpi/ tree in dsp_a; on this SM6350 build the sensor stack runs on the ADSP island (the SENSOR_IMG_bitra.adsp map and sns_bring_to_ear.so under dsp_a:adsp/). Full per-file inventory and program-header dumps: artifacts/re_static/item6_modem_dsp_inventory.txt.

This page catalogs the human-readable config/manifest strings and the container structure; no code was executed.

modem_a is not an ADSP-only image — it is a multi-subsystem non-HLOS bundle. It embeds four subsystem metadata blocks, each with its own QC_IMAGE_VERSION_STRING + IMAGE_VARIANT_STRING: ADSP.VT.5.6-00702.1 (bitra.adsp.prodQ), CDSP.VT.2.6-00570.1 (bitra.cdsp.prodQ), MPSS.HI.2.5.1-01197-BITRA_GENNM_TEST (bitra.gennm.testQ), and NPU.FW.2.3-00083 (bitra.npu.prodQ). String census confirms both the ADSP sensor/audio code (sns_ ×2178, adsp_proc ×182) and real MPSS baseband code (wcdma_ ×414, rrc_ ×354, nas_ ×299, qmi_ ×305, policyman ×173, plus modem_proc/… build paths) are present. The MPSS baseband is dormant, not absent: this is a Wi-Fi-only device with no cellular RF front end (see the RF-leftover notes below), so the flashed generic-Bitra modem stack is never brought up. The sibling core_nhlos_a partition is a second non-HLOS pack (MPSS.HI.2.5.1-01188-BITRA_GEN_PACK, bitra.gen.prodQ) that additionally carries the WLAN firmwareWLAN.HL.3.3.1-01884-QCAHLSWMTPLZ-1 — i.e. the Wi-Fi radio firmware this e-reader actually uses. WLAN (Helium) is the WLAN side of the WCN3990 combo; its Bluetooth/FM side (Cherokee) firmware lives in the bluetooth_a partition (Bluetooth / FM controller firmware (WCN3990 “Cherokee”)).

11.1.1. ADSP (within modem_a)

ADSP.VT.5.6-00702.1-BITRA-1, built 2023-08-24 (CRMBuilds/ADSP.VT.5.6-00702.1-BITRA-1_20230824_021423), builder xcq, tree sm6350_androidT_rom, variant bitra.adsp.prodQ. Runs the SEE / SSC sensor stack + AVS audio stack + sensor/PMIC/thermal proxies. This is the ADSP sub-image of the modem_a bundle described above (which also embeds the MPSS, CDSP, and NPU sub-images).

11.1.1.1. Sensors (SEE — Sensors Execution Environment)

  • Physical IMU: LSM6DST (STMicro 6-axis accel+gyro) — the one identified sensor part (drives auto-rotate / orientation). Consistent with the DTB’s minimal sensor set (DTBO overlays adds a Hall sensor + Wacom via the SoC/overlay side, not ADSP).

  • Sensor framework internals: sns_* heap/instance manager, protection domain sensor_pd (subdomain":"sensor_pd"), virtual sensors motion_detect and sns_bring_to_ear.so (proximity/gesture), -sensor_name= / -sensor= registry plumbing.

  • Sensor power/thermal proxies: /node/pmic/client/sensor_vdd[/_2], sensor_vddio[/_2], sensor_dsp_proxy, /therm/sensor — sensors GDSC power-domain gating (Disabling Sensors GDSC), LPI/LPR Registry.

11.1.1.2. Audio (AVS)

  • Bluetooth/stream codecs: AAC, aptX, SBC, plus CELT (Xiph libcelt — Opus/CELT).

  • Voice/ML: EAI ML/NN algorithms (eai_lib/ml_common/.../nn/{layer,network}_init) — on-DSP neural-net audio; Listen / ListenStreamManager (voice-UI / hotword listen path); HVX vector algorithms.

  • Standard AVS audio encode/decode + calibration.

11.1.1.3. Thermal monitoring (sysmon /therm/sensor)

Active thermal read/sample nodes: xo_therm, pa / pa_1, modem_tsens / modem_tsens1, modem_bcl_warning (battery-current-limit warning). Sampled via /therm/sensor/%s/sampling.

11.1.1.4. Reference-base leftovers (present but not wired)

  • mmWave/5G RF thermals: BEAMER_{E,N,W}_THERM, and a large qfe_mmw{0..3}, qfe_mmw_streamer0, qfe_wtr_pa{0..4}[_fr1], qfe_ret_pa0[_fr1] set — RF PA / mmWave front-end thermal zones.

  • RF-card hwids: rfc_hwid629/630/833_mmwave_sm6350_{na,row,qtm535} — 5G RF-card platform detect.

  • VoWiFi/ePDG carrier config: an <ikev2_info> / <pdn_throttling> XML block (throttling_series, cause_code 10500, esp_auth_algo_list, across_epdg=TRUE) — Wi-Fi-calling IPsec/IKEv2 data config. This is the “thermal throttling XML” of Open questions and limits of analysis; it is ePDG PDN throttling (modem data-services config), not thermal.

These mmWave/5G thermal zones and RF-card hwids are stock SM6350 RF assets carried unchanged with no matching RF hardware — the same class of leftover as the XBL AMOLED panel (Boot image: kernel, DTB, ramdisk, config). Note the distinction from the MPSS baseband proper (RRC/NAS/WCDMA/QMI/policyman) documented in the bundle overview above: that is real, complete modem code — merely dormant for lack of a cellular front end — whereas these thermal/RF-card entries are unpopulated configuration for absent boards.

11.1.2. CDSP — dsp_a

CDSP.VT.2.6-00570.1-BITRA-1, built 2024-02-07 (CRMBuilds/CDSP.VT.2.6-00570.1-BITRA-1_20240207_034818), variant bitra.cdsp.prodQ. Hexagon compute DSP (QuRT RTOS), reached from HLOS via fastRPC. Handles general offload, video post-processing, NN/tensor acceleration, and protected-content compute.

11.1.2.1. Execution model

  • fastRPC transport: _pl_fastrpc_{invoke,smd,mem,uprocess,exception}, __fastrpc_sys_mmap.

  • Protection domains via signed/unsigned PD shells: fastrpc_shell_3 (signed) and fastrpc_shell_unsigned_3 (unsigned PD — allows unsigned test offload), plus fastrpc_shell_0 (ADSP-side).

11.1.2.2. Capabilities (fastRPC dynamic modules / *_skel.so)

Module(s)

Function

libvpp_svc_skel + libvpp_{nr,mvp,aie,qbr}.so, ubwcdma_dynlib

Video Post-Processing — noise-reduction (nr), motion-vector (mvp), AIE, QBR; UBWC compressed DMA

libhta_dsp_skel (npu/hta)

HTA — Hexagon Tensor Accelerator (NPU): on-DSP neural-net inference

dspCV / FastCV (CV/fastcv, gaussian7x7_asm, HVX)

computer-vision primitives

libsysmon_skel, libsysmonhvxthrottle_skel, libsysmonquery_skel, libsysmondomain_skel

DSP sysmon: HVX clock throttling, load/thermal query

libstabilitydomain_skel, libbenchmark_skel, libloadalgo_skel

stability/PD watchdog, benchmark, dynamic-algo loader

libadsp_default_listener1_skel

default listener PD

11.1.2.3. SecurePD (secure protection domain)

  • Present: secure_pd_{mailbox_send,mb_get,mb_receive,mb_delete,thread_create}, secdsplib2, core/securemsm. The shipped example SecurePD is a gaussian HVX algo under platform/securepd/example/{gaussian,proxy} (loadalgo_skel, example_algo.c).

  • This is the CDSP side of protected-content compute — it pairs with the TZ Widevine OEMCrypto path in devcfg (tzdrm/widevine_oemcrypto, Open questions and limits of analysis): DRM/secured buffers can be processed inside a CDSP SecurePD isolated from the normal (unsigned) PDs.

  • The HTA/NPU module builds from a saipan.cdsp.prod sub-tree (shared NPU module reused across SoCs) while the rest is bitra.cdsp.prod — a build-tree leftover, not a functional difference.

Both are test-key-signed where a chain is present (consistent with Secure boot and image signing, Open questions and limits of analysis). Nothing here changes the boot-chain/security findings; this catalogs functionality only.

11.1.3. Audio hardware fabric (LPASS / bolero codec)

The AVS firmware above runs on the Q6 audio DSP inside LPASS; this is the hardware path it drives, for completeness. LPASS is loaded by PIL like the other subsystems — qcom,lpass@3000000 (qcom,pil-tz-generic, xo proxy clock) — so the only firmware below userspace here is the ADSP/AVS image already catalogued; the blocks below are HW driven by that DSP over the APR (qcom,msm-audio-aprqcom,q6core-audio).

  • Bolero on-SoC digital codec (bolero-cdc) with three macros in the LPASS register band: rx-macro@3200000 (playback), tx-macro@3220000 (mic/capture), wsa-macro@3240000 (speaker / WSA path). No va-macro (voice-activation) is instantiated.

  • Each macro fronts a SoundWire master: swr1 = rx, swr2 = tx, swr0 = wsa (aliases in the tree).

  • External codec: WCD938x (Qualcomm WCD9380/85) on the rx/tx SoundWire buses, hardware-reset through TLMM (wcd938x_reset_active / _sleep pinctrl states, Pin control — TLMM and the PMIC GPIOs).

  • USB-C headset: an fsa2275 analog audio switch (GPIO-managed, Pin control — TLMM and the PMIC GPIOs) routes analog audio over the Type-C connector.

  • DAIs: MI2S, CDC-DMA (the bolero DMA lanes) and the Q6 AFE DAIs. The qcom,msm-dai-q6-hdmi DAIs are present but vestigial — there is no HDMI on this device (Absent and vestigial hardware (reference-base leftovers)). BT/FM audio rides the WCN3990 on SLIMbus (Bluetooth / FM controller firmware (WCN3990 “Cherokee”)).

  • Clocks: vote_lpass_core_hw / vote_lpass_audio_hw (qcom,audio-ref-clk) and bolero-clk-rsc-mngr, fed from the RPMh CXO (Clock tree — GCC, domain CCs, RPMh).

Nothing here adds a firmware blob below userspace beyond the ADSP/AVS image; the codec fabric is hardware the DSP and kernel drive.

11.1.4. Hexagon instruction-level disassembly

Everything above this section was derived from container/header parsing and string mining. This section adds an instruction-level pass: a Hexagon disassembler is available in this environment — llvm-objdump (LLVM 23.1.1, under the pixi toolchain at ~/Library/0.UserLibrary/bin/pixi/bin/llvm-objdump) lists hexagon - Hexagon among its registered targets and correctly decodes these images. This section reports what a real instruction-level pass over the ADSP, CDSP, MPSS and NPU images actually found. Full raw disassembly excerpts, the extraction/repackaging method, and the sanity checks used to confirm the decode is genuine (not tool noise) are in artifacts/re_static/item_hexagon_dsp_disasm.txt — this section summarizes and does not repeat that file’s content verbatim.

11.1.4.1. Method, in brief

  • modem_a uses the split PIL form: each <name>.mdt is a small ELF32 header + program-header table + HASH segment only (confirmed 7.5–9.3 KB each); every PT_LOAD segment’s actual bytes live in a sibling <name>.bNN file, where NN is the zero-padded program-header index — verified empirically by matching each non-zero-filesz phdr’s filesz to its .bNN file size exactly, for both adsp.mdt and cdsp.mdt.

  • This build’s llvm-objdump has no raw-binary mode (no -b binary/--target=binary, confirmed via --help): it only disassembles real object files. Each .bNN blob is therefore repackaged into a minimal synthetic ELF32 (e_machine=0xA4 / EM_HEXAGON, one PT_LOAD + one executable-alloc .text section at the segment’s real vaddr, taken from the .mdt program header) before disassembly. Script: artifacts/re_static/hexdis_wrap_elf.py. The result is independently reproducible from the extracted .bNN files.

11.1.4.2. Verifying the decode is genuine

Confirmed on several independent grounds (detailed in the deliverable file): llvm-objdump -f on the synthetic ELF reports elf32-hexagon purely from the e_machine field we set, i.e. the tool engages its real Hexagon decoder; standard VLIW packet syntax ({ instr ; instr }), immext constant extension, predicated (if (p0.new) ...) and .new-forwarded forms, and recognizable ABI idioms (allocframe/dealloc_return prologue-epilogue pairs, call/callr/jumpr r31) appear throughout; and the reset-vector bytes at the base of the ADSP, CDSP, MPSS and NPU code segments decode identically across all four independently-built images (ADSP.VT.5.6, CDSP.VT.2.6, MPSS.HI.2.5.1, NPU.FW.2.3, all 2023–2024 “BITRA” builds) despite each loading at a different vaddr — four separately-built images sharing byte-identical code is not explainable by decoder noise. What it decodes to: a 7-entry self-looping exception-vector table, one real vector jumping to an init routine, then r0=#0; ssr=r0; r0=syscfg; setbit x2; syscfg=r0; dckill; ickill; jump <init> — the textbook Hexagon/QuRT reset-vector idiom (cache-kill + SSR/SYSCFG init). --mcpu=hexagonv66 vs. the tool’s implicit default produced byte-identical output on every excerpt checked.

11.1.4.3. Findings

  • Shared QuRT crt0: ADSP, CDSP, MPSS and NPU each start with the byte-identical reset-vector + early software-TLB-refill-handler sequence (tlbp/tlbr/tlbw/isync walking and installing a TLB entry via a PC-relative page-number computation) — i.e. all four Hexagon cores on this SoC boot through the same compiled QuRT reset stub, just linked at different load addresses (0xf0100000 ADSP, 0xfe000000 CDSP, 0xc0800000 MPSS, 0xb0000000 NPU — ADSP and NPU’s stubs are in fact byte-for-byte identical down to the internal jump offset, suggesting the literal same compiled object).

  • Assert/logging call-site pattern: in the ADSP’s main ~2 MB R‑X segment, a recurring 3-call sequence (fetch a guarded global via a small ugp-null-checked helper, build a {ptr,0,0} struct on the stack, call a fixed helper, then call a second fixed helper passing a small integer in r1) recurs at consecutive, monotonically increasing r1 values (0x295, 0x359, 0x35c, 0x36d, …) consistent with source line numbers — the compiled shape of a FARF/assert-style logging macro invoked at many call sites. This is corroborated, not just guessed: the same image embeds the literal strings " -- assertion failed", "__assert", and "NULL ptr occurenaces in qurtos_free()", and the identical QuRT exception/TLB strings ("!!! QURT_EXCEPT_FLOATING_POINT", "!!! QURT_TLB_MISS_*", "!!! Reserved vector Error") that match the reset/TLB code actually found. The callee address itself was not resolved to a name (no symbol table survives in these production MBN images — shnum=0 in every .mdt); the line-number correlation is inferential, not proven by a symbol.

  • CDSP embeds full build source paths confirming, beyond the header-level inventory above, that the NPU driver (cdsp_proc/npu/npu_driver/*.c) and FastRPC’s invoke-path buffer-range validation (cdsp_proc/platform/fastrpc_invoke/src/fastrpc_invoke.c, with literal failed-assertion source expressions like br[ii]->start_vaddr <= br[ii]->end_vaddr) are compiled into the CDSP image itself, not only into dsp_a’s FastRPC skeleton libraries.

11.1.4.4. Limits

No symbol table exists in any of these images, so every function identity above is inferred from calling convention and string cross-reference, never read from a name. Only small, targeted excerpts were disassembled — the boot vector plus roughly one function’s worth of code per image; the multi-megabyte bulk of the AVS audio stack, the SEE sensor stack, and the CDSP FastRPC/NPU driver code were not walked function-by-function. MPSS’s baseband protocol stack (RRC/NAS/QMI, confirmed present by the string census earlier in this page) was not disassembled beyond its reset vector — consistent with it being dormant firmware on this Wi‑Fi‑only device, a full baseband disassembly pass was not undertaken here. No HVX (vector-extension) instructions were encountered in the excerpts examined, and wlanmdsp.mbn (also Hexagon, per the inventory above) was not disassembled — the same method applies directly if needed.

11.1.5. Modem NV storage (modemst1/modemst2)

Two small LUN5 partitions hold the modem’s non-volatile item store — real data, not blank scaffolding, consistent with the dormant-but-present MPSS baseband documented above. Unlike fsg/fsc on the same LUN (confirmed all-0x00), modemst1.bin and modemst2.bin (2.5 MB each) are 99.59% non-zero, and their SHA256 differ from each other (not an A/B mirror pair). Both open with a Qualcomm EFS2 superblock: a 0x28-byte header whose two little-endian u32 fields at offsets 0x10/0x14 each read 0x0027fe00 = 2,621,440 — the exact size of the 2.5 MB partition itself — followed by an ASCII magic at offset 0x28 that differs between the two: ``IMGEFS1&`` in modemst1.bin, ``IMGEFS2%`` in modemst2.bin (consistent with the two being distinct primary/backup NV-store images, not a mirror pair). This is Qualcomm’s modem-NV filesystem image format (modemst1/modemst2 are its conventional primary/backup NV-store partition names across Qualcomm platforms) — the NV store exists because the baseband image does, even though there is no cellular RF front end to use it. Past the header the two images diverge completely and are high-entropy (no readable strings beyond short printable runs consistent with packed binary NV-item records) — genuinely opaque without the EFS2 NV-item table format, which is not present anywhere in this dump (it lives in Qualcomm’s NV-item build tooling, not on-device).

Source (modemst):

../_READONLY/lun5/modemst1.bin, ../_READONLY/lun5/modemst2.bin.

Method (modemst):

header/magic read directly; distinct-byte-value scan for the 99.59%-non-zero figure; SHA256 compared between the two files.

11.1.6. Provenance

Source:

../_READONLY/lun4/modem_a.bin, ../_READONLY/lun4/core_nhlos_a.bin, ../_READONLY/lun4/dsp_a.bin (read-only); subsystem identity from embedded QC_IMAGE_VERSION_STRING / IMAGE_VARIANT_STRING pairs and a baseband-vs- sensor string census. Audio-fabric nodes (bolero-cdc macros, SoundWire masters, wcd938x reset states, qcom,lpass@3000000, audio DAIs) from artifacts/boot_a/board.dts.

Method:

Located ELF start (zero-pad skip); strings mining for version tags, SEE sensor/registry names, /therm/sensor nodes, thermal/IKE XML, fastRPC *_skel.so, and secure_pd / securepd paths; config blocks quoted from in-image strings. The “Hexagon instruction-level disassembly” section above supersedes this for actual machine-code analysis (llvm-objdump, target hexagon) — see artifacts/re_static/item_hexagon_dsp_disasm.txt.

Cross-refs:

Secure boot and image signing (signing keys), Boot image: kernel, DTB, ramdisk, config (reference-base panel leftover), Open questions and limits of analysis (ADSP identity, Widevine OEMCrypto), DTBO overlays (sensor overlays), Pin control — TLMM and the PMIC GPIOs (WCD938x reset / fsa2275 pins), Clock tree — GCC, domain CCs, RPMh (LPASS audio clocks), Bluetooth / FM controller firmware (WCN3990 “Cherokee”) (WCN3990 SLIMbus BT/FM audio), Absent and vestigial hardware (reference-base leftovers) (HDMI-audio DAIs).