QFIL: Factory Flashing
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,
What QFIL Actually Does
Section titled “What QFIL Actually Does”QFIL is not “Android flashing.” It’s low-level storage programming:
- Host PC sends a Firehose programmer into SoC RAM
- Programmer initializes
/eMMC controllerUFS - Host sends program/patch commands from XML + image files
- Programmer writes bytes to specific LUN/sector ranges
- 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 Mode: Emergency Download
Section titled “EDL Mode: Emergency Download”How You Enter EDL
Section titled “How You Enter EDL”| 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) |
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.elfTarget configured: UFS, 2 LUNs, 4096 sector sizeProgramming xbl.elf → LUN 0, partition xbl ... OKProgramming boot.img → LUN 1, partition boot_a ... OKApplying patch0.xml ... OKResetting device...Firehose is a high-pressure stream of sector writes. You’re not mounting filesystems; you’re hosing bytes into raw partitions.
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.
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.
Step-by-Step QFIL Flash Flow
Section titled “Step-by-Step QFIL Flash Flow”1. Prepare the Flash Package
Section titled “1. Prepare the Flash Package”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.
2. Enter EDL
Section titled “2. Enter EDL”Use test point, ADB, or fixture. Confirm device in Device Manager / lsusb as Qualcomm QDLoader 9008.
3. Launch QFIL (or CLI equivalent)
Section titled “3. Launch QFIL (or CLI equivalent)”- 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
4. Download → Flash
Section titled “4. Download → Flash”QFIL:
- Uploads programmer to RAM
- Sends configure for UFS
- Executes each
<program>entry sequentially - Applies patches
- Resets device
5. Verify Boot
Section titled “5. Verify Boot”First boot after full flash may take longer (file system format, slot init). Check:
- Serial log from
/ABLXBL - 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.
QFIL vs Fastboot vs OTA: Decision Matrix
Section titled “QFIL vs Fastboot vs OTA: Decision Matrix”| 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 <partition>"]
Q -->|"OS running, normal ops"| OTA["OTA / lb campaign"]
Q -->|"Need LUN 0 rewrite"| QFIL
FB -->|"Need full factory reset"| QFIL
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.imgfive times an hour: use fastboot - You’re pushing a signed build to 100 fleet vehicles: use OTA
- You only need
adb shelldebug: 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.
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.
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.
What to remember
Section titled “What to remember”- QFIL programs UFS via EDL + Firehose, below Android and below fastboot.
- rawprogram/patch XML + signed programmer + matched images = one atomic flash package.
- Factory/unbrick/first flash → QFIL. Dev iteration → fastboot. Fleet delivery → OTA.
- 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?
Recall2. When is QFIL the correct tool instead of fastboot?
Applied3. In the Firehose flash flow, what is the role of the programmer (.elf)?
Recall4. QFIL reports all green checks, but serial shows garbage at first XBL instruction. You flashed SA8155P images onto SA8295P hardware. What failed?
Applied5. 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?
SynthesisConnects 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?
SynthesisConnects to: Module 0 — Memory & Storage
- 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
superand 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.