Skip to content

The Boot Chain: PBL to User Space

TL;DR

Every power-on on a Qualcomm cockpit SoC follows a chain of boot stages, each authenticating the next before execution. PBL (Primary Boot Loader, in ROM) is the immutable root. It loads XBL (eXtensible Boot Loader), which brings up AOP, TZ (TrustZone), and QHEE (the hypervisor). ABL (Android Boot Loader / UEFI) then loads guest OS kernels: QNX IFS and AAOS boot.img. Break any link in the chain (bad signature, corrupt partition) and the device refuses to boot, what engineers call bricking. EDL (Emergency Download) mode drops to PBL-level access so QFIL can recover a dead unit by talking below the broken stage.

You flash dozens of images (XBL, ABL, boot, vendor, QNX IFS) but rarely see the order they execute. That order is the boot chain. It’s why some corruption is recoverable and some isn’t.

Qualcomm platforms implement a Chain of Trust (CoT):

  1. Root of trust: code in ROM (PBL) that cannot be modified
  2. Each stage cryptographically verifies the next stage before jumping to it
  3. Only signed images from trusted keys execute
  4. Compromise at any stage stops the chain (fail-closed, not fail-open)

Every handoff is inspected, like airport security between connecting flights.

Mental Model

Boot is a relay race with ID checks. PBL is the starter in the blocks — always there, never swapped. Each runner (XBL → TZ → QHEE → ABL → kernel) must show a valid badge (signature) before the next runner leaves the blocks. A forged badge? The race stops. EDL mode is the race official who can reset runners when everyone is stuck at the starting line.

Property Detail
Location On-chip ROM, burned at manufacturing
Mutability None: the true root of trust
Job Minimal hardware init; locate and verify XBL in flash (UFS/eMMC)
Failure mode If XBL is missing or unsigned → device halts or enters EDL

PBL knows nothing about QNX, Android, or your app. It only knows: find valid XBL, jump to it.

PBL is permanent because it lives in ROM.

Property Detail
Location Flash partition (e.g., xbl, xbl_config)
Job DDR training, clock/power init, load AOP, TZ, QHEE
Your flash tool QFIL / QPST firehose programmer writes here

XBL is the first flashable stage. Corrupt XBL → device won’t reach TZ or hypervisor. Still recoverable via EDL because PBL can receive a fresh XBL over USB.

Tiny always-on core for low-level power management, sleep/wake, and sensor hub duties. Boots early from XBL. Not your QNX/AAOS world, but AOP crashes can cause mysterious wake failures.

Property Detail
ARM level EL3 (Monitor) / secure world
Job Key storage, crypto, secure boot enforcement, DRM, eFuse access
Images tz, devcfg, keymaster region

TrustZone owns secrets. Hypervisor and guest OSes request crypto services through secure monitor calls (SMC). They don’t touch keys directly.

QHEE — Qualcomm Hypervisor Execution Environment

Section titled “QHEE — Qualcomm Hypervisor Execution Environment”
Property Detail
ARM level EL2
Job Type-1 hypervisor: creates VMs, assigns vCPUs, partitions memory and I/O
Images QHEE firmware partition (vendor-specific naming)

QHEE must be running before QNX or AAOS kernels start. It is the landlord; guest OSes are tenants (Page 5.3).

Property Detail
Location abl partition
Job UEFI-style loader: picks and verifies guest boot images
Loads QNX IFS, AAOS boot.img, optionally other VM payloads

Despite the name “Android Boot Loader,” ABL loads all guest kernels configured in the boot flow, not just Android.

Guest Typical Image What Happens Next
QNX IFS (Image Filesystem) QNX microkernel + drivers + hypervisor host services start
AAOS boot.img + vendor/system Linux kernel → init → Zygote → Android framework
Linux (optional) Vendor-specific Secondary VM for ADAS, logging, etc.

Each guest kernel is verified before execution. Then init systems bring up user space, where your adb shell, VHAL, and QNX services live.

flowchart TB
POWER["Power-On / Reset"]
PBL["PBL<br/>Primary Boot Loader<br/>(ROM — Root of Trust)"]
XBL["XBL<br/>eXtensible Boot Loader<br/>(DDR · clocks · flash init)"]
AOP["AOP<br/>Always-On Processor"]
TZ["TZ — TrustZone<br/>(EL3 Secure World)"]
QHEE["QHEE<br/>Hypervisor (EL2)"]
ABL["ABL<br/>Android Boot Loader / UEFI"]
QNX["QNX IFS<br/>Guest VM — EL1"]
AAOS["AAOS boot.img<br/>Guest VM — EL1"]
USERSPACE["User Space<br/>Services · Apps · VHAL"]
POWER --> PBL
PBL -->|"verify signature"| XBL
XBL --> AOP
XBL --> TZ
XBL --> QHEE
QHEE --> ABL
ABL -->|"verify + load"| QNX
ABL -->|"verify + load"| AAOS
QNX --> USERSPACE
AAOS --> USERSPACE
EDL["EDL Mode<br/>(Emergency Download)"]
QFIL["QFIL / Firehose<br/>USB programmer"]
EDL -.->|"bypass broken chain"| PBL
QFIL -.-> EDL
Common Gotcha

“I flashed boot.img but the device is dead”: if XBL, TZ, or QHEE is corrupt or mismatched to the chip, no kernel will run regardless of a perfect Android build. Always verify foundational partitions before debugging guest OS issues. Symptom: instant EDL or black screen with no fastboot. Think low-level boot, not logcat.

Bricking is informal. It covers a spectrum:

Severity What Broke Recovery
Soft brick Guest OS (system, QNX IFS) corrupt Reflash from fastboot/QFIL in normal or EDL mode
Medium brick ABL or single guest boot image bad EDL + QFIL with correct programmer
Hard brick XBL, TZ, or partition table destroyed EDL + firehose, if PBL/USB still responds
True brick Hardware fault, blown eFuse, dead USB JTAG/SDI service tools or RMA

Damage lower layers, need lower tools to fix. QFIL in EDL reaches the bottom layer (PBL).

Bricking is not “the app crashes.” It’s “the SoC refuses to execute the next boot stage.”

EDL (Emergency Download Mode), also called Qualcomm HS-USB QDLoader 9008 in Device Manager, is a PBL-level USB protocol.

Mode Who You Talk To Typical Tool
Normal boot Running OS (ADB, SSH) adb, QNX shell
Fastboot ABL (if reached) fastboot flash
EDL PBL via firehose QFIL, QPST

In EDL:

  1. PBL accepts a firehose programmer over USB
  2. Programmer can read/write raw partitions on UFS
  3. You restore XBL, partition table, full flat build without a working OS
Where You'll See This

This is why QFIL works in EDL mode: it talks to PBL directly.

When a bench unit shows QDLoader 9008 and nothing else:

  • Normal flashing tools that expect ADB or fastboot won’t help
  • QFIL sends a signed firehose programmer that PBL trusts
  • The programmer then writes every partition (XBL through super) as raw bytes

Your daily workflow:

  1. Force EDL: test point, adb reboot edl, or power sequence (platform-specific)
  2. Load programmer: must match chip (SA8155P vs SA8295P firehose)
  3. Flash flat build or individual partitions
  4. First boot: watch serial log from PBL through XBL for auth failures

If auth fails after flash, suspect wrong signature keys (dev vs prod) or mismatched TZ/devcfg, not a bad Android app.

Boot Stages vs Partition Names You'll Flash

Build artifacts don’t always match stage names 1:1. A single QFIL session might write: xbl, xbl_config, aop, tz, hyp (QHEE), abl, boot, vendor, system, qnx_ifs, adsp, cdsp, modem (AMSS). Module 8 maps each partition to its boot stage. Rule of thumb: partitions listed before boot in the flash XML are chain-of-trust stages. Get those right first.

Connect the Dots

Page 5.1 identified your silicon. This page explains how it wakes up. Page 5.3 covers QHEE, the stage that creates VMs before ABL loads QNX and AAOS. Page 5.4 shows which OS runs where after boot completes. Module 8 is the partition flash map for every stage named here.

  1. Boot is a chain of trust: PBL (ROM) → XBL → AOP/TZ/QHEE → ABL → guest kernels.
  2. Each stage verifies signatures on the next. Unsigned or corrupt images halt boot.
  3. Bricking means the chain breaks. Severity depends on how low the damage goes.
  4. EDL mode lets QFIL talk to PBL directly, the recovery path when everything above ROM is broken.

Check Your Understanding

1. Why can QFIL recover a device in EDL mode when fastboot and ADB cannot?

2. In the boot chain, which stage is responsible for creating virtual machines before guest OS kernels start?

3. A device has a corrupt system.img but intact XBL, TZ, QHEE, and ABL. This is best described as: