Binder 驱动学习笔记
来源:互联网 发布:淘宝网汉服女装 编辑:程序博客网 时间:2024/05/18 08:30
转自 http://blog.csdn.net/21cnbao/article/details/8087354
简介
有如下特殊能力:
- 面向对象。Binder 设计目的是进程间传递对象
- 面向进程。文件描述符 + 进程 ID
- 简单。内核态驱动仅有一个 c 文件
- 高性能。再驱动层可以更高校的分发消息,最高效
- 自动化内存管理。容易构建出自动化垃圾回收
- 灵活。实现、拓展都很容易, 用于多种场景
如何被使用
只通过 ioctl() 系统调用完成读写, 通过 binder_write_read 数据结构来描述详细的操作。
binder_write_read bwr;if(ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >=0) err = NO_ERROR;else err = -errno;
参数一:fd 文件描述符,通过 open() 调用得到。
参数二:ioctl 码, 定义于 binder.h 。
参数三:用户态与内核态进行交互的数据结构, bwr 处于用户空间。
- 传递参数给内核:用户态填写好参数内容后, 交给内核态读取;
- 内核态传回参数:内核态改写bwr内部,交给用户态通过 ioctl 读取。
BC_* 系列: Binder Command 的简称,说明用户态给 Binder 驱动发出的命令。
BR_* 系列: Binder Return 的简称, 说明是 Binder 驱动给用户态发回的操作结果反馈。
在 Binder 定义的命令中, 只有
- BC_TRANSACTION
- BC_REPLY
- BR_TRANSACTION
- BR_REPLY
四种能够完成传递数据。
无论是 TRANSACTION 或 REPLY , 通过 ioctl 操作时使用的参数都是一个 binder_transaction_data 的数据结构指针。
struct binder_transaction_data { union { size_t handle; /* target descriptor of command transaction */ void *ptr; /* target descriptor of return transaction */ }target; void *cookie; /* target objectcookie */ unsigned int code; /* transaction command */ unsigned int flags; pid_t sender_pid; uid_t sender_euid; size_t data_size; /* number of bytesof data */ size_t offsets_size; /* number of bytes ofoffsets */ union { struct { const void __user *buffer; const void __user *offsets; }ptr; uint8_t buf[8]; }data;};
至此, 基于 Binder 的数据传输, 可以表现为如下形式:
高效使用参数对象
binder_transaction_data : data.ptr.buffer - 指向一个线性区域, 区域中存放的是用户态 libbinder 通过 Paracelable 接口处理过的对象 (flat_binder_object)。
binder_transaction_data : data.ptr.offsets - 上述线性区域中每个 Paracel 对象的索引
Binder 驱动里处理 Parcel 映射的数据结构 flat_binder_object, 其结构如下:
struct flat_binder_object { unsigned long type; unsigned long flags; union { void __user *binder; /* local object */ signed long handle; /* remote object */ }; void __user *cookie;};
对于本地对象的引用使用 用户态指针 _ _ user *binder
对于远程对象, 使用 long 类型的 handle
完整的 Binder 数据交互图
内部数据结构
Binder 驱动的局部数据结构, 更多的是用来映射 Binder 在用户态的一些概念, 提供一种内核态的辅助手段。
Binder 驱动的实现
在系统里生成一个 /dev/binder 字符设备文件, 不对应任何硬件, 内存虚拟出来的设备。
BINDER_WRITE_READ
把用户态传递到 Binder 驱动的 binder_write_read 数据结构,从用户态拷贝到内核态, 根据 bwr 中的 read_size 和 write_size 是否大于 0 决定后续操作。两个值可能都存在, 所以一个 ioctl 周期里, 可能同时 读写。
- write_size > 0 , binder_thread_write 用户态 写入 内核态
- read_size > 0, binder_thread_read 用户态 读取 内核态的数据
- 都不大于0, binder 无法正常交互, 返回错误
binder_thread_write()
解析 binder_ioctl 得到的 BC_* 命令, 然后再根据命令作出处理。
binder_transaction
binder_thread_read()
Binder 驱动总结
Binder 驱动在 Binder IPC 过程中, 是一种中间容器, 把一个进程的请求, 转发给另一个进程。
1. 高效。 竭力见效内存拷贝的开销, 使用红黑树等算法建立索引。
2. 面向对象。整个 Binder 驱动, 只是 libbinder 的一种辅助手段,继承了其 面向对象的特点。
3. 开销小。Binder 驱动在不使用时开销几乎可以忽略。每次数据的读写都是通过 binder_transcation 这样的元数据来记录,只记录数据变动。 对于大数据量的读写, 使用从用户空间偷来的的内存空间, 只针对进程有效, 不会影响到整个系统的内存分配, 只有一些内部维护的开销。
4. 面向进程。 Binder IPC 传输的本质便是面向进程, 可以从 binder_transaction 的结构中看出来, 并且只使用进程用户空间来处理大数据 buffer , 进一步加强了 binder 的进程化。如果处于 binder 传输过程中的进程出错死掉, 不会带来系统及开销。
5. 简洁。
- Binder 驱动学习笔记
- Binder驱动笔记
- android 4.1 Binder驱动笔记
- android学习笔记--binder
- Android学习笔记--Binder
- Android学习笔记--Binder
- Android学习笔记--Binder
- Android 学习笔记 binder
- binder学习笔记
- Android学习笔记--Binder
- Binder学习笔记
- Android学习笔记--Binder
- Android学习笔记--Binder
- Android学习笔记--Binder
- Binder学习笔记
- Binder学习笔记
- binder学习笔记
- Android Binder学习笔记
- 二叉树两结点的最低公共父结点
- 四大组件之一Service——应用实例二(IntentService类的使用)
- 【VB.NET机房重构】数据传递----实体、DataTable、泛型
- Android之NDK开发Androd.mk
- js 瀑布流加载图片
- Binder 驱动学习笔记
- 42.Trapping Rain Water
- .net Url.Encode 跳转到PHP解析问题
- 记住密码和自动登录
- GET请求解读编码
- 会错意表错情,搭错车上错床——“度日如年”的故事及“feof()”的故事
- [安卓]手机管家(三)homeActivity
- python 白云黄鹤十大
- AD用户操作