userdata.img是如何从AOSP中构造出来的-源码分析

AOSP是如何构造userdata.img

在AOSP中,userdata.img的制作命令如下,可以知道make的target是userdataimage

make userdataimage -j4

第一步: 执行AOSP根目录的Makefile

内容如下:

include build/make/core/main.mk

跳转到main.mk进行处理。

第二步: build/make/core/目录下的main.mk

这个文件是各种编译的核心文件,用于处理不同的make target,根据userdataimage的target,可以在该文件找到相关信息:

.PHONY: userdataimage
userdataimage: $(INSTALLED_USERDATAIMAGE_TARGET)

跳转到$(INSTALLED_USERDATAIMAGE_TARGET)中。

第三步: build/make/core/目录下的Makefile

上面提到的PHONY目标$(INSTALLED_USERDATAIMAGE_TARGET)记录build/make/core/Makefile,如下:

INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)

对于$(BUILT_USERDATAIMAGE_TARGET)需要满足一定的依赖关系才能执行继续执行,如下:

$(INSTALLED_USERDATAIMAGE_TARGET): $(INSTALLED_USERDATAIMAGE_TARGET_DEPS)

依赖$(INSTALLED_USERDATAIMAGE_TARGET_DEPS),有如下定义:

INSTALLED_USERDATAIMAGE_TARGET_DEPS := \
    $(INTERNAL_USERIMAGES_DEPS) \
    $(INTERNAL_USERDATAIMAGE_FILES) \
    $(BUILD_IMAGE_SRCS)

核心是第一个依赖:INTERNAL_USERIMAGES_DEPS
这是一个工具依赖,用于将制作userdata.img的工具连接在一起行程工具链,用于以后循环使用:

ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
INTERNAL_USERIMAGES_DEPS := $(SIMG2IMG)
INTERNAL_USERIMAGES_DEPS += $(MKEXTUSERIMG) $(MAKE_EXT4FS) $(E2FSCK)
ifeq ($(TARGET_USERIMAGES_USE_F2FS),true)
INTERNAL_USERIMAGES_DEPS += $(MKF2FSUSERIMG) $(MAKE_F2FS)
endif
endif

ifeq ($(BOARD_AVB_ENABLE),true)
INTERNAL_USERIMAGES_DEPS += $(AVBTOOL)
endif

ifneq (true,$(TARGET_USERIMAGES_SPARSE_SQUASHFS_DISABLED))
  INTERNAL_USERIMAGES_SPARSE_SQUASHFS_FLAG := -s
endif
ifneq ($(filter $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE) $(BOARD_PRODUCT_SERVICESIMAGE_FILE_SYSTEM_TYPE) $(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE) $(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE) $(BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE),squashfs),)
INTERNAL_USERIMAGES_DEPS += $(MAKE_SQUASHFS) $(MKSQUASHFSUSERIMG) $(IMG2SIMG)
endif

INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))

ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY))
INTERNAL_USERIMAGES_DEPS += $(BUILD_VERITY_METADATA) $(BUILD_VERITY_TREE) $(APPEND2SIMG) $(VERITY_SIGNER)
ifeq (true,$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SUPPORTS_VERITY_FEC))
INTERNAL_USERIMAGES_DEPS += $(FEC)
endif
endif

SELINUX_FC := $(call intermediates-dir-for,ETC,file_contexts.bin)/file_contexts.bin
INTERNAL_USERIMAGES_DEPS += $(SELINUX_FC)

INTERNAL_USERIMAGES_DEPS += $(BLK_ALLOC_TO_BASE_FS)

ifeq ($(INTERNAL_USERIMAGES_USE_EXT),true)
INTERNAL_USERIMAGES_DEPS += $(MKE2FS_CONF)
endif

工具的对应的变量,即工具所在的路径,如$(SIMG2IMG)$(MKEXTUSERIMG)等,可以在build/make/core/config.mk找到,如下:

SIMG2IMG := $(HOST_OUT_EXECUTABLES)/simg2img$(HOST_EXECUTABLE_SUFFIX)
IMG2SIMG := $(HOST_OUT_EXECUTABLES)/img2simg$(HOST_EXECUTABLE_SUFFIX)

满足了上述依赖以后,回到目标INSTALLED_USERDATAIMAGE_TARGET,有:

INSTALLED_USERDATAIMAGE_TARGET := $(BUILT_USERDATAIMAGE_TARGET)
BUILT_USERDATAIMAGE_TARGET := $(PRODUCT_OUT)/userdata.img

这里$(PRODUCT_OUT)表示AOSP编译完成后的输出目录,$(PRODUCT_OUT)/userdata.img即我们需要的文件。

确定了制作目标文件$(PRODUCT_OUT)/userdata.img以后,就要开始进行制作,具体是通过$(build-userdataimage-target)函数进行制作:

