userdata.img里的block count等于userdata partition size/block_size

userdata.img里的block count等于userdata partition size/block_size

build/core/Makefile

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)
TARGET_OUT_DATA is out/target/product/[device]/data
INSTALLED_USERDATAIMAGE_TARGET is out/target/product/$device/userdata.img
TARGET_OUT is out/target/product/$device/system
$(userdataimage_intermediates)/userdata_image_info.txt is:

out/target/product/[device]/obj/PACKAGING/userdata_intermediates/userdata_image_info.txt:

userdata_size=4625268736
ext_mkuserimg=mkuserimg_mke2fs
fs_type=ext4
extfs_sparse_flag=-s
squashfs_sparse_flag=-s
selinux_fc=out/target/product/$(device)/obj/ETC/file_contexts.bin_intermediates/file_contexts.bin
root_dir=out/target/product/$(device)/root
use_dynamic_partition_size=true
skip_fsck=true

build/tools/releasetools/build_image.py

def main(argv):
  in_dir = argv[0]
  glob_dict_file = argv[1]
  out_file = argv[2]
  target_out = argv[3]
  glob_dict = LoadGlobalDict(glob_dict_file)
  if "mount_point" in glob_dict:
    # The caller knows the mount point and provides a dictionary needed by
    # BuildImage().
    image_properties = glob_dict
  else:
    image_filename = os.path.basename(out_file)
    mount_point = ""
    if image_filename == "system.img":
      mount_point = "system"
    elif image_filename == "system_other.img":
      mount_point = "system_other"
    elif image_filename == "userdata.img":
      mount_point = "data"
    elif image_filename == "cache.img":
      mount_point = "cache"
    elif image_filename == "vendor.img":
      mount_point = "vendor"
    elif image_filename == "odm.img":
      mount_point = "odm"
    elif image_filename == "oem.img":
      mount_point = "oem"
    elif image_filename == "product.img":
      mount_point = "product"
    elif image_filename == "product_services.img":
      mount_point = "product_services"
    else:
      logger.error("Unknown image file name %s", image_filename)
      sys.exit(1)

    image_properties = ImagePropFromGlobalDict(glob_dict, mount_point)

  try:
    BuildImage(in_dir, image_properties, out_file, target_out)

  

def ImagePropFromGlobalDict(glob_dict, mount_point):
  elif mount_point == "data":
    # Copy the generic fs type first, override with specific one if available.
    copy_prop("fs_type", "fs_type")
    copy_prop("userdata_fs_type", "fs_type")
    copy_prop("userdata_size", "partition_size")
    copy_prop("flash_logical_block_size", "flash_logical_block_size")
    copy_prop("flash_erase_block_size", "flash_erase_block_size")

 在prop_dict里有了partition_size prop,即device/$vendor/$product/BoardConfig.mk里define的userdata partition size

def BuildImage(in_dir, prop_dict, out_file, target_out=None):
  if (prop_dict.get("use_dynamic_partition_size") == "true" and
      "partition_size" not in prop_dict):
    //not the case
    ...
  //the case
prop_dict["image_size"] = prop_dict["partition_size"] //image_size即为userdata partition size definition mkfs_output = BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config) def BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config): if fs_type.startswith("ext"): build_command = [prop_dict["ext_mkuserimg"]] //ext_mkuserimg值为mkuserimg_mke2fs build_command.append(prop_dict["image_size"]) if "extfs_inode_count" in prop_dict: //以userdata.img为例,它在userdata_image_info.txt里是没有define inode count的 build_command.extend(["-i", prop_dict["extfs_inode_count"]]) build_command.extend(["--inode_size", "256"]) if "selinux_fc" in prop_dict: build_command.append(prop_dict["selinux_fc"]) //将执行ext_mkuserimg,即执行mkuserimg_mke2fs.py mkfs_output = common.RunAndCheckOutput(build_command)

systemextrasext4_utilsMkuserimg_mke2fs.py

def main(argv):
  args = ParseArguments(argv)
  if args.mount_point[0] != '/':
    args.mount_point = '/' + args.mount_point
  if not args.fs_size:
    logging.error("Size of the filesystem is required")
    sys.exit(2)
  mke2fs_cmd, e2fsdroid_cmd = ConstructE2fsCommands(args)
def ParseArguments(argv):
  parser.add_argument("src_dir", help="The source directory for user image.")
  parser.add_argument("output_file", help="The path of the output image file.")
  parser.add_argument("ext_variant", choices=["ext2", "ext4"],
                      help="Variant of the extended filesystem.")
  parser.add_argument("mount_point", help="The mount point for user image.")
  parser.add_argument("fs_size", help="Size of the file system.") //即userdata partition size definition
  parser.add_argument("--inodes", "-i",
                      help="The extfs inodes count (mke2fs).")
  parser.add_argument("--inode_size", "-I",
                      help="The extfs inode size (mke2fs).")
def ConstructE2fsCommands(args):
  BLOCKSIZE = 4096
  if args.inodes:
    mke2fs_opts += ["-N", args.inodes]
  if args.inode_size:
    mke2fs_opts += ["-I", args.inode_size]
  if args.mount_point:
    mke2fs_opts += ["-M", args.mount_point]
  # Round down the filesystem length to be a multiple of the block size
  blocks = int(args.fs_size) / BLOCKSIZE
  mke2fs_cmd = (["mke2fs"] + mke2fs_opts +
                ["-t", args.ext_variant, "-b", str(BLOCKSIZE), args.output_file,
                 str(blocks)])

  e2fsdroid_cmd = (["e2fsdroid"] + e2fsdroid_opts +
                   ["-f", args.src_dir, "-a", args.mount_point,
                    args.output_file])

  return mke2fs_cmd, e2fsdroid_cmd

上述mke2fs_cmd中的blocks是userdata partition size definition/block_size(所以会将其block size对齐,block size是4K),所以生成的userdata.img里是包含userdata partition size信息的,即block count

mke2fs、e2fsdroid是可执行程序,路径在out/host/linux-x86/bin

用dumpe2fs tool解析build出来的userdata.ext4查看block count为1129216,1129216 * 4096 = 4,625,268,736,和userdata partition size definition一致:

dumpe2fs -f userdata.ext4
Block count: 1129216


BOARD_USERDATAIMAGE_PARTITION_SIZE := 4625268736

 

原文地址:https://www.cnblogs.com/aspirs/p/14800046.html