Binder系列1-Binder Driver
Binder系列1-Binder Driver
1. Android采用Binder
Linux Kernel是开源系统,所开放源代码许可协议GPL保护,
Binder Driver
运行在Linux Kernel是GPL协议。用户空间采用Apache-2.0协议,内核空间与用户空间(即在GPL协议与Apache-2.0协议)之间的Lib库中采用BSD证授权方法,GPL协议限定在Linux Kernel,有效隔断了GPL的传染性,仍有较大争议。开源与商业化共存的一个成功典范。【Android,在争议中逃离 Linux 内核的 GPL 约束】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_BINDERFS
、binder_devices_param = CONFIG_ANDROID_BINDER_DEVICES
在kernel/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对象保存到文件指针filphlist_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()
- binder_thread_write() :
get_user(cmd, (uint32_t __user *)ptr)
获取IPC数据BC请求码 - binder_thread_read():根据
w->type
(即binder_work->type
)响应相应处理。
- binder_thread_write() :
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相关推荐
- Binder系列1 Binder总体设计思想
Binder 是 Android 系统进程间通信(IPC)最主要的一种方式.Linux 已经拥有管道,system V IPC,socket 等 IPC 手段,Android 却还要使用专门的 Bin ...
- 【Binder系列课】二、Binder通信服务应知应会
Binder问答 概括Binder机制 1.整体业务层CS架构,BpBinder/BnBinder 2.通信层Binder驱动,writeStrongBinder/readStrongBinder完成 ...
- Binder系列11 死亡通知机制
死亡通知机制概述 如果在 binder 通信已经建立的情况下,出现 binder 服务端的进程意外挂掉,这个挂掉的原因可能是因为进程本身内部发生的错误,也有可能是其它情况导致进程被系统强制结束,总之这 ...
- 由浅入深 学习 Android Binder(十一) binder线程池
Android Binder系列文章: 由浅入深 学习 Android Binder(一)- AIDL 由浅入深 学习 Android Binder(二)- bindService流程 由浅入深 学习 ...
- Android Binder机制(1):Binder架构分析
从这篇博客开始,将进入Binder机制的分析系列,顺序是先讲解Binder机制的框架,理解了整体思想后,再深入分析各层的细节实现,最后会实现一个自己的本地服务. 1.Binder的历史 BeOS是Be ...
- AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting
HAL层(Hardware abstraction layer) 的目的是为了屏蔽底层不同芯片平台的差异,从而使驱动层上面的软件不会随芯片平台而改变.AliOS Things定义了全面的HAL抽象层, ...
- android transact,Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败分析...
Q:Android Native层Binder.transact()函数调用 Binder.onTransact() 函数失败? 在Android Native层调用Camera.h中的api实现一个 ...
- 深入理解Binder系列 1
Binder 作为Android独有的进程间通信(IPC)方式.值得我们每一个Android开发同学去深入学习. As we all know, Android系统是基于Linux内核开发的. 整个熟 ...
- FAILED BINDER TRANSACTION (Android Binder传输数据大小限制)
Android源代码中大小设置 http://androidxref.com/9.0.0_r3/xref/frameworks/native/libs/binder/ProcessState.cpp# ...
最新文章
- datagirdview跟据内容自动适应单元格大小
- nrf51822-使用16位自定义UUID
- Dav1d移动端解码高清视频达30FPS
- win10关闭windows聚焦_Win10优化:这8个操作简单的小方法让你的Win10系统更加流畅...
- 学计算机的心理300字,心理的作文300字7篇
- 记录——《C Primer Plus (第五版)》第九章编程练习第四题
- php分片数据库,4、PHP测试分片集群
- figure函数--Matplotlib
- 金士顿U盘写保护去除
- 进行日常记账后,怎样导出表格
- 机器学习常用衡量标准
- MC34063在扩展后的降压应用
- 小学一年级20以内加减法题目自动生成(家长的福利,孩子的魔鬼)
- HCIP-H12-223练习题
- DCS任务编辑器文件无法正常加载,一直停在‘正在读取。。’
- 现在流行的网络直播都需要什么设备?
- 运动快乐的来源-内啡肽
- wf 《计算机专业英语》,武汉4-5岁MFWF轻松自信说英语课程
- HarmonyOS:实现Button按下后颜色加深的效果
- 豪华曹操传2014 (数据以及存档文件修改)
热门文章
- 【C语言】 -- 三子棋(代码+解析)
- 《毒液》:用Fiddler+MongoDB抓取猫眼APP短评
- Spring Data JPA 实现多表关联查询
- 95号汽油步入9元时代,买得起车却加不起油
- SHOI2003吃豆豆
- 以太坊区块链之基本环境搭建
- Android官方开发文档Training系列课程中文版:打印内容之HTML文档打印
- kali linux 装u盘安装教程,kali linux系统的安装教程(实现便于携带的外置盘系统)...
- 十进制转为任意进制,发糖果
- 蓝桥杯基础训练-十六进制转十进制-c语言