​ OTA(Over-the-AirTechnology)升级是指手机终端通过无线网络下载远程服务器上的升级包,对系统或应用进行升级的技术。

两种不同的OTA升级方式

传统OTA升级————Android M及之前的系统

​ 设备上有一个Android主系统和一个Recovery系统。正常开机状态下,Android主系统运行时与OTA服务器通讯,检测是否需要升级,如果需要升级,则将升级的数据包下载并存放到本地,重启系统后进入Recovery系统,并用下载到本地额OTA更新包更新Android主系统,更新完成后重启进入Android主系统。如果更新失败,设备重启后就不能正常使用了,唯一的办法就是重新升级,直到成功为止。

​ 因此传统OTA对应的闪存分区主要包含以下几个分区:

    • boot

      boot 分区中有Android的引导程序,包含了Linux内核和用来加载system分区和其他分区的ramdisk。该分区损坏会导致无法正确引导系统启动。

    • system

      system 分区中包含Android系统的系统应用、用户安装的应用和一些库文件。在正常操作期间,此分区被装载为只读分区,其内容仅在 OTA 更新期间更改。这个分区就是我们常说的系统,一般所说的刷机也主要是更改此分区的文件。

    • vendor

      vendor 分区中包含该设备硬件相关的库和驱动。在正常操作期间,此分区被装载为只读分区,其内容仅在 OTA 更新期间更改。熟悉 Project Treble 项目的同学应该对这个分区都有所耳闻。

    • userdata

      userdata 分区用来储存系统用户数据和用户安装的应用数据等相关数据文件,OTA更新一般不会更改该分区的数据。我们常说的清除数据就是清理该分区。

    • cache

      cache 分区用于存放一些系统缓存数据

    • recovery

      recovery 分区被认为是另一个相对独立的可启动分区,包含Linux内核和一套恢复系统。我们可以通过recovery格式化或恢复其他分区,通常所说的刷机就是通过该分区完成的

    • misc

      执行恢复操作时使用的微小分区,可在应用 OTA 更新包并重新启动设备时,隐藏某些进程的信息。

    A/B分区OTA更新————Android N及以后的系统

    ​ Android从7.0开始,引入了新的OTA升级方式 A/B System Updates。A/B系统是指设备上有A和B两套可以工作的系统(用户数据只有一份,为两套系统共用),我们可以理解为一套系统分区,另外一套为备份分区.其系统版本可能一样,也可能不一样;通过升级,可以将旧版本也更新为新版本。当然,设备出厂时这两套系统肯定是一样的。

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

    ​ 因此AB/分区的设备闪存主要包含以下分区:

    • bootloader

      存放用于引导linux的bootloader

    • boot_a和boot_b

      与前面的boot分区类似,只不过这里有两个独立的boot分区

    • system_a和system_b

      与前面的system分区类似,这里分别用于存放两套系统各自的应用程序和库文件。

    • vendor_a和vendor_b

      与前面的vendor分区类似

    • userdata

      与前面的userdata分区类似

    OTA升级

    非A/B系统OTA 更新包含以下步骤:
    1. 设备会与 OTA 服务器进行定期确认,并被告知是否有更新可用,包括更新软件包的 URL 和向用户显示的描述字符串。
    2. 将更新下载到缓存或数据分区,并根据 /system/etc/security/otacerts.zip 中的证书验证加密签名。系统提示用户安装更新。
    3. 设备重新启动进入恢复模式,引导恢复分区中的内核和系统启动,而非引导分区中的内核。
    4. 恢复分区的二进制文件由 init 启动。它会在 /cache/recovery/command 中寻找将其指向下载软件包的命令行参数。
    5. 恢复操作会根据 /res/keys (包含在恢复分区中的 RAM 磁盘的一部分)中的公钥来验证软件包的加密签名。
    6. 从软件包中提取数据,并根据需要使用该数据更新引导、系统和/或供应商分区。系统分区上其中一个新文件包含新恢复分区内容。
    7. 设备正常重启。 1.加载最新更新的引导分区,在最新更新的系统分区中装载并开始执行二进制文件。 2.作为正常启动的一部分,系统会根据所需内容(预先存储为 /system 中的一个文件)检查恢复分区的内容。二者内容不同,所以恢复分区会被所需内容重新刷写(在后续引导中,恢复分区已经包含新内容,因此无需重新刷写)。
    Tips:系统更新完后,可以在 /sdcard/cache/UpdaterData/update_log中找到更新的相关日志,例如收到OTA更新以后可以在这里看到OTA更新包的完整路径。不过OTA包会在更新后自动删除

    A/B系统的启动:

    1. 手机启动后,BootLoader会去读取slot metadata,来确定从哪个slot启动
    2. 检查是否有可启动的分区,如果没有则,直接进入bootloader的recovery mode(即bootloader下的刷机模式),一般是进入fastboot命令行.
    3. 如果有可启动的分区,则选择可启动分区中优先级最高的slot(例如,直接选择当前设置为active的分区)
    4. 检查所选择分区的retry count(retry count表示当前分区可以尝试启动的次数),

      如果retry count等于0启动成功(启动成功的分区会标记为successful),大于0则继续尝试从当前分区启动,并且累计递减,而小于0则将所选择分区标记为无效分区(通常设置为unbootable),然后重复第2步,查找下一个可以启动的分区

    5. 最后从当前slot的boot中启动Linux内核,并且挂载system和其他分区
    6. Linux启动后,通过dm-verify机制校验system分区,完成后加载system分区内包含的rootfs,通过/init程序解析/init.rc脚本,完成Android系统的启动

    非Android开发,以上内容整理自网络,欢迎Android大佬评论区纠错

    最后修改:2020 年 10 月 06 日 11 : 59 PM
    如果您觉得本文有帮助,且您手头手头宽裕,可以打赏小站,不胜感激