本篇介绍
binder是android中独有的一种ipc实现,业界有句话是无binder不android。不了解binder,在阅读android代码中会遇到很多困难,因此为了为后续的android知识介绍打下坚实的基础,决定介绍下binder。binder涉及内容很多,单凭一篇是不可能介绍完的,因此这将会是一个系列。
本篇内容
为什么是binder
在介绍binder前需要搞明白这个问题,为什么是binder?在linux上已经有很对ipc实现了,为什么还要做一套新的。接下来我们就分析下这个问题。
IPC | 描述 |
---|---|
socket/管道/消息队列 | 不安全,无法识别来者身份,而且也需要两次拷贝,第一次是将数据从用户空间拷贝至内核空间,第二次是将数据从内核空间拷贝至目标进程用户空间 |
共享内存 | 控制复杂,也无法识别来着身份,效率高,零次拷贝 |
binder | 安全,可以知道来者身份,主要是uid和gid,这个是驱动添加的,业务无法篡改,需要一次拷贝 |
看到这里可能会有疑问,为啥binder不搞成零次拷贝,这样岂不是效率更高?零次拷贝其实就是进程间共享内存了,这样具体实现的时候太复杂,应该是综合复杂度和性能折衷的结果了。
binder如何做到的一次拷贝
这里最核心的就是内存映射mmap,本来进程是无法直接访问物理介质上的数据的,需要将数据从物理介质上拷贝到内核缓存里面,然后再访问内核缓存中的数据。可是通过mmap就可以直接将进程空间中一段内存和物理介质直接映射起来,这样就可以直接访问了。当然对于binder并不是将内存和某个物理介质映射起来了,因为binder不涉及物理介质,而是将用户空间内存和内核空间内存映射起来了,这样内核只需要将偏移通知给用户态,用户态就可以直接访问,而不需要再次将数据从内核拷贝至用户态了。
这儿跑个题,为什么用户态不能直接访问内核态数据?主要是出于安全性考虑,对于linux,所有进程是空间内核空间的,谁也不知道某块内核内存是属于再被哪个进程使用的,如果其他进程可以直接访问,那无疑是很大的安全风险,因此就需要对应的安全机制来提供保护。我们用的比较多的就是将数据拷贝到用户进程空间,这就是copy_to_user,copy_from_user做的事情了。
题归正传,看下下面的图加深下一次拷贝的流程。
binder一次拷贝
binder的架构
binder是基于CS架构,主要涉及4个角色,client,server,servicemanager,binder驱动。如下图所示(网上拷贝,有侵权可以联系本人删除)
binder架构
角色 | 作用 |
---|---|
client | ipc调用方 |
server | ipc请求的处理方 |
servicemanager | binder服务管家,管理包含名字的binder服务,client可以从servicemanager获取其他目标binder服务的proxy,类似于DNS的作用 |
binder驱动 | binder的路由和真正数据传输实现 |
binder的实现覆盖了内核,native,jni,fwk,构建了android的ipc骨架,有了这套机制,android进程间的通信变得十分神奇,这块在后续的文章中会渐渐体会到
本篇总结
本篇简单介绍了下binder的背景,接下来会由浅入深,从代码层面剖析binder,希望这个过程中也可以一块学习收获。
网友评论