Android系统Binder驱动的运行机制简析
摘要:目前Android智能操作系统在移动设备和嵌入式设备中,获得了越来越广泛的应用。作为一种与具体硬件无关的专用驱动程序,Binder驱动凭借其较高的安全性与运行效率,在Android系统的进程通信方式中占据重要地位。在分析Binder驱动功能的基础上,分析了Binder框架的工作原理与工作流程。
关键词:Android系统;Binder驱动;进程通信
中图分类号:TP316 文献标识码:A 文章编号:1009-3044(2013)11-2716-02
1 概述
众所周知,在目前广泛使用的Android系统中,驱动包括两种,即专用驱动和设备驱动,其中专用驱动与通常意义上的硬件驱动相比,前者其实只是一种与具体硬件体系结构无关的专用软件。在进行系统移植的时候,专用驱动通常不需要作出任何修改,在相关的配置文件中,还可以通过配置,灵活选择究竟使用哪些专用驱动,以实现在功能满足的情况下的系统的精简化,提高运行效率。专用驱动程序保存在drivers/stagine/android目录中,当然在这个目前中还包括相关的配置文件。通常来说,专用驱动包括这么下述几种程序:binder和logger驱动程序;timed_output驱动程序框架;内存管理模块;利用控制台驱动的框架。在下文,将对非常重要的Binder驱动程序的工作原理和运行机制。
2 Binder驱动程序概述及功能
在操作系统中,应用程序在运行时,是以进程的方式体现出来,每个进程拥有独立的用户地址空间。在目前的Android智能设备,多进程的运行环境日益普遍,这就引出了在进程与进程之间进行数据通信、数据分享的问题。另外对于现在的Android应用软件来说,很多涉及到网络的软件,都会在内存中驻留后台服务,这同样也有前后台经常进行通信的问题需要解决。同时对于后台服务,用户普遍对于安全性有着疑虑,担心这些后台服务是否在用户不知情的情况下窃取私人数据信息,或是频繁连接网络,造成电池续航时间的缩短。
目前,在Android系统中,有三种较为普遍的进程间通信方式:一是使用标准的Linux Kernel IPC接口;二是使用D-BUS通信接口;三是本文介绍的Binder接口。其中Binder驱动由于其工作机制的简洁、更小的内存占用、安全性能优异,较小的系统风险,受到系统移植、软件开发人员的青睐,得到了越来越广泛的应用。使用Binder进程通信机制,还可以避免传统的进程通信机制所带来的进程开销过大的问题。一般来说,Binder驱动实现了下述几项功能。
1)通过Binder工作机制实现进程之间的数据通信,提供底层支持;
2)通过内存共享机制减少内存占用;
3)为每个进程分配对应的线程池;
4)实现系统对象的引用计数和引用映射。
作为一种专用驱动程序,Binder与一个具体的硬件设备没有关系,只不过它的工作机制与一般的设备驱动程序类似。Binder提供一系列标准的文件操作函数,包快open函数,mmap函数,poll函数,ioctl函数等等,以一种虚拟出来的字符设备注册在Android系统的设备目录中,Binder承担在进程之间建立、实现数据通信的职责,通过引用计数管理,提供数据包在进程间进行数据交互的底层支持。另外Binder程序与Android的应用软件通过ioctl函数进行交互,没有提供传统的read函数,write函数。ioctl函数是Binder驱动中对设备的输入输出通道进行有效管理的函数,通过这个函数控制数据读写与使用write,read函数相比,代码结构清晰,用户程序只须告知驱动程序要完成什么任务即可,至于具体的技术实现细节,用户程序无需关注。在Android系统的整个运行过程中,Binder驱动是工作在内核空间中的。
3 Binder驱动的工作原理
在传统进程通信方式中,如果要想把数据从发送端传送到接收端,一般是按照下述流程:首先是把要传送的数据放在一个预先定义的发送端缓冲区中,接着内核服务程序将数据块从发送端缓冲区拷贝到内核空间的一段缓冲区,之后又将数据从内核缓冲区传到到接收端的缓冲区中,并发出信号唤醒接收线程。从上述流程可以看出,要传输的数据经历了用户空间与内核空间的多次转移过程,传输效率相对低下。另外还有一个问题不容忽视,就是接收端在定义缓冲区大小时,由于预先不知道数据块的大小,所以倾向于定义一个较大的缓冲区,所以可能造成内存空间的浪费。
针对上述问题,在设计Binder驱动时,采用了一种新的方法。Binder是作为一张特殊的字符设备存在的,因为这个所谓的字符设备与普通意义上的存储设备不一样,前者没有真正的物理存储介质。在Binder驱动中实现了mmap系统调用,当完成调用后,Binder的接收方就拥有了一块大小在mmap调用时预先设置的数据接收缓冲区。在具体的实现过程中,ioctl函数与用户空间的进程发生数据交换,binder_thread_write发送读取请求,binder_thread_read函数实现数据读取并返回给前者。
4 Binder框架的工作流程
在系统层面看,采用Binder机制的通讯处理过程贯穿于整个Android系统的运行过程中,一共涉及到四个参与角色,即服务端,客户端,服务管理进程(SMgr)、Binder驱动。首先,在客户端要建立一个服务端的应用。服务端必须先向服务管理进程(SMgr)注册Binder实体,也就是起个易于记忆的名字,类似于在互联网中为了标识某台服务器,除了用IP地址外,还使用更便利的域名。这个名字连同服务以前通过Binder程序传送到SMgr中,建立服务端的一个代理对象。以后客户端就可以通过这个名字来获得服务端的引用,客户端对代理对象的访问等同于对服务端的访问,这种访问是在本地完成的,简化了操作。当客户端需要访问某个服务时,将在SMgr中查询有没有这个服务的代理对象,如果有,会把这个服务的句柄提供给客户端。接着服务器代理对象如果接收到客户端的访问请求,将借助Binder驱动发送到真正的服务端进程,紧接着服务端的进程响应客户请求,并将响应的结果回送给在客户端的服务器引用中,并进一步传回给客户端进程,完成了一次完整的通信处理流程。
5 结论
与传统的进程通信方式相比,Binder机制无论是在安全性还是效率方面都有独特的优势,因此获得了广泛的应用。
参考文献:
[1] 李骏.Android驱动开发与移植实战讲解[M]. 北京:人民邮电出版社,2012.
[2] 陈强.Android底层接口与驱动开发技术详解[M].北京:中国铁道出版社,2012.