1: 概述

Binder的源码相对没有接触过驱动的人来说, 还是比较复杂的, 如果要读懂还是比较难的(本人之前做Java开发, 很少接触C和C++)。
所以读Binder源码的时候比较难, 而且很多内核的知识如果不了解, 读起来也比较费事, 这些都让Binder比较神秘。
所以我整理了一些Binder的基础知识, 带着对Binder比较感性的了解再去读Binder源码, 肯定事半功倍。
这些基础知识, 让你对Binder比较感性的认识, 面对一些比较复杂的逻辑, 如果脑中有一条清晰的Binder的模型, 读起来肯定也少走弯路。

2: Binder中的四大组件功能

1: Client

如果用代理模式理解的话, 这个可以认为是代理端, 用户通过它来访问Server提供的服务。

2: Server

服务提供者。

3: Binder Driver

跨进程的数据传递, 肯定不能直接传输, Binder通过内核来实现的。

4: ServerManager

一个默认的服务(它也是一个服务), 提供两个功能:
1: 供客户端根据服务名查询到系统的服务。
2: 供服务端把自己的服务公开出来。

3: Binder驱动中的几个重要对象

Binder驱动其实工作的主要内容很简单, 就是把调客户的参数信息传递到服务端, 然后服务端处理完毕把返回值再传递给客户端。
这里弄来网上一张图, 比较形象的展示各个关系。

1: binder_proc

用户开机的时候, 系统会自动启动Media进程, 那这个Media进程对应到Binder驱动底层, 就是一个binder_proc. 一个进程对应到驱动就是一个binder_proc。

2: binder_node

这个东西最简单就是一个Binder实体, 例如Media进程启动了Camera服务, 则这个Carmera服务在binder驱动中表现为一个binder_node, media进程下还有其他服务, 所以一个进程中可以有多个binder_node。

3: binder_ref

这个就是一个binder实体的引用, 例如微信需要使用Carmera服务, 则在binder驱动中需要有一个相应的binder_ref才能使用camera服务, 而微信可能还需要其他的一些服务。 所以一个进程中可以有多个binder_node的引用。

4: binder_thread

这个可以考虑它的主要功能, 以一次请求为例。
客户端请求服务, 肯定是在某条thread中进行请求的, 而数据传递到服务端的处理完毕返回给客户端的时候, 如果驱动中没有记录着条thread的话, 客户端肯定无法返回。 所以binder_thread的主要作用就是让客户端能收到服务端返回的数据。 由于一个进程可能同时请求多个服务, 所以一个进程中可以有多个binder_thread。 

5: binder_transaction

这里是客户端同服务端数据传输的数据结构。
数据从客户端开始进行了一系列的包装, 然后在驱动中解包, 最终打包成一个binder_transaction传递到服务端的驱动部分, 然后再解包打包传递到服务端的实际调用。
这个理解的有点问题:
就理解成一个事务操作, 以一次binder请求为例。
客户端发起一次请求: 驱动建立一个事务进行记录, 然后把这个事务传递都服务端, 让服务端处理完毕之后, 然后返回给客户端。
这个事务其实记录了客户端和服务端的信息, 保证了服务端处理完毕之后, 能正确的返回都客户端。 

4: binder客户端调用流程以及数据传递格式

根据这条主线看, 就能明白一次binder调用的逻辑(如何实现跨进程的调用的)。
下面是一张逻辑调用图:
1: 服务端启动后, 一直在驱动中监听客户端的请求
2: 客户端发起一个请求
3: 驱动解析数据, 并激活服务端的等待条件接着唤醒服务端
4: 客户端有返回的话, 就挂起等待服务端的返回数据 
这部分有点问题: 总体效果说的没问题, 但是细节部分不正确。
客户端请求: 
t->work.type = BINDER_WORK_TRANSACTION;
list_add_tail(&t->work.entry, target_list);
tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
list_add_tail(&tcomplete->entry, &thread->todo);
客户端不仅把事务插入了服务端等待队列, 还向当前进程插入了一条 binder_work。
这样客户端的操作其实是先返回到用户空间, 然后再根据是否有返回, 然后再进入驱动监听服务端的返回。
5: 服务端在步骤3被唤醒, 获取根据客户端传递的信息, 在服务程序里面处理并返回给客户端
6: 服务端唤醒客户端
7: 客户端接收服务端的返回数据
附件里面有visio 点击打开链接

5. Binder 线程池相关介绍

Binder的服务端, 提供一个线程池, 阻塞在Binder内核。

当客户端线程T1访问服务端的时候, 服务端从线程池中拿出一个线程S1, S1响应T1的请求, 然后返回给T1.
如果有多个客户端同时请求服务的时候这个说法不对,驱动会在返回到用户空间的时候检查当前的线程池的状态, 服务端的线程池耗尽但未满, 这个时候Binder驱动发送信息 BR_SPAWN_LOOPER 到服务端进程, 服务端读到这个消息的时候, 就启动一个新线程监听客户端的请求。

6. 草图

