Binder系列1-Binder Driver

1. Android采用Binder

  1. Linux Kernel是开源系统,所开放源代码许可协议GPL保护,Binder Driver运行在Linux Kernel是GPL协议。用户空间采用Apache-2.0协议,内核空间与用户空间(即在GPL协议与Apache-2.0协议)之间的Lib库中采用BSD证授权方法,GPL协议限定在Linux Kernel,有效隔断了GPL的传染性,仍有较大争议。开源与商业化共存的一个成功典范。【Android,在争议中逃离 Linux 内核的 GPL 约束】

  2. Binder 是基于开源的OpenBinder实现的,而OpenBinder的作者在Google工作,直接采用 Binder 作为核心的IPC机制。

2. Binder Driver实现

Binder驱动是一个misc device,是虚拟字符设备,主设备号是10,其设备节点是/dev/binder(该节点并不对应真实的硬件设备)。misc类型驱动只需要调用misc_deregister
主要是驱动设备的初始化(binder_init),打开 (binder_open),映射(binder_mmap),数据操作(binder_ioctl)。

linux/drivers/android/binder.c
linux/include/uapi/linux/android/binder.h

  • binder_init:初始化虚拟字符设备,init_binder_device()\init_binderfs()
  • binder_open:打开Binder驱动设备, binder_procs_lock同步锁;
  • binder_mmap:申请内存空间, binder_alloc_mmap_lock同步锁;
  • binder_ioctl:执行相应的ioctl操作, binder_procs_lock同步锁;当处于binder_thread_read过程,read_buffer无数据则释放同步锁。

2.1 binder_init 注册misc设备节点/dev/binder

  • binder_init() -> init_binder_device(device_name) -> misc_register(&binder_device->miscdev) 注册misc设备节点
  • CONFIG_ANDROID_BINDERFSbinder_devices_param = CONFIG_ANDROID_BINDER_DEVICESkernel/configs/xxx/android-base.config配置
  • binder_fops Binder驱动支持的文件操作,其中使用做多的binder_ioctl \ binder_mmap \ binder_open
  • init_binderfs() 注册register_filesystem(&binder_fs_type)(linux/drivers/android/binderfs.c)
const struct file_operations binder_fops = {.owner = THIS_MODULE,.poll = binder_poll,.unlocked_ioctl = binder_ioctl,.compat_ioctl = compat_ptr_ioctl,.mmap = binder_mmap,.open = binder_open,.flush = binder_flush,.release = binder_release,
};static int __init init_binder_device(const char *name)
{// ... ...binder_device->miscdev.fops = &binder_fops;binder_device->miscdev.minor = MISC_DYNAMIC_MINOR;binder_device->miscdev.name = name;// ... ...ret = misc_register(&binder_device->miscdev);// ... ...
}static int __init binder_init(void)
{// ... ...if (!IS_ENABLED(CONFIG_ANDROID_BINDERFS) &&strcmp(binder_devices_param, "") != 0) {/** Copy the module_parameter string, because we don't want to* tokenize it in-place.*/device_names = kstrdup(binder_devices_param, GFP_KERNEL);if (!device_names) {ret = -ENOMEM;goto err_alloc_device_names_failed;}device_tmp = device_names;while ((device_name = strsep(&device_tmp, ","))) {ret = init_binder_device(device_name);if (ret)goto err_init_binder_device_failed;}}ret = init_binderfs();if (ret)goto err_init_binder_device_failed;return ret;err_init_binder_device_failed:// ... ...
err_alloc_device_names_failed:// ... ...
}device_initcall(binder_init);

2.2 binder_open 打开Binder驱动设备

  • binder_proc binder进程,每个进程都有独立的记录;proc->todo todo链表
  • binder_stats_created(BINDER_STAT_PROC) BINDER_PROC对象创建数加1,binder_stats是binder中统计数据载体
  • filp->private_data = proc 把binder_proc对象保存到文件指针filp
  • hlist_add_head(&proc->proc_node, &binder_procs) 把binder_proc加入到全局链表binder_procs
