带你起源Android Binder的设计

来源:互联网 发布:网络直播 经济效益 编辑:程序博客网 时间:2024/06/08 06:05

今日科技快讯

三星宣布将于7月7日开始在韩国销售翻新后的Galaxy Note 7手机,使用的电池与去年引起手机起火的电池不同。预计将销售40万部翻新后Note 7,并命名为“Galaxy Note 7粉丝版”,在韩国售价为69.96万韩元(约合611美元),比这款智能手机的最初发行价约低30%。这些翻新机将利用被召回但已开封的Note 7手机和未使用的Note 7组件制成。

作者简介

周末转眼就过去了,很高兴又到了跟大家见面的时候。

本篇来自 小海2016 的投稿, 直接从底层开始分析Binder机制,本文为系列的第一篇,看完感兴趣的朋友可以访问下面的博客地址查看剩余文章。

小海2016 的博客地址:

http://blog.csdn.net/u010132993

前言

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

  • WHAT :What Is Binder?这部分从Binder的引入以及背景来粗浅地为 Binder 下定义;

  • HOW :How To Use Binder? 知道 Binder 的概念并不够,还要知道怎么用它,这一部分从 Binding Service(绑定服务)入手,浅析 Binder 的应用场景,进而验证第一部分的概念;

  • HOW :How It Works? 知道了 Binder 的概念和使用场景,接下来这部分就是讲述它是如何在这些场景中发挥作用的。

  • WHY:众所周知,Android 基于 Linux 内核,而 Linux 本身具有众多跨进程通信机制,为什么非得使用 Binder?这部分主要比较 Binder 与其他跨进程机制的区别,以说明使用 Binder 的必要性。

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号环未使用),系统进程运行在1号环,用户进程运行在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 call,java 不得不使用一种机制克服这种障碍,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 的概念,以及 DVM,JVM 的区别联系,主要需要注意如下两点:

1. 在 Android 系统中,每个应用都运行在一个进程上,具有自己的 DVM 实例;

2. 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 层看,Binder 是 Service Manager 连接各种 Manager(ActivityManager,PackageManager...) 和相应 Service(ActivityManagerService,PackageManagerService...) 的桥梁;

  • 从客户端看,Binder 是客户端服务器通讯的媒介

至此我们就完成了第一部分的学习,简单讲解Binder由来以及其必要性,由于多半是纯概念的东西,有所了解就好。关于Binder的更多内容可以到作者的博客当中学习,点击最下方的 阅读原文 即可跳转到作者的博客 。

更多

每天学习累了,看些搞笑的段子放松一下吧。关注最具娱乐精神的公众号,每天都有好心情。

如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。

欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: