The Qualcomm Partition Map
Prerequisites: Module 5 (boot chain), Module 6 (OS layers), Module 7 (modem)
What you’ll learn: Qualcomm partition map, QFIL factory flashing, fastboot and ADB, secure boot,
Qualcomm automotive platforms store everything on UFS, partitioned by GPT (GUID Partition Table), the same scheme as PC disks but with automotive-specific names. LUN 0 holds the boot chain (xbl, abl, tz); LUN 1+ holds OS images, modem firmware, and data. Updatable partitions use A/B slots (_a / _b) so OTA can write the inactive slot while the active slot keeps running. Your QFIL flash package ships rawprogram*.xml (what to write, where) and patch*.xml (post-write fixups). Learn the partition names: they’re the vocabulary of every flash log, fastboot command, and OTA failure you’ll debug.
You flash boot.img and super.img weekly. This page is the map on the wall: what each partition is, which LUN it lives on, and why some have _a/_b suffixes while
GPT on UFS: The Address Book
Section titled “GPT on UFS: The Address Book”| Concept | What It Means | Your Context |
|---|---|---|
| UFS | Universal Flash Storage — the physical chip | 64–256 GB on cockpit boards |
| LUN | Logical Unit — virtual disk on one UFS chip | LUN 0 = boot, LUN 1 = OS/firmware |
| GPT | Partition table on each LUN | Defines boot_a, modem, userdata, etc. |
| Partition | Named byte range within a LUN | What QFIL, fastboot, and OTA target by name |
| Image | File that fills a partition | boot.img, NON-HLOS.bin, super.img |
Every flash command resolves a name → LUN → sector offset via GPT.
flowchart TB
subgraph UFS["UFS Chip"]
subgraph LUN0["LUN 0 — Boot Chain"]
GPT0["GPT Header"]
XBL["xbl / xbl_config"]
ABL["abl"]
TZ["tz / devcfg / hyp"]
end
subgraph LUN1["LUN 1 — OS & Firmware"]
GPT1["GPT Header"]
BOOT["boot_a / boot_b"]
SUPER["super"]
MODEM["modem_a / modem_b"]
PERSIST["persist"]
USER["userdata"]
end
end
The Partition Table: Know These Names Cold
Section titled “The Partition Table: Know These Names Cold”Below is a representative Qualcomm automotive layout. Exact sizes vary by platform (SA8155P vs SA8295P) and program. Always trust your programmer XML, not this table’s byte counts.
Boot Chain Partitions (LUN 0, Typically Not A/B Slotted)
Section titled “Boot Chain Partitions (LUN 0, Typically Not A/B Slotted)”| Partition | Full Name / Role | Updated How Often | A/B? |
|---|---|---|---|
| xbl | eXtensible Boot Loader — first code from UFS after ROM | Rarely (BSP milestone) | No |
| xbl_config | XBL configuration / DDR training data | Rarely | No |
| abl | Android Boot Loader — loads kernel, picks A/B slot | Occasionally | No* |
| hyp | Hypervisor image (QHEE) — loads before guest OSes | Milestone | No |
| tz | TrustZone / QSEE — secure world firmware | Milestone | No |
| aop | Always-On Processor firmware — PMIC, sensors, low-power wake | Rarely | No |
| devcfg | Device configuration for TZ / security policies | Milestone | No |
* Some programs slot abl; most automotive BSPs keep ABL singular and let it select between slotted OS partitions.
OS & Firmware Partitions (LUN 1, A/B Slotted)
Section titled “OS & Firmware Partitions (LUN 1, A/B Slotted)”| Partition | Role | A/B? | Why Slotted |
|---|---|---|---|
| boot | Kernel + ramdisk (and sometimes dtb) | Yes | OTA swaps kernel without touching XBL |
| super | Dynamic partition container (system, vendor, product, …) |
Yes | Largest OS payload; primary OTA target |
| modem | AMSS / modem firmware (NON-HLOS) | Yes | Modem updates independent of Android |
| vbmeta | AVB signing metadata for boot/super | Yes | Must match the slot being activated |
| dtbo | Device Tree Overlays (display/camera variants) | Yes | Hardware variant without full reflash |
| vendor_boot | Vendor ramdisk/modules (GKI era) | Yes | Decouples vendor kernel modules from boot |
| persist | Calibration, Wi-Fi/BT MAC, factory tuning | No | Must survive slot switches (shared state) |
| misc | Bootloader message, recovery command, wipe flags | No | Communication channel for recovery/OTA |
| userdata | Apps, settings, maps, logs | No | User data survives OS updates |
| metadata | Encryption metadata, filesystem hints | No | Tied to userdata encryption state |
| frp | Factory Reset Protection token storage | No | Security; not slot-specific |
Partitions that change every sprint usually get _a/_b suffixes. Partitions that must survive a slot flip stay singular: persist, misc, userdata.
Think of UFS as a multi-story parking garage. LUN 0 is the ground floor with the elevator controls — XBL, ABL, TZ. You almost never remodel it. LUN 1 is two identical upper floors — Slot A and Slot B. OTA parks the new build on the empty floor while cars still drive on the other. persist and userdata are the lobby and tenant storage — they don’t duplicate per floor; everyone shares them regardless of which upper floor is active.
GPT is the address book. Each partition is a room. LUN is the floor. rawprogram.xml is the moving instructions.
You run ‘fastboot flash boot boot.img’. The command succeeds but the board doesn’t boot. What partition-level mistake could cause this?
Reveal Answer
The most common mistake is flashing the wrong A/B slot — fastboot flash boot writes to the current slot’s partition, but ABL may boot the other slot, or you updated boot without matching vbmeta for that slot. Run fastboot getvar current-slot and adb shell bootctl get-current-slot before flashing; target the inactive slot explicitly (fastboot flash boot_b boot.img) and always pair boot + vbmeta from the same signed build.
A/B Slot Naming: _a, _b, and the Active Slot
Section titled “A/B Slot Naming: _a, _b, and the Active Slot”Android A/B OTA maintains two copies of updatable firmware. Partition names encode the slot:
boot_a boot_bsystem_a system_b ← inside super (dynamic partitions)modem_a modem_bvbmeta_a vbmeta_bThe bootloader (ABL) reads slot metadata (often in misc or dedicated bootctrl metadata) to decide which slot to boot:
| Property | Meaning |
|---|---|
| Current slot | The slot that booted this session (a or b) |
| Active / successful | Slot marked bootable after successful boot |
| Unbootable | Slot failed verification; skipped until repaired |
| Retry count | Attempts remaining before marking slot bad |
flowchart LR
ABL["ABL reads slot metadata"]
ABL -->|"slot A active"| BOOT_A["boot_a → super (system_a)"]
ABL -->|"slot B active"| BOOT_B["boot_b → super (system_b)"]
BOOT_A --> AAOS["AAOS / QNX guests"]
BOOT_B --> AAOS
After OTA, the roles swap: whichever slot was inactive becomes the one you boot.
The super Partition: Dynamic Partitions Inside One Blob
Section titled “The super Partition: Dynamic Partitions Inside One Blob”Modern AAOS uses dynamic partitions: logical partitions (system, vendor, product, odm) live inside a single physical super partition rather than each having fixed GPT entries.
Inside super |
Typical Contents |
|---|---|
| system | AOSP framework, core apps |
| vendor | HALs, proprietary blobs, QTI extensions |
| product | Product-specific apps and overlays |
| odm | OEM/device-specific customization |
QFIL flashes super.img as one write; lpmake / lpdump (or your build system) defines the internal layout. OTA updates often patch sub-partitions via delta payloads against the inactive slot’s super.
If you flash system.img directly when your platform uses dynamic partitions inside super, you’ll fail or corrupt the layout. Match your flash package to the partition scheme: flat GPT partitions vs super-hosted dynamic partitions. Check BoardConfig.mk and your rawprogram XML, not a generic phone flash guide.
rawprogram*.xml and patch*.xml
Section titled “rawprogram*.xml and patch*.xml”QFIL doesn’t guess offsets. Your flash package includes XML that maps images to partitions:
rawprogram*.xml
Section titled “rawprogram*.xml”Defines bulk programming operations: write this file to this partition on this LUN.
<!-- Simplified example — real files have many entries --><program SECTOR_SIZE_IN_BYTES="4096" file_sector_offset="0" filename="xbl.elf" label="xbl" num_partition_sectors="512" physical_partition_number="0" start_sector="256"/>| XML Attribute | Meaning |
|---|---|
filename |
Image file on your host PC |
label |
GPT partition name |
physical_partition_number |
LUN index (0 = boot LUN) |
start_sector / num_partition_sectors |
Byte range via sector math |
SECTOR_SIZE_IN_BYTES |
Usually 4096 on UFS |
Multiple files exist for multi-LUN flashes: rawprogram0.xml (LUN 0), rawprogram1.xml (LUN 1), etc.
patch*.xml
Section titled “patch*.xml”Defines post-write patches, small fixups that can’t be expressed as a full image write:
- Zeroing/unlocking regions
- Writing partition-table metadata after bulk program
- Setting flags in
miscor provisioning sectors - GPT header updates after partition resize
rawprogram handles bulk loads; patch XML handles precise surgery after the load.
Keep a partition cheat sheet pinned next to your bench:
- Before QFIL: confirm LUN count in XML matches your storage config
- Before fastboot:
fastboot getvar all | grep slotto know the active slot - Before OTA test:
adb shell bootctl get-current-slotto verify which slot you’re about to overwrite - After failed flash: check whether LUN 0 (xbl/abl) was touched. That determines your recovery path.
When a log says FAILED (remote: partition table doesn't exist), you’re targeting a partition name that isn’t in GPT for that LUN. Wrong XML variant or wrong platform build.
Which Partitions Are A/B Slotted (and Why)
Section titled “Which Partitions Are A/B Slotted (and Why)”| Category | Examples | Slotted? | Reason |
|---|---|---|---|
| Boot chain root of trust | xbl, tz, hyp, aop | No | Small, tightly coupled, verified as a chain; brick risk too high to duplicate blindly |
| OS runtime | boot, super, vendor_boot | Yes | Large, frequent updates; need seamless OTA |
| Co-processor firmware | modem, adsp, cdsp | Yes | Independent version streams from Android |
| Verification metadata | vbmeta | Yes | Must match the OS slot being activated |
| Shared persistent state | persist, misc, userdata | No | Must survive slot switches; not versioned as A/B pairs |
| Factory/security | frp, devinfo | No | Tied to device identity, not OS version |
Partition Map Variants Across Programs
The names stay remarkably consistent across SA8155P programs; the sizes and LUN assignment do not. A rear-seat-only variant may shrink super and grow userdata. A telematics-heavy variant enlarges modem. Always flash with the XML set from the exact build ID you’re deploying. Mixing XML from Build A with images from Build B is the fastest path to a bench brick.
Module 0.3 (Memory & Storage) introduced LUNs and why boot lives separately from OS. Module 5.2 (Boot Chain) walks XBL → ABL execution order. Page 8.2 (QFIL) uses these XML files. Page 8.5 (OTA Architecture) explains how the inactive slot gets written during updates.
Takeaways
Section titled “Takeaways”- GPT on UFS LUNs defines every partition; names are your flash vocabulary.
- LUN 0 = boot chain (xbl, abl, tz); LUN 1 = OS, modem, data.
- A/B slots (
_a/_b) apply to updatable firmware; persist, misc, and userdata stay singular. - rawprogram*.xml handles bulk writes; patch*.xml handles post-flash fixups. Always match the platform variant.
Check Your Understanding
1. Which partition is the primary reason A/B OTA can update the OS without rewriting XBL on LUN 0?
Applied2. In rawprogram.xml, what does physical_partition_number="0" typically indicate?
Recall3. Why are persist and misc NOT A/B slotted?
Recall4. You are running slot A. An OTA campaign applies to the inactive slot. Which partition set receives the write?
Applied5. A flash log shows `FAILED (remote: partition table doesn't exist)` when programming `modem` on LUN 2, but your colleague's package uses LUN 1. What UFS concept explains the mismatch?
SynthesisConnects to: Module 0 — Memory & Storage
6. After OTA, ABL must boot slot B. Which LUN 0 component selects the slot without being A/B-duplicated itself?
SynthesisConnects to: Module 5 — Boot Chain
- Android Partitions Overview — Official AOSP guide to system, vendor, boot, and dynamic partition layout inside
super, matching the partition names you flash weekly. - A/B System Updates — How Android names and manages
_a/_bslot pairs, bootctrl metadata, and the inactive-slot write model this page maps to GPT entries. - Dynamic Partitions — Explains the
supercontainer, logical sub-partitions, and why rawprogram flashes one blob instead of individualsystem.imgfiles. - UEFI Specification (GPT) — The GUID Partition Table standard that defines how LUN sector ranges, partition labels, and GUIDs are stored on UFS.
- Qualcomm Developer Portal — Entry point for platform-specific flash packages, programmer binaries, and BSP documentation tied to automotive SoCs like SA8155P.
- JEDEC UFS Standard — The Universal Flash Storage specification underlying multi-LUN automotive storage and sector-addressed programming.