Super分区和动态分区
一. 背景:传统分区布局的问题
在深入动态分区之前,我们必须先了解它要解决什么问题
在传统的 Android 设备上,系统磁盘被划分为多个静态分区,每个都有固定的大小。例如:
- boot: 内核和初始 RAM 磁盘
- system: 操作系统本身 (Android 框架、系统应用)
- vendor: 硬件厂商提供的驱动和软件
- product, system_ext: OEM 或运营商定制软件
- cache: 临时缓存(现在用途已变)
- userdata: 用户数据
问题在于:
这些分区的大小在出厂时就已经固定,无法改变。这导致了两个主要痛点:
- OTA 更新困难: 如果一次系统更新需要更大的
system
分区空间,但当前设备的system
分区没有足够的剩余空间,更新就会失败。即使旁边的vendor
分区有大片空闲,也无法借给system
使用 - 资源浪费: 为了确保未来的更新有足够空间,OEM 厂商通常会为每个分区预留很大的余量。例如,
system
分区可能只用了 2GB,但却占用了 3GB 的空间,导致宝贵的存储空间被白白浪费
动态分区就是为了解决这种“分区墙”的问题而诞生的
二. Super 分区:一个“分区中的分区”
Super 分区是动态分区技术的核心和基础。你可以把它理解为一个容器或硬盘,而这个硬盘内部再被划分成多个“子分区”
- 它是什么? Super 分区是设备上一个预先分配好的、固定大小的物理分区(例如 4GB 或 8GB)。它取代了传统的
system
,vendor
,product
,system_ext
等独立分区 - 它的内容: Super 分区内部包含了一些逻辑分区,如
system
,vendor
,product
,system_ext
等。这些逻辑分区不再是独立的物理分区,而是存在于 Super 这个“大盒子”里 - 只读性: 在设备运行时,Super 分区通常以只读方式挂载,以防止其内容被意外修改
简单比喻:
把你的手机存储空间想象成一个书架
- 传统布局: 书架被分成很多固定大小的格子,每个格子贴好了标签(
system
,vendor
),一本书只能放在对应的格子里,不能越界 - Super 分区: 书架有一个很大的、没有隔断的“超级格子”(Super分区)。里面的书(
system
,vendor
等映像)可以自由摆放,只要总大小不超过这个超级格子的容量即可
三. 动态分区 (Dynamic Partitions):灵活的“子分区”管理
动态分区是指在 Super 分区这个容器内,动态地创建、调整和删除逻辑分区的技术和机制
它的工作原理如下:
- 动态调整: 在执行 OTA 更新时,系统不再受限于固定的分区大小。例如,新版本可能需要的
system
更大,但需要的vendor
更小。动态分区管理器就可以在 Super 分区内动态地重新分配空间,缩小vendor
的逻辑大小,扩大system
的逻辑大小,只要它们的总大小不超过 Super 分区的总容量即可 - 更新机制: Android 使用了虚拟 A/B (A/B Seamless) 更新或传统的 A/B 更新与动态分区紧密结合。更新过程大致为:
○ 系统不是在当前活动的分区上进行更新,而是在 Super 分区内的一组空闲空间或备用槽位(Slot) 中创建新的逻辑分区(system_a
->system_b
)
○ 新的系统映像被写入到这些新创建的逻辑分区中
○ 更新完成后,通过更新引导加载程序 (bootloader) 中的元数据,将启动槽位指向新的集合(例如从 slot A 切换到 slot B)
○ 下次启动时,设备就会从新的、已经更新好的逻辑分区组启动 - 关键组件:
○lpmake
: 用于在编译时将多个系统映像(system.img
,vendor.img
)打包成一个单独的super.img
的工具
○lpadmin
: 在设备上运行的用户空间工具,负责管理动态分区(创建、调整大小、删除)
○ 元数据: Super 分区的开头部分存储了一个元数据区域,记录了内部所有逻辑分区的布局、大小和名称等信息。bootloader 和系统在启动时会读取这些元数据来找到正确的分区
继续用书架的比喻:
- 动态分区: 意味着你可以随时拿走“超级格子”里的隔板,根据书的大小重新摆放和调整隔板的位置。只要所有书的总厚度不超过超级格子的深度,你就可以自由分配每本书占用的空间
四. 动态分区的主要优势
- 灵活的存储空间: 解决了传统分区布局的空间浪费问题。系统、厂商和应用分区的空间可以按需分配,最大化利用存储容量
- 更可靠的 OTA 更新: 极大地降低了因空间不足导致的 OTA 更新失败概率。更新过程不再需要处理复杂的跨分区空间调整
- 支持无缝更新 (A/B Seamless Updates): 与虚拟 A/B 更新完美配合,用户可以在系统更新的同时继续使用手机,更新在后台进行,重启即可生效,几乎无感知
- 简化分区管理: 对 OEM 厂商来说,他们不再需要为不同的设备型号精确计算每个分区的大小,只需确定一个总的 Super 分区大小即可
五. 如何查看设备上的动态分区?
你可以通过 Android 的 ADB shell 来检查你的设备是否使用了动态分区
adb shell
$ ls /dev/block/by-name/super
如果这个 super
符号链接存在,说明你的设备使用了 Super 分区
你还可以使用 lpdump
工具来查看 Super 分区的详细内部布局:
adb shell lpdump /dev/block/by-name/super
或者查看当前槽位的详细信息:
adb shell lpdump --slot 0 # 转储当前槽位的分区信息
输出会显示 Super 分区内所有逻辑分区的名称、大小、属性等信息
总结与对比
特性 | 传统静态分区 | 动态分区 (Super 分区) |
---|---|---|
分区布局 | 多个独立的物理分区 | 一个大的 Super 物理分区,内含多个逻辑子分区 |
分区大小 | 固定不变,出厂即确定 | 动态可调,可在 Super 总容量内按需分配 |
空间利用 | 效率低,每个分区需预留空间,导致浪费 | 效率高,空间池共享,按需使用 |
OTA 更新 | 容易因空间不足失败,更新机制复杂 | 更可靠,支持无缝更新,更新成功率大幅提升 |
管理复杂度 | 对OEM来说,需要为每个设备精确规划分区大小 | 对OEM来说更简单,只需设定一个总容量 |
兼容性 | 所有 Android 设备 | Android 10 及以上的设备要求使用(GKI 要求) |
核心关系:
Super 分区是“容器”,而动态分区是管理这个容器内空间的“机制”。我们通常将这两者结合在一起讨论,因为它们是一个不可分割的整体技术方案