define build-userdataimage-target
  $(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")
  @mkdir -p $(TARGET_OUT_DATA)
  @mkdir -p $(userdataimage_intermediates) && rm -rf $(userdataimage_intermediates)/userdata_image_info.txt
  $(call generate-image-prop-dictionary, $(userdataimage_intermediates)/userdata_image_info.txt,userdata,skip_fsck=true)
  $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
      build/make/tools/releasetools/build_image.py \
      $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)
  $(hide) $(call assert-max-image-size,$(INSTALLED_USERDATAIMAGE_TARGET),$(BOARD_USERDATAIMAGE_PARTITION_SIZE))
endef

第一行打印debug的信息,打印出打包后userdata.img文件的保存位置:

$(call pretty,"Target userdata fs image: $(INSTALLED_USERDATAIMAGE_TARGET)")

INSTALLED_USERDATAIMAGE_TARGET的值默认情况一般是:

INSTALLED_USERDATAIMAGE_TARGET=BUILT_USERDATAIMAGE_TARGET=out/target/product/hikey960/userdata.img

第二、三行用于创建文件夹,以及删除上次使用的配置文件 userdata_image_info.txt:

@mkdir -p $(TARGET_OUT_DATA)
@mkdir -p $(userdataimage_intermediates) && rm -rf $(userdataimage_intermediates)/userdata_image_info.txt

第四行用于重新生成配置文件userdata_image_info.txt:

$(call generate-image-prop-dictionary, $(userdataimage_intermediates)/userdata_image_info.txt,userdata,skip_fsck=true)

其中函数generate-image-prop-dictionary的关键部分如下,echo 了一些信息到userdata_image_info.txt:

define generate-image-prop-dictionary
...
$(if $(filter $(2),userdata),\
    $(if $(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE),$(hide) echo "userdata_fs_type=$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)" >> $(1))
    $(if $(BOARD_USERDATAIMAGE_PARTITION_SIZE),$(hide) echo "userdata_size=$(BOARD_USERDATAIMAGE_PARTITION_SIZE)" >> $(1))
)
...
endef

其中$(BOARD_USERDATAIMAGE_FILE_SYSTEM_TYPE)$(BOARD_USERDATAIMAGE_PARTITION_SIZE)等值在编译的时候,或者BoardConfig.mk中指定了。
第五行先配置一下打包image所使用到的工具的环境变量,然后调用一个python脚本build_image.py去打包:

$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
      build/make/tools/releasetools/build_image.py \
      $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)

用于配置环境变量的$(INTERNAL_USERIMAGES_BINARY_PATHS)是由上面提及的工具链变量$(INTERNAL_USERIMAGES_DEPS)转换而来的变量,定义如下:

INTERNAL_USERIMAGES_BINARY_PATHS := $(sort $(dir $(INTERNAL_USERIMAGES_DEPS)))

然后通过foreach循环,加入到PATH中:

PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH

然后执行python脚本build_image.py去制作image:

build/make/tools/releasetools/build_image.py \
      $(TARGET_OUT_DATA) $(userdataimage_intermediates)/userdata_image_info.txt $(INSTALLED_USERDATAIMAGE_TARGET) $(TARGET_OUT)

上述提及到变量一般在Hikey设备中的具体路径就是:

$(TARGET_OUT_DATA)=out/target/product/hikey960/data
$(userdataimage_intermediates)/userdata_image_info.txt=out/target/product/hikey960/obj/PACKAGING/userdata_intermediates/userdata_image_info.txt
$(INSTALLED_USERDATAIMAGE_TARGET)=out/target/product/hikey960/userdata.img
$(TARGET_OUT)=out/target/product/hikey960/system

python脚本的核心是调用shell脚本mkf2fsuserimg.sh,这是用于制作f2fs类型的userdata.img,如果是ext4则是ext_mkuserimg,调用的形式如下:

mkf2fsuserimg.sh \
    out/target/product/hikey960/userdata.img \
    25845301248 \
    -f out/target/product/hikey960/data \
    -D out/target/product/hikey960/system \
    -s out/target/product/hikey960/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin \
    -t data -L data

脚本mkf2fsuserimg.sh一般在out/host/linux-x86-bin可以找到它的定义:

#!/bin/bash
...

MAKE_F2FS_CMD="make_f2fs -S $SIZE -f -O encrypt -O quota -O verity $MKFS_OPTS $OUTPUT_FILE"
echo $MAKE_F2FS_CMD
$MAKE_F2FS_CMD
if [ $? -ne 0 ]; then
  exit 4
fi

SLOAD_F2FS_CMD="sload_f2fs -S $SLOAD_OPTS $OUTPUT_FILE"
echo $SLOAD_F2FS_CMD
$SLOAD_F2FS_CMD
if [ $? -ne 0 ]; then
  rm -f $OUTPUT_FILE
  exit 4
fi

可以看到分别使用了make_f2fs对userdata.img进行格式化,然后使用sload_f2fs将预置app或者文件保存到userdata.img中。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值