recovery image的OTA升级过程

来源:互联网 发布:用友u8软件2016多少钱 编辑:程序博客网 时间:2024/06/06 03:19

recovery image的OTA升级主要是如下几步:

1. 做OTA升级包的时候,将recovery.img和boot.img进行比较,生成recovery.img相对于boot.img的补丁,即system/recovery-from-boot.p;

2. 同时,生成一个生成recovery.img的shell脚本,即system/etc/install-recovery.sh;

3. 正常的OTA升级之后,手机重启到normal模式,在init的过程中,执行install-recovery.sh,生成目标recovery.img.


下面给出以上步骤涉及的文件。


1. build/tools/releasetools/ota_from_target_files

def WriteFullOTAPackage(input_zip, output_zip):  # .................  script.UnpackPackageDir("recovery", "/system")  # .................  boot_img = common.GetBootableImage("boot.img", "boot.img",                                     OPTIONS.input_tmp, "BOOT")  recovery_img = common.GetBootableImage("recovery.img", "recovery.img",                                         OPTIONS.input_tmp, "RECOVERY")  MakeRecoveryPatch(OPTIONS.input_tmp, output_zip, recovery_img, boot_img)


其中升级包中的recovery内容,是由MakeRecoveryPatch()函数生成的;recovery-from-boot.p的计算过程,也是在这个函数中。

def MakeRecoveryPatch(input_tmp, output_zip, recovery_img, boot_img):  """Generate a binary patch that creates the recovery image starting  with the boot image.  (Most of the space in these images is just the  kernel, which is identical for the two, so the resulting patch  should be efficient.)  Add it to the output zip, along with a shell  script that is run from init.rc on first boot to actually do the  patching and install the new recovery image.  recovery_img and boot_img should be File objects for the  corresponding images.  info should be the dictionary returned by  common.LoadInfoDict() on the input target_files.  Returns an Item for the shell script, which must be made  executable.  """  diff_program = ["imgdiff"]  path = os.path.join(input_tmp, "SYSTEM", "etc", "recovery-resource.dat")  if os.path.exists(path):    diff_program.append("-b")    diff_program.append(path)    bonus_args = "-b /system/etc/recovery-resource.dat"  else:    bonus_args = ""  d = common.Difference(recovery_img, boot_img, diff_program=diff_program)  _, _, patch = d.ComputePatch()  common.ZipWriteStr(output_zip, "recovery/recovery-from-boot.p", patch)  Item.Get("system/recovery-from-boot.p", dir=False)  boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict)  recovery_type, recovery_device = common.GetTypeAndDevice("/recovery", OPTIONS.info_dict)  sh = """#!/system/bin/shif ! applypatch -c %(recovery_type)s:%(recovery_device)s:%(recovery_size)d:%(recovery_sha1)s; then  log -t recovery "Installing new recovery image"  applypatch %(bonus_args)s %(boot_type)s:%(boot_device)s:%(boot_size)d:%(boot_sha1)s %(recovery_type)s:%(recovery_device)s %(recovery_sha1)s %(recovery_size)d %(boot_sha1)s:/system/recovery-from-boot.pelse  log -t recovery "Recovery image already installed"fi""" % { 'boot_size': boot_img.size,        'boot_sha1': boot_img.sha1,        'recovery_size': recovery_img.size,        'recovery_sha1': recovery_img.sha1,        'boot_type': boot_type,        'boot_device': boot_device,        'recovery_type': recovery_type,        'recovery_device': recovery_device,        'bonus_args': bonus_args,        }  common.ZipWriteStr(output_zip, "recovery/etc/install-recovery.sh", sh)  return Item.Get("system/etc/install-recovery.sh", dir=False)

上面代码中的recovery-resource.dat这个文件,如果用二进制编辑器打开,发现其开头二个字节是PK,即是一个压缩文件。当重命名成zip之后,可以解压缩,可以看到存放的是recovery image的图片资源和密钥。


2. init.rc

system/core/init.rc最终会拷贝到生成的boot image中,Linux内涵会执行init.rc中的命令,其中就包括对recovery image的升级,如下:

service flash_recovery /system/etc/install-recovery.sh    class main    oneshot


0 0