AOSP - 安卓架构

文章目录[x]
  1. 1:应用框架
  2. 2:Binder IPC
  3. 2.1:多个 Binder 域
  4. 2.2:分散-集中
  5. 2.3:精细锁定
  6. 2.4:实时优先级继承
  7. 2.5:AIDL 与 HIDL 之间的主要差异
  8. 3:系统服务
  9. 4:硬件抽象层 (HAL)
  10. 4.1:HAL类型
  11. 4.2:绑定式HAL
  12. 4.3:直通式HAL
  13. 4.4:Same-Process HAL
  14. 4.5:传统 HAL 和旧版 HAL
  15. 5:Linux 内核

在本文中,将简单介绍Android整个系统架构,以便能够系统的学习其中的各个模块。Android 系统架构包含以下组件:

应用框架

应用框架最常被应用开发者使用,应用开发者应该非常了解。很多 API 都可以直接映射到底层 HAL 接口,并可提供与实现驱动程序相关的实用信息。

Binder IPC

Binder 进程间通信 (IPC) 机制允许应用框架通过AIDL跨越进程边界并调用 Android 系统服务代码,这使得高级框架 API 能与 Android 系统服务进行交互。在应用框架级别,开发者无法看到此类通信的过程。HAL层也可使用HIDL与框架层通信。

Android 8开始,Android 框架和 HAL 使用 Binder 互相通信。由于这种通信方式极大地增加 Binder流量,因此 Android 8 包含了几项改进,旨在确保 Binder IPC 的速度。

多个 Binder 域

在通用内核 4.4及更高版本中,为了在框架(独立于设备)和供应商(特定于设备)代码之间彻底拆分 Binder 流量,Android 8 引入了“Binder 上下文”的概念。每个 Binder 上下文都有自己的设备节点和上下文(服务)管理器。只能通过上下文管理器所属的设备节点对其进行访问,并且在通过特定上下文传递 Binder 节点时,只能由另一个进程从相同的上下文访问上下文管理器,从而确保这些域完全互相隔离。

供应商进程都使用 Binder 进程间通信 (IPC) 技术进行通信。在 Android 8 中,/dev/binder 设备节点成为框架进程的专有节点,这意味着供应商进程无法再访问此节点。供应商进程可以访问 /dev/hwbinder,但必须将其 AIDL 接口转为使用 HIDL。对于想要继续在供应商进程之间使用 AIDL 接口的供应商,Android 会按以下方式支持 Binder IPC

vndbinder

Android 8 支持供应商服务使用的新 Binder 域,访问此域需要使用 /dev/vndbinder(而非 /dev/binder)。添加 /dev/vndbinder 后,Android 现在拥有以下 3 个 IPC 域:

IPC域 说明
/dev/binder 框架/应用进程之间的 IPC,使用 AIDL 接口
/dev/hwbinder 框架/供应商进程之间的 IPC,使用 HIDL 接口 框架/供应商进程之间的 IPC,使用 HIDL 接口供应商进程之间的 IPC,使用 HIDL 接口
/dev/vndbinder 供应商/供应商进程之间的 IPC,使用 AIDL 接口

通常,供应商进程不直接打开 Binder 驱动程序,而是链接到打开 Binder 驱动程序的 libbinder 用户空间库。为 ::android::ProcessState() 添加方法可为 libbinder 选择 Binder 驱动程序。供应商进程应该在调用 ProcessState,、IPCThreadState 或发出任何普通 Binder 调用之前调用此方法。如需使用该方法,请在供应商进程(客户端和服务器)的 main() 后放置以下调用:

ProcessState::initWithDriver("/dev/vndbinder");

vndservicemanager

以前,Binder 服务通过 servicemanager 注册,其他进程可从中检索这些服务。在 Android 8 中,servicemanager 现在专供框架使用,而应用进程和供应商进程无法再对其进行访问。

不过,供应商服务现在可以使用 vndservicemanager,这是一个使用 /dev/vndbinder(作为构建基础的源代码与框架 servicemanager 的相同)而非 /dev/binderservicemanager 的新实例。供应商进程无需更改即可与 vndservicemanager 通信;当供应商进程打开 /dev/vndbinder 时,服务查询会自动转至 vndservicemanager

vndservicemanager 二进制文件包含在 Android 的默认设备 Makefile 中。

警告:如果搭载 Android 11 或更高版本的设备需要使用这些功能,必须指定 PRODUCT_PACKAGES += vndservicemanager,从而明确选择使用 vndservicemanager。

分散-集中

在通用内核 4.4及更高版本中,在之前的 Android 版本中,Binder 调用中的每条数据都会被复制 3 次

  • 一次是在调用进程中将数据序列化为 Parcel
  • 一次是在内核驱动程序中将 Parcel 复制到目标进程
  • 一次是在目标进程中反序列化 Parcel

Android 8 使用分散-集中优化将副本数量从 3 减少到 1。数据保留其原始结构和内存布局,且 Binder 驱动程序会立即将数据复制到目标进程中,而不是先在 Parcel 中对数据进行序列化。在目标进程中,这些数据的结构和内存布局保持不变,并且,在无需再次复制的情况下即可读取这些数据。

精细锁定

在通用内核 4.4及更高版本中,在之前的 Android 版本中,Binder 驱动程序使用全局锁来防范对重要数据结构的并发访问。虽然采用全局锁时出现争用的可能性极低,但主要的问题是,如果低优先级线程获得该锁,然后实现了抢占,会导致同样需要获得该锁的优先级较高的线程出现严重的延迟。这会导致平台卡顿。

原先尝试解决此问题的方法是在保留全局锁的同时禁止抢占。但是,这更像是一种临时应对手段而非真正的解决方案,最终被上游拒绝并舍弃。后来尝试的解决方法侧重于提升锁定的精细程度,自 2017 年 1 月以来,Pixel 设备上一直采用的是更加精细的锁定。虽然这些更改大部分已公开,但后续版本中还会有一些重大的改进。

实时优先级继承

通用内核4.4和通用内核4.9,Binder 驱动程序一直支持 nice 优先级继承。随着 Android 中以实时优先级运行的进程日益增加,现在出现以下这种情形也属正常:如果实时线程进行 Binder 调用,则处理该调用的进程中的线程同样会以实时优先级运行。为了支持这些用例,Android 8 现在在 Binder 驱动程序中实现了实时优先级继承。

除了事务级优先级继承之外,“节点优先级继承”允许节点(Binder 服务对象)指定执行对该节点的调用所需的最低优先级。之前版本的 Android 已经通过 nice 值支持节点优先级继承,但 Android 8 增加了对实时调度政策节点继承的支持。

AIDL 与 HIDL 之间的主要差异

  • AIDL 语言的语法更接近 JavaHIDL 语言的语法类似于 C++
  • 所有 AIDL 接口都具有内置的错误状态。不要创建自定义状态类型,而应在接口文件中创建常量状态 int,并在 CPP/NDK 后端使用 EX_SERVICE_SPECIFIC,在 Java 后端使用 ServiceSpecificException
  • 未经检查的传输错误不会导致 AIDL 终止运行(未经检查的错误会导致 HIDL Return 终止运行)。
  • AIDL 只能为每个文件声明一种类型。
  • 除了 output 参数外,AIDL 参数还可以指定为 in/out/inout(没有“同步回调”)。
  • AIDLfd 用作基元类型,而不是句柄。
  • HIDL 对不兼容的更改使用 Major 版本,对兼容的更改使用 Minor 版本。在 AIDL 中,向后兼容的更改已就位。 AIDL 没有对 Major 版本进行明确定义,而是将其并入软件包名称中。例如,AIDL 可能会使用软件包名称 bluetooth2

系统服务

系统服务是专注于特定功能的模块化组件,例如窗口管理器、搜索服务或通知管理器。应用框架 API 所提供的功能通过Binder可与系统服务通信,以访问底层硬件。Android 包含两组服务:“系统”(诸如窗口管理器和通知管理器之类的服务)和“媒体”(与播放和录制媒体相关的服务)。

硬件抽象层 (HAL)

HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现。借助 HAL,可以顺利实现相关功能,而不会影响或更改更高级别的系统。HAL实现会被封装成模块,并会由 Android 系统适时地加载。

HAL类型

Android 8.0中重新设计了 Android 操作系统框架(在一个名为“Treble”的项目中),以便让制造商能够以更低的成本更轻松、更快速地将设备更新到新版 Android 系统。在这种新架构中,HAL 接口定义语言(HIDL,发音为“hide-l”)指定了 HAL 和其用户之间的接口,让用户无需重新构建 HAL,就能替换 Android 框架。

利用新的供应商接口,HIDL 将供应商实现(由芯片制造商编写的设备专属底层软件)与 Android 操作系统框架分离开来。供应商或 SOC 制造商构建一次 HAL,并将其放置在设备的 /vendor 分区中;框架可以在自己的分区中通过无线下载 (OTA) 更新进行替换,而无需重新编译 HAL

搭载 Android 8.0 或更高版本的设备必须支持使用 HIDL 语言编写的 HAL,下面列出了一些例外情况。这些 HAL 可以是绑定式 HAL 也可以是直通式 HALAndroid 11 也支持使用 AIDL 编写的 HAL。所有 AIDL HAL 均为绑定式。

  • 绑定式HAL:以 HAL 接口定义语言 (HIDL) 或 Android 接口定义语言 (AIDL) 表示的 HAL。这些 HAL 取代了早期 Android 版本中使用的传统 HAL 和旧版 HAL。在绑定式 HAL 中,Android 框架和 HAL 之间通过 Binder 进程间通信 (IPC) 调用进行通信。所有在推出时即搭载了 Android 8.0 或后续版本的设备都必须只支持绑定式 HAL
  • 直通式 HAL:以 HIDL 封装的传统 HAL 或旧版 HAL。这些 HAL 封装了现有的 HAL,可在绑定模式和 Same-Process(直通)模式下使用。升级到 Android 8.0 的设备可以使用直通式 HAL

绑定式HAL

Android 要求所有 Android 设备(无论是搭载 Android O 的设备还是升级到 Android O 的设备)上的下列 HAL 均为绑定式:

  • android.hardware.biometrics.fingerprint@2.1:取代 Android 8.0 中已不存在的 fingerprintd
  • android.hardware.configstore@1.0:Android 8.0 中的新 HAL
  • android.hardware.dumpstate@1.0:HAL 提供的原始接口可能无法继续使用,并且已更改。因此,dumpstate_board 必须在指定的设备上重新实现(这是一个可选的 HAL)。
  • android.hardware.graphics.allocator@2.0: Android 8.0 中,此 HAL 必须为绑定式,因此无需在可信进程和不可信进程之间分享文件描述符。
  • android.hardware.usb@1.0Android 8.0 中的新 HAL
  • android.hardware.wifi@1.0:Android 8.0 中的新 HAL,可取代此前加载到 system_server 中的旧版 WLAN HAL 库。
  • android.hardware.wifi.supplicant@1.0:在现有 wpa_supplicant 进程之上的 HIDL 接口。

Android 提供的以下 HIDL 接口将一律在绑定模式下使用:android.frameworks.*android.system.*android.hidl.*(不包括 android.hidl.memory@1.0)。

直通式HAL

Android 要求所有 Android 设备(无论是搭载 Android O 的设备还是升级到 Android O 的设备)上的下列 HAL 均在直通模式下使用:

  • android.hardware.graphics.mapper@1.0:将内存映射到其所属的进程中。
  • android.hardware.renderscript@1.0:在同一进程中传递项(等同于 openGL)。

上方未列出的所有 HAL 在搭载 Android O 的设备上都必须为绑定式。

Same-Process HAL

Same-Process HAL (SP-HAL) 一律在使用它们的进程中打开,其中包括未以 HIDL 表示的所有 HAL,以及那些绑定式的 HALSP-HAL的成员只能由 Google 控制。

SP-HAL 包括以下 HAL

  • openGL
  • Vulkan
  • android.hidl.memory@1.0(由 Android 系统提供,一律为直通式)
  • android.hardware.graphics.mapper@1.0
  • android.hardware.renderscript@1.0

传统 HAL 和旧版 HAL

传统 HAL(在 Android 8.0 中已弃用)是指与具有特定名称及版本号的应用二进制接口 (ABI) 标准相符的头文件。大部分 Android 系统接口(相机、音频和传感器等)都采用传统 HAL 形式(在hardware/libhardware/include/hardware定义 ),如蓝牙

Linux 内核

开发设备驱动程序与开发典型的 Linux 设备驱动程序类似。Android 使用的 Linux 内核版本包含一些特殊的补充功能,例如低内存终止守护进程(一个内存管理系统,可更主动地保留内存)、唤醒锁定(一种 PowerManager 系统服务)、Binder IPC 驱动程序,以及对移动嵌入式平台来说非常重要的其他功能。这些补充功能主要用于增强系统功能,不会影响驱动程序开发。

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像

Title - Artist
0:00