本文转载自:https://blog.csdn.net/guyongqiangx/article/details/71334889

Android从7.0开始引入新的OTA升级方式,A/B System Updates,这里将其叫做A/B系统。

版权声明:
本文为guyongqiangx原创,欢迎转载,请注明出处:
Android A/B System OTA分析(一)概览: http://blog.csdn.net/guyongqiangx/article/details/71334889

A/B系统涉及的内容较多,分多篇对A/B系统的各个方面进行分析。本文为第一篇,概览。

1. A/B系统的特点
顾名思义,A/B系统就是设备上有A和B两套可以工作的系统(用户数据只有一份,为两套系统共用),简单来讲,可以理解为一套系统分区,另外一套为备份分区。其系统版本可能一样;也可能不一样,其中一个是新版本,另外一个旧版本,通过升级,将旧版本也更新为新版本。当然,设备出厂时这两套系统肯定是一样的。

之所以叫套,而不是个,是因为Android系统不是由一个分区组成,其系统包括boot分区的kernel和ramdisk,system和vendor分区的应用程序和库文件,以及userdata分区的数据

A/B系统实现了无缝升级(seamless updates),有以下特点:

出厂时设备上有两套可以正常工作的系统,升级时确保设备上始终有一个可以工作的系统,减少设备变砖的可能性,方便维修和售后。
OTA升级在Android系统的后台进行,所以更新过程中,用户可以正常使用设备,数据更新完成后,仅需要用户重启一次设备进入新系统
如果OTA升级失败,设备可以回退到升级前的旧系统,并且可以尝试再次更新升级。
Android 7.0上传统OTA方式和新的A/B系统方式都存在,只是编译时只能选择其中的一种OTA方式。由于A/B系统在分区上与传统OTA的分区设计不一样,二者无法兼容,所以7.0以前的系统无法通过OTA方式升级为A/B系统。

啰嗦一下7.0以前传统的OTA方式:

设备上有一个Android主系统和一个Recovery系统,Android主系统运行时检测是否需要升级,如果需要升级,则将升级的数据包下载并存放到cache分区,重启系统后进入Recovery系统,并用cache分区下载好的数据更新Android主系统,更新完成后重新启动进入Android主系统。如果更新失败,设备重启后就不能正常使用了,唯一的办法就是重新升级,直到成功为止。

A/B系统主要由运行在Android后台的update_engine和两套分区‘slot A’和‘slot B’组成。Android系统从其中一套分区启动,在后台运行update_engine监测升级信息并下载升级数据,然后将数据更新到另外一套分区,写入数据完成后从更新的分区启动。

与传统OTA方式相比,A/B系统的变化主要有:

系统的分区设置
传统方式只有一套分区
A/B系统有两套分区,称为slot A和slot B
跟bootloader沟通的方式
传统方式bootloader通过读取misc分区信息来决定是进入Android主系统还是Recovery系统
A/B系统的bootloader通过特定的分区信息来决定从slot A还是slot B启动
系统的编译过程
传统方式在编译时会生成boot.img和recovery.img分别用于Android主系统和Recovery系统的ramdisk
A/B系统只有boot.img,而不再生成单独的recovery.img
OTA更新包的生成方式
A/B系统生成OTA包的工具和命令跟传统方式一样,但是生成内容的格式不一样了
由于内容较多,分多篇文章来详细分析整个A/B系统。

本文主要从分区和总体操作流程上来描述A/B系统,也可以参考Android官方对A/B系统的说明:"A/B System Updates"。

2. A/B系统的分区
2.1 传统OTA的分区
传统OTA方式下的分区主要包括:

bootloader

存放用于引导linux的bootloader

boot

存放Android主系统的linux kernel文件和用于挂载system和其他分区的ramdisk

system

Android主系统分区,包括Android的系统应用程序和库文件

vendor

Android主系统分区,主要是包含开发厂商定制的一些应用和库文件,很多时候开发厂商也直接将这个分区的内容直接放入system分区

userdata

用户数据分区,存放用户数据,包括用户安装的应用程序和使用时生成的数据

cache

临时存放数据的分区,通常用于存放OTA的升级包

recovery

存放Recovery系统的linux kernel文件和ramdisk

misc

存放Android主系统和Recovery系统跟bootloader通信的数据

2.2 A/B系统的分区
bootloader

存放用于引导linux的bootloader

boot_a和boot_b

分别用于存放两套系统各自的linux kernel文件和用于挂载system和其他分区的ramdisk

system_a和system_b

Android主系统分区,分别用于存放两套系统各自的系统应用程序和库文件

vendor_a和vendor_b

Android主系统分区, 分别用于存放两套系统各自的开发厂商定制的一些应用和库文件,很多时候开发厂商也直接将这个分区的内容直接放入system分区

userdata

用户数据分区,存放用户数据,包括用户安装的应用程序和使用时生成的数据

misc或其他名字分区

存放Android主系统和Recovery系统跟bootloader通信的数据,由于存放方式和分区名字没有强制要求,所以部分实现上保留了misc分区(代码中可见Brillo和Intel的平台),另外部分实现采用其他分区存放数据(Broadcom机顶盒平台采用名为eio的分区)。

2.3 一张图比较传统分区和A/B系统分区
关于分区的区别,文字描述不够直观,采用图片清楚多了。

主要区别在于A/B系统:

boot,system和vendor系统分区从传统的一套变为两套,叫做slot A和slot B;
不再需要cache和recovery分区
misc分区不是必须
关于cache和misc分区:

仍然有部分厂家保留cache分区,用于一些其他的用途,相当于temp文件夹,但不是用于存放下载的OTA数据。
部分厂家使用misc分区存放Android系统同bootloader通信数据,另有部分厂家使用其它名字的分区存储这类数据。
3. A/B系统的状态
3.1 系统分区属性
对于A/B系统的slot A和slot B分区,其都存在以下三个属性:

active

系统的活动分区标识,这是一个排他属性,系统只能有一个分区设置为active属性,启动时bootloader选取设置为active的分区进行启动。

bootable

分区可启动标识,设置为bootable的分区表明该分区包含了一个完整的可以启动的系统。

successful

分区成功运行标识,设置为successful的分区表明该分区在上一次启动或当前启动中可以正确运行。

3.2 系统的典型场景
典型的应用场景有以下4个(假定当前从B分区启动):

图中:

当前运行的系统(current)用绿色方框表示,当前没有用的系统(unused)用灰色方框表示。
属性标识为红色,表示该状态下相应属性被设置,标识为灰色标识该状态下属性没有设置或设置为相反属性,如:
”active” 表示已经设置active属性,当前为活动分区;”active” 表示没有设置active属性
“bootable” 表示已经设置bootable属性;”bootable” 表示设置为unbootable或没有设置bootable属性
“successful” 表示已经设置successful属性,”successful” 表示没有设置successful属性
每个场景详细说明如下:

普通场景(Normal cases)

最常见的情形,例如设备出厂时,A分区和B分区都可以成功启动并正确运行,所以两个分区都设置为bootable和successful,但由于是从B分区启动,所以只有B分区设置为active。

升级中(Update in progress)

B分区检测到升级数据,在A分区进行升级,此时将A分区标识为unbootable,另外清除successful标识;B分区仍然为active,bootable和successful。

更新完成,等待重启(Update applied, reboot pending)

B分区将A分区成功更新后,将A分区标识为bootable。另外,由于重启后需要从A分区启动,所以也需要将A分区设置为active,但是由于还没有验证过A分区是否能成功运行,所以不设置successful;B分区的状态变为bootable和successful,但没有active。

从新系统成功启动(System rebooted into new update)

设备重启后,bootloader检测到A分区为active,所以加载A分区系统。进入A系统后如果能正确运行,需要将A分区标识为successful。对比第1个普通场景,A和B系统都设置为bootable和successful,但active从B分区切换到A分区。至此,B分区成功更新并切换到A分区,设备重新进入普通场景。

4. A/B系统的更新流程
整个A/B系统的升级更新在后台完成,升级中任何时间点都是可中断和可恢复的,相当于下载中的断点续传,更新操作对用户是透明的,在不影响用户操作的情况下完成升级。

设备可以设置数据下载、更新升级的场景和策略,例如:

只有在WiFi连接时才下载数据
电量较少时不下载数据、不进行更新
用户没有活动时才进行数据下载和更新等
具体有哪些策略依赖于开发者和用户的设置。

Android A/B System OTA分析(一)概览【转】的更多相关文章

  1. android recovery 主系统代码分析

    阅读完上一篇文章: http://blog.csdn.net/andyhuabing/article/details/9226569 我们已经清楚了如何进入正常模式和Recovery模式已有深刻理解了 ...

  2. android recovery 主系统代码分析【转】

    本文转载自:http://blog.csdn.net/andyhuabing/article/details/9248713 阅读完上一篇文章: http://blog.csdn.net/andyhu ...

  3. (转)Android 系统 root 破解原理分析

    现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的 原理吗?root破解的本质是什么呢?难道是利用了Lin ...

  4. [Android]Android系统启动流程源码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html Android系统启动流程源码分析 首先 ...

  5. Android 系统 root 破解原理分析 (续)

    上文<Android系统root破解原理分析>介绍了Android系统root破解之后,应用程序获得root权限的原理.有一些网友提出对于root破解过程比较感兴趣,也提出了疑问.本文将会 ...

  6. Android权限说明 system权限 root权限

    原文链接:http://blog.csdn.net/rockwupj/article/details/8618655 Android权限说明 Android系统是运行在Linux内核上的,Androi ...

  7. 阿里早期Android加固代码的实现分析

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/78320445 看雪上有作者(寒号鸟二代)将阿里移动早期的Android加固进行了逆 ...

  8. 1.Android 视图及View绘制分析笔记之setContentView

    自从1983年第一台图形用户界面的个人电脑问世以来,几乎所有的PC操作系统都支持可视化操作,Android也不例外.对于所有Android Developer来说,我们接触最多的控件就是View.通常 ...

  9. Android Studio导入System Library步骤

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6242170.html 请尊重知识产权!!!  同步更新到CSDN:http://blog.csdn.net ...

随机推荐

  1. 继续了解Java的纤程库 – Quasar

    前一篇文章Java中的纤程库 – Quasar中我做了简单的介绍,现在进一步介绍这个纤程库. Quasar还没有得到广泛的应用,搜寻整个github也就pinterest/quasar-thrift这 ...

  2. Spring 实战 第4版 读书笔记

    第一部分:Spring的核心 1.第一章:Spring之旅 1.1.简化Java开发 创建Spring的主要目的是用来替代更加重量级的企业级Java技术,尤其是EJB.相对EJB来说,Spring提供 ...

  3. MySQL--使用mysqldump进行数据库版本升级

    在MySQL跨版本升级时,建议使用mysqldump方式导出用户权限和用户数据,即使是小版本升级,导出过程中也应忽略系统数据库,避免系统表不兼容. 导出用户数据库脚本和用户创建脚本 ##======= ...

  4. 【Docker】docker的安装和常用命令

    一.docker安装和启动 1.yum 命令 yum install docker 2.docker启动命令 sudo systemctl start docker 二.docker常用命令 dock ...

  5. golang之reflection

    反射就是程序能够在运行时检查变量和值,求出它们的类型. reflect包实现运行时反射. 创建一个接收任何数据类型任何数值的查询string: func createQuery(q interface ...

  6. C# 获取操作系统空闲时间

    获取系统鼠标和键盘没有任何操作的空闲时间 public class CheckComputerFreeState { /// <summary> /// 创建结构体用于返回捕获时间 /// ...

  7. 长为N的数组,元素范围是0-N-1,其中只有一个数是重复的,找出这个重复元素

    思路:如果限制空间复杂度为O(1),我们就无法采用哈希表的方法去求解.题目中数组中所以数字都在范围[0, N-1],因此哈希表的大小为N即可.因此我们实际要做的就是对N个范围为0到N-1的数进行哈希, ...

  8. vue 的computed 和 watch 两者的区别

    computed是计算属性,依赖其他属性计算,并且computed的值有缓存,只有当计算值发生变化才会返回内容. computed 用来监控自己定义的变量,该变量不在data里面声明,直接在compu ...

  9. [Javascript] Use requestIdleCallback to schedule JavaScript tasks at an optimal time

    JavaScript is single-threaded, which can present some problems when creating an interactive user exp ...

  10. LeetCode 1000. Minimum Cost to Merge Stones

    原题链接在这里:https://leetcode.com/problems/minimum-cost-to-merge-stones/ 题目: There are N piles of stones ...