目录
  1. 1. 一、Binder 驱动的整体架构
    1. 1.1. 1.1 Linux 内核中的位置
    2. 1.2. 1.2 Binder 的 misc 字符设备
  2. 2. 二、核心数据结构四元组
    1. 2.1. 2.1 binder_proc——进程上下文
    2. 2.2. 2.2 binder_thread——线程上下文
    3. 2.3. 2.3 binder_node——Binder 实体
    4. 2.4. 2.4 binder_ref——Binder 引用
  3. 3. 三、ioctl 命令体系
    1. 3.1. 3.1 binder_ioctl——所有操作的总入口
    2. 3.2. 3.2 BINDER_WRITE_READ——最核心的命令
  4. 4. 四、BC_TRANSACTION / BR_TRANSACTION——事务流转
    1. 4.1. 4.1 BC_TRANSACTION 的发送端处理
    2. 4.2. 4.2 binder_transaction——核心事务处理
    3. 4.3. 4.3 BR_TRANSACTION 的接收端处理
  5. 5. 五、一次拷贝的奥秘
    1. 5.1. 5.1 传统 IPC 的数据拷贝次数
    2. 5.2. 5.2 Binder 的一次拷贝原理
  6. 6. 六、Binder 线程池模型
  7. 7. 七、死亡通知机制
  8. 8. 八、Binder 协议版本演进
  9. 9. 九、核心面试题
【深入内核篇】Binder驱动

Binder 是 Android 的核心 IPC 机制,运行在 Linux 内核空间。从最底层的 /dev/binder 字符设备,到内核中的 binder_proc/binder_thread/binder_node/binder_ref 四元组数据结构,再到著名的”一次拷贝”机制,Binder 驱动的设计体现了嵌入式场景下对效率、安全和简洁性的极致追求。本文深入内核层,基于 Android 通用内核(common kernel)的 Binder 驱动源码进行全面分析。

一、Binder 驱动的整体架构

1.1 Linux 内核中的位置

用户空间
┌──────────────┐ ┌──────────────┐
│ Client 进程 │ │ Server 进程 │
│ │ │ │
│ BpBinder │ │ BBinder │
│ (Binder 代理)│ │ (Binder 实现)│
│ ↓ │ │ ↑ │
│ ioctl() │ │ ioctl() │
└──────┬───────┘ └──────┬───────┘
│ │
═══════╪═══════════════════════════════╪════════
│ Linux Kernel │
└───────┬───────────────────────┘

┌──────────▼──────────┐
│ /dev/binder 设备 │
│ binder_ioctl() │
│ binder_ioctl_write_read()│
└──────────┬──────────┘

┌──────────▼──────────┐
│ binder_transaction │ ← "一次拷贝" 的核心
└─────────────────────┘

AOSP 内核源码路径:在 Android 通用内核(common kernel)中:

  • drivers/android/binder.c — Binder 驱动主文件
  • drivers/android/binder_alloc.c — Binder 内存分配
  • drivers/android/binder_trace.h — Binder trace 点

Android 用户空间 Binder 库:

  • frameworks/native/libs/binder/ — libbinder (C++ 用户空间库)
    • Binder.cpp / BpBinder.cpp / IPCThreadState.cpp / Parcel.cpp

1.2 Binder 的 misc 字符设备

Binder 驱动在 Linux 中注册为 misc 字符设备:

// drivers/android/binder.c
static const struct file_operations binder_fops = {
.owner = THIS_MODULE,
.poll = binder_poll,
.unlocked_ioctl = binder_ioctl, // 核心:所有操作通过 ioctl
.compat_ioctl = binder_ioctl,
.mmap = binder_mmap, // 核心:内存映射(一次拷贝的基础)
.open = binder_open, // 打开设备时创建 binder_proc
.flush = binder_flush,
.release = binder_release, // 关闭时清理资源
};

static struct miscdevice binder_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "binder", // 设备名:/dev/binder
.fops = &binder_fops
};

static int __init binder_init(void)
{
// 注册 misc 设备
ret = misc_register(&binder_miscdev);
// 创建 debugfs 目录
binder_debugfs_dir_entry_root = debugfs_create_dir("binder", NULL);
// ...
}

二、核心数据结构四元组

Binder 驱动用四个核心数据结构来描述所有通信实体。

2.1 binder_proc——进程上下文

每个使用 Binder 的进程在驱动中对应一个 binder_proc 结构:

// drivers/android/binder.c
struct binder_proc {
struct hlist_node proc_node; // 挂入全局 binder_procs 哈希表
struct rb_root threads; // 此进程中的所有 binder_thread(红黑树)
struct rb_root nodes; // 此进程中所有 binder_node(Binder 实体)
struct rb_root refs_by_desc; // 此进程中所有 binder_ref(按 handle 索引)
struct rb_root refs_by_node; // 按 binder_node 索引
struct list_head waiting_threads; // 等待中的线程
int pid;
struct task_struct *tsk;
struct list_head todo; // 此进程的待处理事务队列
wait_queue_head_t wait; // 等待队列(线程在此阻塞等待工作)
struct binder_alloc alloc; // Binder 内存分配器(mmap 的内存)
int max_threads; // 最大线程数(默认 15)
int requested_threads; // 已请求但未启动的线程数
int requested_threads_started; // 已启动的线程数
};

当进程调用 open("/dev/binder") 时触发 binder_open()

static int binder_open(struct inode *nodp, struct file *filp)
{
struct binder_proc *proc;
proc = kzalloc(sizeof(*proc), GFP_KERNEL);
proc->tsk = current->group_leader;
INIT_LIST_HEAD(&proc->todo);
init_waitqueue_head(&proc->wait);
proc->default_priority = task_nice(current);
// ... binder_alloc 初始化
binder_alloc_init(&proc->alloc);
// ...
filp->private_data = proc; // 绑定到 file 对象
hlist_add_head(&proc->proc_node, &binder_procs); // 加入全局列表
return 0;
}

2.2 binder_thread——线程上下文

每个在 Binder 驱动中工作的线程对应一个 binder_thread

struct binder_thread {
struct binder_proc *proc; // 所属进程
struct rb_node rb_node; // 挂入 proc->threads 红黑树
struct list_head waiting_thread_node; // 挂入 waiting_threads
int pid;
int looper; // BINDER_LOOPER_STATE_* 标志
struct binder_transaction *transaction_stack; // 事务栈(嵌套调用)
struct list_head todo; // 此线程的待处理事务
struct binder_error return_error; // 出错时的返回值
wait_queue_head_t wait; // 线程等待队列
bool looper_need_return; // 需要返回的信号
};

binder_thread 中的 transaction_stack 维护了一个 RPC 调用栈,记录了从当前事务回溯到最外层事务的完整路径。这对理解 Binder 的事务嵌套至关重要——当 Binder 调用链是 A→B→C 时,C 中的 transaction_stack 指向 B 发给 C 的事务,该事务的 from_parent 又指向 A 发给 B 的事务。

2.3 binder_node——Binder 实体

每个 Binder 对象(即 BnXXX 服务端)在驱动中有一个 binder_node。这是 Service 端暴露的实体的内核表示:

struct binder_node {
int debug_id;
struct binder_work work;
union {
struct rb_node rb_node; // 挂入 proc->nodes(按 ptr+cookie 索引)
struct hlist_node dead_node; // 死亡列表
};
struct binder_proc *proc; // 所属进程
struct hlist_head refs; // 引用此 node 的所有 binder_ref
int internal_strong_refs; // 内部强引用计数
int local_weak_refs; // 本地弱引用计数
int local_strong_refs; // 本地强引用计数
int tmp_refs; // 临时引用计数
binder_uintptr_t ptr; // 用户空间 BBinder 的地址
binder_uintptr_t cookie; // BBinder 的指针
// ... 死亡通知相关字段
};

关键点:ptrcookie 分别存储了用户空间 BBinder 对象的弱指针地址和实际指针。驱动通过 binder_node 将物理地址映射为跨进程的逻辑实体。

2.4 binder_ref——Binder 引用

每个进程对远程 Binder 实体的引用对应一个 binder_ref。这是 Client 端持有的代理:

struct binder_ref {
int debug_id;
struct rb_node rb_node_desc; // 挂入 proc->refs_by_desc(按 desc/handle 索引)
struct rb_node rb_node_node; // 挂入 proc->refs_by_node(按 node 索引)
struct hlist_node node_entry; // 挂入 node->refs
struct binder_proc *proc; // 持有此引用的进程
struct binder_node *node; // 指向的 binder_node
uint32_t desc; // handle 号(进程内唯一)
int strong; // 强引用计数
int weak; // 弱引用计数
struct binder_ref_death *death; // 死亡通知
};

每个 binder_ref 有一个 desc(通常称为 handle),在目标进程内是唯一的。当 Client 通过 Binder 发送请求时,它使用的是 handle(如 handle=1 对应 ServiceManager),驱动在内部通过 binder_ref 找到对应的 binder_node,进而定位到 Server 进程。

三、ioctl 命令体系

3.1 binder_ioctl——所有操作的总入口

// drivers/android/binder.c
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct binder_proc *proc = filp->private_data;
void __user *ubuf = (void __user *)arg;

switch (cmd) {
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
break;
case BINDER_SET_MAX_THREADS:
proc->max_threads = (int)arg;
break;
case BINDER_SET_CONTEXT_MGR:
ret = binder_ioctl_set_ctx_mgr(filp); // 注册为 ServiceManager
break;
case BINDER_THREAD_EXIT:
binder_thread_exit(proc, thread);
break;
case BINDER_VERSION:
// 返回 Binder 协议版本号
break;
}
return ret;
}

3.2 BINDER_WRITE_READ——最核心的命令

这是 Binder 中使用频率最高的 ioctl,几乎所有通信(事务发送、回复、ACK、死亡通知)都通过它完成:

static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread)
{
struct binder_write_read bwr;

// 1. 从用户空间拷贝 binder_write_read 结构
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
ret = -EFAULT;
goto out;
}

// 2. 执行写操作(BC_TRANSACTION / BC_REPLY 等)
if (bwr.write_size > 0) {
ret = binder_thread_write(proc, thread,
bwr.write_buffer, bwr.write_size, &bwr.write_consumed);
}

// 3. 执行读操作(BR_TRANSACTION / BR_REPLY 等)
if (bwr.read_size > 0) {
ret = binder_thread_read(proc, thread, bwr.read_buffer,
bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK);
}

// 4. 将结果拷贝回用户空间
if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {
ret = -EFAULT;
}
return ret;
}

binder_write_read 结构的定义:

// drivers/android/binder.c (UAPI header: include/uapi/linux/android/binder.h)
struct binder_write_read {
binder_size_t write_size; // 写缓冲区大小
binder_size_t write_consumed; // 实际消耗的写字节数
binder_uintptr_t write_buffer; // 写缓冲区的用户空间地址
binder_size_t read_size; // 读缓冲区大小
binder_size_t read_consumed; // 实际消耗的读字节数
binder_uintptr_t read_buffer; // 读缓冲区的用户空间地址
};

四、BC_TRANSACTION / BR_TRANSACTION——事务流转

4.1 BC_TRANSACTION 的发送端处理

当 Client 发起 Binder 调用时,用户空间构造 BC_TRANSACTION 命令,通过 ioctl 写入驱动。驱动在 binder_thread_write 中处理:

// drivers/android/binder.c
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed)
{
while (ptr < end && thread->return_error.cmd == BR_OK) {
// 获取命令
get_user(cmd, (uint32_t __user *)ptr);
switch (cmd) {
case BC_TRANSACTION:
case BC_REPLY: {
struct binder_transaction_data tr;
// 从用户空间拷贝事务数据
copy_from_user(&tr, ptr, sizeof(tr));

// 处理事务
binder_transaction(proc, thread, &tr,
cmd == BC_REPLY, 0);
break;
}
// ... 其他命令
}
}
}

4.2 binder_transaction——核心事务处理

这是 Binder 驱动的灵魂——所有跨进程数据传递都在这里完成:

// drivers/android/binder.c
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, int reply,
binder_size_t extra_buffers_size)
{
// 1. 查找目标进程
if (reply) {
// 回复模式:从 transaction_stack 找到源事务
in_reply_to = thread->transaction_stack;
target_proc = in_reply_to->from->proc;
target_thread = in_reply_to->from;
target_node = NULL;
} else {
// 发送模式:根据 handle 找到 binder_ref → binder_node → target_proc
if (tr->target.handle) {
// 非零 handle:查找 binder_ref
ref = binder_get_ref_olocked(proc, tr->target.handle, true);
target_node = ref->node;
target_proc = target_node->proc;
} else {
// handle == 0 → ServiceManager
target_node = binder_context_mgr_node;
target_proc = target_node->proc;
}
}

// 2. 分配事务对象
t = kzalloc(sizeof(*t), GFP_KERNEL);

// 3. ★★★ 核心:数据拷贝 ★★★
// 在目标进程的 mmap 区域中分配缓冲区
t->buffer = binder_alloc_buf(&target_proc->alloc, tr->data_size,
tr->offsets_size, extra_buffers_size, !reply && (t->flags & TF_ONE_WAY));

// 从发送者用户空间拷贝数据到内核空间(目标进程的 mmap 映射区域)
copy_from_user(t->buffer->data,
(const void __user *)(uintptr_t)tr->data.ptr.buffer,
tr->data_size);

// 4. 处理 Binder 对象(嵌套的 Binder 对象)
// binder_flat_binder_object → binder_node → binder_ref
// 在目标进程中创建新的 binder_ref(或复用已有)
off_end = (void *)off_start + tr->offsets_size;
for (; offp < off_end; offp++) {
struct flat_binder_object *fp;
fp = (struct flat_binder_object *)(t->buffer->data + *offp);
switch (fp->hdr.type) {
case BINDER_TYPE_BINDER: // Server 端传引用给自己
ret = binder_translate_binder(fp, t, thread);
break;
case BINDER_TYPE_HANDLE: // Client 端传 handle 给对端
ret = binder_translate_handle(fp, t, thread);
break;
case BINDER_TYPE_FD: // 文件描述符传输
ret = binder_translate_fd(fp, t, thread);
break;
}
}

// 5. 将事务挂入目标进程/线程的 todo 队列
if (target_thread) {
// 同步回复:直接发给等待的线程
binder_enqueue_thread_work(target_thread, &t->work);
wake_up_interruptible_sync(&target_thread->wait);
} else {
// 新事务:放入进程的 todo 队列
binder_enqueue_work_ilocked(&t->work, &target_proc->todo);
wake_up_interruptible(&target_proc->wait);
}
}

4.3 BR_TRANSACTION 的接收端处理

目标进程在 binder_thread_read 中等待并获取事务:

// drivers/android/binder.c
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
{
// 循环等待工作
while (1) {
if (!list_empty(&thread->todo)) {
w = list_first_entry(&thread->todo, struct binder_work, entry);
} else if (!list_empty(&proc->todo)) {
w = list_first_entry(&proc->todo, struct binder_work, entry);
} else {
// 没有待处理工作 → 进入等待
if (non_block) {
ret = -EAGAIN; goto out;
}
// 在内核等待队列上睡眠
wait_event_freezable_exclusive(proc->wait,
binder_has_work(thread));
}

switch (w->type) {
case BINDER_WORK_TRANSACTION: {
t = container_of(w, struct binder_transaction, work);
// 如果是 BR_TRANSACTION(非回复),记录事务栈
if (!(t->flags & TF_ONE_WAY)) {
t->to_parent = thread->transaction_stack;
t->to_thread = thread;
thread->transaction_stack = t;
}
// 构造 BR_TRANSACTION 响应写入用户空间
// ... put_user(BR_TRANSACTION, ...)
// 用户空间的 IPCThreadState 收到后,写入 Parcel 并进行 dispatch
}
}
}
}

五、一次拷贝的奥秘

5.1 传统 IPC 的数据拷贝次数

传统 IPC(如 SysV 消息队列、Unix Domain Socket)至少需要两次拷贝:

  1. 发送者用户空间 → 内核缓冲区
  2. 内核缓冲区 → 接收者用户空间

如果数据量大,两次拷贝加上上下文切换成为性能瓶颈。

5.2 Binder 的一次拷贝原理

Binder 实现一次拷贝的关键在于 mmap + 内核在接收者地址空间分配缓冲区

步骤1:Server 进程初始化时,通过 mmap 将内核缓冲区映射到用户空间
binder_mmap(proc, vma)
→ 在内核中分配物理内存页
→ 映射到 Server 进程的用户空间地址

步骤2:Client 发起 Binder 调用时:
binder_transaction()
→ binder_alloc_buf(&target_proc->alloc, data_size, ...)
(在目标进程(Server)的 mmap 区域中分配缓冲区)
→ copy_from_user(t->buffer->data, client_user_buf, data_size)
(从 Client 用户空间拷贝到内核空间 —— 同时也是 Server 的 mmap 区域)

步骤3:Server 收到 BR_TRANSACTION 后:
直接读取自己的 mmap 区域,无需额外拷贝!
Parcel 数据已经在内核中 → 同时也映射在 Server 的进程地址空间
// drivers/android/binder_alloc.c
// binder_alloc_buf 在目标进程的 mmap 区域中分配缓冲区
struct binder_buffer *binder_alloc_buf(struct binder_alloc *alloc,
binder_size_t data_size,
binder_size_t offsets_size,
binder_size_t extra_buffers_size,
int is_async)
{
// 遍历 alloc->free_buffers 红黑树,找到合适大小的空闲缓冲区
// 或者扩展 mmap 区域
// 返回的 binder_buffer->data 指向目标进程 mmap 区域内的地址
}

// drivers/android/binder.c
static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct binder_proc *proc = filp->private_data;

// 限制 mmap 大小为 4MB
if ((vma->vm_end - vma->vm_start) > SZ_4M)
vma->vm_end = vma->vm_start + SZ_4M;

// 分配物理页
proc->alloc.buffer = (void *)vma->vm_start;
// 使用 vm_insert_page 将物理页映射到用户空间
alloc->pages = kvmalloc_array(...);
for (i = 0; i < alloc->buffer_size / PAGE_SIZE; i++) {
// 分配物理页
page = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
alloc->pages[i] = page;
// 映射到进程的虚拟地址空间
vm_insert_page(vma, (unsigned long)alloc->buffer + i * PAGE_SIZE, page);
}
return 0;
}

关键点总结:

  • 内核只做一次 copy_from_user,数据从发送者用户空间进入内核页。
  • 接收者通过 mmap 可以直接访问这些内核页(同一块物理内存映射到了不同的虚拟地址空间)。
  • 因此,Binder 完成了 一次拷贝 的跨进程通信。

六、Binder 线程池模型

Binder 支持 Service 端多线程处理。驱动管理如下:

static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed)
{
switch (cmd) {
// ...
case BC_REGISTER_LOOPER:
// 线程注册为 Binder 工作线程
thread->looper |= BINDER_LOOPER_STATE_REGISTERED;
break;
case BC_ENTER_LOOPER:
thread->looper |= BINDER_LOOPER_STATE_ENTERED;
break;
case BC_EXIT_LOOPER:
thread->looper |= BINDER_LOOPER_STATE_EXITED;
break;
}
}

static int binder_thread_read(...)
{
// 如果需要更多线程(当前没有空闲线程且工作积压)
if (proc->requested_threads + proc->requested_threads_started
< proc->max_threads &&
(thread->looper & (BINDER_LOOPER_STATE_REGISTERED |
BINDER_LOOPER_STATE_ENTERED)) &&
!list_empty(&proc->todo)) {
proc->requested_threads++;
// 告知用户空间需要启动新线程
put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer);
}
}

默认最大线程数为 15(proc->max_threads),可通过 BINDER_SET_MAX_THREADS ioctl 调整。ServiceManager 设置为 0(不需要额外线程池)。

七、死亡通知机制

Binder 支持死亡通知(Death Recipient),当 Service 端进程意外退出时,Client 端可以收到通知。

// Client 端发送 BC_REQUEST_DEATH_NOTIFICATION
case BC_REQUEST_DEATH_NOTIFICATION: {
uint32_t target;
binder_uintptr_t cookie;
struct binder_ref *ref;
struct binder_ref_death *death;

get_user(target, (uint32_t __user *)ptr);
get_user(cookie, (binder_uintptr_t __user *)(ptr + sizeof(uint32_t)));

ref = binder_get_ref_olocked(proc, target, false);
death = kzalloc(sizeof(*death), GFP_KERNEL);
death->cookie = cookie;
ref->death = death;

// 如果目标 node 已经死亡,立即返回 BR_DEAD_BINDER
if (ref->node->proc == NULL) {
binder_enqueue_work(proc, &death->work, &thread->todo);
}
}

// Server 进程退出时,binder_release 被调用:
static int binder_release(struct inode *nodp, struct file *filp)
{
struct binder_proc *proc = filp->private_data;
// 遍历所有 binder_node,标记为已死亡
binder_deferred_release(proc);
}

// 为所有引用死亡节点的地方发送 BR_DEAD_BINDER:
static void binder_send_dead_binder(struct binder_proc *proc,
struct binder_ref *ref)
{
// 向持有该 ref 的进程发送 BR_DEAD_BINDER
binder_enqueue_work(proc, &death->work, &proc->todo);
}

八、Binder 协议版本演进

Binder 协议有多个版本,通过 BINDER_VERSION ioctl 查询:

版本 特性
7 (Linux 3.x-4.x) 基础 Binder,无 scatter-gather
8 (Linux 4.14+) 引入 scatter-gather I/O(BINDER_TYPE_PTR 支持跨进程引用嵌套数据)
9 (Linux 5.4+) 引入 binderfs,支持多 Binder 实例和命名空间隔离

Android 内核通常使用版本 8 的 binder。

九、核心面试题

Q1:Binder 的”一次拷贝”到底是怎么实现的?为什么传统 IPC 需要两次?

传统 IPC 的数据路径:发送者用户空间 → 内核通用缓冲区 → 接收者用户空间(两次 copy_from_user/copy_to_user)。Binder 的优化在于:Server 进程通过 mmap 将内核分配的物理页直接映射到自己的用户空间。当 Client 发送数据时,驱动在 Server 的 mmap 区域中分配缓冲区(binder_alloc_buf),然后做一次 copy_from_user 将 Client 数据拷入这块区域。由于这块区域同时映射在 Server 的用户空间,Server 可以直接读取,无需第二次拷贝。

Q2:Binder 的 binder_node 和 binder_ref 设计解决了什么核心问题?

这是 Binder 的”能力安全模型”的实现基础。binder_node 是”能力”的实体端(Server 端),binder_ref 是”能力”的引用端(Client 端)。当 Client 通过 Binder 传递一个 handle 给另一进程时,驱动自动在目标进程创建新的 binder_ref 指向同一个 binder_node。这意味着:进程只能使用显式授予给它的 Binder 引用,无法伪造或猜测 handle,天然实现了细粒度的权限控制。这与传统的 Unix 权限模型(基于 UID/GID 的水平权限)完全不同。

Q3:Binder 如何处理递归和重入?transaction_stack 的作用是什么?

Binder 支持同步调用链(A 调 B,B 调 C),这种情况下 A 的 Binder 线程在等待 B 的回复,而 B 的线程又被 C 占用。transaction_stack 维护了调用栈关系:每个同步调用的 binder_transaction 通过 from_parentto_parent 指针链接,形成一条调用链。当 C 回复时,驱动根据 transaction_stack 找到 B 的等待线程,唤醒其处理回复。线程优先级继承(priority inheritance)也依赖 transaction_stack 在调用链上传播。

AOSP 核心路径参考:

  • drivers/android/binder.c — Binder 驱动核心
  • drivers/android/binder_alloc.c — Binder 内存分配器
  • include/uapi/linux/android/binder.h — Binder 协议头文件
  • frameworks/native/libs/binder/Binder.cpp
  • frameworks/native/libs/binder/BpBinder.cpp
  • frameworks/native/libs/binder/IPCThreadState.cpp
  • frameworks/native/libs/binder/Parcel.cpp
  • frameworks/native/libs/binder/ProcessState.cpp
打赏
  • 微信
  • 支付宝

评论