http://blog.csdn.net/huangyabin001/article/details/43763419
第一步:解压缩(ota_from_target_files)
[python] view plain copy
-
print "unzipping target target-files..."
-
OPTIONS.input_tmp, input_zip = common.UnzipTemp(args[0])
上面的代码是开始进行解压缩的入口
-
def UnzipTemp(filename, pattern=None):
-
-
-
-
-
-
-
-
-
-
tmp = tempfile.mkdtemp(prefix="targetfiles-")
-
OPTIONS.tempfiles.append(tmp)
-
-
def unzip_to_dir(filename, dirname):
-
-
cmd = ["unzip", "-o", "-q", filename, "-d", dirname]
-
if pattern is not None:
-
cmd.append(pattern)
-
-
p = Run(cmd, stdout=subprocess.PIPE)
-
-
p.communicate()
-
if p.returncode != 0:
-
raise ExternalError("failed to unzip input target-files \"%s\"" %
-
(filename,))
-
-
m = re.match(r"^(.*[.]zip)\+(.*[.]zip)$", filename, re.IGNORECASE)
-
-
if m:
-
unzip_to_dir(m.group(1), tmp)
-
unzip_to_dir(m.group(2), os.path.join(tmp, "BOOTABLE_IMAGES"))
-
filename = m.group(1)
-
else:
-
-
unzip_to_dir(filename, tmp)
-
-
-
-
return tmp, zipfile.ZipFile(filename, "r")
#这里开启新的进程来执行解压缩的命令
-
def Run(args, **kwargs):
-
-
-
if OPTIONS.verbose:
-
print " running: ", " ".join(args)
-
-
return subprocess.Popen(args, **kwargs)
接着回到main函数中对解压缩返回的结果进行处理
-
OPTIONS.target_tmp = OPTIONS.input_tmp
-
OPTIONS.info_dict = common.LoadInfoDict(input_zip)
第二步,解析target.zip中META/misc_info.txt、imagesizes.txt中的信息,如下图:
这是misc_info.txt中的内容:
-
recovery_api_version=3
-
fstab_version=2
-
tool_extensions=out/target/product/wt98360/obj/CUSTGEN/config/../common
-
default_system_dev_certificate=build/target/product/security/testkey
-
mkbootimg_args=
-
use_set_metadata=1
-
update_rename_support=1
-
fs_type=ext4
-
system_size=1363148800
-
userdata_size=1152385024
-
cache_size=132120576
-
extfs_sparse_flag=-s
-
mkyaffs2_extra_flags=-c 2048 -s 64
-
selinux_fc=out/target/product/wt98360/root/file_contexts
具体代码如下:
-
def LoadInfoDict(zip):
-
-
-
-
d = {}
-
try:
-
-
for line in zip.read("META/misc_info.txt").split("\n"):
-
line = line.strip()
-
if not line or line.startswith("#"): continue#跳过注释信息
-
k, v = line.split("=", 1)
-
d[k] = v
-
except KeyError:
-
-
pass
-
-
-
-
-
-
if "mkyaffs2_extra_flags" not in d:
-
try:
-
d["mkyaffs2_extra_flags"] = zip.read("META/mkyaffs2-extra-flags.txt").strip()
-
except KeyError:
-
-
pass
-
-
if "recovery_api_version" not in d:
-
try:
-
d["recovery_api_version"] = zip.read("META/recovery-api-version.txt").strip()
-
except KeyError:
-
raise ValueError("can't find recovery API version in input target-files")
-
-
if "tool_extensions" not in d:
-
try:
-
d["tool_extensions"] = zip.read("META/tool-extensions.txt").strip()
-
except KeyError:
-
-
pass
-
-
if "fstab_version" not in d:
-
d["fstab_version"] = "1"
-
-
try:
-
data = zip.read("META/imagesizes.txt")
-
for line in data.split("\n"):
-
if not line: continue
-
name, value = line.split(" ", 1)
-
if not value: continue
-
if name == "blocksize":
-
d[name] = value
-
else:
-
d[name + "_size"] = value
-
except KeyError:
-
pass
-
-
def makeint(key):
-
if key in d:
-
if d[key].endswith('M'):
-
d[key] = d[key].split("M")[0]
-
d[key] = int(d[key], 0) * 1024 * 1024
-
else:
-
d[key] = int(d[key], 0)
-
-
makeint("recovery_api_version")
-
makeint("blocksize")
-
makeint("system_size")
-
makeint("userdata_size")
-
makeint("cache_size")
-
makeint("recovery_size")
-
makeint("boot_size")
-
makeint("fstab_version")
-
-
makeint("custom_size")
-
-
-
d["fstab"] = LoadRecoveryFSTab(zip, d["fstab_version"])
-
d["build.prop"] = LoadBuildProp(zip)
-
return d
上面的代码中,在方法的末尾有分别去解析了分区表和Build属性,那么具体的操作流程,我们下面进行详细的分析
第三步,解析recovery分区信息
这里fastab_version的版本是2,因此
def LoadRecoveryFSTab(zip, fstab_version):
class Partition(object):
pass
try:
data = zip.read("RECOVERY/RAMDISK/etc/recovery.fstab")#当前target.zip中并没有这文件,因此这里暂不作详解
except KeyError:
print "Warning: could not find RECOVERY/RAMDISK/etc/recovery.fstab in %s." % zip
data = ""
if fstab_version == 1:
d = {}
for line in data.split("\n"):
line = line.strip()
if not line or line.startswith("#"): continue
pieces = line.split()
if not (3 <= len(pieces) <= 4):
raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
p = Partition()
p.mount_point = pieces[0]
p.fs_type = pieces[1]
p.device = pieces[2]
p.length = 0
options = None
if len(pieces) >= 4:
if pieces[3].startswith("/"):
p.device2 = pieces[3]
if len(pieces) >= 5:
options = pieces[4]
else:
p.device2 = None
options = pieces[3]
else:
p.device2 = None
if options:
options = options.split(",")
for i in options:
if i.startswith("length="):
p.length = int(i[7:])
else:
print "%s: unknown option \"%s\"" % (p.mount_point, i)
d[p.mount_point] = p
elif fstab_version == 2:
d = {}
for line in data.split("\n"):
line = line.strip()
if not line or line.startswith("#"): continue
pieces = line.split()
if len(pieces) != 5:
raise ValueError("malformed recovery.fstab line: \"%s\"" % (line,))
# Ignore entries that are managed by vold
options = pieces[4]
if "voldmanaged=" in options: continue
# It's a good line, parse it
p = Partition()
p.device = pieces[0]
p.mount_point = pieces[1]
p.fs_type = pieces[2]
p.device2 = None
p.length = 0
options = options.split(",")
for i in options:
if i.startswith("length="):
p.length = int(i[7:])
else:
# Ignore all unknown options in the unified fstab
continue
d[p.mount_point] = p
else:
raise ValueError("Unknown fstab_version: \"%d\"" % (fstab_version,))
return d
第四步,解析SYSTEM/build.prop属性信息,将解析的属性信息保存为一个数据字典,并返回
-
def LoadBuildProp(zip):
-
try:
-
data = zip.read("SYSTEM/build.prop")
-
except KeyError:
-
print "Warning: could not find SYSTEM/build.prop in %s" % zip
-
data = ""
-
-
d = {}
-
for line in data.split("\n"):
-
line = line.strip()
-
if not line or line.startswith("#"): continue
-
name, value = line.split("=", 1)
-
d[name] = value
-
return d
-
阅读(2290) | 评论(0) | 转发(0) |