热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

OTA和Recovery系统升级流程介绍

OTA和Recovery系统升级流程介绍2016-05-0417:44960人阅读评论(0)收藏举报
 

OTA和Recovery系统升级流程介绍

  960人阅读  评论(0)  收藏  举报
  分类:

目录(?)[+]

本文介绍了Android原生OTA和Recovery升级过程步骤.

进入升级

- 1.1 正常启动和进入Recovery的区别

下面给出了升级流程的简单示意图。 
这里写图片描述 
上图中的上下两个部分,上面一部分是正常的启动模式,下面一部分为Recovery模式。正常的启动模式是从boot.img启动系统(Main System),而recovery模式则是从reovery.img启动系统;(reovery.img只包含内核、简单的文件管理系统和图形系统)

Boot分区包括linux内核和Ramdisk,Recovery分区也包括Linux内核和Ramdisk,一般来说内核是一样的,但Ramdisk区别则非常大,recovery中的ramdisk会有更多的recovery需要使用的程序和数据。

- 1.2 分区介绍

这里说到的boot.img和recovery.img,其实就对应了一个Android设备中的分区,一般来说,android设备会包含以下几个分区

Boot:包含Linux内核和一个最小的root文件系统(装载到RAM disk中),用于挂载系统和其他的分区,并开始Runtime 
System:包括了系统应用和库文件(AOSP中可以获取到源代码),在运行的过程中,这个分区是read-only的,只有在OTA升级的时候才会发生变化 
Vendor:包括了系统应用和库文件(AOSP中不能获取到源代码),和System分区一样,只有在OTA升级的时候才会发生变化 
Userdata:用户安装的应用程序会把数据保存在这里,正常情况下OTA是不会清除这里的数据的,指定要删除出具的除外 
Cache:临时的保存应用数据(要把数据保存在这里,需要特地的app permission),OTA的升级包也可以保存在这里。OTA升级过程可能会清楚这个分区的数据。 
Recovery:包括了一个完整Linux内核和一些特殊的recovery binary,可以读取升级文件用这些文件来更新其他的分区 
Misc:一个非常小的分区,recovery用这个分区来保存一些关于升级的信息,应对升级过程中的设备掉电重启的状况

这些分区是Google官方的标准,实际的情况可能不太一样,就Find 7而言,刷机包里面的分区只有以下几个 :芯片厂商和手机厂商会根据自己的需要加一些其他的分区,如下面的persist.img是高通的,reserve4是我们自己加的保留分区,MTK还有preloader、lk,高通的还有NON-HLOS.bin、sbl、emms_aboot等。

Bootloader

- 2.1 什么是Bootloader? 
在嵌入式操作系统中,Bootloader在操作系统内核运行之前运行,可以初始化硬件设备、建立内存空间映射图,为调用操作系统内核准备好正确的环境。Bootloader和硬件是强相关的,且厂商一般都会对bootloader加锁,这样就不能随便刷机了。 
当然bootloader也是可以解锁的,这里不得不提一下root和bootloader解锁分别是怎么一回事:root是通过内核漏洞获取最高的权限,也就是所谓的超级用户(su,superuser),属于系统层面,root之后就可以修改system分区的数据;bootloader解锁则属于硬件层面的解锁boot和recovery分区,解锁bootloader不会root手机。更多见参考文献[1].

- 2.2 Fastboot和recovery的区别? 
Bootloader过程中,先做一些初始化,然后根据组合键做不同的事情,这个过程内核没有加载,机器知识在按顺序执行指令。 
Fastboot:在这种模式下,可以修改手机的硬件,并且允许我们发送一些命令给Bootloader。如使用电脑刷机,则需要进入fastboot模式,通过电脑执行命令将系统镜像刷到通过USB刷到手机中。 
Recovery:Recovery是一个小型的操作系统,并且会加载部分文件系统,这样才能从sdcard中读取升级包。 
Bootloader.cpp 
Bootloader(bootable/recovery/bootloader.cpp)会读取位于MISC分区的启动控制信息块BCB(Bootloader Control Block),通过函数

int get_bootloader_message(struct bootloader_message *out);
int set_bootloader_message(const struct bootloader_message *in);
  • 1
  • 2
  • 1
  • 2

如果command的值为“boot-recovery”时,就进入recovery模式。Recovery升级过程中掉电,下次按power键开机也会进入recovery模式就是因为misc分区依然存在recovery信息(掉电保护)。

Recovery模式

- 3.1 Recovery、Bootloader以及Main System通信方法 
图1中给出模式比较简单,实际上三个实体的交互过程并不是图1那种单向的顺序流程,而是一个双向的流程,于是就涉及到个三个部分的通信方法的实现。 
Recovery和Main System交互 
这一部分源代码(bootable/recovery/recovery.cpp)注释中有详细的介绍,这里大致总结一下:这两个部分交互是通过/cache文件来实现的,涉及到的文件如下表。 
这里写图片描述 
Recovery、Main System和Bootloader交互 
这个交互过程是通过BCB来完成的,BCB其实就是一个struct(在misc分区),在(bootable/recovery/bootloader.h)中定义。

struct bootloader_message {
    char command[32];//command存储在这个field里面
    char status[32];
    char recovery[768];
    char stage[32];
    char reserved[224];
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Command:重启进入recovery或者是更新radio或Bootloader硬件时,会更新这个域; 
Status:在bootloader完成“update-radio”和”update-hboot”命令之后更新; 
Recovery:用于system和recovery之间的通信; 
Stage:需要重启多次的packages会写入这个值,表示所处的状态。 
上面的过程可以总结为如下的示意图: 
这里写图片描述

cache/recovery/command中command有哪些? 
下表给出一些常用的命令和其含义。 
这里写图片描述

- 3.3 Factory Reset—恢复出厂设置 
恢复出厂设置也在recovery.cpp中完成,具体的流程如下: 
1) 用户选择恢复出厂设置 
2) Main System会在cache/recovery/command中写入—wipe-data的命令,然后重启进入recovery 
3) 通过get_args在BCB中写入boot-recovery和wipe-data命令 
4) 然后重启进行erase_volume 
5) 擦除数据之后调用finish_recovery将BCB中的数据清除 
6) main()函数调用reboot()进入Main System; 
这里写图片描述

OTA安装

  • 4.1 OTA简介

OTA,即Over the air,它可以实现完整的版本升级,也可以是增量升级。用户可以选择在SD卡中作本地升级,也可以直接采用网络在线升级。不管是哪种方式,都有几个过程:生成升级包、获取升级包、执行升级包,生成升级包不做介绍,。 
实际上,所谓OTA的整个过程可以用如下示意图表示。 
这里写图片描述 
首先,用户用手机的OTA检查更新(或者是自动更新),发送查询数据给服务器,然后服务器查询到相应的包,并返回下载地址给OTA.apk,然后OTA.apk进行下载,把下载的数据存储在手机的某个分区。完成之后用于选择是否升级,升级的时候OTA会发送命令给Main System,进入recovery,recovery根据利用下载下来的升级包完成升级过程。 
从图中,我们可以看出OTA.apk实际上只是完成了从服务下下载安装包,以及发送升级命令,功能似乎很容易描述,但是实际上要做的事情却是非常多的,特别是OTA 2.0将Applypatch功能移植到OTA.apk之后,复杂度进一步增加了。

  • 4.2 OTA安装流程

    下面对Recovery的升级步骤做一个梳理: 
    1) Main System下载OTA升级包,官方推荐下载到/cache分区下,但是实际上可以自己选择存储地方; 
    2) Main System在/cache/recovery/command中写入“—update_package=安装包路径” 
    3) 系统重启进入recovery,这一步是通过PowerManager的reboot(“recovery”)实现的 
    4) Get_args()在BCB中写入“boot-recovery”和”—update_package“,这样就保证了即便是设备出故障重启了,只有这两个命令还在,就会尝试重新安装OTA升级包 
    5) Install_package尝试开始安装OTA升级包 
    6) Finish_package擦除BCB 
    7) 如果升级失败 
    Prompt_and_wait显示错误,并等待用户响应 
    用户重启 
    8) 设备重启进入MainSystem 
    此外,还有个maybe_install_firmware_upadate,具体过程不做介绍了。

下面是Recovery的代码的区别,实际上2.3/3.0/4.4和5.0的代码差别还是非常大的,原因是5.0的recovery用C++改写了一遍,官方文档两者改写的函数进行了对比 
这里写图片描述 
这里写图片描述

