设为首页 加入收藏

TOP

Android Recovery升级原理(五)
2019-09-19 11:10:27 】 浏览:143
Tags:Android Recovery 升级 原理
%s (%s)\n", binary, strerror(errno)); _exit(-1); } ...... int status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { //安装失败,返回INSTALL_ERROR return INSTALL_ERROR; } //安装成功,返回INSTALL_SUCCESS return INSTALL_SUCCESS; }

总的来说,try_update_binary主要做了以下几个操作:

(1)mzOpenZipArchive():打开升级包,并将相关的信息拷贝到一个临时的ZipArchinve变量中。注意这一步并未对我们的update.zip包解压。

(2)mzExtractZipEntryToFile(): 解压升级包特定文件,将升级包里面的META-INF/com/google/android/update-binary 解压到内存文件系统的/tmp/update_binary中。

(3)fork创建一个子进程 , 使用系统调用函数execv( ) 去执行/tmp/update-binary程序,

(4)update-binary: 这个是Recovery OTA升级的核心程序,是一个二进制文件,实现代码位于系统源码bootable/recovery/updater。其实质是相当于一个脚本解释器,能够识别updater-script中描述的操作并执行。

(5)updater-script:updater-script是我们升级时所具体使用到的脚本文件,具体描述了更新过程,它主要用以控制升级流程的主要逻辑。具体位置位于升级包中/META-INF/com/google/android/update-script,在我们制作升级包的时候产生。在升级的时候,由update_binary程序从升级包里面解压到内存文件系统的/tmp/update_script中,并按照update_script里面的命令,对系统进行升级。比如,一个完整包升级的update_script的内容大致如下所示:


assert(getprop("ro.product.device") == "rk31sdk" ||
       getprop("ro.build.product") == "rk301dk");
show_progress(0.500000, 0);
format("ext4", "EMMC", "/dev/block/mtd/by-name/system", "0", "/system");
mount("ext4", "EMMC", "/dev/block/mtd/by-name/system", "/system");
package_extract_dir("recovery", "/system");
package_extract_dir("system", "/system");
symlink("Roboto-Bold.ttf", "/system/fonts/DroidSans-Bold.ttf");
symlink("mksh", "/system/bin/sh");
......
set_perm_recursive(0, 0, 0755, 0644, "/system");
set_perm_recursive(0, 2000, 0755, 0755, "/system/bin");
......
set_perm(0, 0, 06755, "/system/xbin/su");
set_perm(0, 0, 06755, "/system/xbin/tcpdump");
show_progress(0.200000, 0);
show_progress(0.200000, 10);
write_raw_image(package_extract_file("boot.img"), "boot");
show_progress(0.100000, 0);
clear_misc_command();
unmount("/system");

update_script常用的命令如下:

image

因此,根据上面的升级脚本,可以知道,升级包的大致升级流程如下:

  1. 判断是不是升级包是否适用于该设备,如果不适用,则停止升级,否则继续。
  2. 显示进度条
  3. 格式化system分区
  4. 挂载system分区
  5. 将ota升级包里面的system、recovery目录解压到system分区
  6. 建立一些软链接,升级过程需要用到
  7. 设置部分文件权限
  8. 将升级包里面的boot.img写入到/boot分区
  9. 清空misc分区,即BCB块置为NULL
  10. 卸载system分区

6. wipe data/cache

main函数,在执行完install_package后,会根据传入的wipe_data/wipe_cache,决定是否执行/data和/cache分区的清空操作。

7. prompt_and_wait

这个函数的作用就是一直在等待用户输入,是一个不断的循环,可以选择Recovery模式下的一些选项进行操作,包括恢复出厂设置和重启等。如果升级失败, prompt_and_wait会显示错误,并等待用户响应。

8. finish_recovery

OTA升级成功,清空misc分区(BCB置零),并将保存到内存系统的升级日志/tmp/recovery.log保存到/cache/recovery/last_log。重启设备进入Main System,升级完成。

9. install-recovery.sh

从上面的流程中,可以知道,Recovery模式下的OTA升级成功,只是更新了/system和/boot两个最核心的分区,而本身用来升级的Recovery自身并没有在那个时候得到更新。Recovery分区的更新,是在重启进入主系统的时候,由install-recovery.sh来更新的。这样可以保证,即使升级失败,Recovery模式也不会受到影响,仍然可以手动进入Recovery模式执行升级或擦除数据操作。

在Recovery升级的时候,有一句:

package_extract_dir("recovery", "/system");

这条命令就是将升级包里面的recovery目录的内容,解压到/system分区

recovery目录下的文件,主要有install-recovery.sh和 recov

首页 上一页 2 3 4 5 下一页 尾页 5/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇linux 的swap、swappiness及kswap.. 下一篇android-ramdisk.img分析、recove..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目