add_img_to_target_files.py
文件位置: build/tools/releasetools/add_img_to_target_files.py
Android 在編譯成生成OTA文件時會被調用.
(注)這裏只關心system.img創建流程,其他img也是類似的.
原生Android 命令幫助
$ build/tools/releasetools/add_img_to_target_files.py -h
Given a target-files zipfile that does not contain images (ie, does
not have an IMAGES/ top-level subdirectory), produce the images and
add them to the zipfile.
Usage: add_img_to_target_files [flag] target_files
-a (--add_missing)
Build and add missing images to "IMAGES/". If this option is
not specified, this script will simply exit when "IMAGES/"
directory exists in the target file.
-r (--rebuild_recovery)
Rebuild the recovery patch and write it to the system image. Only
meaningful when system image needs to be rebuilt.
--replace_verity_private_key
Replace the private key used for verity signing. (same as the option
in sign_target_files_apks)
--replace_verity_public_key
Replace the certificate (public key) used for verity verification. (same
as the option in sign_target_files_apks)
--is_signing
Skip building & adding the images for "userdata" and "cache" if we
are signing the target files.
-p (--path) <dir>
Prepend <dir>/bin to the list of places to search for binaries
run by this script, and expect to find jars in <dir>/framework.
-s (--device_specific) <file>
Path to the python module containing device-specific
releasetools code.
-x (--extra) <key=value>
Add a key/value pair to the 'extras' dict, which device-specific
extension code may look at.
-v (--verbose)
Show command lines being executed.
-h (--help)
Display this usage message and exit.
示例
$./build/tools/releasetools/add_img_to_target_files.py -a -v -p linux-x86 target_files
一.add_img_to_target_files執行過程
- 它會檢查輸入參數
- 判斷輸入文件目錄格式(文件夾,ZIP)
- 解析META/misc_info.txt 配置參數
- 按順序生成boot.img, reovery.img, system.img, vendor.img, vbmate.img, userdata.img
其中,system.img, vendor.img這兩個比較特殊,是sparse格式的.文件頭以0xED26FF3A開頭,
boot.img 的文件頭是以 0xEDFE0DD0開頭
vbmete.img :是 0x30425641開頭的.$file IMAGES/boot.img IMAGES/boot.img: data
這個程序的流程圖:
二.system.img創建過程
- 從這AddSystem函數開始調用.
判斷是否存在system.img,存在,則返回.否則,調用:CreateImage(OPTIONS.input_tmp, OPTIONS.info_dict, "system", img, block_list=block_list)
- 下面是CreateImage代碼, 下面只分析system.img的創建.
def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
print("creating " + what + ".img...")
# The name of the directory it is making an image out of matters to
# mkyaffs2image. It wants "system" but we have a directory named
# "SYSTEM", so create a symlink.
temp_dir = tempfile.mkdtemp()
OPTIONS.tempfiles.append(temp_dir)
try:
os.symlink(os.path.join(input_dir, what.upper()),
os.path.join(temp_dir, what))
except OSError as e:
# bogus error on my mac version?
# File "./build/tools/releasetools/img_from_target_files"
# os.path.join(OPTIONS.input_tmp, "system"))
# OSError: [Errno 17] File exists
if e.errno == errno.EEXIST:
pass
#info_dict是MATE/misc_info.txt內容,image_props生成Image屬性字典
#ImagePropFromGlobalDict:Build an image property dictionary from the global dictionary
image_props = build_image.ImagePropFromGlobalDict(info_dict, what)
fstab = info_dict["fstab"]
mount_point = "/" + what
if fstab and mount_point in fstab:
image_props["fs_type"] = fstab[mount_point].fs_type
# Use a fixed timestamp (01/01/2009) when packaging the image.
# Bug: 24377993
epoch = datetime.datetime.fromtimestamp(0)
timestamp = (datetime.datetime(2009, 1, 1) - epoch).total_seconds()
image_props["timestamp"] = int(timestamp) #保存時間戳
if what == "system":
fs_config_prefix = ""
else:
fs_config_prefix = what + "_"
fs_config = os.path.join(
input_dir, "META/" + fs_config_prefix + "filesystem_config.txt")
if not os.path.exists(fs_config): #判斷fs_config文件是否存在
fs_config = None
# Override values loaded from info_dict.
if fs_config:
image_props["fs_config"] = fs_config
if block_list:
image_props["block_list"] = block_list.name
# Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
# build fingerprint).
uuid_seed = what + "-"
if "build.prop" in info_dict:
build_prop = info_dict["build.prop"]
if "ro.build.fingerprint" in build_prop:
uuid_seed += build_prop["ro.build.fingerprint"]
elif "ro.build.thumbprint" in build_prop:
uuid_seed += build_prop["ro.build.thumbprint"]
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
hash_seed = "hash_seed-" + uuid_seed
image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))
print(image_props)
'''
上面的輸出: {'partition_size': '4294967296', 'selinux_fc': 'out/target/product/mt2712 \/obj/PACKAGING/target_files_intermediates/car_mtxxxx_vp1-target_files-eng.xxx/META/file_contexts.bin', 'mount_point': 'system', 'fs_type': 'ext4', 'uuid': '8b37e1c4-2644-587d-98ba-2c4b4051713e', 'avb_enable': 'true',
'avb_avbtool': 'avbtool', 'timestamp': 1230739200, 'ramdisk_dir': 'out/target/product/mt2712/obj/PACKAGING/target_files_intermediates/mtxxxx_vp1-target_files-eng.xxx/ROOT', 'block_list': '/home/xxx/xxx_back
/out/target/product/mt2712/obj/PACKAGING/target_files_intermediates/mtxxxx_vp1-target_files-eng.xxx/IMAGES/system.map', 'fs_config': '/home/xxx/xxx_back/out/target/product/mt2712/obj/PACKAGING
/target_files_intermediates/mtxxxx_vp1-target_files-eng.xxx/META/filesystem_config.txt',
'avb_hashtree_enable': 'true', 'ext_mkuserimg': 'mkuserimg.sh', 'extfs_sparse_flag': '-s', 'squashfs_sparse_flag': '-s', 'avb_salt':
'1f142b82683fef0e8b0959e671966be80060f3ccd8cd11287679a64819830199', 'system_root_image': 'true', 'partition_name': 'system', 'ramdisk_fs_config': 'out/target/product/mt2712/obj/PACKAGING/target_files_intermediates/mtxxxx_vp1-target_files-eng.xxx/META/root_filesystem_config.txt',
'avb_add_hashtree_footer_args': '--setup_as_rootfs_from_kernel', 'hash_seed':
'31c34b75-754c-5bf1-a15f-0f045e3b27f8## 標題'}
'''
succ = build_image.BuildImage(os.path.join(temp_dir, what),
image_props, output_file.name) #生成Image
#在BuildImage函數中運行下面命令
'''
['mkuserimg.sh', '-s', '/tmp/tmpNrCt3J', '/home/xxx/xxx_back/out/target/product/mt2712/obj/PACKAGING/target_files_intermediates/**/IMAGES/system.img', 'ext4', '/', '4227117056', '-T', '1230739200',
'-C', '/tmp/root_fs_configrVsgbS.txt', '-B', '/home/xxx/xxx_back/out/target/product/mt2712/obj/PACKAGING/target_files_intermediates/mtxxxx_vp1-target_files-eng.xxx/IMAGES/system.map', '-L', '/',
'out/target/product/mt2712/obj/PACKAGING/target_files_intermediates/mtxxxx_vp1-target_files-eng.xxx/META/file_contexts.bin']
'''
assert succ, "build " + what + ".img image failed"
output_file.Write()
if block_list:
block_list.Write()
#MATE/care_map.txt. 這裏面保存的img是調整前的sparse格式 的數據CHUNK_TYPE_DONT_CARE
# Set the 'adjusted_partition_size' that excludes the verity blocks of the
# given image. When avb is enabled, this size is the max image size returned
# by the avb tool.
is_verity_partition = "verity_block_device" in image_props
verity_supported = (image_props.get("verity") == "true" or
image_props.get("avb_enable") == "true")
is_avb_enable = image_props.get("avb_hashtree_enable") == "true"
print('--------------is_verity_partition-------------------',is_verity_partition)# False
print('--------------verity_supported-------------------',verity_supported) #True
print('--------------is_avb_enable-------------------',is_avb_enable) #True
if verity_supported and (is_verity_partition or is_avb_enable):
adjusted_blocks_value = image_props.get("partition_size")
if adjusted_blocks_value:
adjusted_blocks_key = what + "_adjusted_partition_size"
info_dict[adjusted_blocks_key] = int(adjusted_blocks_value)/4096 - 1
這裏有個問題需要注意一下
在原生android編譯生成的system.img 和vender.img 都是經過調整後的,所以生成care_map.txt 的內容都都要小一些.
如果已經存在的img. 這是生成的care_map.txt的內容就要大一些.
(注)care_map.txt 是 MATE/care_map.txt
build/tools/releasetools/add_img_to_target_files -a -v -p linux-x86 target_files
例如:
原生Android生成的.
$ cat care_map.txt
system
92,0,32766,32768,32770,33025,.....省略
vendor
10,0,17607,32768,32770,32793,.....省略
自己用上面工具生成
system
94,0,32766,32768,32770,33025,.....省略
vendor
14,0,17607,32768,32770,32793,.....省略
爲什麼出現這個問題呢?
因爲add_img_to_target_files生成時,將avbtool 增加footer 計算到了.care_map.txt文件中.
實際care_map.txt文件是保存sprase format 的 Don’t care 數據類型.
care_map.txt
system保存的哪個img
92: 這後面有92個數據 0 輸入數據塊 32766輸出塊偏移量 32768輸出塊
Android 稀疏鏡像格式 (android sparse image format)