这里写图片描述

  • 4.3 Install_package过程

    安装过程在/bootable/recovery/install.cpp中, 
    install_package(const char* path, int* wipe_cache, const char* install_file, bool needs_mount) 
    在recovery的main函数中传入的参数如下: 
    install_package(update_package, &wipe_cache, TEMPORARY_INSTALL_FILE, true); 
    参数列表: 
    -Path:传入的安装包地址 
    -wipe_cache:是否擦除cache分区 
    -install_file:实际上是安装过程的临时安装文件的地址(/tmp/last_install),包括install_log 
    -needs_mount:是否需要Mount,安装过程传入的是true 
    在install_package函数中,其实真正调用的是really_install_package函数: 
    result = really_install_package(path, wipe_cache, needs_mount); 
    这里对几个重要的流程做一些介绍: 
    -Set_install_mounts:检查安装包所在路径的分区是否挂载,否则返回安装失败 
    -Set_backgroud:升级过程的UI界面显示 
    -Load_keys,加载公钥,我们系统的签名文件放在/build/target/product/security/目录下。这样做的目的是为了防止用户使用不同的项目的升级包进行混刷,导致刷机变砖的情况; 
    -verify_file():对升级包update.zip包进行签名验证; 
    -mzOpenZipArchive():打开升级包,并将相关的信息拷贝到一个临时的ZipArchinve变量中。这一步并未对我们的update.zip包解压。 
    -try_update_binary():在这个函数中才是对我们的update.zip升级的地方。这个函数一开始先根据我们上一步获得的zip包信息,以及升级包的绝对路径将update_binary文件拷贝到内存文件系统的/tmp/update_binary中 
    -execv(binary,args)的作用就是去执行binary程序,这个程序的实质就是去解析update.zip包中的updater-script脚本中的命令并执行 
    这里写图片描述

  • 4.4 Update-binary和Updater-script

上面,我们讲到execv执行二进制文件和Updater-script脚本中的命令,这两个文件在下面的目录。Apply_patch过程其实是会预先在APK端提取出来这两个文件的。 
try_update_binary运行时,会首先从安装包中读取出update-binary这个可执行文件。创建一个管道(作用稍后会讲到),并在一个新线程中运行这个update-binary(即updater,主函数见bootable/recovery/updater/updater.c),update-binary运行的时候,先会从升级包中读取update-script。 
bootable/recovery/updater/updater.c中会注册函数,而这些被注册的函数在updater-script中有使用到。

    // Configure edify's functions.
    RegisterBuiltins();
    RegisterInstallFunctions();
    RegisterBlockImageFunctions();
    RegisterDeviceExtensions();
    FinishRegistration();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

常用的Updater-script命令 
这里写图片描述

1

推荐阅读
  • 这个问题困扰了我两天,卸载Dr.COM客户端(我们学校上网要装这个客户端登陆服务器,以后只能在网页里输入用户名和密码了),问题解决了。问题的现象:在实验室机台式机上安装openfire和sp ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • Java如何导入和导出Excel文件的方法和步骤详解
    本文详细介绍了在SpringBoot中使用Java导入和导出Excel文件的方法和步骤,包括添加操作Excel的依赖、自定义注解等。文章还提供了示例代码,并将代码上传至GitHub供访问。 ... [详细]
  • 本文讨论了在dva中引入antd组件table时没有显示样式的问题。提供了.roadhogrc文件的配置,包括环境和import的设置。同时介绍了extraBabelPlugins和transform-runtime的使用方法,并解释了libraryName和css的含义。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • Jquery 跨域问题
    为什么80%的码农都做不了架构师?JQuery1.2后getJSON方法支持跨域读取json数据,原理是利用一个叫做jsonp的概念。当然 ... [详细]
  • php缓存ri,浅析ThinkPHP缓存之快速缓存(F方法)和动态缓存(S方法)(日常整理)
    thinkPHP的F方法只能用于缓存简单数据类型,不支持有效期和缓存对象。S()缓存方法支持有效期,又称动态缓存方法。本文是小编日常整理有关thinkp ... [详细]
  • Annotation的大材小用
    为什么80%的码农都做不了架构师?最近在开发一些通用的excel数据导入的功能,由于涉及到导入的模块很多,所以开发了一个比较通用的e ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • OWASP(安全防护、漏洞验证工具)开放式Web应用程序安全项目(OWASP,OpenWebApplicationSecurityProject)是一个组织 ... [详细]
author-avatar
啊123
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有