二.脚本ota_from_target_files(第二部分)

来源:互联网 发布:游戏账号交易平台软件 编辑:程序博客网 时间:2024/05/07 01:38

二.脚本ota_from_target_files(第二部分)  

主功能:WriteFullOTAPackage

 345 def WriteFullOTAPackage(input_zip, output_zip):

346   if OPTIONS.script_mode == "auto":
347     script = both_generator.BothGenerator(2)
348   elif OPTIONS.script_mode == "amend":
349     script = amend_generator.AmendGenerator()
350   else:
351     # TODO: how to determine this?  We don't know what version it will
352     # be installed on top of.  For now, we expect the API just won't
353     # change very often.
354     script = edify_generator.EdifyGenerator(2)
 首先,我们获得脚本生成器,他们的实现见脚本:edify_generator.py 等。
 356   metadata = {"post-build": GetBuildProp("ro.build.fingerprint", input_zip),
357               "pre-device": GetBuildProp("ro.product.device", input_zip),
358               "post-timestamp": GetBuildProp("ro.build.date.utc", input_zip),
359               }
 获得一些环境变量,来自android 环境变量。 Google 一下即知其义。
 361   device_specific = common.DeviceSpecificParams(
362       input_zip=input_zip,
363       input_version=GetRecoveryAPIVersion(input_zip),
364       output_zip=output_zip,
365       script=script,
366       input_tmp=OPTIONS.input_tmp,
367       metadata=metadata)
 设备相关参数,不深究。
 369   if not OPTIONS.omit_prereq:
370     ts = GetBuildProp("ro.build.date.utc", input_zip)
371     script.AssertOlderBuild(ts)
 如果需要,在脚本中增加一个Assert语句,要求update zip包只能用于升级老的系统。
 373   AppendAssertions(script, input_zip)
 如果需要,在脚本中增加一个Assert语句,要求update zip包只能用于同一设备,即目标设备的 ro.product.device必须跟update.zip中的相同。

 

374   device_specific.FullOTA_Assertions()
 Callback, 用于调用设备相关代码。调用时机为即将开始升级。类似还有:
FullOTA_InstallEnd IncrementalOTA_Assertions IncrementalOTA_VerifyEnd。 不深究。
 376   script.ShowProgress(0.5, 0)
 在升级脚本中加入显示进度的语句, 参数一表示底下的操作(到下一条同类语句或者到末尾)将暂用的时间在总体时间的比例。参数二用于控制显示的速度。比如,50 则表示底下的操作估计50秒内完成,要求进度条显示线程用50秒显示这一部分的进度。表示不自动更新,手动控制(使用SetProgress)
 378   if OPTIONS.wipe_user_data:
379     script.FormatPartition("userdata")
 如果需要,在脚本中增加语句,擦除 userdata 分区。
 381   script.FormatPartition("system")
 在脚本中增加语句,擦除 system分区。
 382   script.Mount("MTD", "system", "/system")
 在脚本中增加语句,安装 system分区到 /system 目录。
383   script.UnpackPackageDir("recovery", "/system")
384   script.UnpackPackageDir("system", "/system")
在脚本中增加语句,将recovery以及system中的内容拷贝到 /system目录。其中recovery 目录包含一个patch 以及应用该patch 的脚本。
 386   symlinks = CopySystemFiles(input_zip, output_zip)
387   script.MakeSymlinks(symlinks)
 386 行从输入 ZIP  /system 拷贝文件到输出 ZIP  /system。由于这个过程不支持链接文件,所以它将这些文件返回。 于 387 行做继续处理。该行建立这些link 文件。所有的link文件都指向 toolbox
 389   boot_img = File("boot.img", common.BuildBootableImage(
390       os.path.join(OPTIONS.input_tmp, "BOOT")))
391   recovery_img = File("recovery.img", common.BuildBootableImage(
392       os.path.join(OPTIONS.input_tmp, "RECOVERY")))
393   MakeRecoveryPatch(output_zip, recovery_img, boot_img)
 这个复杂,MakeRecoveryPatch 做了两件事:
1.在输出 ZIP包中生成一个patch: recovery/recovery-from-boot.p(boot.img recovery.imgpatch), 它最后会位于:system/recovery-from-boot.p
2.在输出 ZIP包中生成一个脚本:recovery/etc/install-recovery.sh , 它最后会位于system/etc/install-recovery.sh.
该脚本的内容为:
#!/system/bin/sh
if ! applypatch -c MTD:recovery:2048:6a167ffb86a4a16cb993473ce0726a3067163fc1; then
  log -t recovery "Installing new recovery image"
  applypatch MTD:boot:2324480:9a72a20a9c2f958ba586a840ed773cf8f5244183 MTD:recovery f6c2a70c5f2b02b6a49c9f5c5507a45a42e2d389 2564096 9a72a20a9c2f958ba586a840ed773cf8f5244183:/system/recovery-from-boot.p
else
  log -t recovery "Recovery image already installed"
fi
 395   Item.GetMetadata(input_zip)
 从 META/filesystem_config.txt 中获得 system 目录下的各文件权限信息。
 396   Item.Get("system").SetPermissions(script)
 在脚本中增加语句,设置 system 目录下文件的权限及属主等。
 398   common.CheckSize(boot_img.data, "boot.img")
 检查 boot.img 文件大小是否超标.
 399   common.ZipWriteStr(output_zip, "boot.img", boot_img.data)
 boot.img 放到输出 ZIP 包中。
 400   script.ShowProgress(0.2, 0)
402   script.ShowProgress(0.2, 10)
 更行进度条。
 403   script.WriteRawImage("boot", "boot.img")
 在脚本中增加语句,将 boot.img 写到 boot 分区。
 405   script.ShowProgress(0.1, 0)
 更行进度条。
 406   device_specific.FullOTA_InstallEnd()
 Callback, 同前。
 408   if OPTIONS.extra_script is not None:
409     script.AppendExtra(OPTIONS.extra_script)
 如果有额外脚本,加入。
 411   script.UnmountAll()
 在脚本中增加语句,umount 所有分区。
 412   script.AddToZip(input_zip, output_zip)
 1)将前面生成的脚本输出到:META-INF/com/google/android/updater-script (对于edify
 
  1. assert(getprop("ro.product.device") == "thedevicename" ||  
  2.   
  3.        getprop("ro.build.product") == "theproductname");  
  4.   
  5. show_progress(0.5000000);  
  6.   
  7. format("MTD""system");  
  8.   
  9. mount("MTD""system""/system");  
  10.   
  11. package_extract_dir("recovery""/system");  
  12.   
  13. package_extract_dir("system""/system");  
  14.   
  15. symlink("dumpstate""/system/bin/dumpcrash");  
  16.   
  17. symlink("toolbox""/system/bin/cat""/system/bin/chmod",  
  18.   
  19.         "/system/bin/chown""/system/bin/cmp""/system/bin/date",  
  20.   
  21.         "/system/bin/dd""/system/bin/df""/system/bin/dmesg",  
  22.   
  23.         "/system/bin/fb2bmp""/system/bin/getevent""/system/bin/getprop",  
  24.   
  25.         "/system/bin/hd""/system/bin/id""/system/bin/ifconfig",  
  26.   
  27.         "/system/bin/iftop""/system/bin/insmod""/system/bin/ioctl",  
  28.   
  29.         "/system/bin/kill""/system/bin/ln""/system/bin/log",  
  30.   
  31.         "/system/bin/ls""/system/bin/lsmod""/system/bin/mkdir",  
  32.   
  33.         "/system/bin/mount""/system/bin/mv""/system/bin/netstat",  
  34.   
  35.         "/system/bin/newfs_msdos""/system/bin/notify""/system/bin/printenv",  
  36.   
  37.         "/system/bin/ps""/system/bin/reboot""/system/bin/renice",  
  38.   
  39.         "/system/bin/rm""/system/bin/rmdir""/system/bin/rmmod",  
  40.   
  41.         "/system/bin/route""/system/bin/schedtop""/system/bin/sendevent",  
  42.   
  43.         "/system/bin/setconsole""/system/bin/setprop""/system/bin/sleep",  
  44.   
  45.         "/system/bin/smd""/system/bin/start""/system/bin/stop",  
  46.   
  47.         "/system/bin/sync""/system/bin/top""/system/bin/umount",  
  48.   
  49.         "/system/bin/vmstat""/system/bin/watchprops",  
  50.   
  51.         "/system/bin/wipe");  
  52.   
  53. set_perm_recursive(0007550644"/system");  
  54.   
  55. set_perm_recursive(0200007550755"/system/bin");  
  56.   
  57. set_perm(0300302755"/system/bin/netcfg");  
  58.   
  59. set_perm(0300402755"/system/bin/ping");  
  60.   
  61. set_perm_recursive(1002100207550440"/system/etc/bluez");  
  62.   
  63. set_perm(000755"/system/etc/bluez");  
  64.   
  65. set_perm(100210020440"/system/etc/dbus.conf");  
  66.   
  67. set_perm(101420000550"/system/etc/dhcpcd/dhcpcd-run-hooks");  
  68.   
  69. set_perm(020000550"/system/etc/init.goldfish.sh");  
  70.   
  71. set_perm(000544"/system/etc/install-recovery.sh");  
  72.   
  73. set_perm_recursive(0007550555"/system/etc/ppp");  
  74.   
  75. set_perm_recursive(0200007550755"/system/xbin");  
  76.   
  77. show_progress(0.2000000);  
  78.   
  79. show_progress(0.20000010);  
  80.   
  81. assert(package_extract_file("boot.img""/tmp/boot.img"),  
  82.   
  83.        write_raw_image("/tmp/boot.img""boot"),  
  84.   
  85.        delete("/tmp/boot.img"));  
  86.   
  87. show_progress(0.1000000);  
  88.   
  89. unmount("/system");  
 
2)将升级程序:OTA/bin/updater 从输入ZIP包中拷贝到输出ZIP包中的:META-INF/com/google/android/update-binary
 413   WriteMetadata(metadata, output_zip)

将前面获取的metadata 写入输出包的文件中: META-INF/com/android/metadata

至此,我们就得到了一个update.zip包。可以开始升级了。

思考

1 虽然提供了更新recovery分区的机制,但是没有看到触发该更新的语句。所以,缺省的情况是不会更新recovery分区的。大概是为了安全的原因吧。 但是,有时确实需要更新recovery 分区(比如,设备的硬件配置、分区表等发生改变),这该如何操作呢?

原创粉丝点击