动态分区(Dynamic Partitions)是 Android 10 引入的分区管理机制,旨在解决传统固定分区(如 system
、vendor
)在系统更新时面临的 空间浪费 和 灵活性不足 的问题。它的核心思想是:将多个物理分区合并为一个“超级分区”(super partition),并在其中动态分配逻辑分区的空间。
动态分区的核心概念
1. 传统分区的局限性
在 Android 9 及更早版本中,每个分区(如 system
、vendor
、product
)是独立的,大小固定。这会导致:
- 空间浪费:例如
system
分区必须按最大可能需求分配,即使实际使用量很小。 - 更新困难:如果 OTA 更新需要调整分区大小,必须重新分区(可能导致数据丢失)。
2. 动态分区的解决方案
动态分区通过以下方式改进:
- 超级分区(Super Partition):将所有动态分区(如
system
、vendor
)合并到一个大的super
分区中。 - 逻辑分区动态分配:在
super
分区内,各逻辑分区(如system
、vendor
)的大小可以 按需调整。 - 支持无缝更新(A/B):通过元数据槽(
metadata slots
)实现回滚。
动态分区的实现原理
1. 分区布局
super
分区:一个物理分区(如/dev/block/by-name/super
),存储所有动态分区。- 逻辑分区:在
super
分区内划分的逻辑单元(如system
、vendor
、product
)。 - 元数据(Metadata):记录分区布局、大小和属性(存储在
super
分区的头部)。
2. 关键组件
组件 | 作用 |
---|---|
lpmake | 打包多个镜像(system.img 、vendor.img )成 super.img 。 |
lpdump | 查看 super 分区的布局信息。 |
dm-linear (内核驱动) | 将 super 分区的逻辑块映射到动态分区。 |
init 和 fs_mgr | 在启动时加载动态分区。 |
3. 工作流程
(1)构建阶段
- 使用
mkuserimg_mke2fs
生成各分区镜像(如system.img
)。 - 用
lpmake
将所有镜像打包成super.img
:lpmake --device-size=5G \ --group=main:4G \ --partition=system:2G:main:readonly \ --partition=vendor:1G:main:readonly \ --image=system=system.img \ --image=vendor=vendor.img \ --output=super.img
main
是分区组,剩余空间(4G - 2G - 1G = 1G
)可用于未来扩展。
(2)刷机阶段
- 通过
fastboot
刷入super.img
:fastboot flash super super.img
(3)启动阶段
- 内核 读取
super
分区的元数据。 dm-linear
驱动 将逻辑分区映射到虚拟块设备(如/dev/block/mapper/system
)。init
挂载 这些设备到/system
、/vendor
等目录。
动态分区的优势
特性 | 传统分区 | 动态分区 |
---|---|---|
分区大小 | 固定 | 动态调整 |
空间利用率 | 可能浪费 | 按需分配 |
OTA 更新 | 需严格匹配分区大小 | 可动态扩展 |
A/B 更新 | 需要双倍分区 | 通过元数据槽支持 |
实际应用场景
- OTA 更新:
- 如果新版本
system
需要更多空间,可以直接从super
分区未分配区域扩展,无需重新分区。
- 如果新版本
- 厂商自定义:
- 设备厂商可以灵活调整
odm
、system_ext
等分区大小。
- 设备厂商可以灵活调整
- GKI(通用内核镜像):
- 动态分区是 GKI 的配套功能,确保内核与分区解耦。
动态分区的限制
- 只读分区:
system
、vendor
必须为只读(readonly
),否则无法通过 Android 验证(AVB)。
- 兼容性:
- 仅支持 Android 10+ 设备,旧设备需保留传统分区。
- 调试复杂性:
- 需使用
lpdump
或adb shell ls /dev/block/mapper
查看动态分区状态。
- 需使用
如何检查动态分区
1. 查看 super
分区布局
adb shell lpdump
输出示例:
Partition table:
Name: system
Group: main
Size: 2 GiB
Attributes: readonly
...
2. 查看映射的设备节点
adb shell ls /dev/block/mapper
输出示例:
system
vendor
product
总结
动态分区是 Android 10 引入的现代化分区管理方案,通过 超级分区 + 逻辑动态分配 解决了传统分区的空间浪费和更新难题。它的实现依赖于:
super
分区 作为物理容器。lpmake
工具 打包镜像。- 内核驱动
dm-linear
提供动态映射。
对于 Android ROM 开发者和设备厂商,动态分区提供了更大的灵活性,但同时也需要适配新的工具链和调试方法。
结束语
Flutter是一个由Google开发的开源UI工具包,它可以让您在不同平台上创建高质量、美观的应用程序,而无需编写大量平台特定的代码。我将学习和深入研究Flutter的方方面面。从基础知识到高级技巧,从UI设计到性能优化,欢饮关注一起讨论学习,共同进入Flutter的精彩世界!