1: 服务端启动过程, 主要是何时启动了服务端的监听线程:
2:  客户端请求操作
3:  Client 在驱动中处理的部分流程

4:  binder 驱动数据结构以及binder只进行一次内存拷贝的原理
5: binder_transaction的数据结构
6: Parcel的模型(如果不了解Parcel里面数据存储的模型, 读binder驱动的时候会有点难以理解 binder_transaction操作)

如何去读Binder的源码相关推荐

  1. lfi读取php,php LFI读php文件源码以及直接post webshell

    php LFI读php文件源码以及间接post 网站shell 假如如下一个场景 (1) http://vulnerable/fileincl/example1.php?page=intro.php( ...

  2. rock带你读CornerNet-lite系列源码(二)

    文章目录 前言 CorNerNet 结构 CornerNet_saccade结构 attention机制 CornerNet_Squeeze结构 构建Groundtruth 热图 focal loss ...

  3. Python基于OpenCV的图像去雾算法[完整源码&部署教程]

    1.图片识别 2.视频展示 [项目分享]Python基于OpenCV的图像去雾算法[完整源码&部署教程]_哔哩哔哩_bilibili 3.算法原理 图像增强算法常见于对图像的亮度.对比度.饱和 ...

  4. php7伪静态 源码,freekan3.8.3去授权完整版源码

    freekan3.8.3去授权完整版源码 所属分类:其他 开发工具:PHP 文件大小:34865KB 下载次数:12 上传日期:2018-06-28 04:18:12 上 传 者:migua 说明:  ...

  5. 2022去/水印小程序源码+基于WordPress插件

    正文: 2022去/水印小程序源码+基于WordPress插件,本版本代码是全开源的,基于Wordpress的插件开发的. 上传到Wordpress,安装插件,启动之后,绑定自己的小程序id即可,wo ...

  6. 读PythonRobotics StateLatticePlanner源码-代码注释篇

    文章目录 2.注释 2.1motion_model.py 2.2model_predictive_trajectory_generator.py 2.3 lookuptable_generator.p ...

  7. 读Kafka Consumer源码

    最近一直在关注阿里的一个开源项目:OpenMessaging OpenMessaging, which includes the establishment of industry guideline ...

  8. 读懂 Redis 源码,我总结了这7点心得

    作者|Magic Kaito 来源|水滴与银弹 阅读本文大约需要 8 分钟. 你好,我是 Kaito. 用了这么久的 Redis,也翻了很多次源码,经常有人问我到底怎么读 Redis 源码. 一提到读 ...

  9. 读写锁ReentrantReadWriteLock源码分析

    文章目录 读写锁的介绍 写锁详解 写锁的获取 写锁的释放 读锁详解 读锁的获取 读锁的释放 锁降级 读写锁的介绍 在并发场景中用于解决线程安全的问题,我们几乎会高频率的使用到独占式锁,通常使用java ...

最新文章

  1. 6.5 不同类型的数据集
  2. winform弹出唯一窗体的方法
  3. 【Linux】用户与权限
  4. 12名高校教师被降级!打破职称终身制,山东在行动!
  5. 2021年上半年直播电商行业洞察
  6. 【英语学习】【WOTD】disparage 释义/词源/示例
  7. Pentium II Pentium III架构/微架构/流水线 (5) - MMX
  8. mysql备份恢复出错_MySQL:MySQL备份失败,原因和解决方式
  9. 「三分钟系列03」3分钟看懂什么是三次握手/四次挥手
  10. java生成仿银行卡的会员号
  11. Zabbix钉钉机器人报警
  12. 传奇源码分析-服务器端(SelGate服务器分析)
  13. 管道—过滤器简介 软件体系结构
  14. c4d r21中文语言包安装失败怎么办,Windows10系统下语言包安装失败的解决方案
  15. 用Jsoup爬取中国天气网的实时天气(空气质量、温度、相对湿度、降雨量、风力风向)
  16. 技术干货 | PACMOO:基于帕累托最优的公平性约束协同过滤算法
  17. 金蝶KIS商贸版—(业务结账)期末结账操作介绍
  18. 201871010134-周英杰《面向对象程序设计(java)》第一周学习总结
  19. 【面试软技巧】你如何看待加班?
  20. 合合信息——用智能文字识别技术赋能古彝文原籍数字化

热门文章

  1. 活着,总有你看不惯的人,也有看不惯你的人.
  2. 2015年最好的员工心态培养 -- 我们需要把简单的事情做到极致
  3. 感谢大家对课程的关注和喜爱
  4. 基于WinSvr2012共享文件夹的Hyper-V实时迁移之二文件服务器及迁移用虚拟机的创建...
  5. 精简的Linux启动过程
  6. Eclipse中Latex配置
  7. Arduino 硬件开发 教程收集
  8. Gradle项目同步失败错误
  9. 拿3000工资与30000工资的区别,5张聊天记录让你醍醐灌顶
  10. php oracle 存储过程 返回值,PHP 调用 Oracle 存储过程 之 查询