写给应用开发的 Android Framework 教程是一个系列教程,目前已更新以下内容:
-
系统开发基础
-
AOSP 上手指南
-
学穿 Binder 系列
-
HAL 与硬件服务
1. Binder 是什么?
在 linux 中,每个进程都有自己的虚拟内存地址空间。虚拟内存地址空间又分为了用户地址空间和内核地址空间。
不同进程之间用户地址空间的变量和函数是不能相互访问的。
很多时候,提供系统功能的数据和函数都会放在固定的几个进程中(比如显示画面,播放声音等),我们编写的用户程序要实现相应的功能就需要通过跨进程通信技术来访问这些数据和函数。
2. 实现跨进程通信的思路
虽然用户地址空间是不能互相访问的,但是不同进程的内核地址空间是相同和共享的,我们可以借助内核地址空间作为中转站来实现进程间数据的传输。
具体的我们在 B 进程使用 copy_from_user 将用户态数据 int a
拷贝到内核态,这样就可以在 A 进程的内核态中访问到 int a
更进一步,可以在 A 进程中调用 copytouser 可以将 int a
从内核地址空间拷贝到用户地址空间。至此,我们的进程 A 用户态程序就可以访问到进程 B 中的用户地址空间数据 int a
了
3. 优化我们的方案
为了访问 int a
,需要拷贝两次数据。能不能优化一下?我们可以通过 mmap 将进程 A 的用户地址空间与内核地址空间进行映射,让他们指向相同的物理地址空间:
完成映射后,B 进程只需调用一次 copyfromuser,A 进程的用户空间中就可以访问到 int a
了。这里就优化到了一次拷贝。
以上就是 binder 最基本的原理了。
总结
- 跨进程通信的需求普遍存在
- binder 跨进程通信核心原理是 copyfromuser 和 mmap
参考资料
-
韦东山 Android 系统教程
-
《Android 框架解密》
-
《Android 源代码情景分析》
-
《深入理解 Android 》系统图书
关于
如果你对 Android Framework 感兴趣,可以持续关注:
- 掘金平台个人技术博客
- 我的个人公众号
- 我的个人微信(可以加我微信进 Android Framework 交流群)