Android 系统架构

最后更新: 2022-01-06 03:13:05 +0800 +0800
原文以英文撰写。您正在阅读AI翻译版本。

Android 使用 Linux 内核实现调度、进程隔离、设备驱动、网络和文件系统,但提供自己的原生库、运行时、框架和应用模型。Bionic 是 Android 的 C 库。ART 执行 DEX 字节码,而 Binder 提供主要的跨进程 RPC 机制。

运行时和进程创建 #

构建工具将 Java 或 Kotlin 源代码编译为类文件,然后将其转换为 DEX 代码。APK 或应用包交付拆分会对 DEX、资源、原生库、签名元数据和清单进行打包。ART 会根据设备和配置文件状态,适当地编译或解释 DEX;APK 并不只是一个可执行 JAR。

init 是 Android 的 PID 1 进程。它挂载早期文件系统、应用策略、启动原生服务并启动 Zygote。Zygote 预加载常用的运行时类和资源,然后根据系统请求 fork 应用进程。fork 模型会在任一进程写入页面之前共享这些页面,从而降低应用启动成本。

应用隔离和 Binder #

安装软件包时通常会分配一个独立的 Linux UID。文件所有权和内核凭据隔离应用私有文件,而 SELinux 会对进程、文件、服务和 Binder 调用应用强制访问控制策略。除内核控制之外,框架和服务边界也会检查权限。

在另一个软件包中启动的应用组件会在目标软件包的进程中运行。Binder 会将事务传递到该进程,并携带调用方身份以进行权限检查。Binder 对象引用是具备生命周期和权限语义的能力;导出的组件或服务必须验证所有由调用方控制的参数。

系统分区和更新 #

现代设备会将操作系统映像划分为逻辑分区,这些分区通常为只读:

MountPurpose
/system核心框架、运行时和平台应用
/system_ext具有平台特定生命周期的系统扩展
/product产品和 OEM 定制
/vendor硬件供应商库、HAL 和配置
/odm设备特定的供应商覆盖层和配置
/vendor_dlkm, /system_dlkm可动态加载的内核模块
/data按设备和用户划分的可写应用数据
/metadata加密和启动服务所需的元数据

动态分区会将逻辑分区置于物理 super 分区中。dm-5 等 Device-mapper 名称表示这些逻辑块设备。报告容量接近满载的只读映像通常是不变的文件系统映像,并不表示用户数据存储空间已耗尽。

Verified Boot 为启动过程和已验证分区建立信任链。A/B 更新会写入非活动槽位,并在验证后选择该槽位;如果新槽位无法启动,则可以回滚。

APEX 和原生接口 #

APEX 软件包交付选定的底层平台模块,包括 ART 和 Conscrypt。Android 会在启动早期验证并将 APEX 映像挂载到 /apex 下;稳定路径会公开活动版本。供应商接口和硬件抽象层按照特定 Android 版本的兼容性规则,将框架版本与供应商实现分离。

可写存储和挂载命名空间 #

/data 是主要的可写分区。基于文件的加密会区分设备加密存储和凭据加密存储:前者在用户解锁前即可使用,后者在用户解锁后可用。每个用户的路径包括 /data/user/0 和 /data/user_de/0。

模拟共享存储通过 /storage/emulated/0 等路径公开,并由 /data/media 下的私有存储提供支持。FUSE 和挂载命名空间为每个应用和用户提供适当的视图,并强制执行分区存储访问规则。/storage/self/primary 会解析为进程的主共享存储视图;代码应使用平台存储 API,而不是硬编码实现路径。

proc、sysfs、binderfs、selinuxfs、cgroupfs 和 tracefs 等伪文件系统公开的是内核接口,而不是持久文件。mount 列表与设备、版本和进程命名空间相关,因此应视为诊断证据,而不是可移植的文件系统契约。

评论

在 GitHub 上阅读或评论(发表评论需要登录)