binder Driver (binder IPC) 功能介绍与分析

概要

在我的Android体系架构解读一文中,在kernel层有很多个驱动,Android Logger,Shared Memory Driver,Binder Driver是非常通用非常重要的几个。 其中Binder Driver是Android Framework IPC机制的核心,来学习一下

源码目录

整个Binder架构所涉及的总共有以下5个目录:
/framework/base/core/java/ (Java)
/framework/base/core/jni/ (JNI)
/framework/native/libs/binder (Native)
/framework/native/cmds/servicemanager/ (Native)
/kernel/drivers/staging/android (Driver)

Java framework

/framework/base/core/java/android/os/
- IInterface.java
- IBinder.java
- Parcel.java
- IServiceManager.java
- ServiceManager.java
- ServiceManagerNative.java
- Binder.java
/framework/base/core/jni/
- android_os_Parcel.cpp
- AndroidRuntime.cpp
- android_util_Binder.cpp (核心类)

Native framework

/framework/native/libs/binder
- IServiceManager.cpp
- BpBinder.cpp
- Binder.cpp
- IPCThreadState.cpp (核心类)
- ProcessState.cpp (核心类)
/framework/native/include/binder/
- IServiceManager.h
- IInterface.h
/framework/native/cmds/servicemanager/
- service_manager.c
- binder.c

Kernel

/kernel/drivers/staging/android/
- binder.c(核心类)
- uapi/binder.h

kernel核心类

binder.c
核心method comments
static int __init binder_init(void) init
static int binder_open(struct inode *nodp, struct file *filp) 打开binder驱动
static int binder_mmap(struct file *filp, struct vm_area_struct *vma) mmap,共享物理内存到内核虚拟地址空间和用户虚拟内存空间,binder数据传输能减少一次数据拷贝得益于此
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) 内核空间里面的ioctl,有几种cmd:BINDER_WRITE_READ,BINDER_SET_MAX_THREADS,BINDER_SET_CONTEXT_MGR等,最重要的一种是binder_write_read
static struct binder_thread *binder_get_thread(struct binder_proc *proc) binder_ioctl的过程中会尽量从proc的threads树中查找和current线程匹配的binder_thread节点,如果找不到,就会创建一个新的节点并插入树中
static int binder_ioctl_write_read(struct file *filp,unsigned int cmd, unsigned long arg, struct binder_thread *thread) 通过binder的写或者读的方法在内核空间最终会运行到这个方法里
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) 该过程就是把binder_buffer里面的指令执行完毕的过程,该过程里面涉及到的指令也比较多,主要有BC_TRANSACTION、BC_REPLAY等等,从用户空间拷贝到内核空间,读出一个指令,然后根据指令完成相应的操作,比如对于BC_TRANSACTION指令就是从用户空间拷贝一段binder_transaction_data数据到内核空间copy_from_user(&tr, ptr, sizeof(tr)
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) 该过程需要通过binder_inner_proc_lock(proc)持有同步锁;当处于binder_thread_read过程,read_buffer无数据则释放同步锁,并处于binder_wait_for_work过程,等signal_pending(current)有数据到来则唤醒并尝试持有同步锁。循环从&thread->todo或者&proc->todo里面拿出一个binder_work,根据binder_work的内容从内核空间向用户空间发送BR_TRANSACTION、BR_TRANSACTION_COMPLETE、BR_DEAD_BINDER、BR_SPAWN_LOOPER等等命令,直至处理完毕
struct binder_proc

binder_proc是描述Binder进程上下文信息的结构体。Binder驱动的文件节点是"/dev/binder",当程序构造ProcessState并打开binder驱动(该文件节点)之时,会调用到驱动层的binder_open()函数,而binder_proc就是在binder_open()函数中创建的。新创建的binder_proc会作为一个节点,插入一个总链表(binder_procs)中。4个变量threads、nodes、refs_by_desc、refs_by_node非常重要。传输过程就是依赖于它们来实现的

类型 成员变量 解释
struct hlist_node proc_node; // 根据proc_node,可以获取该进程在"全局哈希表binder_procs(统计了所有的binder proc进程)"中的位置
struct rb_root threads; // binder_proc进程内用于处理用户请求的线程组成的红黑树(关联binder_thread->rb_node)
struct rb_root
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值