Skip to content

Memory, Storage & Boot Media

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 but may never have asked: where does this data physically live, and why does the partition map mention LUN0 and LUN1? This page answers that.

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 pyramid: fast and small at the top, slow and large 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

eMMC and UFS are not interchangeable: 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.

Mental Model

Think of LPDDR as the kitchen counter — everything actively being cooked lives here, but wipe the power and it’s empty. Think of UFS as the pantry and freezer — ingredients persist between meals. LUNs are separate 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).

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

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

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

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
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 for general compute would make the UI feel like it’s running through molasses. Why? Random access latency.

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.

  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?

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

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