Android Framework 基于 IPC Binder驱动使用 RPC

先来点高大上的普及:
加粗样式
何谓IPC

在Linux中,是以进程为单位分配和管理资源的。出于保护机制,一个进程不能直接访问另一个进程的资源,也就是说,进程之间互相封闭。但是,一个复杂的应用系统中,通常会使用多个相关的进程来共同完成一项任务,因此要求进程之间必须能够互相通信,从而共享资源和信息。所以,操作系统内核必须提供进程间的通信机制(IPC)。

何谓RPC

Android的RPC并不需要实现不同主机或不同操作系统间的远程调用,所以、它属于一个轻量级的RPC。

Android系统的RPC = Binder进程间通信 + 在Binder基础上建立起来的进程间函数调用机制。

我要讲的课题就是说白了: 进程A 通过ServiceManager调用进程B实现的接口,使用的是Binder驱动。

先介绍ServiceManager,

如以下代码,Android启动脚本在开机时候,默认启动此项服务。

在这里插入图片描述
是的,你看到了main函数。

353行: binder_open 打开binder驱动程序,就像你open("/dev/led",r);那么简单

359行: 告诉使用binder驱动的我们即将介绍的A和B进程,洒家是manager哦。

364行–383行: 安全相关,不在讨论范围,此处无需理会。

386行: binder_loop 从名字上看,是一个循环,重复做某些高尚的事情,说难听点在拉皮条。

          大概能猜测, B告诉manager,我有某些接口(大姑娘,拿去用),比如print_hello.

manager把他放入(资源)链表

                                A进程问manager, 哥,我需要调用print_hello函数(大姑娘),你那可以介绍给我么?

                                manager这个死媒婆就把刚才的B的闺女介绍给A享用了。 

          不要忘记了,他们的对话都是基于Binder驱动,所以A,B进程都有一句底下353行binder_open();

          合不合理啊。

在这里插入图片描述

我们来看看binder_loop在干啥子

for(;;)死循环,一直在找姑娘资源放在手里,然后介绍给各种A

378行: res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

ioctl哦,就是在数据交互啦。注意最后一个参数bwr, 这个结果体就是数据传输载体啦。

             ioctl阻塞着,一直在路边等待,等待什么呢?  也许从binder驱动这边来一个B进程来介绍他的函数(闺女),也许是来一个A进程来找函数。

             有数据返回时394行:binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); 

             这个函数在做什么呢?

此情此景,大概知道

                   1. 如果是B进程,他是把函数注册过来,manager放入链表中去

                   2. 如果是A进程,查询链表,返回他需要的函数。

                   我们去看看代码,是否是这样的。

在这里插入图片描述

--------------------------------------------------------友好的分界线,底下是binder_parse--------------------------------------------

哥们,看到各种case了吗, binder_parse 根据case后面的各种指令做不一样的事情哦。

看到227行:case BR_TRANSACTION: 这个分支主要来处理函数的注册和分配哈。

看到234行:if (func) {
此处的func 是调用binder_parse的binder_loop传来的,调用loop处:binder_loop(bs, svcmgr_handler);

 很容易,就能追踪到,this func is svcmgr_handler(); 

 很自然,我们要看看svcmgr_handler()做了什么勾当。


       。。。。。。。。。。。。。。

      。。。。。。。。。。。。。。。。

在这里插入图片描述

---------------------------------------------------------------------------------华丽的分割线,以下svcmgr_handler的实现-----------------------------------------------

依然还是看到各种 case

还有友好的宏的名字:292 293行

case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE: 从名字来看,A进程来通讯的时候,他的结构体里面必定带有此类宏,来告诉他,我来找啥子
273行:handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);

          通过do_find_service需找A要的函数,返回一个handle句柄。(其中的数据结构,哥另外一个章节分析)



                                      。。。。。。。。。。。。。。。。。。

                                     。。。。。。。。。。。。。。。。。。。

在这里插入图片描述


以上就是servicemanager的基本框架。


来获取服务的A进程做什么事情呢?

看看,也有main函数,也有bs = binder_open(128*1024);

174行:

handle = svcmgr_lookup(bs, svcmgr, “goodbye”);

需找他需要的服务,叫做goodbye服务. 我写的goodbye服务里面提供两个接口: saygoodbye 和saygoodbye_to
在这里插入图片描述

A进程调用自己的saygoodbye,哈哈哈

大家这会儿明白了没, 此处的saygoodbye并非真正实现saygoodbye的具体功能,而是在做通信,在需找其他进程当中的saygoodbye。

这个就算远程调用啦,轻量级的RPC

通过107行: binder_call 来找goodbye服务里面,代号为GOODBYE_SVR_CMD_SAYGOODBYE的函数,并将需要传输的参数等放在msg中,在远端找到的B进程里面

                    执行。多么的高大上啊。

既然这样,我们肯定要分析binder_call做什么啦。
在这里插入图片描述

                   注意107行,binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE);美丽宏哦,给manager用,底下会用到

----------------------------------------------------------------------------华丽分割,以下binder_call源码-----------------------------------------------------------

做好数据交互对象bwr以后

351行: res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

           注意332行:  writebuf.cmd = BC_TRANSACTION;这个漂亮的宏就是告诉manager调用binder_parse函数里面的case BC_TRANSACTION,然后调用func,

           也就是以上分析的svcmgr_handler

跟manager通信,把我要的东西放在bwr里面。

           这样manager收到信息以后呢,就进入 到

case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:为他找到进程B,并且执行A想要的函数。
在这里插入图片描述

好啦,以上就是A进程,我们称之客户端进程想servicemanager要服务B里面的接口的过程啦。

B进程怎么像manager注册呢,分析完了A,B就不是难事啦。

我简单贴上代码,自行分析哈。

217行: 熟悉的open bs = binder_open(128*1024);

224行: svcmgr_publish(bs, svcmgr, “hello”, hello_service_handler); 这个接口用来发布B的接口

----------------------------------------------------------------------------------------------------------------------svcmgr_publish----------------------------

同样 29行有binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE)
在这里插入图片描述

但是注意 第三个参数: SVC_MGR_ADD_SERVICE加入服务 哇哈哈哈

大概的三者框架就是这样,其中具体的handle数据分析,等待哥哥下期分析啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃鸡米花的豆丁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值