At the heart of Android's Inter-Process Communication (IPC) is the Binder driver. Unlike traditional Linux IPC mechanisms (pipes, sockets, message queues), Binder is specifically optimized for Android's object-oriented, heavily multithreaded environment.
Binder as a Linux Kernel Driver
Binder is implemented as a character device driver within the Linux kernel (drivers/android/binder.c). It operates strictly in kernel space, ensuring security and isolation. Processes interact with it via the standard open(), mmap(), and ioctl() system calls.
/dev/binder, /dev/vndbinder, /dev/hwbinder
Historically, there was only one Binder device. With Project Treble (Android 8.0), Google split Binder into three distinct domains to enforce modularity and prevent vendor code from accessing core framework APIs directly:
/dev/binder: The framework binder. Used for IPC between the system server and standard Android applications./dev/vndbinder: The vendor binder. Used exclusively for IPC between different vendor-specific daemons./dev/hwbinder: The hardware binder. Used for IPC between the framework and the Hardware Abstraction Layer (HAL).
mmap-based Shared Memory Region
When a process (like an app) opens the Binder driver, it immediately calls mmap(). This maps a region of physical memory into the process's virtual address space. Crucially, the Binder kernel driver maps this same physical memory into kernel space.
By default, the framework allocates a 1MB memory buffer for each process to handle incoming Binder transactions. (Note: Async transactions are limited to half of this space).
One-copy Data Transfer Mechanism
The mmap architecture is the secret to Binder's performance. In a traditional IPC mechanism like a pipe or socket, moving data from Process A to Process B requires two copies:
- Process A copies data from user space to kernel space.
- Kernel copies data from kernel space to Process B's user space.
Binder requires only one copy.
When Process A sends a message to Process B, it passes the data to the kernel via ioctl. The kernel copies the data directly from Process A's user space into the memory region that was mmap-ed for Process B. Process B can then read the data directly from its own user space without any further copying.
Why Binder is Faster than Pipes and Sockets
- Reduced memory copying: The one-copy mechanism significantly reduces memory bus bandwidth and CPU overhead.
- Thread Pool Management: The driver natively understands thread pools. If Process A calls Process B, the driver can automatically wake up an idle thread in Process B's Binder thread pool.
- Object References: Binder tracks object references (IBinder pointers) across process boundaries. It automatically manages reference counting and triggers Death Recipients if a process holding an object dies.