Skip to content

Memory, Storage & Boot Media

Intermediate9 min read
Assumes: 0.1 Anatomy of an SoC
TL;DR

Memory (SRAM, DRAM) is fast and volatile: it holds running code and data but loses everything on power loss. Storage (Flash, eMMC, UFS) is slower and persistent; it holds bootloaders, OS images, and user data across reboots. On Qualcomm automotive platforms, UFS is the primary storage, organized into LUNs (Logical Units), separate virtual disks on one physical chip. Boot firmware (XBL) often lives on a different LUN than the OS (Android/QNX), which is why A/B updates can swap system partitions without touching the boot chain. When QFIL writes a partition, it’s targeting a specific offset on a specific LUN, not “the hard drive” as a single blob.

You flash partitions weekly — click, wait, pray — but may never have asked: where does this data physically live, and why does the partition map keep mentioning LUN0 and LUN1? Let’s fix that knowledge gap before it costs you a three-hour debug session.

Memory (RAM) Storage (Flash/UFS)
Speed Very fast (ns) Slower (µs–ms)
Persistence Volatile (lost on power-off) Non-volatile (survives power-off)
Typical size 4–16 GB (LPDDR) 32–256 GB (UFS)
Holds Running programs, heap, stack, GPU textures Bootloaders, OS images, firmware, logs, user data
Automotive analogy Workbench (active project) Filing cabinet (archived projects)

Think of it this way: RAM is “right now”; storage “stays.”

Not all memory is equal. The CPU accesses data through a hierarchy that looks suspiciously like a corporate org chart: fast and expensive at the top, slow and plentiful at the bottom.

flowchart BT
    REG["CPU Registers<br/>~KB · fastest"]
    L1["L1 Cache (SRAM)<br/>~64 KB per core"]
    L2["L2 Cache (SRAM)<br/>~256 KB – 1 MB per cluster"]
    L3["L3 Cache (SRAM)<br/>~2–8 MB shared"]
    DRAM["Main Memory — LPDDR (DRAM)<br/>4–16 GB"]
    UFS["Storage — UFS Flash<br/>32–256 GB · slowest"]

    REG --- L1
    L1 --- L2
    L2 --- L3
    L3 --- DRAM
    DRAM --- UFS

When boot completes, the flow is: UFS → DRAM → CPU caches → execution. Flash holds the bits; DRAM holds the running image; caches hide DRAM latency from the CPU.

  • On-chip in CPU caches (L1/L2/L3)
  • Extremely fast, expensive per bit, small
  • No refresh needed (unlike DRAM); “static” holds data while powered
  • You don’t buy SRAM separately; it’s inside the SoC die
  • Off-chip LPDDR4X/LPDDR5 packages soldered next to the SoC
  • Large (gigabytes), moderate speed, volatile
  • Requires periodic refresh; “dynamic” cells leak charge
  • Shared by all subsystems: CPU, GPU, DSP, NPU, ISP all access the same LPDDR pool via the memory controller
  • Hypervisor assigns memory regions to each VM; QNX gets its slice, Android gets its slice

DRAM is dynamic and large (main memory). SRAM is small and speedy (cache).

Flash retains data without power. Automotive Qualcomm platforms overwhelmingly use UFS (Universal Flash Storage), faster and more flexible than older eMMC.

Technology Interface Typical Speed Automotive Status
NOR Flash Parallel/SPI Fast read, slow write Boot sectors, EEPROM-style config
NAND Flash Raw Block-oriented Underlying technology in eMMC/UFS
eMMC Legacy embedded MMC ~250 MB/s read Older IVI, being phased out
UFS M-PHY, SCSI-like ~1–2+ GB/s read Current Qualcomm cockpit standard
Common Gotcha

Beginner thinks eMMC and UFS are interchangeable storage — just pick the cheaper one. That’s like saying HDMI and USB-C are the same because they’re both connectors.

Reality: different pinouts, different drivers, different partition tools. A board designed for UFS cannot boot from eMMC without hardware changes. Always check the BOM and platform BSP docs before assuming storage type. This assumption has derailed more board bringups than anyone wants to admit.

Common Gotcha

Beginner thinks more RAM means faster boot. If only it were that simple — we’d all have 128 GB boards and sub-second boot times.

Reality: boot time is dominated by storage I/O and the init sequence — reading XBL/UEFI/ABL from UFS, DDR training, loading kernel into LPDDR, then starting dozens of services. Doubling RAM from 8 GB to 16 GB barely moves cold-boot numbers if UFS read speed and service startup order stay the same. Want faster boot? Profile the init chain, not the RAM spec sheet.

Mental Model

Think of LPDDR as the kitchen counter — everything actively being cooked lives here, but wipe the power and it’s empty (hope you weren’t mid-recipe). Think of UFS as the pantry and freezer — ingredients persist between meals, even if you trip the circuit breaker. LUNs are labeled cabinets in the pantry — snacks in one, frozen meals in another, cleaning supplies in a third. You don’t reorganize the whole pantry to swap one frozen dinner (A/B system update) if the recipe cards (bootloader) live in a locked cabinet (separate LUN).

Mnemonic: SRAM is your hands (fast, tiny), DRAM is the counter (bigger, needs constant attention), UFS is the fridge (huge, slow to open, but your food survives the night).

UFS LUNs: Why “One Chip” ≠ “One Disk”

Section titled “UFS LUNs: Why “One Chip” ≠ “One Disk””

Here’s where it gets interesting — and where most flash-related confusion lives.

UFS presents storage as Logical Units (LUNs): independent address spaces on the same physical flash die, like virtual disks. One chip, multiple personalities.

On Qualcomm automotive platforms, you’ll commonly see:

LUN Typical Contents Why Separated
LUN 0 Boot chain: XBL, UEFI, ABL, DDR training firmware, some trust zone images Critical boot path: small, protected, rarely updated
LUN 1+ OS partitions: boot, vendor, system, userdata, DSP firmware, modem (AMSS), persist, misc Frequently updated: OTA targets, A/B slots
  1. Boot isolation: Corrupting an OTA’d Android system partition on LUN 1 doesn’t brick the XBL bootloader on LUN 0 (assuming verified boot catches bad images).
  2. Different update policies: Boot chain updates are rare, heavily tested, and often require special signing. OS updates happen monthly.
  3. Access control: TrustZone and secure boot policies can restrict write access to LUN 0 independently.
  4. A/B slotting: _a and _b suffix partitions (e.g., system_a, system_b) live on the data LUN; the boot manager on LUN 0 picks the active slot.
flowchart TB
    subgraph UFS["UFS Physical Chip"]
        subgraph LUN0["LUN 0 — Boot / Trust"]
            XBL["xbl / xbl_config"]
            UEFI["uefi"]
            ABL["abl (Android Boot Loader)"]
            TZ["tz / devcfg"]
        end
        subgraph LUN1["LUN 1 — OS & Firmware"]
            BOOT["boot_a / boot_b"]
            VENDOR["vendor_a / vendor_b"]
            SYSTEM["system_a / system_b"]
            ADSP["adsp_a / adsp_b"]
            MODEM["modem_a / modem_b"]
            USER["userdata"]
        end
    end

    POWER["Power On"] --> XBL
    XBL --> UEFI
    UEFI --> ABL
    ABL -->|"Select slot A or B"| BOOT
    BOOT --> SYSTEM

One way to remember: LUN 0 is for launch (boot); LUN 1 is for living (OS and apps).

A/B Booting and XBL on a Separate LUN

A/B updates maintain two copies of updatable partitions. During OTA, the inactive slot is written while the active slot continues running. On reboot, the boot loader (ABL) switches slots. Because XBL lives on LUN 0, outside the A/B slot mechanism, a failed system_b flash still leaves XBL intact to fall back to system_a. This is why partition maps show boot chain entries without _a/_b suffixes but OS entries with them. Module 8.5 (OTA Architecture) walks through the full update flow.

Boot Media: Where Bootloaders Live vs Where the OS Lives

Section titled “Boot Media: Where Bootloaders Live vs Where the OS Lives”

The boot sequence reads from specific storage locations in a fixed order:

  1. ROM code (in SoC, not flash): first instructions after power-on; loads XBL from UFS LUN 0
  2. XBL (eXtensible Boot Loader): trains DDR, initializes basic hardware, loads UEFI
  3. UEFI: platform initialization, may load TrustZone, hypervisor, or ABL
  4. ABL (Android Boot Loader) or QNX IFS loader: loads the OS kernel from LUN 1 partitions
  5. OS kernel: loaded into LPDDR from flash, then execution transfers to RAM

Critical insight: the OS doesn’t run from flash. Flash holds the stored image; on boot, it’s copied (or memory-mapped) into DRAM, and the CPU executes from RAM. Flash is the archive; DRAM is the stage.

Stage Stored On Executes From
XBL / UEFI UFS LUN 0 SRAM / limited DRAM during early boot
Hypervisor / QNX IFS UFS LUN 1 LPDDR after load
Android kernel + ramdisk UFS LUN 1 (boot partition) LPDDR after load
Running AAOS apps — LPDDR (heap, code cache)
AMSS modem firmware UFS LUN 1 (modem partition) Modem internal RAM + shared LPDDR
Think About It

Your QFIL flash takes 8 minutes. The same data copies to a USB drive in 30 seconds. Your coffee is getting cold. Why is QFIL taking so long — is it just slow, or is something more interesting happening?

Reveal Answer

QFIL writes through Firehose protocol to UFS LUN sectors — not a bulk file copy. Each partition targets a specific LUN, offset, and slot (system_a, modem, xbl) with erase-write-verify cycles, sparse image parsing, and often secure-boot signature checks before the next region starts. USB copy is sequential block I/O with no per-partition handshake, no DDR training between stages, and no digest validation. Those 8 minutes are surgical programming across dozens of named regions on LUN 0 and LUN 1 — a wrong-offset “fast” copy would silently brick the board. Your coffee can wait; the firmware can’t.

Type Read Speed Write Speed Size Persists Power-Off? Cost/GB
SRAM (cache) ~1 ns ~1 ns KB–MB No Highest
LPDDR ~10–20 ns ~10–20 ns 4–16 GB No High
UFS ~100 µs ~ms (varies) 32–256 GB Yes Low
eMMC (legacy) Slower than UFS Slower 8–64 GB Yes Lower

When someone asks “why not run everything from flash to save RAM?” — flash is orders of magnitude slower for random access and has limited write endurance. RAM exists because executing directly from UFS would make the UI feel like it’s running through wet concrete. The physics of latency don’t negotiate.

Where You'll See This

When QFIL writes partitions, it’s targeting specific offsets on UFS storage: a particular LUN, a named partition, a defined byte range. Your flash configuration XML (or programmer build) maps human-readable names to physical locations:

  • Flashing xbl → LUN 0, boot chain region
  • Flashing system_a → LUN 1, A-slot OS image
  • Flashing modem → LUN 1, AMSS firmware region
  • Flashing adsp → LUN 1, Hexagon DSP image

A “successful flash” that wrote to the wrong LUN or wrong slot is worse than a failed flash. It silently corrupts the wrong region. Always verify:

  1. Platform variant (SA8155P vs SA8295P; partition sizes differ)
  2. Storage type (UFS vs eMMC)
  3. Active slot (_a vs _b) before OTA testing
  4. Sparse vs raw image format for the target partition

When debugging “won’t boot after flash,” the first question is: “Did we touch LUN 0 (boot chain) or only LUN 1 (OS)?” If LUN 0 is intact, recovery options exist. If XBL is corrupted, you’re looking at emergency recovery mode or JTAG, not a simple re-flash of system.

Module 5.2 (The Boot Chain) walks step-by-step through XBL → UEFI → ABL with the exact partition names. Module 8.1 (Qualcomm Partition Map) is the reference you’ll keep open during flash sessions. Module 8.2 (QFIL) covers the tool that writes these LUN offsets in production.

Connect the Dots
  • Module 0.4 (Power Architecture): UFS storage requires its own power rail from the PMIC. Flash read speed depends on the UFS controller’s voltage domain being stable.
  • Module 5.2 (Boot Chain): PBL loads from UFS LUN 0. The boot chain stages map directly to the memory hierarchy: ROM → SRAM → DRAM → UFS.
  • Module 8.1 (Partition Map): The partition table lives on UFS and maps every OS image, firmware blob, and data partition to specific LUN offsets.
  • Module 8.2 (QFIL): QFIL writes directly to UFS LUN sectors via Firehose protocol. Understanding LUN layout is essential for flash recovery.
  1. RAM is volatile and fast; storage is persistent and slow. OS images live in storage, run from RAM.
  2. UFS LUNs are separate virtual disks: boot chain (LUN 0) vs OS/firmware (LUN 1+).
  3. A/B updates swap OS slots on LUN 1 without rewriting the boot chain on LUN 0.
  4. Every QFIL partition write is a surgical strike at a named offset. Know your LUN before you flash.

Check Your Understanding

1. After power loss, which data is lost?

Recall

2. Why is the XBL bootloader typically stored on a separate UFS LUN from Android system partitions?

Applied

3. During normal operation, where does the Android kernel execute from?

Applied

4. In the memory hierarchy, where is SRAM located on a Qualcomm cockpit SoC?

Recall

5. An OTA writes a corrupted `system_b` image but LUN 0 (XBL/UEFI/ABL) is intact and verified boot catches the bad signature. What recovery path is available?

Applied

6. A QFIL session accidentally writes a sparse image to the wrong partition name — `system_a` data lands in the `modem` region on LUN 1. XBL on LUN 0 is untouched. Symptom: device boots to Android but telematics is dead and `adb` shows no cellular interface. First recovery step?

Synthesis

Connects to: Module 8 — Build, Flash & Update · Module 7 — Connectivity & Telematics

Further Reading