1、动态分区介绍
动态分区是 Android 10.0 上新功能,是 Android 系统的用户空间分区系统,在软件 OTA 更新时允许增加、删除和重定义只读分区大小;此功能的优势在于厂商不再需要关心 system,vendor,product 等只读分区的大小。只需要定义一个 Super 分区和对应大小即可,而 Super 分区的子分区存储空间可以动态调整。这也意味着单个分区镜像不再需要为将来的 OTA 升级预留空间。相反,super 中的剩余空间可用于所有动态分区。
动态分区是基于 Linux kernel device-Mapper 实现的用户空间的分区结构,Super 分区包含元数据用于记录着每个动态分区的名称和在 Super 分区中的存储范围。在 Init 第一阶段执行期间会解析和校验 Super分区的元数据,并创建虚拟的块设备对应各个动态分区。
1.1 动态分区创建
Google release Android 10.0 的代码中包含了一整套工具用于创建和解析动态分区文件,如图 1-1 所示:
图 1-1 中各部分的说明如下:
-Images:各个动态分区编译出的镜像文件,同 Android 10.0 之前的版本分区镜像。
-Misc_info.txt:提供 Super Image 文件的基本参数,在编译时创建,用于记录动态分区大小、分组信息和组内成员。
-Build_super_image.py:提供四种编译 Super image 的方式:基于Dict、基于 Target、基于 Zip 文件、基于文件
-Lpmake:用于创建 Super image 文件。该文件不是镜像文件,仅仅是数据文件。其主要功能是将传入的参数按照 Metadata 的数据结构存储,并将 metadata 和动态分区镜像文件写入 Super image中。
-Lpdump:工具有两个编译目标,PC 和手机上。PC 上可以使用该工具读取 Super image 文件的metadata 数据并打印输出;手机上功能是一样的,在 shell 输入 Lpdump 即可打印出 Super image metadata 数据。可用于版本检查。
-Lpflash:用于更新 Super Image 中 metadata 数据,暂时还没有使用的场景。
-Lpunpack:用于解包 Super Image 文件,将其输出为动态分区的镜像文件,可用于 DEBUG 和检查文件是否破坏。需要注意的是 Super Image 只能使用 Lpunpack 解包,其实现也很简单,先读取metadata 数据,再根据 metadata 数据读出各个子分区镜像文件单独存储。
-Liblp:提供 metadata 数据结构定义,Super Image 文件读写接口。所有对 Super Image 文件的解析都需要 Liblp 支持,其也会编译出 Host 和 Device 两个安装目标。Liblp 是 Userspace 的动态库,这也就决定了动态分区只能在 Userspace 中解析和挂载。
1.2 gpt 调整
前面章节已经提到动态分区的功能允许厂商只定义一个 Super 分区和对应的大小,在 Super 中可以动态调整其子分区存储顺序和存储空间。哪些分区可以作为 Super 分区的子分区呢?前面介绍一个前提是只读分区,所以 userdata、cache 读写分区肯定不在范围内。其次动态分区是用户空间的分区系统,所以在 bootloader 阶段需要加载的分区也不在范围内,比如 boot、dtbo、vbmeta、recovery 等分区。
支持的分区有:
-System 分区
-Vendor 分区
-Product 分区
这些分区一旦作为 Super 子分区后,就不再是独立的物理分区,需要将其从 EMMC GPT 中删除,并将Super 分区和对应的大小信息存储到 GPT 中。 UNISOC 的 GPT 是通过 researchdownload 工具在下载过程中写入的,只需要调整 PAC 中分区配置文件即可。