Skip to content

QFIL: Factory Flashing

Advanced10 min read
Assumes: 8.1 Partition Map
TL;DR

QFIL (Qualcomm Flash Image Loader) is the factory-grade tool for writing raw images to UFS/eMMC when normal boot paths are dead or you need a clean slate. It talks to the SoC in EDL (Emergency Download) mode via USB, using the Firehose protocol and a signed programmer (.elf/.mbn) to execute rawprogram*.xml and patch*.xml from your flash package. QFIL bypasses Android, fastboot, and the running OS entirely. It speaks directly to storage. Use it for first flash, unbrick, partition table rebuild, and milestone re-provision. Use fastboot for iterative dev flashes and OTA for field updates.

When fastboot says FAILED (remote: unknown command) and ADB shows no device, QFIL is the tool that still sees the silicon. This page is the factory flash playbook. Every engineer learns to respect QFIL after their first accidental full-erase at 6 PM on a Friday.

QFIL is not “Android flashing.” It’s low-level storage programming:

  1. Host PC sends a Firehose programmer into SoC RAM
  2. Programmer initializes UFS/eMMC controller
  3. Host sends program/patch commands from XML + image files
  4. Programmer writes bytes to specific LUN/sector ranges
  5. Device reboots into whatever boot chain you just wrote
Layer Tool Speaks To
Application OTA agent / lb Update service over gRPC + SOME/IP
OS bootloader fastboot ABL in fastboot mode
Factory/recovery QFIL Firehose programmer in EDL
Dead silicon QFIL + authorized programmer PBL/ROM loader in EDL

QFIL loads images before any OS exists to refuse them.

EDL (Emergency Download Mode) is a USB boot path baked into Qualcomm ROM code. The SoC enumerates as a Qualcomm HS-USB QDLoader device (often PID 9008).

Method When Used Risk
Test point / EDL button Bench boards with exposed pads Low (hardware intent)
ADB: reboot edl Debug builds with allowed command Medium (needs working ADB)
Fastboot: reboot emergency Some platforms Medium
Dead boot / blank flash Automatic; PBL falls to EDL N/A (you’re already there)
Special boot strap pins Production fixtures Low (fixture-controlled)
Common Gotcha

If you use phone EDL cable tricks (short D+/D−) on an automotive bench board, you may trip security fuses or leave the board in an undefined state. Automotive boards use test points or fixture control. Don’t assume phone forum hacks work on your cockpit harness.

flowchart TD
    POWER["Power On / Reset"] --> PBL["PBL (ROM)"]
    PBL -->|"Valid XBL on UFS"| XBL["Normal Boot → XBL → ABL → OS"]
    PBL -->|"No valid boot chain / forced EDL"| EDL["EDL Mode<br/>USB QDLoader 9008"]
    EDL --> QFIL["QFIL sends Firehose programmer"]
    QFIL --> FH["Firehose running in RAM"]
    FH --> WRITE["Execute rawprogram + patch XML"]
    WRITE --> REBOOT["Reboot to new firmware"]

Firehose Protocol: The Language QFIL Speaks

Section titled “Firehose Protocol: The Language QFIL Speaks”

Once in EDL, the host cannot simply “copy a file to disk.” The SoC needs a programmer: a tiny signed binary loaded into RAM that understands Firehose commands.

Firehose Concept Purpose
Programmer (.elf / .mbn / .melf) Chip-specific loader; must match SoC (e.g., SA8155P variant)
Configure Set storage type (UFS), LUN count, sector size
Program Write image data to partition/sector range
Patch Apply small fixups from patch XML
Reset Reboot device after flash complete
Digest / signature Verify programmer authenticity (secure boot enforced on production units)

Typical QFIL log flow:

Connecting to QDLoader 9008...
Sending programmer: prog_firehose_ddr.elf
Target configured: UFS, 2 LUNs, 4096 sector size
Programming xbl.elf → LUN 0, partition xbl ... OK
Programming boot.img → LUN 1, partition boot_a ... OK
Applying patch0.xml ... OK
Resetting device...

Firehose is a high-pressure stream of sector writes. You’re not mounting filesystems; you’re hosing bytes into raw partitions.

Think About It

QFIL writes all partitions. Fastboot writes one. When would you choose QFIL over fastboot?

Reveal Answer

Choose QFIL when the board only enumerates as QDLoader 9008 in EDL — no ABL means no fastboot — or when LUN 0 / GPT is corrupt and you need a full rawprogram XML rewrite. Also use QFIL for first provision on blank UFS, milestone re-provision, or recovery after a wrong XML flash. Reserve fastboot for iterative single-partition work (boot, vendor_boot) when the device already boots into bootloader mode.

Mental Model

Normal boot is a tenant moving into a furnished apartment — ABL opens the door, Android unpacks into RAM. EDL + Firehose is demolition and reconstruction — the building manager (PBL) lets the construction crew (programmer) strip walls to studs and rebuild from blueprints (rawprogram XML). Nothing inside the apartment matters because you’re not going through the front door.

QFIL = the nuclear option. It writes EVERYTHING. Use it when fastboot can’t reach the damage.

Your BSP/build drop contains:

flash_package/
├── prog_firehose_*.elf # Programmer for your SoC + storage
├── rawprogram0.xml # LUN 0 programs
├── rawprogram1.xml # LUN 1 programs
├── patch0.xml
├── patch1.xml
├── xbl.elf
├── abl.elf
├── boot.img
├── super.img
├── NON-HLOS.bin # modem
├── vbmeta.img
└── ...

Verify: build ID, platform variant, UFS vs eMMC, sparse vs raw image formats.

Use test point, ADB, or fixture. Confirm device in Device Manager / lsusb as Qualcomm QDLoader 9008.

  • Select Flat Build (most automotive packages)
  • Point to prog_firehose programmer
  • Load rawprogram0.xml (+ rawprogram1, etc.)
  • Load matching patch.xml*
  • Ensure image search path includes all referenced filename= entries

QFIL:

  1. Uploads programmer to RAM
  2. Sends configure for UFS
  3. Executes each <program> entry sequentially
  4. Applies patches
  5. Resets device

First boot after full flash may take longer (file system format, slot init). Check:

  • Serial log from XBL/ABL
  • ADB availability
  • Active slot: adb shell bootctl get-current-slot
  • Modem attach if AMSS was flashed
Sparse Images vs Raw Images

Large partitions (system, super) often ship as sparse images, an Android format that encodes “skip these empty blocks.” Firehose understands sparse natively on most programmers. Flashing a sparse image as raw (or vice versa) produces wrong-size writes or corrupt filesystems with no immediate error. Match the format in your XML filename to what the build system generated.

Scenario Tool Why
Brand-new board, empty UFS QFIL No bootloader exists to enter fastboot
Bricked boot / corrupt GPT QFIL Must rewrite LUN 0 and partition table
Full milestone re-provision QFIL Clean, reproducible factory state
Iterative kernel/boot test fastboot Seconds per flash, OS not required
Single partition swap (boot, vendor_boot) fastboot Surgical, preserves userdata
Field fleet update OTA (lb / update_engine) Signed, staged, rollback-aware
Modem-only update (AMSS drop) fastboot or QFIL fastboot if partition exposed; QFIL for full NON-HLOS refresh
Userdata wipe + reflash OS QFIL or fastboot -w QFIL for total rebuild; fastboot for dev wipe
flowchart TD
    Q{"What's the device state?"}
    Q -->|"No boot at all"| QFIL
    Q -->|"Fastboot available"| FB["fastboot flash &lt;partition&gt;"]
    Q -->|"OS running, normal ops"| OTA["OTA / lb campaign"]
    Q -->|"Need LUN 0 rewrite"| QFIL
    FB -->|"Need full factory reset"| QFIL
QFIL is your nuclear option

Reach for QFIL when:

  • The board doesn’t enumerate in fastboot; only QDLoader 9008 appears
  • You need to change partition layout or recover from a wrong XML flash
  • You’re doing first article bring-up with a golden flash package
  • Someone flashed phone firmware onto an automotive board (yes, it happens)

Don’t reach for QFIL when:

  • You’re iterating on boot.img five times an hour: use fastboot
  • You’re pushing a signed build to 100 fleet vehicles: use OTA
  • You only need adb shell debug: QFIL is overkill and wipes state

Bench ritual: Before every QFIL session, screenshot the build ID, programmer filename, and rawprogram variant. After every QFIL session, log active slot and first-boot result. Future-you debugging a bricked board will need all three.

Common Gotcha

If you use a programmer or rawprogram from the wrong chip stepping (SA8155P build on SA8295P hardware), QFIL often “succeeds” then fails silently at first XBL instruction. The flash log shows all green checks. The serial log shows garbage. Programmer + XML + images must be a matched set from one release artifact.

Connect the Dots

Page 8.1 maps partition names to LUNs, the labels in your rawprogram XML. Page 8.3 covers fastboot for day-to-day dev. Page 8.4 explains why unsigned programmers get rejected on production-fused units. Page 8.6 covers OTA for everything QFIL shouldn’t touch in the field. Page 10.1 (Debug Bench) shows the physical test points and connectors used to enter EDL mode. Page 10.2 (Boot Modes) places EDL in the full mode ladder — it’s the lowest-level escape hatch when all other modes are inaccessible.

  1. QFIL programs UFS via EDL + Firehose, below Android and below fastboot.
  2. rawprogram/patch XML + signed programmer + matched images = one atomic flash package.
  3. Factory/unbrick/first flash → QFIL. Dev iteration → fastboot. Fleet delivery → OTA.
  4. QFIL success in the log ≠ boot success. Always verify serial, slot, and modem.

Check Your Understanding

1. What transport mode does QFIL use to communicate with a Qualcomm SoC during factory flashing?

Recall

2. When is QFIL the correct tool instead of fastboot?

Applied

3. In the Firehose flash flow, what is the role of the programmer (.elf)?

Recall

4. QFIL reports all green checks, but serial shows garbage at first XBL instruction. You flashed SA8155P images onto SA8295P hardware. What failed?

Applied

5. A bricked board shows no UART output and USB enumerates as Qualcomm HS-USB QDLoader 9008. PBL reached EDL because XBL verification failed. What is the lowest-level recovery path?

Synthesis

Connects to: Module 10 — Debug Engineering

6. Your flash package has rawprogram0.xml and rawprogram1.xml. Why does Firehose need separate XML files per LUN instead of one monolithic script?

Synthesis

Connects to: Module 0 — Memory & Storage

Further Reading
  • Qualcomm Developer Tools — Official portal for QFIL, programmer packages, and platform flash utilities used in factory and recovery workflows.
  • Qualcomm Automotive Solutions — Product context for cockpit SoCs and the BSP drops that ship rawprogram/patch XML with each milestone.
  • Android Bootloader Fastboot Protocol — Contrasts fastboot (ABL-level) with factory flash; useful when deciding QFIL vs fastboot for a given failure mode.
  • Sparse Image Format — How large super and system images encode empty blocks, which Firehose must handle correctly during QFIL sessions.
  • USB Implementers Forum — Background on USB enumeration behavior when the SoC presents as QDLoader 9008 in Emergency Download mode.
  • JEDEC UFS Standard — Storage-layer reference for LUN configuration, sector size, and the physical media QFIL programs through Firehose.