AOSP Framework & Internals
3 min read

Block Drivers

Learn how Android manages massive storage devices like eMMC and UFS through random-access block abstraction.

While character drivers handle streaming data, Android devices must also store massive amounts of persistent data, such as the operating system itself, user photos, and installed applications.

This persistent storage is managed by Block Drivers.

What is a Block Driver?

A block driver is designed for hardware devices that hold data in fixed-size blocks (typically 512 bytes or 4KB) and allow for random access.

Unlike a character device, you can instantly request block number 50,000 without having to read blocks 1 through 49,999. Flash memory chips (eMMC, UFS, NVMe) are the primary examples of block devices in an Android smartphone.

# List block devices on an Android device
# Notice the 'b' at the start of the line indicating a block device
adb shell ls -l /dev/block
# Output example: brw------- 1 root root 259, 0 2024-01-01 12:00 sda

Storage Technologies in Android

The evolution of Android performance is heavily tied to the evolution of block storage hardware:

  1. eMMC (Embedded MultiMediaCard): The older standard used in early Android phones and budget devices today. It is half-duplex, meaning it cannot read and write at the same time, severely bottlenecking app launch speeds.
  2. UFS (Universal Flash Storage): The standard for modern mid-range and flagship Android devices. UFS is full-duplex (simultaneous read/write) and utilizes a SCSI-like command set, offering SSD-like speeds in a mobile form factor.
  3. NVMe: Used extensively by Apple and occasionally in specialized Android hardware, offering direct PCIe lane access for massive bandwidth.

The Block Layer Architecture

Block drivers are significantly more complex than character drivers because random access storage is notoriously slow compared to CPU speeds.

Request Queues

If an app asks to read a file, and immediately after, another app asks to read a different file, the kernel does not process these requests sequentially immediately.

Instead, it places the requests into an I/O Request Queue. The kernel's I/O Scheduler then sorts, merges, and reorders these requests to minimize the physical latency of the flash chip before sending them down to the actual UFS block driver.

Partitioning and Block Devices

In Android, the physical flash chip is usually represented as a primary block device (e.g., /dev/block/sda for a UFS drive).

The bootloader carves this physical drive into logical partitions (boot, system, userdata). The kernel reads the GUID Partition Table (GPT) and automatically creates sub-block devices for each partition (e.g., /dev/block/sda1, /dev/block/sda2).

# You can view all block devices and their sizes (in bytes/blocks)
adb shell cat /proc/partitions

Android framework developers rarely interact with block drivers directly. The kernel mounts file systems (like EXT4 or F2FS) on top of these block devices, allowing user-space apps to simply use standard java.io.File APIs.