Binder是Android系统提供的一种IPC( 进程间通信) 机制。 由于Android是基于Linux内核的, 因此除了Binder以外,还存在其他的IPC机制, 例如管道和socket等。

Binder相对于其他IPC机制来说, 就更加灵活和方便了。在基于Binder通信的C/S架构体系中, 除了C/S架构所包括的Client端和Server端外, Android还有一个全局的ServiceManager端, 它的作用是管理系统中的各种服务( Service)。除此之外还有一个很重要的东西,就是Binder驱动程序。因为Android基于linux系统,在linux系统中每个进程都有独立的用户空间,例如前面提到的Client端就应该属于客户端进程中,Service端就应该属性服务端进程之中,他们相互隔离即不能直接通信,因此就诞生了一个属于android特定的binder驱动程序,因为是驱动程序,所以它位于内核空间(注意不同的进程共同拥有这个内核空间),这样才能实现进程之间的通信。他们的关系如下:

Binder死磕到底

一、Linux内存管理

在一个32位的Linux系统中,一个进程可以使用的地址范围为0x00-0xFFFFFFFF,即在这程序中我们定义一个指针,因为指针在32位的系统中占用4个字节,因此能够通过这个指针访问任何该范围的内存地址单元,然而这些内存地址单元目前并没有对应真实的物理内存,因此又叫做虚拟地址空间。根据上面的理论我们可以知道在32位Linux系统中,每个进程都能够访问4G的线性虚拟地址空间(线性就是连续的意思,即能够访问编号0x00 0x01 0x02 ... 0xfffffffe 0xffffffff这些虚拟地址)。因此在Linux系统中每个进程都有拥有4G内存空间,我们不妨想象一下,如果有多个进程那么岂不是4G内存空间的整数倍。哈哈,当然不是这样的,这里说的4G空间完全是一个虚拟的,其实根本就不存在。

从宏观上来看Linux操作系统的体系架构分为用户态和内核态(或者用户空间和内核)。内核从本质上看是一种软件——控制计算机的硬件资源,并提供上层应用程序运行的环境。用户态即上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源,包括CPU资源、存储资源、I/O资源等。为了使上层应用能够访问到这些资源,内核必须为上层应用提供访问的接口:即系统调用。

每个进程都可以使用访问0到4G这段线性虚拟地址,Linux系统为了系统的安全为也把4G的线性虚拟地址划分为两部分:即0x00-0xbfffffff(3G)为用户空间(用户态才能访问),0xc0000000-0xffffffff(3G-4G)为内核空间(内核态才能访问)。同样不管内核空间还是用户空间,它们都是虚拟地址,即“可以寻址”4G,意思是虚拟地址的0-3G对于一个进程的用户态可以访问的,而3-4G是只有进程的内核态可以访问的。并不是说这个进程会用满这些空间。

上面可以知道0-4G的线性虚拟空间被分为了用户空间和内核空间。但他们目前都没有指向真实的物理内存,因此就有了分页技术可以实现将一个虚拟地址对应到一个真实的物理内存设备上的某个地址。即当应用程序访问一个虚拟地址时,首先必须将虚拟地址转化成物理地址,然后处理器才能解析地址访问请求。地址的转换工作需要通过查询页表才能完成,概括地讲,地址转换需要将虚拟地址分段,使每段虚地址都作为一个索引指向页表,而页表项则指向下一级别的页表或者指向最终的物理页面。内存映射其实也是用的上面的分页技术来实现的。

一般而言一个进程虽然拥有3G虚拟内存访问权限,但是实际需要的内存可能很少。各个进程均拥有3G虚拟内存,那么操作系统是如何做到各进程所使用的实际物理内存不会互相占用呢?实际上,各个进程均有自己的内存映射表。任意一个时刻,在一个CPU上只有一个进程在运行。所以对于此CPU来讲,在这一时刻,整个系统只存在一个4GB的虚拟地址空间,这个虚拟地址空间是面向此进程的。当进程发生切换的时候,虚拟地址空间也随着切换。由此可以看出,每个进程都有自己的虚拟地址空间,只有此进程运行的时候,其虚拟地址空间才被运行它的CPU所知。在其它时刻,其虚拟地址空间对于CPU来说,是不可知的。所以尽管每个进程都可以有4 GB的虚拟地址空间,但在CPU眼中,只有一个虚拟地址空间存在。虚拟地址空间的变化,随着进程切换而变化。

内核空间具有相对独立的特性。即内核的虚拟地址空间范围是自己独有的,不与任何用户进程共享(内核实质也是一个进程)。这样可保证内核空间的安全性。但是由于内核虚拟地址空间较小0xc000000~0xFFFFFFFF 仅有1G大小,Linux将内核地址空间划分为三部分ZONE_DMA、ZONE_NORMAL和ZONE_HIGHMEM,其中3G-(3G+896M)这段空间直接映射了物理内存设备的前面896M实际物理地址,它们之间是简单的线性对应关系。所以不论有多少个进程,它们都共用了物理内存设备的同一块区域。如下图:

Binder死磕到底

参考链接:

二、Binder驱动

 

相关文章: