binder相关问题总结

Linux内核的基础知识

进程隔离和虚拟地址空间

为了保护操作系统中进程数据的安全性,设计了进程隔离机制;
目的是为了防止进程A可以去操作进程B的数据;

进程的隔离技术用到了虚拟地址空间
进程A的虚拟地址空间和进程B的虚拟地址空间是不同的;
这样就防止了进程A的数据可以写到进程B中去;

linux操作系统中,不同的进程之间的数据是不共享的;
所以对于每个进程来说,独享的是操作系统的虚拟地址空间

如果要一个进城与另一个进程进行通信,这需要通过进程间通信机制才能完成;

系统调用

Linux中有一个非常重要的概念叫系统调用;
目的是为了保护内核空间的数据安全,应用程序可以通过系统调用来安全的访问内核空间的数据;

binder驱动

在android系统中,各个进程通过binder通信的内核来进行交互的模块叫做binder驱动;
驱动程序一般指的是设备的驱动程序,是可以让计算机和设备进行通信的特殊程序;
其实也是一种软件,但是又相当于硬件的接口,操作系统可以通过这段程序来控制硬件的设备;

Binder通信机制的介绍

为什么要使用binder

  1. android使用linux内核,内核中有非常多的跨进程通信机制
    比如管道、socket等

  2. 性能
    移动设备频繁使用跨进程通信对通信机制肯定有有严格的要求;
    而binder相对于传统的ipc方式更加的高效
    (高效在哪里???)一次拷贝

  3. 安全
    由于传统的ipc通信方式没有对双方的身份没有做出严格的认证,只有上层协议才会进行架构;比如socket通信的ip地址是客户端手动填写的;
    可以进行人为的伪造;
    而binder机制协议本身就支持双方的身份验证大大提高了程序的安全性。

binder通信模型

1. 通讯录: ServiceManager

通讯录中保存了每一个人的信息和号码,可以方便去查询。A通过查找B的号码就可以方便的与B进行通讯;

2. 基站:binder驱动

两个人通信不但需要知道号码,还必须有基站的支持才能打电话;
类比到binder机制,两个用户空间的进程,想要通信不但需要通过ServiceManager这个通讯录查找到对方,还需要一个运行在内核空间的基站即binder驱动来完成转发。

binder通信模型

看下面这张图
image

第一步: ServiceManger的建立,前面说过ServiceManger相当于通讯录,所以说首先要有一个进程向驱动提出申请为ServiceManager,而内核驱动同意后,ServiceManager就负责管理所有的通信号码,这时候还没有人向ServiceManger中注册号码,所以说这时候号码是没有的;

第二步: A同学想要联系B同学,就必须将自己的号码注册到ServiceManager,在每个同学的进程启动之后,随即就会向ServiceManager进行报告,ServiceManager会存储同学的名称以及号码(就是服务的名称和内存地址)。ServiceManger中会建立一张表对应各个同学的名字和电话号码

第三步:就是图中client想要跟Server2通信,需要先通过ServiceManager查询Server2的号码,然后Client就可以通过binder与Server2进行通信了;

binder如何实现跨进程通信

image

假设client想要调用Server端的add方法,这就是一个跨进程通信的调用;

首先:Server会把自己注册到ServiceManager的查询表中
然后:Client开始查询ServiceManger,拿到Server的代理对象;为什么是代理对象,因为client和server都是在用户空间,binder驱动是在内核空间
无法返回一个真正的server对象,只能返回代理对象,这一层封装对于client是透明的。

总结一下:
Server端把自己注册到ServiceManager,而Client端想要调用Server端的一个方法比如add方法,它会到ServiceManager中去查询是否有这样的一个方法;
这时候ServiceManager会返回给Client端一个代理对象的add方法,但这个add方法是一个空方法,什么都做不了;
空方法的主要作用是当client端调用add方法时,会返回给内核驱动;
内核驱动接收到了代理对象的add方法,它就知道client端想要调用的是Server端的add方法,这时候内核驱动会去调用Server端的add方法,然后Server端的add方法调用完之后,把结果返回给内核驱动层的ServiceManager,然后ServiceManager再把结果返回给Client,这样就是一个完整的binder跨进程通信原理。

客户端只不过是持有了服务端的代理对象,然后通过代理对象协助驱动去跨进程通信。

什么是binder

  1. 通常意义下,binder指的是一种通信机制

  2. 对Server端来说,Binder指的是Binder本地对象,对于Client端来说,Binder指的是Binder代理对象

  3. 对于传输过程而言,binder是可以跨进程传输的对象

Aidl

image

aidl文件通过编译后生成一个Stub类,本质就是一个Binder,只不过实现了我们自定义的接口IFirstAidl,从设计模式角度看可以认为是一种策略模式;

asInterface 方法: asInterface参数是一个Binder对象代表了一种跨进程传输的能力;只要实现了这个接口就能将对象进行跨进程传递;

image

①:如果这里是不跨进程就使用 lin
②:如果是跨进程就使用代理对象

image

定义的compute方法:
①:这个方法里面首先是通过Parcel进行一个序列化操作
②:通过调用transact方法,这个是一个native方法,最终会调用到onTransact方法

image

onTransact方法:
第一步:根据跨进程的编号,code值选择操作
第二三步:跨进程调用自定的compute方法

posted @ 2022-07-06 18:49  cfdroid  阅读(78)  评论(0编辑  收藏  举报