Android Factory分区介绍
1. 背景¶
Factory分区的创建用于存放一些设备出厂设定的信息例如:SN号、IMEI号等。该分区可能会先被烧录一个具有初始设定的镜像,随后在工厂模式下会继续往分区添加信息。在进入Android系统时,该分区可能被挂载成只读且通过SeLinux限制进程访问。以上介绍的Factory分区的常见使用场景。本文主要介绍Factory分区的编译配置以及挂载配置。
2. 编译配置¶
编译factory.img的Makefile位于:
device/sigmastar/common/build/factory_image.mk
如果某个product需要编译factory.img,则需要在AndroidBoard.mk中导入该Makefile,以pioneer5下的product为例:
yi.huang@xml3bc12801:~/workspace/AOSP/device/sigmastar/pioneer5$ grep -rnw factory_image.mk pioneer5_sdp_lr/AndroidBoard.mk:19:include device/sigmastar/common/build/factory_image.mk pioneer5_sdp/AndroidBoard.mk:19:include device/sigmastar/common/build/factory_image.mk pioneer5_fpga/AndroidBoard.mk:19:include device/sigmastar/common/build/factory_image.mk pioneer5_ad/AndroidBoard.mk:19:include device/sigmastar/common/build/factory_image.mk pioneer5_voip/AndroidBoard.mk:19:include device/sigmastar/common/build/factory_image.mk
factory_image.mk内容大致如下:
1 # 2 # Copyright (c) [2019~2020] SigmaStar Technology. 3 +--- 12 lines: -------------------------------------------------------------------------------------------------------------------------------------------------------------------- 15 ifdef BOARD_FACTORY_PARTITION_SIZE 16 ifdef BOARD_SSTAR_FACTORYIMAGE_DIR 17 18 SSTAR_INSTALLED_FACTORYIMAGE_TARGET := $(PRODUCT_OUT)/factory.img 19 20 $(SSTAR_INSTALLED_FACTORYIMAGE_TARGET): $(HOST_OUT_EXECUTABLES)/img2simg$(HOST_EXECUTABLE_SUFFIX) 21 $(SSTAR_INSTALLED_FACTORYIMAGE_TARGET): $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) 22 $(SSTAR_INSTALLED_FACTORYIMAGE_TARGET): $(shell find $(BOARD_SSTAR_FACTORYIMAGE_DIR)) 23 echo "Install factoryimage: $@" 24 $(hide) rm -f $@ 25 $(hide) $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) \ 26 -d $(BOARD_SSTAR_FACTORYIMAGE_DIR) -t ext4 \ 27 -O ^metadata_csum,^64bit $@.ext4 \ 28 $(shell echo "($(BOARD_FACTORY_PARTITION_SIZE)+1023)/1024"|bc) || exit; 29 $(hide) $(HOST_OUT_EXECUTABLES)/img2simg$(HOST_EXECUTABLE_SUFFIX) \ 30 $@.ext4 $@ || exit; 31 $(hide) rm -f $@.ext4; 32 33 factoryimage: $(SSTAR_INSTALLED_FACTORYIMAGE_TARGET) 34 35 .PHONY: factoryimage 36 37 droidcore-unbundled: $(SSTAR_INSTALLED_FACTORYIMAGE_TARGET) 38 endif 39 endif
整体逻辑并不复杂,主要的过程:
25-28行:调用mke2fs生成一个factory.img.ext4的ext4文件系统镜像
29-30行:调用img2simg将factory.img.ext4转换成稀疏格式镜像
关于factory镜像,主要需要配置两个BoardConfig:
-
BOARD_FACTORY_PARTITION_SIZE 设定了factory分区的大小,这决定了生成的factory.img.ext4的大小,可以看到28行将BOARD_FACTORY_PARTITION_SIZE对1K做了向上除法取整传递给了mke2fs。关于mke2fs的参数设定请参考其帮助文档。关于BOARD_FACTORY_PARTITION_SIZE在哪里设定请参考《Android分区说明》。
-
BOARD_SSTAR_FACTORYIMAGE_DIR 设定了factory的资源目录,即factory.img.ext4的根目录位置,以pioneer5为例,目前是device公共的,位于:
# device/sigmastar/pioneer5/BoardConfig-common.mk BOARD_SSTAR_FACTORYIMAGE_DIR := device/sigmastar/pioneer5/factory
3. 分区相关配置¶
请先参考《Android分区说明》,以non-dynamic和disable AVB的配置为例,选中如下配置文件:
device/sigmastar/common/partition/partition-table-8GB-nondynamic.mk device/sigmastar/common/partition/partition-table-8GB-nondynamic-noavb.json
以上两个文件作用不再赘述,可以看到当前:
# partition-table-8GB-nondynamic.mk # factory.img(4MB) BOARD_FACTORY_PARTITION_SIZE := 4194304
{ "settings": { "disk_alignment": 512, "disk_size": "7 GB" }, "partitions": [ { "label": "factory", "size": 4194304, "guid": "auto", "type_guid": "brillo_misc", "hw_part_name": "UDA", "image_name": "factory.img", "is_download": false }, ] }
4. 挂载相关配置¶
请先参考《Android Fstab配置说明》,以non-dynamic和disable AVB的配置为例,选中如下配置文件:
device/sigmastar/pioneer5/fstab.sstar.nondynamic.nonavb
其中:
# Android fstab file. #<dev> <mnt_point> <type> <mnt_flags options> <fs_mgr_flags> /dev/block/platform/soc/soc:emmc/by-name/factory /mnt/factory ext4 nosuid,nodev,nodiratime,noatime,errors=panic latemount,wait
该fstab的设定将factory分区挂载到了/mnt/factory目录。在开发板中也可以看到:
console:/ # df -h Filesystem Size Used Avail Use% Mounted on /dev/block/mmcblk0p11 1.2G 826M 433M 66% / /dev/block/mmcblk0p13 240M 190M 50M 80% /vendor /dev/block/mmcblk0p15 7.4M 604K 6.8M 8% /odm /dev/block/mmcblk0p1 2.8M 21K 2.8M 1% /mnt/factory /dev/block/mmcblk0p18 3.2G 35M 3.1G 2% /data /dev/block/mmcblk0p17 3.7M 20K 3.7M 1% /cache console:/ # ls -la /dev/block/by-name/factory lrwxrwxrwx 1 root root 20 1970-01-01 00:00 /dev/block/by-name/factory -> /dev/block/mmcblk0p1
5. 读写factory分区¶
5.1. Kernel下读写¶
Kernel space下请通过vfs接口读写,和其他分区的文件一样。
User space下可以直接读写其所在挂载点下的文件,和其他分区的文件一样。
5.2. U-boot下读写¶
U-boot有如下Kconfig与ext4文件系统有关:
# fs/ext4/Kconfig config FS_EXT4 bool "Enable ext4 filesystem support" help This provides support for reading images from the ext4 filesystem. ext4 is a widely used general-purpose filesystem for Linux. You can also enable CMD_EXT4 to get access to ext4 commands. config EXT4_WRITE bool "Enable ext4 filesystem write support" depends on FS_EXT4 help This provides support for creating and writing new files to an existing ext4 filesystem partition. # cmd/Kconfig config CMD_EXT4 bool "ext4 command support" select FS_EXT4 help Enables EXT4 FS command config CMD_EXT4_WRITE depends on CMD_EXT4 bool "ext4 write command support" select EXT4_WRITE help Enables EXT4 FS write command
所有配置均打开的情况下,U-boot会有以下命令:
-
ext4load:将文件系统中的文件load到内存指定位置
-
ext4ls:获取文件系统指定目录的内容
-
ext4size:获取文件系统指定文件的大小
-
ext4write:将内存指定位置的内容写到文件系统指定文件
在代码中可以使用fs/fs.c
提供的通用文件系统操作接口进行操作。