文章目录
在早期 Android 设备上(4.x),主要包含以下分区:
- boot 分区
- system 分区
- data 分区
- cache 分区
- recovery 分区
- misc 分区
Android 设备分区大总结
boot 分区
boot 分区包含 Android 系统的 kernel 镜像,以及启动时使用的 ramdisk。
system 分区
Android 系统的主分区,包含 Android 系统以及内置(预装)的各种应用程序。
data 分区
用户数据分区,包含用户安装的应用和数据,包括自定义数据,后面分区名字改为 userdata。
cache 分区
顾名思义,cache 与缓冲相关,所以用来存放临时数据,例如在传统的 Non-A/B 系统中,在升级时,提前将升级包 update.zip 下载到 /cache 分区,重启后在 recovery 系统中打开 update.zip 用于升级。
recovery 系统
recovery 分区包含 Android 恢复(recovery)系统的 kernel 镜像,以及用于 recovery 功能的 ramdisk。
misc 分区
存放了 BCB 数据(Bootloader Control Block),用于 Android 主系统,Bootloader 和 Recovery 系统进行通信。
Bootloader 读取并解析 misc 分区的 BCB 数据来决定是启动 Android 系统还是 Recovery 系统。
Recovery 系统通过读取并解析 misc 分区的 BCB 数据来执行相应的 Recovery 操作。
在 Android 5.0 以后,又相继引入了 vendor, oem 和 product 等分区。引入这些分区的目的主要是为了存放厂商定制代码,以及硬件抽象层。
vendor 分区
vendor 分区包含所有无法分发给 AOSP 的二进制文件,主要是芯片厂家的各种驱动和固件。例如,当你下载 AOSP 开源代码进行学习时,QCom 等芯片厂家的代码不开源,所以直接从 Android 网站下载一个 vendor.img。
odm 分区
odm 分区主要就是存储各 Android 设备开发厂家自己的 BSP 驱动等各种代码,达到和 Android 系统自身(system),芯片厂家(vendor) 进行分离的目的。
所谓的 odm,全称就是原始设计制造商 (ODM, Original Design Manufacturer) 。
ODM 可以替换或自定义 SoC 组件,并在硬件抽象层 (HAL) 上为板级组件、守护程序和 ODM 特定的功能实现内核模块。
product 分区
我自己没有见过单独的 product 分区,据说此分区主要用于存放 Google 应用和系统应用。按照 Google 官方的解释,此分区可以使用允许的界面安装未与任何其他分区捆绑的特定于产品的模块。
关于 system, vendor, odm 和 product 分区,Android 官方是这么解释的:
Android 9 开始支持构建 product 分区,让您可为不同 product.img 映像提供的多个软件 SKU 使用同一个系统映像。product 分区适用于软件 SKU,而 odm 分区适用于硬件 SKU。
有了专用的 product 分区和 ODM 分区,您可以使用 system 分区来容纳通用代码(这类代码在许多软件 SKU 之间共享),并使用 vendor 分区来容纳 SoC 专属 BSP 代码(这类代码根据特定的 SoC 在多款设备之间共享)。
特别需要说明的是:product
分区不得与 vendor
或 odm
分区有直接交互。
radio 分区
radio 分区包含无线装置映像,我记得有些厂家用来存放基带的固件。
dtbo 分区
dtbo 分区存放设备树(device tree)相关数据。
随着 Android AVB 系统和数据加密的引入,陆续增加了 vbmeta 和 metadata 分区。
vbmeta 分区
vbmeta 分区存放 Android AVB 验证启动所需要的各种数据。
metadata 分区
metadata 分区用于在设备使用元数据加密时存储元数据加密密钥,大小为 16 MB 或更大,此分区本身没有加密。
后期此分区也用来存放一些 Android 动态分区的动态分区表 lp_metadata
,以及 Virtual A/B 系统的升级状态等数据。
super 分区
在 Android 10(Q) 开始,设备上新增了 super 分区。
super 分区是一个存在于 Android 设备全局分区表(例如 GPT 分区表)中的物理分区,里面包含了 system, vendor 等其他的逻辑分区。
在 Android 系统启动后,将 super 分区内部的 system, vendor 等映射为 Android 系统下可以看到的 system, vendor 等分区。
vendor_boot 分区
Android 11 引入了通用内核映像 (GKI) 的概念。为了能够使用 GKI 启动任意设备,Android 11 设备可以使用启动映像头文件版本 3。在版本 3 中,所有供应商专用信息都已从 boot 分区分离出来并转移到新的 vendor_boot 分区中。
简单来说,就是原来的 boot 分区镜像的 ramdisk 中关于芯片厂家(vendor)的部分,移动到单独的 vendor_boot 分区中。
关于 boot 中原来通用的 ramdisk 和 vendor 中的 ramdisk 该如何共存呢?
Android 官方的解释是这样的:
bootloader 必须将通用 ramdisk 紧跟在vendor ramdisk 之后加载到内存中(CPIO、Gzip 和 lz4 格式均支持这种串联)。请勿对齐通用 ramdisk 映像的页面,也不要在内存中通用 ramdisk 映像与 vendor ramdisk 末尾之间引入任何其他空间。内核解压缩后,它会将串联的文件提取到
initramfs
中,这样做所得到的文件结构是通用 ramdisk 叠加在供应商 ramdisk 之上的文件结构。由于通用 ramdisk 和供应商 ramdisk 已串联,它们必须具有相同的格式。GKI 启动映像使用经 lz4 压缩的通用 ramdisk,因此符合 GKI 要求的设备必须使用经 lz4 压缩的供应商 ramdisk。
vendor_dlkm 和 odm_dlkm 分区
第一次看到 dlkm 这个后缀简直惊了个呆~这是个什么鬼?
DLKM 是 Dynamically Loadable Kernel Module 的简称。
vendor_dlkm 分区专门用于存储供应商(vendor)内核模块。将 vendor 内核模块存储在 vendor_dlkm 分区(而不是 vendor
分区)中后,无需更新 vendor 分区即可更新内核模块。
odm_dlkm 区专门用于存储 ODM 内核模块。将 ODM 内核模块存储在 odm_dlkm 分区(而不是 odm 分区)中后,无需更新 odm 分区即可更新 ODM 内核模块。
init_boot 分区
Android 13 之前发布的设备中的 ramdisk 最开始存放在 boot 分区中,后来从 boot 分区分离后存放到 system 分区(system-as-root)。后来将通用的 ramdisk 和芯片厂家(vendor) 的 ramdisk 分开,芯片厂家(vendor)的 ramdisk 存放到 vendor_boot 中。
出厂时搭载 Android 13 系统的设备使用单独的 init_boot 分区用于存放通用的 ramdisk。
system_ext 分区
Android 11 开始,Android 提出了 SSI 镜像的概念,并引入了 /system_ext 分区作为可选分区。
/system_ext
分区是放置 /system
分区中与 AOSP 定义的组件紧密耦合的非 AOSP 组件的位置。)/system_ext
分区被视为是 /system
分区特用于 OEM 的扩展,且未在两个分区间定义接口。/system_ext
分区中的组件可以对 /system
分区进行私有 API 调用,反之,/system
分区中的组件也可以对 /system_ext
分区进行私有 API 调用。
所谓 SSI (Shared System Image),即 Android 设备 OEM 可利用这些机制构建自己的跨产品线共享系统映像 (SSI)。
理论上多个产品先可以使用同一个 system 镜像,但是不同产品自己差异化的部分放入 system_ext 分区中。
Android 官方是这样说的:
在 SSI 中,特定于产品的软件组件和 OEM 扩展会被放入新的
/product
分区中。/product
分区中的组件使用明确定义的稳定接口与/system
分区中的组件进行交互。OEM 可以选择构建一个 SSI,也可以选择将少量 SSI 用于多个设备 SKU。Android 操作系统的最新版本发布后,OEM 只需投入一次时间和精力将 SSI 更新至最新 Android 版本。然后即可重复使用 SSI 更新多款设备,而无需更新/product
分区。
我模糊记得在某家的产品中还存在 vendor_ext 分区,但具体细节已经不记得了。估计大概跟 system 和 system_ext 分区的关系差不多。但在 Android 官方并没有提到关于 vendor_ext 的描述。
tos 分区
tos 分区用于存储 Trusty 操作系统的二进制映像文件,仅在设备包含 Trusty 时使用。
Trusty 是 Google 的可信执行环境 (TEE) 操作系统实现,源码可以在 Android 中可以看到,与 Android 并行运行。
如果设备没有采用 Trusty 作为 TEE,则不会包含 tos 分区。
Android 为了解耦 AOSP 和芯片厂家(vendor),以及设备厂家(odm) 的关系,真是操碎了心。就一个分区隔离都看得我云里雾里,更不用还有跟分区变更紧密相关的 ramdisk 变更,不论是分区变更,还是 ramdisk 变更,都可以单独起一个单独的专题。不知道你晕了没有,反正我感觉很晕。
以上就是目前为止我了解到的 Android 的一些分区,如果有遗漏,欢迎通过留言或微信指出,后续我会更新完善。
其它
我有几个 Android OTA 升级讨论群,里面现在有小几百的朋友,主要讨论手机,车机,电视,机顶盒,平板等各种设备的 OTA 升级话题,如果您从事 OTA 升级工作,欢迎加群一起交流,请在加我微信时注明“Android OTA 交流”。此群仅限 Android OTA 开发者参与~
公众号“洛奇看世界”后台回复“wx”获取个人微信。