Android OTA升级原理和流程分析(六)---Recovery服务流程细节

转载自:http://blog.chinaunix.net/uid-22028566-id-3533855.html

         Recovery服务毫无疑问是Recovery启动模式中最核心的部分。它完成Recovery模式所有的工作。Recovery程序对应的源码文件位于:/gingerbread0919/bootable/recovery/recovery.c。

一、 Recovery的三类服务:

         先看一下在这个源码文件中开始部分的一大段注释,这将对我们理解Recovery服务的主要功能有很大帮助。代码如下:

/* 
 * The recovery tool communicates with the main system through /cache files. 
 *   /cache/recovery/command - INPUT - command line for tool, one arg per line 
 *   /cache/recovery/log - OUTPUT - combined log file from recovery run(s) 
 *   /cache/recovery/intent - OUTPUT - intent that was passed in 
 * 
 * The arguments which may be supplied in the recovery.command file: 
 *   --send_intent=anystring - write the text out to recovery.intent 
 *   --update_package=path - verify install an OTA package file 
 *   --wipe_data - erase user data (and cache), then reboot 
 *   --wipe_cache - wipe cache (but not user data), then reboot 
 *   --set_encrypted_filesystem=on|off - enables / diasables encrypted fs 
 * 
 * After completing, we remove /cache/recovery/command and reboot. 
 * Arguments may also be supplied in the bootloader control block (BCB). 
 * These important scenarios must be safely restartable at any point: 
 * 
 * FACTORY RESET 
 * 1. user selects "factory reset" 
 * 2. main system writes "--wipe_data" to /cache/recovery/command 
 * 3. main system reboots into recovery 
 * 4. get_args() writes BCB with "boot-recovery" and "--wipe_data" 
 *    -- after this, rebooting will restart the erase -- 
 * 5. erase_volume() reformats /data 
 * 6. erase_volume() reformats /cache 
 * 7. finish_recovery() erases BCB 
 *    -- after this, rebooting will restart the main system -- 
 * 8. main() calls reboot() to boot main system 
 * 
 * OTA INSTALL 
 * 1. main system downloads OTA package to /cache/some-filename.zip 
 * 2. main system writes "--update_package=/cache/some-filename.zip" 
 * 3. main system reboots into recovery 
 * 4. get_args() writes BCB with "boot-recovery" and "--update_package=..." 
 *    -- after this, rebooting will attempt to reinstall the update -- 
 * 5. install_package() attempts to install the update 
 *    NOTE: the package install must itself be restartable from any point 
 * 6. finish_recovery() erases BCB 
 *    -- after this, rebooting will (try to) restart the main system -- 
 * 7. ** if install failed ** 
 *    7a. prompt_and_wait() shows an error icon and waits for the user 
 *    7b; the user reboots (pulling the battery, etc) into the main system 
 * 8. main() calls maybe_install_firmware_update() 
 *    ** if the update contained radio/hboot firmware **: 
 *    8a. m_i_f_u() writes BCB with "boot-recovery" and "--wipe_cache" 
 *        -- after this, rebooting will reformat cache & restart main system -- 
 *    8b. m_i_f_u() writes firmware image into raw cache partition 
 *    8c. m_i_f_u() writes BCB with "update-radio/hboot" and "--wipe_cache" 
 *        -- after this, rebooting will attempt to reinstall firmware -- 
 *    8d. bootloader tries to flash firmware 
 *    8e. bootloader writes BCB with "boot-recovery" (keeping "--wipe_cache") 
 *        -- after this, rebooting will reformat cache & restart main system -- 
 *    8f. erase_volume() reformats /cache 
 *    8g. finish_recovery() erases BCB 
 *        -- after this, rebooting will (try to) restart the main system -- 
 * 9. main() calls reboot() to boot main system 
 * 
 * SECURE FILE SYSTEMS ENABLE/DISABLE 
 * 1. user selects "enable encrypted file systems" 
 * 2. main system writes "--set_encrypted_filesystems=on|off" to 
 *    /cache/recovery/command 
 * 3. main system reboots into recovery 
 * 4. get_args() writes BCB with "boot-recovery" and 
 *    "--set_encrypted_filesystems=on|off" 
 *    -- after this, rebooting will restart the transition -- 
 * 5. read_encrypted_fs_info() retrieves encrypted file systems settings from /data 
 *    Settings include: property to specify the Encrypted FS istatus and 
 *    FS encryption key if enabled (not yet implemented) 
 * 6. erase_volume() reformats /data 
 * 7. erase_volume() reformats /cache 
 * 8. restore_encrypted_fs_info() writes required encrypted file systems settings to /data 
 *    Settings include: property to specify the Encrypted FS status and 
 *    FS encryption key if enabled (not yet implemented) 
 * 9. finish_recovery() erases BCB 
 *    -- after this, rebooting will restart the main system -- 
 * 10. main() calls reboot() to boot main system 
 */  

          从注释中我们可以看到Recovery的服务内容主要有三类:

         ①FACTORY RESET,恢复出厂设置。

         ②OTA INSTALL,即我们的update.zip包升级。

         ③ENCRYPTED FILE SYSTEM ENABLE/DISABLE,使能/关闭加密文件系统。具体的每一类服务的大概工作流程,注释中都有,我们在下文中会详细讲解OTA INSTALL的工作流程。这三类服务的大概的流程都是通用的,只是不同操作体现与不同的操作细节。下面我们看Recovery服务的通用流程。

二、Recovery服务的通用流程:

        在这里我们以OTA INSTALL的流程为例具体分析。并从相关函数的调用过程图开始,如下图:

          我们顺着流程图分析,从recovery.c的main函数开始:

1.    ui_init()

Recovery服务使用了一个基于framebuffer的简单ui(miniui)系统。这个函数对其进行了简单的初始化。在Recovery服务的过程中主要用于显示一个背景图片(正在安装或安装失败)和一个进度条(用于显示进度)。另外还启动了两个线程,一个用于处理进度条的显示(progress_thread),另一个用于响应用户的按键(input_thread)。

2.    get_arg()

这个函数主要做了上图中get_arg()往右往下直到parse arg/v的工作。我们对照着流程一个一个看。

                ①get_bootloader_message():主要工作是根据分区的文件格式类型(mtd或emmc)从MISC分区中读取BCB数据块到一个临时的变量中。

                ②然后开始判断Recovery服务是否有带命令行的参数(/sbin/recovery,根据现有的逻辑是没有的),若没有就从BCB中读取recovery域。如果读取失败则从/cache/recovery/command中读取然后。这样这个BCB的临时变量中的recovery域就被更新了。在将这个BCB的临时变量写回真实的BCB之前,又更新的这个BCB临时变量的command域为“boot-recovery”。这样做的目的是如果在升级失败(比如升级还未结束就断电了)时,系统在重启之后还会进入Recovery模式,直到升级完成。

                ③在这个BCB临时变量的各个域都更新完成后使用set_bootloader_message()写回到真正的BCB块中。

                这个过程可以用一个简单的图来概括,这样更清晰:

                                 

3.     parserargc/argv

解析我们获得参数。注册所解析的命令(register_update_command),在下面的操作中会根据这一步解析的值进行一步步的判断,然后进行相应的操作。

4.    if(update_package)

判断update_package是否有值,若有就表示需要升级更新包,此时就会调用install_package()(即图中红色的第二个阶段)。在这一步中将要完成安装实际的升级包。这是最为复杂,也是升级update.zip包最为核心的部分。我们在下一节详细分析这一过程。为从宏观上理解Recovery服务的框架,我们将这一步先略过,假设已经安装完成了。我们接着往下走,看安装完成后Recovery怎样一步步结束服务,并重启到新的主系统的。

5.    if(wipe_data/wipe_cache)

这一步判断实际是两步,在源码中是先判断是否擦除data分区(用户数据部分)的,然后再判断是否擦除cache分区。值得注意的是在擦除data分区的时候必须连带擦除cache分区。在只擦除cache分区的情形下可以不擦除data分区。

6.    maybe_install_firmware_update()

如果升级包中包含/radio/hboot firmware的更新,则会调用这个函数。查看源码发现,在注释中(OTA INSTALL)有这一个流程。但是main函数中并没有显示调用这个函数。目前尚未发现到底是在什么地方处理。但是其流程还是向上面的图示一样。即,① 先向BCB中写入“boot-recovery”和“—wipe_cache”之后将cache分区格式化,然后将firmware image 写入原始的cache分区中。②将命令“update-radio/hboot”和“—wipe_cache”写入BCB中,然后开始重新安装firmware并刷新firmware。③之后又会进入图示中的末尾,即finish_recovery()。

7.    prompt_and_wait()

这个函数是在一个判断中被调用的。其意义是如果安装失败(update.zip包错误或验证签名失败),则等待用户的输入处理(如通过组合键reboot等)。

8.    finish_recovery()

这是Recovery关闭并进入Main System的必经之路。其大体流程如下:

                                               

 

               ① 将intent(字符串)的内容作为参数传进finish_recovery中。如果有intent需要告知Main System,则将其写入/cache/recovery/intent中。这个intent的作用尚不知有何用。

               ② 将内存文件系统中的Recovery服务的日志(/tmp/recovery.log)拷贝到cache(/cache/recovery/log)分区中,以便告知重启后的Main System发生过什么。

               ③ 擦除MISC分区中的BCB数据块的内容,以便系统重启后不在进入Recovery模式而是进入更新后的主系统。

               ④ 删除/cache/recovery/command文件。这一步也是很重要的,因为重启后Bootloader会自动检索这个文件,如果未删除的话又会进入Recovery模式。原理在上面已经讲的很清楚了。

9.    reboot()

这是一个系统调用。在这一步Recovery完成其服务重启并进入Main System。这次重启和在主系统中重启进入Recovery模式调用的函数是一样的,但是其方向是不一样的。所以参数也就不一样。查看源码发现,其重启模式是RB_AUTOBOOT。这是一个系统的宏。

至此,我们对Recovery服务的整个流程框架已有了大概的认识。下面就是升级update.zip包时特有的也是Recovery服务中关于安装升级包最核心的第二个阶段。即我们图例中的红色2的那个分支。

我们将在下一篇详细讲解这一部分,即Recovery服务的核心部分install_package函数。

上一篇:Android OTA升级原理和流程分析(五)---update.zip包从上层进入Recovery服务

下一篇:Android OTA升级原理和流程分析(七)---Recovery服务的核心install_package函数

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android OTA(Over-The-Air)升级是指通过网络传输直接在设备上进行系统升级的一种方法。下面简要介绍Android OTA升级流程以及常见问题分析Android OTA升级流程通常包括以下几个步骤: 1. 系统准备:开发者根据新版本的要求,为设备准备升级所需的系统文件。这些文件包括操作系统文件、应用程序文件以及升级脚本等。 2. 设备请求:设备通过连接到网络,并向服务器请求最新的系统升级服务器根据设备的型号和当前系统版本,判断是否需要进行升级。 3. 传输升级文件:如果服务器确认设备需要进行升级,那么就会将升级文件传输给设备。这通常是通过HTTP或FTP等协议进行数据传输。 4. 升级验证:设备接收到升级文件后,会进行文件校验,以确保文件的完整性和一致性。 5. 升级安装:设备在校验通过后,会进行系统升级安装。这通常会涉及到文件解压、系统分区扩展等操作。 6. 安装后处理:升级完成后,设备会重新启动并进行一些后期处理工作,例如数据迁移、应用优化等。 常见问题分析: 1. 升级失败:升级过程中可能出现各种原因导致升级失败,如网络中断、升级文件损坏、设备存储空间不足等。解决方法可以包括重新尝试升级、检查网络连接、清理设备存储空间等。 2. 兼容性问题:新版本的系统可能对设备硬件或软件要求更高,而一些老旧设备可能无法满足这些要求。这可能导致升级后设备性能下降或功能不可用。解决方法可以是提供适配的系统版本或更新设备硬件。 3. 数据丢失:升级过程中可能导致设备的数据丢失,包括联系人、短信、应用程序数据等。为了避免这种问题,可以提醒用户备份数据或提供数据迁移工具。 4. 升级时间过长:升级过程可能需要较长时间,尤其是在升级文件较大或设备性能较低的情况下。解决方法可以是优化升级文件的大小和传输速度,或提供快速升级选项。 总结:Android OTA升级通过网络直接在设备上进行系统升级流程包括准备、请求、传输、验证、安装和处理。常见问题包括升级失败、兼容性问题、数据丢失和升级时间过长等,需要通过合适的解决方法来处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值