Bootstrap

Android 分区相关介绍

目录

一、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镜像的时候会涉及到很多分区,这里统一介绍一下各个平台相关联的知识。

一、MTK平台

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就会删除此分区

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字段一致

3、MTK平台分区表配置不生效

在某些时候分区配置表与手机实际大小并不一致,或者分区表配置修改了后没有生效,如下两个FQA回答了可能的原因:FAQ11445   FAQ21282

4、Super分区的研究

Super分区也叫做dynamic动态分区,动态分区是Android的用户空间分区系统,在Android R版本开始引入,目的是为了解决system和vender等分区size不能动态调整的问题。例如物理分区表配置固定size后,如果软件版本对system,verdor分区size需要频繁调整时,需要修改物理分区表和重新编译gpt表,使用起来不是很便利。

我们可以通过命令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_a
  Group: main_a
  Attributes: readonly
  Extents:
    0 .. 253743 linear super 2048
------------------------
  Name: product_b
  Group: main_b
  Attributes: readonly
  Extents:
------------------------
  Name: system_a
  Group: main_a
  Attributes: readonly
  Extents:
    0 .. 1410975 linear super 256000
------------------------
  Name: system_b
  Group: main_b
  Attributes: readonly
  Extents:
    0 .. 15647 linear super 1667072
------------------------
  Name: system_ext_a
  Group: main_a
  Attributes: readonly
  Extents:
    0 .. 700503 linear super 1683456
------------------------
  Name: system_ext_b
  Group: main_b
  Attributes: readonly
  Extents:
------------------------
  Name: vendor_a
  Group: main_a
  Attributes: readonly
  Extents:
    0 .. 430351 linear super 2385920
------------------------
  Name: vendor_b
  Group: main_b
  Attributes: readonly
  Extents:
------------------------
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: super
  First sector: 2048
  Size: 2147483648 bytes
  Flags: none
------------------------
Group table:
------------------------
  Name: default
  Maximum size: 0 bytes
  Flags: none
------------------------
  Name: main_a
  Maximum size: 2145386496 bytes
  Flags: none
------------------------
  Name: main_b
  Maximum size: 2145386496 bytes
  Flags: none
------------------------

其中重点需要关注的内容如下:

1)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

2)Block device table

此部分记录了super分区的总大小,即2147483648 /1024  /1024 = 2048MB,此值应该和上面的super分区表的值对应,如果不对应,需要check第三节的内容,是否存在定制

  Partition name: super
  First sector: 2048
  Size: 2147483648 bytes
  Flags: none

二、高通平台

三、展锐平台

四、相关案例

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分区有客制化定义

经过此案例以及可疑点我们可以得出如下几个结论:

经验一:在MTK平台针对分区表配置不生效或者跟实际对不上的情况,需要搜索是否存在BOARD_MTK_XXX_SIZE_KB的客制化。
结论一:针对super分区应该只关心super分区总大小,其内部各个子分区大小不用根据实际情况来进行调整,例如product_a实际使用了1.7G,但是分区表配置的256MB并没有导致什么报错或者异常,system_a和system_b分区在分区表配置了3G,即这两部分加起来都超过super配置的4G了,但同样也没有存在什么报错或者异常。其原因为super分区内部根据各个实际大小来进行动态调整。
;