Android系统Recovery工做原理之使用update.zip升级过程分析(四)---A...

Android系统Recovery模式的工做原理


        在使用update.zip包升级时怎样从主系统(main system)重启进入Recovery模式,进入Recovery模式后怎样判断作何种操做,以及怎样得到主系统发送给Recovery服务的命令,这一系列问题的解决是经过整个软件平台的不一样部分之间的密切通讯配合来完成的。为此,咱们必需要了解Recovery模式的工做原理,这样才能知道咱们的update.zip包是怎样一步步进入Recovery中升级并最后到达主系统的。架构

1、Recovery模式中的三个部分函数

         Recovery的工做须要整个软件平台的配合,从通讯架构上来看,主要有三个部分。spa

        MainSystem:即上面提到的正常启动模式(BCB中无命令),是用boot.img启动的系统,Android的正常工做模式。更新时,在这种模式中咱们的上层操做就是使用OTA或则从SD卡中升级update.zip包。在重启进入Recovery模式以前,会向BCB中写入命令,以便在重启后告诉bootloader进入Recovery模式。
命令行

        Recovery:系统进入Recovery模式后会装载Recovery分区,该分区包含recovery.img(同boot.img相同,包含了标准的内核和根文件系统)。进入该模式后主要是运行Recovery服务(/sbin/recovery)来作相应的操做(重启、升级update.zip、擦除cache分区等)。接口

        Bootloader:除了正常的加载启动系统以外,还会经过读取MISC分区(BCB)得到来至Main system和Recovery的消息。ip

2、Recovery模式中的两个通讯接口字符串

       在Recovery服务中上述的三个实体之间的通讯是必不可少的,他们相互之间又有如下两个通讯接口。源码

       (一)经过CACHE分区中的三个文件:string

             Recovery经过/cache/recovery/目录下的三个文件与mian system通讯。具体以下             flash

            /cache/recovery/command:这个文件保存着Main system传给Recovery的命令行,每一行就是一条命令,支持一下几种的组合。

                --send_intent=anystring   //write the text out to recovery/intent     在Recovery结束时在finish_recovery函数中将定义的intent字符串做为参数传进来,并写入到/cache/recovery/intent中

                --update_package=root:path   //verify install an OTA package file     Main system将这条命令写入时,表明系统须要升级,在进入Recovery模式后,将该文件中的命令读取并写入BCB中,而后进行相应的更新update.zip包的操做。

                --wipe_data    //erase user data(and cache),then reboot。擦除用户数据。擦除data分区时必需要擦除cache分区。

                --wipe_cache   //wipe cache(but not user data),then reboot。擦除cache分区。

            /cache/recovery/log:Recovery模式在工做中的log打印。在recovery服务运行过程当中,stdout以及stderr会重定位到/tmp/recovery.log在recovery退出以前会将其转存到/cache/recovery/log中,供查看。

            /cache/recovery/intent:Recovery传递给Main system的信息。做用不详。

       (二)经过BCB(Bootloader Control Block):

             BCB是bootloader与Recovery的通讯接口,也是Bootloader与Main system之间的通讯接口。存储在flash中的MISC分区,占用三个page,其自己就是一个结构体,具体成员以及各成员含义以下:

             struct bootloader_message{

                       char command[32];

                       char status[32];

                       char recovery[1024];

              };

            command成员:其可能的取值咱们在上文已经分析过了,即当咱们想要在重启进入Recovery模式时,会更新这个成员的值。另外在成功更新后结束Recovery时,会清除这个成员的值,防止重启时再次进入Recovery模式。

            status:在完成相应的更新后,Bootloader会将执行结果写入到这个字段。

            recovery:可被Main System写入,也可被Recovery服务程序写入。该文件的内容格式为:

                               “recovery\n

                               <recovery command>\n

                               <recovery command>”

            该文件存储的就是一个字符串,必须以recovery\n开头,不然这个字段的全部内容域会被忽略。“recovery\n”以后的部分,是/cache/recovery/command支持的命令。能够将其理解为Recovery操做过程当中对命令操做的备份。Recovery对其操做的过程为:先读取BCB而后读取/cache/recovery/command,而后将两者从新写回BCB,这样在进入Main system以前,确保操做被执行。在操做以后进入Main system以前,Recovery又会清空BCB的command域和recovery域,这样确保重启后再也不进入Recovery模式。

3、如何从Main System重启并进入Recovery模式

       咱们先看一下以上三个部分是怎样进行通讯的,先看下图:

                       

               咱们只看从Main System如何进入Recovery模式,其余的通讯在后文中详述。先从Main System开始看,当咱们在Main System使用update.zip包进行升级时,系统会重启并进入Recovery模式。在系统重启以前,咱们能够看到,Main System定会向BCB中的command域写入boot-recovery(粉红色线),用来告知Bootloader重启后进入recovery模式。这一步是必须的。至于Main System是否向recovery域写入值咱们在源码中不能确定这一点。即使如此,重启进入Recovery模式后Bootloader会从/cache/recovery/command中读取值并放入到BCB的recovery域。而Main System在重启以前确定会向/cache/recovery/command中写入Recovery将要进行的操做命令。

         至此,咱们就大概知道了,在上层使用update.zip升级时,主系统是怎样告知重启后的系统进入Recovery模式的,以及在Recovery模式中完成什么样的操做。

         下一篇开始分析第一个阶段,即咱们在上层使用update.zip包升级时,Main System怎样重启并进入Recovery服务的细节流程。

相关文章
相关标签/搜索