目录
一、MTK平台
1、MTK平台分区表配置
2、MTK平台刷机配置表
3、MTK平台分区表配置不生效
4、Super分区的研究
1)Super partition layout
2)Block device table
二、高通平台
三、展锐平台
四、相关案例
1、Super分区不够导致编译报错
经验一:在MTK平台针对分区表配置不生效或者跟实际对不上的情况,需要搜索是否存在BOARD_MTK_XXX_SIZE_KB的客制化。
结论一:针对super分区应该只关心super分区总大小,其内部各个子分区大小不用根据实际情况来进行调整,例如product_a实际使用了1.7G,但是分区表配置的256MB并没有导致什么报错或者异常,system_a和system_b分区在分区表配置了3G,即这两部分加起来都超过super配置的4G了,但同样也没有存在什么报错或者异常。其原因为super分区内部根据各个实际大小来进行动态调整。
在刷Android镜像的时候会涉及到很多分区,这里统一介绍一下各个平台相关联的知识。
1 MTK平台
1.1 MTK平台分区表配置
MTK官方文档专门针对分区表进行介绍:FAQ28492
Legacy单分区的分区配置路径:
alps/vendor/mediatek/proprietary/tools/ptgen/MTxxxx/partition_table_emmc.csv
AB 版本双分区的分区配置路径:
alps/vendor/mediatek/proprietary/tools/ptgen/MTxxxx/partition_table_emmc_ab.csv
其中几个重要解释如下:
- Type:RAW data 或 EXT4,这种定义其实只有在 正在运行挂载时才会被用到,但对OTA 升级的同仁,就要注意,因为某些判断脚本中会根据这个type 类型决定加入镜像
- Size_KB:分区大小单位kb,这个定义了 eng 和 user 版本在storage中占用的空间。但目前user 和eng 版本没有区分,所以只需要设定一个即可
- Region:分区所在的区域,如:EMMC_BOOT1_BOOT2,UFS_LU0_LU1 就表明在 EMMC 和 UFS 的 boot区域;而在 EMMC_USER 或 UFS_LU2,就表明 在EMMC 和 UFS 的user区域,也就是可供客制化的区域
- Group:可以填写动态分区的名称,默认只有main 函数。感觉没有什么用
- Reserved:用的不多,后续补充~应该是预留的空间,一般分区都是 N
- Download:是否下载标记,这个比较重要,关联刷机包的配置
- Download File:下载的镜像,这个也比较重要,我们可以很直观了解到对应哪个IMG文件
- OTA Update:分区是否支持升级
- EmptyBoot_Needed:在pl 阶段可以起来的分区,如 gz、tee、logo几个分区
- FastBoot_Erase:fastboot是否可以擦除,像super、userdata通常配置为yes,即可以通过恢复出厂设置擦除?
- FastBoot_Download:fastboot是否可以下载
- Operation_Type:操作类型。AUTO就会根据对齐进行调整大小;BOOTLOADERS表示设备启动镜像(例如preloader分区);INVISIBLE不可见不用刷机只定义范围;PROTECTED/BINREGION/RESERVED表示需要保留的分区,固件升级Fireware upgrade会备份数据,只有格式化刷机才会擦除
- Addr_Align:对齐方式,为写保护
- Delete_Rule:是否需要这个分区,通过判断条件来确定是否需要这个分区。例如le(PRODUCT_SHIPPING_API_LEVEL,30)表示PRODUCT_SHIPPING_API_LEVEL小于30就会删除此分区
1.2 MTK平台刷机配置表
MTK平台的刷机工具Flash Tool工具加载MTXXXX_Android_scatter.txt文件,改工具根据txt文件里面定义的标准格式解析如下信息:分区名称,起始地址和结束地址,镜像的路径来进行刷机。scatter.txt文件的内容者根据第一节分区表配置而来。
其原理就是build ptgen阶段会解析默认分区表文件partition_table_MT65XX.xls并生成相关的partition .c/.h文件和flash download使用的scatter file。他的格式如下:
如上Flash Tools工具显示的需要下载的分区和镜像文件也和分区表中配置的Download与Download File字段一致
1.3 MTK平台分区表配置不生效
在某些时候分区配置表与手机实际大小并不一致,或者分区表配置修改了后没有生效,如下两个FQA回答了可能的原因:FAQ11445 FAQ21282
1.4 Super分区的研究
Super分区也叫做dynamic动态分区,动态分区是Android的用户空间分区系统,在Android R版本开始引入,目的是为了解决system和vender等分区size不能动态调整的问题。例如物理分区表配置固定size后,如果软件版本对system,verdor分区size需要频繁调整时,需要修改物理分区表和重新编译gpt表,使用起来不是很便利。
1.4.1 adb shell lpdump
我们可以通过命令adb shell lpdump来输出打印super分区的具体内容:
$ lpdump
Slot 0:
Metadata version: 10.2
Metadata size: 1000 bytes
Metadata max size: 65536 bytes
Metadata slot count: 3
Header flags: virtual_ab_device
Partition table:
------------------------Name: product_aGroup: main_aAttributes: readonlyExtents:0 .. 253743 linear super 2048
------------------------Name: product_bGroup: main_bAttributes: readonlyExtents:
------------------------Name: system_aGroup: main_aAttributes: readonlyExtents:0 .. 1410975 linear super 256000
------------------------Name: system_bGroup: main_bAttributes: readonlyExtents:0 .. 15647 linear super 1667072
------------------------Name: system_ext_aGroup: main_aAttributes: readonlyExtents:0 .. 700503 linear super 1683456
------------------------Name: system_ext_bGroup: main_bAttributes: readonlyExtents:
------------------------Name: vendor_aGroup: main_aAttributes: readonlyExtents:0 .. 430351 linear super 2385920
------------------------Name: vendor_bGroup: main_bAttributes: readonlyExtents:
------------------------
Super partition layout:
------------------------
super: 2048 .. 255792: product_a (253744 sectors)
super: 256000 .. 1666976: system_a (1410976 sectors)
super: 1667072 .. 1682720: system_b (15648 sectors)
super: 1683456 .. 2383960: system_ext_a (700504 sectors)
super: 2385920 .. 2816272: vendor_a (430352 sectors)
------------------------
Block device table:
------------------------Partition name: superFirst sector: 2048Size: 2147483648 bytesFlags: none
------------------------
Group table:
------------------------Name: defaultMaximum size: 0 bytesFlags: none
------------------------Name: main_aMaximum size: 2145386496 bytesFlags: none
------------------------Name: main_bMaximum size: 2145386496 bytesFlags: none
------------------------
其中重点需要关注的内容如下:
1.4.2 Super partition layout
此部分记录了super分区从第一个扇区到最后一个扇区的内容
super: 2048 .. 255792: product_a (253744 sectors)
---->super的第2048扇区到255792扇区是product_a,总共占用了253744个扇区
super: 256000 .. 1666976: system_a (1410976 sectors)---->super的第256000扇区到1666976扇区是system_a,总共占用了1410976个扇区
super: 1667072 .. 1682720: system_b (15648 sectors)---->super的第1667072扇区到1682720扇区是system_b,总共占用了15648个扇区
super: 1683456 .. 2383960: system_ext_a (700504 sectors)---->super的第1683456 扇区到2383960扇区是system_ext,总共占用了700504个扇区
super: 2385920 .. 2816272: vendor_a (430352 sectors)---->super的第2385920扇区到2816272扇区是vendor_a,总共占用了430352个扇区
注意:单位为扇区,因此需要转换为MB,公式为sectors * 512 /1024/1024
即这段内容表明super分区按照顺序包含如下几个分区:product_a占用124MB,system_a占用689MB,system_b占用8MB,system_ext_a占用342MB,vendor_a占用210MB
1.4.3 Block device table
此部分记录了super分区的总大小,即2147483648 /1024 /1024 = 2048MB,此值应该和上面的super分区表的值对应,如果不对应,需要check第三节的内容,是否存在定制
Partition name: super
First sector: 2048
Size: 2147483648 bytes
Flags: none
2 高通平台
3 展锐平台
4 相关案例
4.1 Super分区不够导致编译报错
问题背景:此项目需要集成google mainline和google gms包,集成之后导致super分区不够编译失败,报错日志如下:
问题分析:根据如上日志进行解读,在编译super的时候,produc_a先申请了1795MB,system_a申请了749MB,system_b申请了54MB,system_ext_a需要428MB,最后vendor_a需要申请226MB,但因为空间不够无法申请。
前后对比:因为上面日志是加了google mainline gms包之后的,加之前这块的编译日志如下,即product_a从129MB飙升到1795MB,挤压super空间,导致最后的vendor_a分区没有足够的大小。
解决思路:从日志已经很明确是super分区不够,从日志中显示super分区为3244949504b即大约3094MB,从前面的produc_a+system_a+system_b+system_ext_a+vendor_a = 3252MB即,刚好差200多M。查看分区表配置信息如下:
通过adb shell lpdump之前的机器,super各个分区的大小和这个编译日志能够匹配的上,super大小和编译日志里面记录的'super:3244949504'一致,和分区表配置的4G完全不一样,最后通过MTK的FQA,找到BoardConfig.mk中对super分区有客制化定义:
经过此案例以及可疑点我们可以得出如下几个结论: