Phase 03a — Custom UEFI ABL

Phase 03a — Custom UEFI ABL

Status: ✅ Complete — v2.4 stable. Source: LA.UM.7.2.c25 branch of clo/la/abl/tianocore/edk2 (QcomModulePkg).


Why a Custom ABL?

  • Stock ABL: fastboot flash / fastboot boot hang at “Sending” — bulk data transfer path broken
  • Stock ABL: fastboot oem returns “unknown command”
  • Boot mode selection (TWRP vs Android) needed for daily use
  • Secure boot is off (fuses not provisioned) — Onyx ships their production ABL signed with qtestsign test keys. Any qtestsign-signed image works.

ABL Version History

VersionKey ChangeOutcome
v1.0Baseline LA.UM.7.2.c25, VERIFIED_BOOT=0❌ FDE bootloop — TrustZone RoT call missing
v1.1VERIFIED_BOOT=1❌ 05c6:f000 diagnostic mode — AVB1 fails on Magisk-patched boot
v1.2Cmdline injection (VB params hardcoded)❌ FDE loop persists — cmdline not the root cause
v1.3VBSendRot + EnableDisplayMenu=FALSE + oem reboot-edl✅ FDE resolved, display fix, EDL escape works
v1.4-v1.6USB DMA buffer experiments❌ Fastboot bulk hang unresolved; broke getvar
v2.0Clean source: reverted all flashing fixes, kept v1.3 advances✅ Android boots, ADB works
v2.1Hall sensor GPIO 105 (south tile TLMM) for boot mode selection❌ Data abort — raw MmioRead32 on unmapped address
v2.2GCD memory mapping before MMIO + graceful fallback✅ Hall sensor reads work without crash
v2.3Boot counter logic: 2 consecutive normal boots → Android; cover closed → TWRP✅ Boot mode selection fully functional
v2.4Stability fixes; current stable release✅ Confirmed stable — all features working

Critical Lessons

qtestsign MUST use -v 5 for SDM636

The default -v 3 produces a hash segment that XBL silently rejects — device drops straight to EDL 9008 with no diagnostic output. Always use qtestsign -v 5 abl. Use tools/abl-build which handles this automatically.

Never use raw MmioRead32 without GCD memory mapping

ABL v2.1 used MmioRead32(0x03069004) for TLMM GPIO. The address was not in the UEFI memory map → data abort → ABL crash → device bricked. Recovery required full battery drain + cold-boot PBL 9008. Always call gDS->GetMemorySpaceDescriptor() first; add via AddMemorySpace() + SetMemorySpaceAttributes(EFI_MEMORY_UC) if unmapped.

Fastboot bulk hang = USB hub / autosuspend (not ABL)

After 6+ ABL builds failing to fix “Sending” hang, usbmon capture revealed: the device disconnects from the USB hub before any bulk data is transmitted. The hub’s autosuspend (2s) drops the port during the interactive diagnostic prompt gap. On direct connection with autosuspend disabled, the hang has not been reproduced. All v1.0–v1.6 “Sending” hangs were likely this same disconnect pattern.


Build Infrastructure

  • tools/abl-build <version> — mandatory wrapper: Docker build + qtestsign -v 5 in one step. Never build or sign manually.
  • tools/docker/abl-builder/Dockerfile — Ubuntu 20.04 + clang + aarch64-linux-gnu + python2 + cryptography
  • Build flags: VERIFIED_BOOT=0, USER_BUILD_VARIANT=0 (DEBUG), BOARD_BOOTLOADER_PRODUCT_NAME=NoteAir
  • Output: builds/abl/abl-v<N>.elf

EDL PBL Timing Rules

  • Blacklist qcserial: /etc/modprobe.d/no-qcserial.conf — otherwise qcserial claims the Sahara interface within ~850ms
  • Start edl-run before plugging in: PBL sends HELLO in a narrow ~1-2s window after USB enumeration, then goes silent
  • One write per Sahara session: second EDL invocation reuses programmer with broken GPT state

More posts