Android Binder Analysis(1)

来源:互联网 发布:幸运星 知乎 编辑:程序博客网 时间:2024/05/16 01:55

Android Binder Analysis(1)

@(Android)[Binder|AIDL|Messenger]

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布

Binder这个名词大家或许有些许陌生,但是在Android系统中却具有至关重要的作用,作为Android系统所特有的特征之一,无论是系统服务的调度还是跨进程通信中,处处皆可见其身影,接下来我会从四个层面逐一介绍Binder
(简称BinderWH2W),即:

  • WHATWhat Is Binder?这部分从Binder的引入以及背景来粗浅地为Binder下定义;
  • HOWHow To Use Binder?知道Binder的概念并不够,还要知道怎么用它,这一部分从Binding Service(绑定服务)入手,浅析Binder的应用场景,进而验证第一部分的概念;
  • HOWHow It Works?知道了Binder的概念和使用场景,接下来这部分就是讲述它是如何在这些场景中发挥作用的。
  • WHY:众所周知,Android基于Linux内核,而Linux本身具有众多跨进程通信机制,为什么非得使用Binder?这部分主要比较Binder与其他跨进程机制的区别,以说明使用Binder的必要性。

  • Android Binder Analysis1
  • 本篇文章已授权微信公众号 guolin_blog 郭霖独家发布
    • Linux OS Foundation
      • MultitaskingProcesses and Threads
      • Process Isolation进程隔离
      • User Space and Kernel Space用户空间和内核空间
      • IPCInter-Process Communication
    • Android OS Foundation
      • Java Native Interface
      • Dalvik Virtual Machine
      • Kernel
      • Android Component
      • Component Communication
    • Binder Concept

Linux OS Foundation

这一部分中我们讲介绍Binder相关的一些Linux基础知识,为了便于大家更好的理解,为中英文对照部分,各位英文好的看英文,英文不好的看中文。

Multitasking,Processes and Threads

Multitasking is the ability to execute multiple instances of programs or processes at the same time. An operating system therefore creates for every binary exe-cutable le a certain memory frame with its own stack, heap, data and shared mapped libraries. It also assigns special internal management structures. This is called a process .The operating system must provide fair proportioning, because only one process can use the CPU at the same time. All processes must be interruptible. The operating system sends them to sleep or wakes them on their time slot. This work is done by a scheduler , supplying each process with an optimal time slot.A thread is a process without own address space in memory, it shares the address space with the parent process. Processes can have child threads, and a thread must be assigned to a process.

上述英文中描述了对任务,进程和线程的基本概念,学过操作系统的小伙伴对这些应该很熟悉了,我把这部分英文翻译成如下三句定义:
- 多任务 :多任务是操作系统同时执行多个程序或进程实例的能力;
- 进程 :操作系统为一个二进制可执行文件创建了一个载有该文件自己的栈,堆、数据映射以及共享库的内存片段,还为其分配特殊的内部管理结构。这就是一个进程。操作系统必须提供公平的比例,因为在同一时间只有一个进程在使用CPU。所有进程都是可以中断的。操作系统在流水线上唤醒或中断进程,这项工作是由调度器完成,提供每个流水线的最佳时段;
- 线程 :线程是没有自己内存地址空间的过程,它与父进程共享内存地址空间。进程可以有多个子线程,一个线程必然拥有唯一的一个进程

Process Isolation(进程隔离)

Due to security and safety reasons, one process must not manipulate the data of another process. For this purpose an operating system must integrate a concept for process isolation. In Linux, the virtual memory mechanism achieves that by assigning each process accesses to one linear and contiguous memory space. This virtual memory space is mapped to physical memory by the operating system.Each process has its own virtual memory space, so that a process cannot manip-ulate the memory space of another process. The memory access of a process is limited to its virtual memory. Only the operating system has access to physical memory。The process isolation ensures for each process memory security, but in many cases the communication between process is wanted and needed. The operating system must provide mechanisms to approve interprocess communication。

