2. Binder驱动基础

Binder 驱动是 Android Binder IPC 机制在内核空间的核心实现。它不是一个字符设备驱动,而是一个混杂设备(misc device),注册在虚拟总线 platform 上,通过设备节点 /dev/binder 与用户空间交互。理解 Binder 驱动在内核源码树中的位置、文件组织方式以及设备节点的注册流程,是后续分析驱动入口函数、binder_ioctl 和内存映射的基础。

2.1 Binder驱动在内核源码树中的位置

Binder 驱动源码位于 Linux 内核的 drivers/android/ 目录下。该目录专门存放与 Android 相关的内核驱动,Binder 是其中最重要的组件之一。以下是该目录的核心文件清单:

文件名 功能描述 关键程度
binder.c Binder 驱动主实现:包含 open、release、mmap、ioctl 等文件操作函数,以及事务处理、节点管理、引用管理等核心逻辑。 核心
binder.h Binder 驱动的头文件:定义驱动内部数据结构(binder_proc、binder_node、binder_ref、binder_transaction 等)和内部常量。 核心
binder_alloc.c Binder 内存分配器:管理每个进程的 Binder 缓冲区,负责物理页面的分配、映射和回收。 重要
binder_alloc.h Binder 内存分配器的头文件:定义 binder_alloc 结构体和分配器接口。 重要
binder_trace.h Binder 跟踪点定义:用于 ftrace 和 perf 的 trace event,辅助调试和性能分析。 辅助
binderfs.c Binder 文件系统实现(可选):用于在容器或命名空间场景下创建独立的 Binder 设备节点。 扩展
学习提示: 初学者应优先阅读 binder.c 中的 binder_open()、binder_mmap() 和 binder_ioctl() 三个函数,它们构成了 Binder 驱动与用户空间交互的三大入口。
Binder驱动在内核源码树中的位置 Linux Kernel Source Tree (drivers/) drivers/android/ 核心文件 binder.c (主实现) binder.h (数据结构) binder_alloc.c (内存分配) binder_alloc.h (分配器头) binder_trace.h (跟踪点) binderfs.c (文件系统) 说明:binder.c + binder.h 构成驱动核心,binder_alloc.c 管理缓冲区,binderfs.c 用于容器场景

2.2 驱动文件结构:binder.c 的模块组织

binder.c 是 Binder 驱动的单一主文件,采用模块化函数布局,按功能划分为以下几个逻辑区域:

  1. 模块初始化与退出:binder_init() 和 binder_exit(),负责注册 misc 设备和 platform 驱动。
  2. 文件操作接口:binder_open()、binder_release()、binder_mmap()、binder_ioctl(),构成 struct file_operations。
  3. 事务处理引擎:binder_transaction()、binder_thread_read()、binder_thread_write(),实现 IPC 数据传递。
  4. 节点与引用管理:binder_new_node()、binder_get_ref_for_node()、binder_dec_ref(),维护 Binder 对象引用计数。
  5. 缓冲区管理:binder_alloc_buf()、binder_free_buf(),委托给 binder_alloc.c 实现。
  6. 调试与统计:binder_stats_show()、binder_state_show(),通过 debugfs 输出驱动状态。
关键设计: Binder 驱动采用单文件 + 辅助文件的架构,binder.c 约 6000 行,binder_alloc.c 约 1000 行。这种设计在保持核心逻辑内聚的同时,将内存管理独立出来,便于后续优化和移植。
binder.c 模块结构图 binder.c 主模块 文件操作接口 (file_operations) 事务处理引擎 (transaction) 节点管理 | 引用管理 | 缓冲区管理 (委托 binder_alloc.c) 说明:自上而下分层调用,binder_ioctl 作为总入口分发命令到事务引擎和底层管理 binder_mmap 直接调用 binder_alloc 分配物理页面并建立内核-用户空间映射

2.3 设备节点 /dev/binder 的注册过程

Binder 驱动通过 misc 设备框架 注册设备节点。misc 设备是 Linux 内核中用于小型字符设备驱动的简化注册方式,主设备号为 10,次设备号动态分配。注册流程如下:

步骤 函数/操作 说明
1 binder_init() 驱动入口函数,在模块加载时调用,执行初始化逻辑。
2 misc_register(&binder_miscdev) 向内核注册 misc 设备,自动创建设备节点 /dev/binder。
3 platform_driver_register(&binder_driver) 注册 platform 驱动,用于电源管理和设备匹配(在部分内核版本中可选)。
4 debugfs_create_dir("binder", ...) 创建 debugfs 目录 /sys/kernel/debug/binder/,导出驱动状态。

关键数据结构 binder_miscdev 的定义如下:

static struct miscdevice binder_miscdev = {
    .minor = MISC_DYNAMIC_MINOR,   // 次设备号由内核动态分配
    .name = "binder",              // 设备节点名称 → /dev/binder
    .fops = &binder_fops           // 文件操作函数表
};

其中 binder_fops 是驱动暴露给用户空间的操作接口:

static const struct file_operations binder_fops = {
    .owner = THIS_MODULE,
    .open = binder_open,
    .release = binder_release,
    .mmap = binder_mmap,
    .unlocked_ioctl = binder_ioctl,
    .compat_ioctl = binder_ioctl,   // 32位兼容接口
};
注意事项: 在 Android 系统中,/dev/binder 的权限通常设置为 0666 或由 SELinux 策略控制。普通应用通过 Binder 库间接访问该节点,不会直接调用 open/ioctl。驱动开发者需要关注的是 binder_ioctl 中命令码的解析和事务处理逻辑。
/dev/binder 设备节点注册流程 ① binder_init() ② misc_register() ③ platform_driver_register() ④ debugfs 注册结果:/dev/binder 设备节点创建 主设备号 10,次设备号动态分配 关键数据结构关系 binder_miscdev → .name = "binder" → 设备节点 /dev/binder binder_miscdev → .fops = &binder_fops → open/mmap/ioctl 用户空间通过 open("/dev/binder") 获得 fd,然后调用 mmap 和 ioctl

2.4 驱动初始化代码片段解析

以下是 binder_init() 的核心逻辑,展示了设备节点注册和平台驱动注册的完整流程:

static int __init binder_init(void)
{
    int ret;

    // 1. 创建 Binder 工作队列(用于异步事务处理)
    binder_deferred_workqueue = create_singlethread_workqueue("binder");
    if (!binder_deferred_workqueue)
        return -ENOMEM;

    // 2. 注册 misc 设备 → 创建 /dev/binder
    ret = misc_register(&binder_miscdev);
    if (ret) {
        pr_err("binder: cannot register misc device\n");
        destroy_workqueue(binder_deferred_workqueue);
        return ret;
    }

    // 3. 注册 platform 驱动(用于电源管理回调)
    ret = platform_driver_register(&binder_driver);
    if (ret) {
        pr_err("binder: cannot register platform driver\n");
        misc_deregister(&binder_miscdev);
        destroy_workqueue(binder_deferred_workqueue);
        return ret;
    }

    // 4. 创建 debugfs 目录(可选,用于调试)
    binder_debugfs_dir = debugfs_create_dir("binder", NULL);
    if (IS_ERR(binder_debugfs_dir))
        binder_debugfs_dir = NULL;

    pr_info("binder: Binder driver initialized\n");
    return 0;
}
驱动开发要点: 注意错误处理路径——当 platform_driver_register 失败时,需要先注销 misc 设备并销毁工作队列,避免资源泄漏。这是内核驱动开发中回滚(rollback)的典型模式。

2.5 本章小结

  • Binder 驱动位于 drivers/android/ 目录,核心文件为 binder.c 和 binder.h,辅助文件 binder_alloc.c 管理内存。
  • 驱动通过 misc 设备框架注册,创建设备节点 /dev/binder,主设备号固定为 10。
  • 文件操作接口 binder_fops 提供 open、mmap、ioctl 三个核心入口,用户空间通过它们完成 IPC 通信。
  • 初始化流程包含工作队列创建、misc 设备注册、platform 驱动注册和 debugfs 创建,每一步失败都需要正确回滚。