首页 安卓教程

动态分区是使用 Linux 内核中的 dm-linear device-mapper 模块实现的。super 分区包含列出了 super 中每个动态分区的名称和块范围的元数据。在第一阶段 init 期间,系统会解析并验证此元数据,并创建虚拟块设备来表示每个动态分区。[Android 开源项目 | 动态分区]

为什么建议改造

因为旧的机型空间分配不均匀,而且随着Android版本的迭代,增加的新特性越来越多,对系统空间占用也越来越高。所以改造动态分区就很有必要了。

改造示意图 [来自Google]

改造

从图中可以看到,我们的system,product,system_ext,vendor和odm已经合并为一个大分区,名为super。
改造的动态分区优点有很多,首先我们不用改动分区表,这个对于个人维护者也很方便,改造失败也容易救回。

改造前的准备

  • AOSP源码要求为Android10+,这里使用Android 13的源码
  • 必须要改为first stage mount, 而不是内核dtbo fstab来完成第一阶段启动
  • 不得使用SAR(System as root)

开始改造

device.mk部分

添加以下flag:

PRODUCT_USE_DYNAMIC_PARTITIONS := true
PRODUCT_RETROFIT_DYNAMIC_PARTITIONS := true

这些操作用于启用动态分区,第二个flag为改造动态分区,都需要进行启用。

然后我们需要构建fastbootd以刷入这些逻辑分区

PRODUCT_PACKAGES += \
    fastbootd

fstab

移除厂商原来的system和vendor挂载点,例如

/dev/block/bootdevice/by-name/system         /system                 ext4    ro,barrier=1                                                                                      wait,first_stage_mount
/dev/block/bootdevice/by-name/vendor         /vendor                 ext4    ro,barrier=1                                                                                      wait,first_stage_mount

改造为

system                                       /system                 ext4    ro,barrier=1                                                                                      wait,avb=vbmeta,logical,first_stage_mount
system_ext                                   /system_ext             ext4    ro,barrier=1                                                                                      wait,avb,logical,first_stage_mount
vendor                                       /vendor                 ext4    ro,barrier=1                                                                                      wait,avb,logical,first_stage_mount
product                                      /product                ext4    ro,barrier=1                                                                                      wait,avb,logical,first_stage_mount

这时候细心的小可爱发现了,我在原来system和vendor基础上添加了product和system_ext,因为目前情况下我们已经把system和vendor的所有空间改装成了一个super分区,所以现在的system,vendor,product,system_ext都为逻辑分区。
做个比方,super相当于一块硬盘,我们从super切出一块一块分区。

BoardConfig(板级配置)修改

这里我们需要添加以下flag:

BOARD_SUPER_PARTITION_SIZE # 改造super分区大小,如果你的设备有system和vendor,那么super分区大小为总和,如果是AB分区,则为所有AB分区总和/2
BOARD_SUPER_PARTITION_GROUPS # Super分区组,命名打个比方如果机型为oneplus,可以设置为op_dynamic_partitions,接下来的就以op_dynamic_partitions来介绍
BOARD_SUPER_PARTITION_METADATA_DEVICE # metadata设备,设置为system
BOARD_SUPER_PARTITION_BLOCK_DEVICES # Super分区要利用的挂载点,如果你的设备有system和vendor,那么设置为system vendor(中间空格隔开或者\换行)
BOARD_SUPER_PARTITION_SYSTEM_DEVICE_SIZE # System分区大小
BOARD_SUPER_PARTITION_VENDOR_DEVICE_SIZE # Vendor分区大小
BOARD_OP_DYNAMIC_PARTITIONS_PARTITION_LIST # 逻辑分区组我们设置为system system_ext product vendor(中间空格隔开或者\换行),依照fstab添加分区来更改
BOARD_OP_DYNAMIC_PARTITIONS_SIZE # Super盘大小,这里数值建议(BOARD_SUPER_PARTITION_SIZE - 4MB),以免出现奇怪问题

# 以下为设置分区格式(ext4/erofs[内核需支持])
BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE    := ext4
BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE := ext4
BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE     := ext4

# 设置输出位置(无需解释)
TARGET_COPY_OUT_PRODUCT    := product
TARGET_COPY_OUT_SYSTEM_EXT := system_ext
TARGET_COPY_OUT_VENDOR := vendor

SELinux政策

改造动态分区存储设备必须使用 super_block_device_type 属性进行标记。例如,如果设备已经有 system 和 vendor 分区,并且您希望将它们用作块存储设备来存储改造动态分区的 extent,并且其按名称符号链接标记为 system_block_device:

/dev/block/platform/soc/10000\.ufshc/by-name/system   u:object_r:system_block_device:s0
/dev/block/platform/soc/10000\.ufshc/by-name/vendor   u:object_r:system_block_device:s0

然后,将以下行添加到 device.te:

typeattribute system_block_device super_block_device_type;

第一次刷入改造动态分区

首先我们需要刷入改造动态分区后构建的recovery并且进入
然后选择Enter fastboot,进入fastbootd模式
然后刷入super_empty.img开始使用动态分区

fastboot wipe-super super_empty.img

注意:如果fastboot提示没有找到命令,则需要升级最新版本fastboot,若有提示权限问题,请忽略。若提示报错,请检查BOARD_SUPER_PARTITION_BLOCK_DEVICES标志第一分区是否为BOARD_SUPER_PARTITION_METADATA_DEVICE指定的分区。

然后选择enter recovery,进行正常刷机步骤即可体验动态分区



文章评论

目录