static int binder_open(struct inode *nodp, struct file *filp)
{struct binder_proc *proc, *itr;struct binder_device *binder_dev;struct binderfs_info *info;struct dentry *binder_binderfs_dir_entry_proc = NULL;// ... ...proc = kzalloc(sizeof(*proc), GFP_KERNEL);// ... ...INIT_LIST_HEAD(&proc->todo);init_waitqueue_head(&proc->freeze_wait);proc->default_priority = task_nice(current);// ... ...binder_stats_created(BINDER_STAT_PROC);proc->pid = current->group_leader->pid;INIT_LIST_HEAD(&proc->delivered_death);INIT_LIST_HEAD(&proc->waiting_threads);filp->private_data = proc;mutex_lock(&binder_procs_lock);hlist_for_each_entry(itr, &binder_procs, proc_node) {if (itr->pid == proc->pid) {existing_pid = true;break;}}hlist_add_head(&proc->proc_node, &binder_procs);mutex_unlock(&binder_procs_lock);// ... ...
}

2.3 binder_mmap 申请内存空间

  • binder_alloc_mmap_handler 申请内存空间,linux/drivers/android/binder_alloc.c
static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
{struct binder_proc *proc = filp->private_data;if (proc->tsk != current->group_leader)return -EINVAL;binder_debug(BINDER_DEBUG_OPEN_CLOSE,"%s: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",__func__, proc->pid, vma->vm_start, vma->vm_end,(vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,(unsigned long)pgprot_val(vma->vm_page_prot));if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {pr_err("%s: %d %lx-%lx %s failed %d\n", __func__,proc->pid, vma->vm_start, vma->vm_end, "bad vm_flags", -EPERM);return -EPERM;}vma->vm_flags |= VM_DONTCOPY | VM_MIXEDMAP;vma->vm_flags &= ~VM_MAYWRITE;vma->vm_ops = &binder_vm_ops;vma->vm_private_data = proc;return binder_alloc_mmap_handler(&proc->alloc, vma);
}

2.4 binder_ioctl 执行相应的ioctl操作

  • binder_ioctl 函数负责在两个进程间收发IPC数据和IPC reply数据处理
  • 核心方法binder_ioctl_write_read() -> binder_thread_write()\binder_thread_read()
    1. binder_thread_write() :get_user(cmd, (uint32_t __user *)ptr) 获取IPC数据BC请求码
    2. binder_thread_read():根据w->type(即binder_work->type)响应相应处理。
ioctl命令cmd 说明
BINDER_WRITE_READ 收发Binder IPC数据
BINDER_SET_MAX_THREADS 设置Binder线程最大个数
BINDER_SET_CONTEXT_MGR 设置Service Manager节点
BINDER_SET_CONTEXT_MGR_EXT
BINDER_THREAD_EXIT 释放Binder线程
BINDER_VERSION 获取Binder版本信息
static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{int ret;struct binder_proc *proc = filp->private_data;struct binder_thread *thread;unsigned int size = _IOC_SIZE(cmd);// ... ...trace_binder_ioctl(cmd, arg);ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);// ... ...thread = binder_get_thread(proc);// ... ...switch (cmd) {case BINDER_WRITE_READ:ret = binder_ioctl_write_read(filp, cmd, arg, thread);if (ret)goto err;break;case BINDER_SET_MAX_THREADS://......case BINDER_SET_CONTEXT_MGR_EXT://......case BINDER_SET_CONTEXT_MGR://......case BINDER_THREAD_EXIT://......case BINDER_VERSION://......case BINDER_GET_NODE_INFO_FOR_REF://......case BINDER_GET_NODE_DEBUG_INFO://......case BINDER_FREEZE://......case BINDER_GET_FROZEN_INFO://......case BINDER_ENABLE_ONEWAY_SPAM_DETECTION://......case BINDER_GET_EXTENDED_ERROR://......default:ret = -EINVAL;goto err;}// ... ...if (thread)thread->looper_need_return = false;wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);// ... ...
}

3. Binder通信模型

Binder是基于C/S架构的,简单解释下C/S架构,是指客户端(Client)和服务端(Server)组成的架构,Client端有什么需求,直接发送给Server端去完成。Android系统中对外只暴露Client端,Client端将任务发送给Server端。

Binder系列1-Binder Driver相关推荐

  1. Binder系列1 Binder总体设计思想

    Binder 是 Android 系统进程间通信(IPC)最主要的一种方式.Linux 已经拥有管道,system V IPC,socket 等 IPC 手段,Android 却还要使用专门的 Bin ...

  2. 【Binder系列课】二、Binder通信服务应知应会

    Binder问答 概括Binder机制 1.整体业务层CS架构,BpBinder/BnBinder 2.通信层Binder驱动,writeStrongBinder/readStrongBinder完成 ...

  3. Binder系列11 死亡通知机制

    死亡通知机制概述 如果在 binder 通信已经建立的情况下,出现 binder 服务端的进程意外挂掉,这个挂掉的原因可能是因为进程本身内部发生的错误,也有可能是其它情况导致进程被系统强制结束,总之这 ...

  4. 由浅入深 学习 Android Binder(十一) binder线程池

    Android Binder系列文章: 由浅入深 学习 Android Binder(一)- AIDL 由浅入深 学习 Android Binder(二)- bindService流程 由浅入深 学习 ...

  5. Android Binder机制(1):Binder架构分析

    从这篇博客开始,将进入Binder机制的分析系列,顺序是先讲解Binder机制的框架,理解了整体思想后,再深入分析各层的细节实现,最后会实现一个自己的本地服务. 1.Binder的历史 BeOS是Be ...

  6. AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting

    HAL层(Hardware abstraction layer) 的目的是为了屏蔽底层不同芯片平台的差异,从而使驱动层上面的软件不会随芯片平台而改变.AliOS Things定义了全面的HAL抽象层, ...

  7. android transact,Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败分析...

    Q:Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败? 在Android Native层调用Camera.h中的api实现一个 ...

  8. 深入理解Binder系列 1

    Binder 作为Android独有的进程间通信(IPC)方式.值得我们每一个Android开发同学去深入学习. As we all know, Android系统是基于Linux内核开发的. 整个熟 ...

  9. FAILED BINDER TRANSACTION (Android Binder传输数据大小限制)

    Android源代码中大小设置 http://androidxref.com/9.0.0_r3/xref/frameworks/native/libs/binder/ProcessState.cpp# ...

最新文章

  1. datagirdview跟据内容自动适应单元格大小
  2. nrf51822-使用16位自定义UUID
  3. Dav1d移动端解码高清视频达30FPS
  4. win10关闭windows聚焦_Win10优化:这8个操作简单的小方法让你的Win10系统更加流畅...
  5. 学计算机的心理300字,心理的作文300字7篇
  6. 记录——《C Primer Plus (第五版)》第九章编程练习第四题
  7. php分片数据库,4、PHP测试分片集群
  8. figure函数--Matplotlib
  9. 金士顿U盘写保护去除
  10. 进行日常记账后,怎样导出表格
  11. 机器学习常用衡量标准
  12. MC34063在扩展后的降压应用
  13. 小学一年级20以内加减法题目自动生成(家长的福利,孩子的魔鬼)
  14. HCIP-H12-223练习题
  15. DCS任务编辑器文件无法正常加载,一直停在‘正在读取。。’
  16. 现在流行的网络直播都需要什么设备?
  17. 运动快乐的来源-内啡肽
  18. wf 《计算机专业英语》,武汉4-5岁MFWF轻松自信说英语课程
  19. HarmonyOS:实现Button按下后颜色加深的效果
  20. 豪华曹操传2014 (数据以及存档文件修改)

热门文章

  1. 【C语言】 -- 三子棋(代码+解析)
  2. 《毒液》:用Fiddler+MongoDB抓取猫眼APP短评
  3. Spring Data JPA 实现多表关联查询
  4. 95号汽油步入9元时代,买得起车却加不起油
  5. SHOI2003吃豆豆
  6. 以太坊区块链之基本环境搭建
  7. Android官方开发文档Training系列课程中文版:打印内容之HTML文档打印
  8. kali linux 装u盘安装教程,kali linux系统的安装教程(实现便于携带的外置盘系统)...
  9. 十进制转为任意进制,发糖果
  10. 蓝桥杯基础训练-十六进制转十进制-c语言