出于安全考虑,一个进程不能操作另一个进程的数据,进而一个操作系统必须具备进程隔离这个特性。在Linux系统中,虚拟内存机制为每个进程分配了线性连续的内存空间,操作系统将这种虚拟内存空间映射到物理内存空间,每个进程有自己的虚拟内存空间,进而不能操作其他进程的内存空间,每个进程只能操作自己的虚拟内存空间,只有操作系统才有权限操作物理内存空间.进程隔离保证了每个进程的内存安全,但是在大多数情形下,不同进程间的数据通讯是不可避免的,因此操作系统必须提供跨进程通信机制。

User Space and Kernel Space(用户空间和内核空间)

Processes run normally in an unprivileged operation mode, that means they have no access to physical memory or devices. This operation mode is called in Linux user space. More abstractly, the concept of security boundaries of an operating system introduces the term ring. Note, that this must be a hardware supported feature of the platform. A certain group of rights is assigned to a ring. Intel hardware [21] supports four rings, but only two rings are used by Linux. These are ring 0 with full rights and ring 3 with least rights. Ring 1 and 2 are unused.System processes run in ring 0 and user processes in ring 3. If a process needs higher privileges, it must perform a transition from ring 3 to ring 0. The transition passes a gateway, that performs security checks on arguments. This transition is called system call and produces a certain amount of calculating overhead。

进程通常运行在一个特定的操作模式中,在这种模式下它们并没有接触物理内存或设备的权限,这种操作模式被称为Linux 用户空间。
抽象来看,操作系统中安全边界的概念就像环路的概念一样(前提是系统支持这种特性),一个环上持有一个特定的权限组,Intel 支持四层环,但是Linux只使用了其中的两环(0号环持有全部权限,3号环持有最少权限,1号和2号环未使用),系统进程运行在0号环,用户进程运行在3号环,如果一个用户进程需要其他高级权限,其必须从3号环过渡成0号环,过渡需要通过一个安全参数检查的网关,这种过渡被称为系统调用,在执行过程中会产生一定数量的计算开销。
对于用户空间和内核空间的环路模型,我画了如下图示方便大家理解:
这里写图片描述
在这个环路中,用户空间要访问内核空间的唯一方式就是系统调用(System Call),系统调用指的是内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用的(System Call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序.系统调用是用户程序和内核交互的接口.

IPC(Inter-Process Communication)

关于IPC我主要说明如下两点:
- IPC是一种用于多进程间数据信号交换的框架;
- IPC方式包括信息传递,数据同步,共享内存和远程过程调用等;

这里以一个客户端调用服务器的接口的过程来简单说明上述机制发挥作用的具体位置:
这里写图片描述

Android OS Foundation

Java Native Interface

Four programming languages are used for system development: Assembler, C,C++ and Java. The kernel has a small amount of Assembler but is mainly written in C. Some native applications and libraries are written in C++.All other applications, especially custom apps, are written in Java.
A distinction is made between programs compiled for the virtual machine and programs compiled to run on a specific computation platform, like Intel x86 or ARM. Programs compiled for a specific platform are called native. Because Java is executed in a virtual machine with its own byte-code, no native code can be executed directly. Due to the need to access low-level os mechanism like kernel calls, Java has to overcome this obstacle. This is done by the Java native interface (JNI) [22], which allows Java to execute compiled code from libraries written in other languages, e.g. C++. This is a trade-off between gaining capabilities of accessing the system and decreasing the level of security in Java.

在Android系统中使用了四种编程语言,汇编,C,C++JAVA,其中Kernel部分主要由C编写,包含少量汇编,一些底层的库或者应用使用C++编写,其他的用户,尤其是用户的自定义应用,使用JAVA编写。

虚拟机编译程序和特定平台编译程序的区别在于(如英特尔x86或ARM之间的区别),为特定平台编译的程序称为native,因为是java字节码在虚拟机中执行。原生代码不可以直接执行。出于访问系统底层机制的需要,如Kernel calljava不得不使用一种机制克服这种障碍,Java Native Interface就是用来处理这个障碍,JNI赋予JAVA执行其他语言编译后代码的能力(如C++),这种机制平衡了访问系统底层机制与降低JAVA安全机制之间的矛盾。

Dalvik Virtual Machine

The Dalvik virtual machine (DVM) [5] runs the Java programmed apps. The DVM does not claim to be a Java virtual machine (JVM) due to license reasons,but fulfills the same purpose. Java 5 programs can run in that environment.The Sun JVM is stack based, because a stack machine can be run on every hardware. Hardware and platform independence were major design principles of Java. The DVM is register based for performance reasons and well adapted to ARM hardware. This is a different design principle, taking the advantage of hardware independence for high performance and less power consumption, which is essential for mobile purposes with limited battery capability. The possibility to use the Java native interface weakens the security guarantying property of Java to implicit checking the bounds of variables and to encapsulate system calls and the force to use JVM defined interfaces to the system. The use of native libraries can allow by passing the type and border checking of the virtual machine and opens the door to stack-overflow attacks. Even it is a security issue, the JNI is essential for the interprocess communication mechanism because the middleware of Binder are C++ libraries and must be accessed with JNI.

上述英文简单介绍了DVM的概念,以及DVMJVM的区别联系,主要需要注意如下两点:
- 在Android系统中,每个应用都运行在一个进程上,具有自己的DVM实例;
- Dalvik基于寄存器,而JVM基于栈,在受电量限制的移动平台上,硬件独立所带来的性能及电量优化不容小视,JNI弱化了JAVA的变量安全边界检查,系统调用的封装及系统调用JVM接口方法,可以通过本地库的参数类型以及边界进行系统攻击。尽管这是一个安全隐患,但是JNI仍然是系统中不可缺失的内部通信部分,因为中间件Binder就是使用C++编写的,只能通过JNI调用;

Kernel

Android is based on a Linux 2.6 standard kernel but enhanced with new exten-sions for mobile needs. These are kernel modules Alarm,Ashmem,Binder, Powermanagement,Low Memory Killer, a kernel debugger and a logger. We will analyze the Binder driver in this work, that overs a new IPC mechanism to Linux.

Android是一个基于Linux 内核(2.6 版)开发的具备移动平台特性的操作系统,这些特性包括:定时器,匿名共享内存,粘合剂,低内存管理器,电源管理驱动,日志系统和调试系统。
- 低内存管理器(Low Memory Killer) 比Linux的标准的OOM(Out Of Memory)机制更加灵活,它可以根据需要杀死进程以释放需要的内存。源代码位于drivers/staging/ android/lowmemorykiller.c
- 匿名共享内存(Ashmem) 为进程间提供大块共享内存,同时为内核提供回收和管理这个内存的机制。源代码位于mm/ashmem.c
- Android电源管理(PM) 一个基于标准Linux电源管理系统的轻量级Android电源管理驱动,针对嵌入式设备做了很多优化;
- Android Alarm 提供了一个定时器,用于把设备从睡眠状态唤醒,同时它还提供了一个即使在设备睡眠时也会运行的时钟基准。源代码位于drivers/rtc/alarm.c

Android Component

这里写图片描述
如上图,Android中任一应用均是由这四大组件中的一个或多个组合而成,这些组件有可能运行在同一个进程,也有可能运行在不同进程,同一个进程通信自然很简单,但是不同进程通信就受到进程隔离的限制,因为Android系统必须提供一种行之有效的IPC方案,以用于实现组件件跨进程通信。

Component Communication

这里写图片描述
这里我绘制了常见的组件交互情形,以供大家更清楚的认识到跨进程通信机制的必要性。

Binder Concept

前文中描述了IPC机制的由来以及必要性,我想大家已经深刻认识到跨进程通信机制的重要性,那么Android所特有的Binder,作为IPC机制的一种实现方式,又是什么呢?这里我引用刚哥(任玉刚)提出的基本概念:
- 从代码角度来看,Binder是一个类,实现了IBinder接口;
- 从来源看,Binder来自于OpenBinder,Android IPC机制中的一种,Binder还可以理解成一个虚拟物理设备,设备驱动是dev/binder
- 从Framework层看,BinderService Manager连接各种Manager(ActivityManager,PackageManager...)和相应Service(ActivityManagerService,PackageManagerService...)桥梁
- 从客户端看,Binder是客户端服务器通讯的媒介

至此我们就完成了第一部分的学习,简单讲解Binder由来以及其必要性,由于多半是纯概念的东西,有所了解就好。第二部分将有大批代码僵尸涌来,敬请期待。

最新文章更新在微信公众号上,欢迎关注获取详情:
这里写图片描述


感谢阅读这份博文。转载请注明出处:小海窝