Session 31 — 2026-03-29b — A2 Waveform Kernel RE; NOP Patch Identified

Session 31 — 2026-03-29b

FieldValue
Date2026-03-29
Phase03b — TWRP (A2 waveform RE)
Duration~3 h

Transform Function Decoded

onyx_waveform_mode_transform() at kernel offset 0x427a8c:

  • Loads 18-entry transform table from driver state (64 bytes per entry)
  • Compares waveform firmware version byte against each entry
  • If matched: replaces requested mode with table’s value (waveform v0x19 maps A2 → AUTO → GC16)
  • map_auto_mode() at 0x427bc8 maps AUTO (0xFF) → GC16 for full-screen updates

Call Site and Patch

FieldValue
Patch offset0x41d410
Original instructionBL 0x427a8c = 0x9400299F
Patched instructionNOP = 0xD503201F

Effect: all waveform modes pass through unchanged to EPDC hardware. AUTO (0xFF) still mapped by subsequent map_auto_mode(). Standard modes (DU, GC16, GC4, A2) are hardware-supported — the transform was overly conservative.

SET_EBC_UPDATE_SCHEME — Dead Code

Four scheme validation strings exist in the kernel binary but have zero ADRP+ADD references. The scheme-setting ioctl was never compiled in (or was eliminated by the linker). No userspace API exists to change the update scheme in this kernel build.

Two Kernel Display Paths

  1. /dev/ebc ioctl (TWRP path): goes through onyx_waveform_mode_transform() → A2 blocked
  2. HWC/SurfaceFlinger (Android path): uses onyx_epdc_set_mode() → bypasses transform → A2 works

Tools Created

  • tools/ebc-probe.c — comprehensive EBC ioctl prober, tests all ioctls and waveform modes
  • tools/patch-kernel-waveform-transform.py — NOPs the BL at 0x41d410; --dry-run verified against extracted kernel

More posts