Android创建新的自定义系统分区实现OTA内容修改
Android 从 Android 10(Q) 开始正式引入 动态分区(Dynamic Partitions) 机制,来解决传统分区大小固定、OTA升级时无法灵活调整分区大小的问题。引入一个名为 super
的物理分区,内部可以动态分配逻辑分区(如 system
、vendor
、product
等)系统不再直接通过 fastboot flash system system.img
等方式刷写逻辑分区,而是通过 super.img
或 fastbootd
进行管理。
这样一来,就无法方便的对ota升级包进行随意修改编辑,比如新增或替换某些文件。如果系统能有一个分区专门用来存放需要变更的数据而又不会被OTA升级覆盖的话,我们就可以在升级完成后进行一次拷贝覆盖就可以了。
解决方案是有了,关键是系统原生各个数据分区在升级时会覆盖原有数据,而且有权限限制。所以我们需要新增一个自定义的数据分区专门来存放要修改的数据避免被升级覆盖。下面给出基于RK3568 Android12,参考系统创建分区流程来新增自定义分区的实现流程。
✅ 一、目标概述
在 Android 12 源码中新增一个名为 private
的系统分区,用于存放差分升级包、OTA 脚本或其他私有数据。
✅ 二、分区添加流程总览
表格
复制
步骤 | 目标 | 涉及文件 |
---|---|---|
1 | 声明分区变量 | BoardConfig.mk / Partitions.mk |
2 | 添加分区构建逻辑 | build/make/core/Makefile |
3 | 配置构建开关 | product.mk , product_config.mk , envsetup.mk |
4 | 配置 SELinux 权限 | device/tegra/sepolicy/ 下各 .te 文件 |
5 | 配置挂载点与 fstab | fstab.in , recovery.fstab , init.rc |
6 | 镜像打包与脚本处理 | mkimage.sh , build_image.py |
7 | 应用层访问支持 | init.rc , file_contexts , vold.te , shell.te 等 |
✅ 三、详细步骤拆解
🔧 1. 声明分区变量(Board 级别)
目的:让系统识别 private
分区的大小和文件系统类型。
文件:
-
device/rockchip/common/build/rockchip/Partitions.mk
添加内容:
BOARD_PRIVATEIMAGE_FILE_SYSTEM_TYPE ?= ext4
BOARD_PRIVATEIMAGE_PARTITION_SIZE ?= 1073741824 # 1GB
🔧 2. 添加构建逻辑(Makefile)
目的:让 private.img
能被构建出来,并加入到系统镜像中。
文件:
-
build/make/core/Makefile
添加内容:
-
定义
INSTALLED_PRIVATEIMAGE_TARGET
-
添加构建规则
build-privateimage-target
-
加入
BUILT_TARGET_FILES_PACKAGE
依赖
🔧 3. 配置构建开关(Product 级别)
目的:让系统知道是否启用 private
分区镜像构建。
文件:
-
build/make/core/product.mk
-
build/make/core/product_config.mk
-
build/make/core/envsetup.mk
添加内容:
PRODUCT_BUILD_PRIVATE_IMAGE := true
🔧 4. SELinux 权限配置
目的:让系统服务(如 init
, vold
, fsck
, shell
)能访问 private
分区。
文件:
-
device/rockchip/common/sepolicy/vendor/device.te
-
file.te
,file_contexts
-
init.te
,vold.te
,fsck.te
,shell.te
,vendor_init.te
添加内容:
# device.te
type private_block_device, dev_type;# file.te
type private_data_file_type, file_type, mlstrustedobject;# file_contexts
/dev/block/by-name/private u:object_r:private_block_device:s0
/private(/.*)? u:object_r:private_data_file_type:s0# init.te / vold.te / fsck.te / shell.te
allow xxx private_block_device:blk_file { rw_file_perms };
allow xxx private_data_file_type:dir { rw_dir_perms };
🔧 5. 配置挂载点与 fstab
目的:让系统在启动时自动挂载 /private
分区。
文件:
-
device/rockchip/common/scripts/fstab_tools/fstab.in
-
device/rockchip/rk356x/rk3568_s/recovery.fstab
添加内容:
/dev/block/by-name/private /private ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard wait,check
🔧 6. 镜像打包与脚本处理
目的:让 private.img
被打包进最终固件。
文件:
-
mkimage.sh
-
build/make/tools/releasetools/build_image.py
添加内容:
# mkimage.sh
cp -av $OUT/private.img $IMAGE_PATH/private.img
Python
复制
# build_image.py
elif image_filename == "private.img":mount_point = "private"
这样新编出来的系统就会在根目录下多出一个自定义的private目录。下面提供完整的git修改记录供参考:
diff --git a/build/make/core/Makefile b/build/make/core/Makefile
index d351cffb59..62104a5b20 100644
--- a/build/make/core/Mak