Android binder driver 分析

本文详细分析了Android Binder驱动的工作流程,从binder_ioctl开始,探讨了BINDER_WRITE_READ命令的处理,包括binder_ioctl_write_read函数,接着重点剖析了binder_thread_write的执行步骤,如调整数据指针、读取协议指令等,最后介绍了binder_thread_read的处理逻辑,阐述了如何将数据返回给用户空间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. binder_ioctl

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
首先调用binder_get_thread从该proc的thread红黑树找到对应该线程的binder_thread结构体。
thread = binder_get_thread(proc);

binder_get_thread的内部实现是根据current宏在binder_proc中的threads红黑树找到描述当前请求线程的binder_thread结构体.
如果没有找到,则为当前调用线程创建一个binder_thread结构体。
这属于binder driver主动将当前线程设置为BINDER_LOOPER_STATE_NEED_RETURN,后面会需要用户空间返回。

处理各种ioctl控制命令码

binder.h中定义如下7种命令码

#defineBINDER_WRITE_READ_IOWR('b', 1, struct binder_write_read)
#defineBINDER_SET_IDLE_TIMEOUT_IOW('b', 3, __s64)
#defineBINDER_SET_MAX_THREADS_IOW('b', 5, __u32)
#defineBINDER_SET_IDLE_PRIORITY_IOW('b', 6, __s32)
#defineBINDER_SET_CONTEXT_MGR_IOW('b', 7, __s32)
#defineBINDER_THREAD_EXIT_IOW('b', 8, __s32)
#defineBINDER_VERSION_IOWR('b', 9, struct binder_version)

因为ioctl的cmd是32位,有一定的格式。利用_IOWR,_IOW等宏辅助生成32位cmd数字。具体可以百度之,属于linux driver的标准实现。

比如:
#define BINDER_WRITE_READ _IOWR(‘b’, 1, struct binder_write_read)

  • _IOWR : 表示用于双向传输
  • ‘b’ : driver type, binder
  • 1: 用于区别各种命令,1 代表的时BINDER_WRITE_READ
  • struct binder_write_read:指定要传递数据的类型。可以根据指定的类型,得到所需要传递数据的大小。

2. 主要分析ioctl 控制命令码BINDER_WRITE_READ的处理过程

case BINDER_WRITE_READ:  
        ret = binder_ioctl_write_read(filp, cmd, arg, thread);  

参数分别为:

  • flip:当前调用进程第一次访问binder设备时创建的struct file,每次系统调用binder_ioctl时,都会将该struct传递过来 . (内核根据用户空间传过来的fd,找到在内核中对应的file。)
  • cmd:ioctl 控制命令,当前为BINDER_WRITE_READ
  • arg:用户空间传递下来的数据 binder_read_write 的地址
  • thread:表示为当前调用线程在binder driver 中记录的的binder_thread结构体

2.1 分析binder_ioctl_write_read

首先需要根据传送下来的地址(参数arg),将数据binder_write_read 从用户空间拷贝到内核空间。copy_from_user

void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;

…

if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {

binder_write_read 数据结构体如下,主要用户描述通信过程所传输的数据的size,已经消耗的size,真正数据的地址.

/*  
* On 64-bit platforms where user code may run in 32-bits the driver must
* translate the buffer (and local binder) addresses appropriately.
*/  

struct binder_write_read {
binder_size_t write_size; /* bytes to write */
binder_size_t write_consumed; /* bytes consumed by driver */
binder_uintptr_t write_buffer;
binder_size_t read_size; /* bytes to read */
binder_size_t read_consumed; /* bytes consumed by driver */
binder_uintptr_t read_buffer;
};  
  • write_xx表示从用户空间传输到binder驱动程序的数据,如果write_xx不为0,表示用户空间有数据需要传递给binder 驱动程序处理。
  • read_xx表示binder驱动程序返回给用户空间的数据。如果read_size 不为0,表示用户空间需要等待驱动
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值