浅谈Binder的基本原理

网上有一堆关于Binder原理的文章,都很长,我希望能尽量把这个问题讲得简短些。

1)关于binder驱动
Binder
Android里被设计成了一个驱动,安装在/dev/binder,这也是Androidlinux的重要区别之一:Android提出了一个新的进程间通信方式(IPC)。另外,这种方式是通过远程过程调用(RPC)实现的。
Binder的操作和对其它驱动的操作是一样的,看这个结构体:

static const struct file_operations binder_fops= {
	.owner = THIS_MODULE,
	.poll = binder_poll,
	.unlocked_ioctl = binder_ioctl,
	.mmap = binder_mmap,
	.open = binder_open,
	.flush = binder_flush,
	.release = binder_release,
};


所有对 /dev/binder 这个 driver 做的事情都会转换成 binder 自己定义的函数。比如当一个进程要打开 Binder 设备的时候总要调用
static int open_driver()

{
...
    int fd =open("/dev/binder", O_RDWR);

...
}

在经过binder驱动解释后就变成了binder_open
又如:
status_t IPCThreadState::talkWithDriver(bool doReceive){
...
#if defined(HAVE_ANDROID_OS)
        if (ioctl(mProcess->mDriverFD,BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
...
{
注意,这里的ioctl因为涉及到进程间通信,需要进行进程切换。
2)关于如何使用binder
一个serivce:

int main()
{
proc(ProcessState::self());
sm =defaultServiceManager();
sm->addService(“service.name”,newXXXService());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}
service manager 需要把这个 service 放到一个全局的链表 srvlist 中,这样, Client 就可以根据 service 的名字找到它了。比如 media.player

客户端试图拿到serviceBinder时,调用getService,如下:

void addBatteryData(uint32_t params) {
    sp<IBinder> binder =
       defaultServiceManager()->getService(String16("media.player"));
    sp<IMediaPlayerService>service = interface_cast<IMediaPlayerService>(binder);
    CHECK(service.get() != NULL);
    service->addBatteryData(params);
}


怎么写一个 Client 呢?

其实 Binder 机制和 Socket 编程里的 cs 架构一样, service 有一个 loop ,不停查找是不是 driver 上有命令写到了自己的 buffer Client 则向 binder 写数据,当然它要告诉 binder 谁需要收数据。

一个 Service ,对于 ServiceManager 来说也是 Client
Client
Service 之间通过什么通信呢?本质上是 BpBinder BBinder ,但是上层有一个对他们的封装接口 BpInterface BnInterface
BpInterface
的创建需要一个 BpBinder ,它的函数 remote ()返回的也是这个 BpBinder
BpBinder
service 上实体 Binder 的一个代理,跟它聊就等于跟 service 上的 Binder

BpBinder::BpBinder(int32_thandle),它是有一个handle构建了,这个handle其实就是Service的索引。ServiceManager的索引是0.


3)Binder为什么交换次数只有一次?
这是在内核决定的,因为Binder利用mmapBinder设备同时映射到用户空间和内核空间,所以在一个进程里,不需要进行用户空间和内核空间的copy,而只需要把数据从发送进程的用户空间拷贝到接收进程的内核空间。所以只需要拷贝一次。

TBC...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值