使用: 系统工程师、 应用工程师
引言
Client,Server,Service Manager之间交互都是虚线表示,是由于它们彼此之间不是直接交互的,而是都通过与Binder驱动进行交互的
Binder驱动
binder请求码,以”BC_“开头,简称BC码,用于从IPC层传递到Binder Driver层;
binder响应码,以”BR_“开头,简称BR码,用于从Binder Driver层传递到IPC层;
对于请求码为BC_TRANSACTION或BC_REPLY时,会执行binder_transaction()方法
ServiceManager
启动ServiceManager
[-> service_manager.c] svcmgr_handler()
1.do_add_service//注册指定服务 2.do_find_service//根据名称查找相应服务
驱动设备的四大操作:初始化(binder_init),打开 (binder_open),映射(binder_mmap),数据操作(binder_ioctl)
内存机制:bind_mmap
虚拟进程地址空间(vm_area_struct)和虚拟内核地址空间(vm_struct)都映射到同一块物理内存空间。当Client端与Server端发送数据时,Client(作为数据发送端)先从自己的进程空间把IPC通信数据copy_from_user拷贝到内核空间,而Server端(作为数据接收端)与内核共享数据,不再需要拷贝数据,而是通过内存地址空间的偏移量,即可获悉内存地址,整个过程只发生一次内存拷贝
为何不直接让发送端和接收端直接映射到同一个物理空间,那样就连一次复制的操作都不需要了,0次复制操作那就与Linux标准内核的共享内存的IPC机制没有区别了,对于共享内存虽然效率高,但是对于多进程的同步问题比较复杂,而管道/消息队列等IPC需要复制2两次,效率较低
Binder在进程间数据通信的流程图,从图中更能明了Binder的内存转移关系。
获取ServiceManager
由defaultServiceManager()返回的是BpServiceManager(单例)
- 通过继承接口IServiceManager实现了接口中的业务逻辑函数;
- 通过成员变量mRemote= new BpBinder(0)进行Binder通信工作
- BpBinder通过handler来指向所对应BBinder, 在整个Binder系统中handle=0代表ServiceManager所对应的BBinder
getContextObject等价于new BpBinder(0);
defaultServiceManager 等价于 new BpServiceManager(new BpBinder(0));
ProcessState对象(单例)
- 成员变量mDriverFD记录binder驱动的fd,用于访问binder设备
- mmap的binder分配的默认内存大小为1M-8k,BINDER_VM_SIZE = (110241024) - (4096 *2),
服务注册
defaultServiceManager()
-> addService(String16("media.player"), new MediaPlayerService());
-> status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
-> status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
Binder代理类调用transact()方法,真正工作还是交给IPCThreadState来进行transact工作,
- 1.MediaPlayerService进程调用ioctl()向Binder驱动发送IPC数据
- 2.Binder驱动收到该Binder请求,生成BR_TRANSACTION命令,选择目标处理该请求的线程,即ServiceManager的binder线程
- 3.Service Manager的线程调用服务注册函数将服务”media.player”注册到服务目录中。当服务注册完成后,生成IPC应答数据(BC_REPLY)
- 3.Binder驱动收到该Binder应答请求,生成BR_REPLY命令。在MediaPlayerService收到该命令后,知道服务注册完成便可以正常使用
BC_TRANSACTION和BR_TRANSACTION过程是一个完整的事务过程;BC_REPLY和BR_REPLY是一个完整的事务过程
服务获取
getService()->循环5次checkService()
其中remote()为BpBinder
->BpBinder::transact()->
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);