本文主要介绍
Android 10.0的OTA升级功能开发和验证办法。
1、Android 10.0新功能DP介绍
1.1 DP 简介
由于 Android 9.0 及以前系统上 system、vendor、
product 等分区预留大小为固定值,而分区大小会随着系统文件增减进行增大或者缩小调整。因此,需要在出厂时预留足够的空间,预留空间不足会造成 OTA 级失败。为解决该问题,Android 10.0 增加 DP(Dynamic Partition,动态分区调整)功能,其核心是将system、vendor、product、other 等包含只读文件系统的系统镜像放置在一个物理分区中,预留一定空间,根据各镜像间彼此消长动态调整其占用的大小,无需单独更改某物理分区。
动态分区主要特点:
●只需定义一个 Super 分区和对应大小,Super 分区的子分区存储空间可以动态调整。
●单个分区镜像不再需要为将来的 OTA 升级预留空间。
●Super 中的剩余空间可用于所有动态分区。
●OTA 更新时允许增加、删除和重定义只读分区大小。
●基于
linux kernel device-M
APPer 实现
用户空间的分区结构。
●Super 分区的
METAdata 记录各动态分区的名称和各自存储范围。
●Init 第一阶段解析和校验 Super 的 metadata,创建虚拟的块设备对应各个动态分区。
1.2 DP 适配升级
1.2.1 关键软件开关
在使能 DP 功能后,对应的软件开关会被打开,执行
MAKE otapackage 时会将其信息收集至 target 包中的META/misc_info.txt 文件中,以用作打包时获取 DP 各信息之用,制作 OTA 包时用到 DP 相关信息包括:
●use_dynamic_partitions=true开启 DP 功能。
●super_metadata_device=super将只读镜像的 metadata 放置分区定为 super。
●super_block_devices=super将只读镜像放置的分区取为 super。
●super_super_device_size=4299161600super 分区大小。
●dynamic_partition_list= system vendor product进行动态调整的只读镜像序列。
●super_partition_groups=group_un
ISOc进行 super 分区内镜像组名定义。
●super_group_uni
SOC_group_size=4299161600先前定义的镜像组的大小。
●super_group_
UNISOC_partition_list=system vendor product镜像组包含的镜像序列。
1.2.2 对 DP 分区升级处理
1.2.2.1 DP 镜像处理
在打包过程中,专门引入新的类“DynamicPartitionsDifference”来处理动态分区里面各镜像组以及镜像组内镜像的伸缩等。
其最终要生成一个文件“dynamic_partitions_op_list”,此文件在升级包中升级脚本被调用,并由升级程序使 用“update_dynamic_partitions()”函数来解释执行。“dynamic_partitions_op_list”文件中包含所有对 super 动态分区中的各镜像组等增减、伸缩,以及镜像组中各镜像的增减、伸缩动作。
1.2.2.2 产生 op_list 步骤
步骤 1 添加“删除所有镜像组动作 re
MOVe_all_groups”。如果是
差分包前后 group 无变化,则无此动作。
步骤 2 比较新旧版本的镜像组(super_partition_groups)是否有增减、伸缩,并产生相应增减动作:
"add_group","resize_group","remove_group",具体比较规则是:
− 源版本有某 group 而目标版本没有某 group,则添加" remove_group(group_name)"动作。
− 源版本没有某 group 而目标版本有某 group,则添加"add_group(group_name)"动作。
− 源版本和目标版本都有某 group,且其变小,则使用“resize_group(group_name)”缩小(shrink)该group。
− 原版本和目标版本都有某 group,且其变大,则使用“resize_group(group_name)”扩大(grow)该group。
步骤 3 对某镜像组,检查其子镜像的增减伸缩变化,产生镜像对应的操作动作:"add"、 "move"、 "remove"、 "resize",具体比较产生规则:
− 源版本无某子镜像,而目标版本有,则添加"add(sub-partition_name)"动作。
− 源版本有某子镜像,而目标版本无,则添加"remove(sub-partition_name)"动作。
− 源版本和目标版本都有某子镜像,且变小,则使用"resize(sub-partition_name)"来缩小(shrink)其大小。
− 源版本和目标版本都有某子镜像,且变大,则使用"resize(sub-partition_name)"来缩小(grow)其大小。
− 源版本和目标版本都有某子镜像,但分属不同的镜像组,则使用"move(sub-partition_name,group_name)"来将其移动至目标 group。
步骤 4 产生各镜像的升级动作。
其差异计算仍旧采取块升级比较算法,镜像的块升级动作包含在“sub-partition_name.transfer.list”文件中,新增数据放在“sub-partition_name. new.dat”中,patch 数据放在“sub-partition_name. patch.dat”中。
而具体操作的设备则变为由先前的"add"、 "move"、"remove"子镜像操作产生的虚拟块设备,获取该设备名称由“map_partition("sub-partition_name")”, 最终产生的子镜像升级动作为: block_image_update(map_partition("sub-partition_name"), package_extract_file("sub-partition_name.transfer.list"), "sub- partition_name.new.dat", "sub-partition_name.patch.dat")
----结束
1.2.2.3 具体升级动作简介
对镜像组和子镜像相关的操作如下,其主要是使用 MetadataBuilder 类(来自 liblp)对 metadata 进行计算重组,使用 DeviceMapper 类(来自 libdm)对虚拟块设备进行计算重组。
{"resize", PerformOpResize},
{"remove", PerformOpRemove},
{"add", Perform
OPAdd},
{"move", PerformOpMove},
{"add_group", PerformOpAddGroup},
{"resize_group", PerformOpResizeGroup},
{"remove_group", PerformOpRemoveGroup},
{"remove_all_groups", PerformOpRemoveAllGroups},
而获取设备节点的“map_partition("sub-partition_name")”动作则调用 DeviceMapper 类通过 subpartition_name 获取设备节点。
1.3 非 DP 只读系统分区升级
对于没有放入 super 分区的非 DP、带有文件系统(ext4)的系统分区来说,基线有 socko 和 odmko 两分 区,其延续 Android 9.0 时的升级方法。同样,镜像的块升级动作包含在“sub-partition_name.transfer.list”文件中,新增数据放在“sub-partition_name. new.dat”中,patch 数据放在“sub-partition_name. patch.dat”中。只是操作的设备节点是根据其固有设备节点写定的,最终升级动作为:
block_image_update("/dev/block/platform/soc/soc:ap-apb/71400000.
SDIO/by- name/partition_name", package_extract_file("partition_name.transfer.list"), "partition_name.new.dat", "partition_name.patch.dat")
2、升级分区说明
目前基线中,所有分区及其作用的简略说明、在 OTA 升级时是否进行升级,请参见下文(分别以
SC9863A 和 UDS710_UDX710 为例,主要区别在于
Modem_bins 的升级)。
2.1 SC9863A
EMMC物理分区 | 分区Name | 大小 | 作用 | OTA时是否进行升级 |
BOOTArea 1 | spl | 128K | 引导Uboot | 是 |
BOOTArea2 | spl_bak | 128K | spl备份分区 | 是 |
RPMB | Replay Protected memory Block | 128K | 存放重要安全域数据 | 否 |
User Data Area | prodnv | 10M | 存放数种校准数据 | 否 |
User Data Area | miscdata | 1M | 存放重要系统数据 | 否 |
User Data Area | recovery | 40M | recovery 分区 | 是 |
User Data Area | misc | 1M | 主系统跟recovery模式命令传递分区 | 否 |
User Data Area | trustos | 6M | tee-tos | 是 |
User Data Area | trustos_bak | 6M | tee-tos备份分区 | 是 |
User Data Area | sml | 1M | tee-sml | 是 |
User Data Area | sml_bak | 1M | tee-sml备份分区 | 是 |
User Data Area | uboot | 1M | uboot分区 | 是 |
User Data Area | uboot_bak | 1M | uboot备份分区 | 是 |
User Data Area | uboot_log | 4M | uboot运行log存储分区 | 否 |
2.2 UDS710_UDX710
emmc物理分区 | 分区Name | 大小 | 作用 | OTA时是否进行升级 |
User Data Area | prodnv | 10M | 存放数种校准数据 | 否 |
User Data Area | miscdata | IM | 存放重要系统数据 | 否 |
User Data Area | recovery | 40M | recovery 分区 | 是 |
User Data Area | misc | IM | 主系统跟recovery模式命令传递分区 | 否 |
User Data Area | nr_fixnvl | 8M | modem nv | 是 |
User Data Area | nr_fixnv2 | 8M | modem nv 备份 | 是 |
User Data Area | nr_runtimenvl | 10M | 运行中nv | 否 |
User Data Area | nr_runtimenv2 | 10M | 运行中nv | 否 |
User Data Area | trustos | 6M | tee-tos | 是 |
User Data Area | trustos_bak | 6M | tee-tos备份分区 | 是 |
User Data Area | sml | IM | tee-sml | 是 |
User Data Area | sml_bak | IM | tee-sml备份分区 | 是 |
User Data Area | uboot | IM | uboot分区 | 是 |
User Data Area | uboot_bak | IM | uboot备份分区 | 是 |
User Data Area | uboot_log | 4M | uboot运行log存储分区 | 否 |
User Data Area | logo | 8M | 正常模式logo | 否 |
User Data Area | fbootlogo | 8M | FASTBOOT 模式 logo | 否 |
User Data Area | l_pmsys | IM | pmsys | 是 |
User Data Area | l_agDSP | 6M | modem-LTE gdsp | 是 |
更多详细内容请下载附件查看