OTA官网介绍:
https://source.android.com/devices/tech/ota/
OTA–卡刷全包、差分升级包制作、分析

1 .OTA升级流程框架

标准的OTA升级流程包括一下几个步骤:
1).Android设备首先会与OTA服务器进行交互,如果有更新会推送给客户。推送的信息常常会包含OTA更新包的下载地址和一些版本信息。
2).Update程序会将更新包下载到cache分区下,并提醒用户安装更新。
3).设备会重启进入recovery模式,同时启动recovery分区下运行环境,不再启动boot分区下的运行环境。
4).recovery运行环境初始化时会启动recovery二进制程序并根据/cache/recovery/command中的命令对更新包进行下一步操作。
5).Recovery运行环境对更新包中/res/key的签名进行校验,如果校验失败会中断升级。
6).Recovery二进制程序会对更新包中的数据进行解压同时根据解压出的数据对boot、system、和vender分区进行相应的更新。对system分区的更新也同时包含了新的recovery分区的更新。
7).重启设备
a.载入新的boot分区,并执行升级后的system分区中的二进制文件。
b.系统启动时会同时校验recovery分区,如果recovery与升级时保存在system分区下的信息不一致会对recovery进行更新。
8).系统更新完成。

2、OTA全包、差分包制作步骤

在源码目录下新建文件夹OTA

1、source build/envsetup.sh。

2、 lunch 然后选择需要的配置。

3、make 编译

4、 make otapackage。

5、拷贝out/target/product/(项目名)/ (项目名)-ota-eng.(用户名).zip到OTA并 且重命名A1.zip

6、拷贝out/target/product/(项目名)/obj/PACKAGING/target_files_intermediates/(项目名)-target_files-eng.(用户名).zip到OTA并重命名A2.zip

7、修改源码添加一个log信息,然后删除out/target/product/(项目名)/system/build.prop

8、source build/envsetup.sh

9、 lunch 然后选择配置。

10、make 编译

11、make otapackage。

12、拷贝out/target/product/(项目名)/ (项目名)-ota-eng.(用户名).zip到OTA并且重命名B1.zip

13、拷贝out/target/product/(项目名)/obj/PACKAGING/target_files_intermediates/(项目名)-target_files-eng.(用户名).zip到OTA并重命名B2.zip

14、制作差分包:

./build/tools/releasetools/ota_from_target_files.py -k build/target/product/security/testkey -i ./OTA/A2.zip ./OTA/B2.zip ./OTA/update.zip (A1.zip B1.zip 不能制作差分包)

15、现在OTA下有五个文件:A1.zip A2.zip B1.zip B2.zip update.zip

    其中A1.zip    B1.zip 是可以卡刷的全包,但是不能制作差分包A2.zip       B2.zip是不能卡刷的全包,但是能制作差分包。

16、拷贝到SD卡

17、平板链接:adb devices,adb reboot fastboot (recovery) 音量上下键选择和power键确认,调整进入recover 模式

18、差分包的升级一定要以A1.zip烧制的那个系统版本为基础
(按一下“音量下”键,选择“apply update from ADB”,然后按下电源键确认.

在命令行中输入"adb sideload update.zip"(ota.zip为自己命名的手机系统升级包)
adb sideload线刷 OTA 升级的方法)
19、System reboot

3、OTA制包过程理论分析,代码追踪

3.1、OTA本质
先以PC机进行类比。假设计算机操作系统装在C盘,当加电启动时,引导程序会将C盘的系统程序装入内存并运行,而系统升级或重装系统,则是将C盘中原来的系统文件部分或全部重写。对于手机及其上的Android系统而言,同样如此,需要一个存储系统文件的“硬盘”。

图1 是某款手机的存储设备结构图,其存储区(红色框图部分)分为四部分:SRAM、Nand Flash、SDRAM及外设地址空间。其中Nand Flash中存储着全部系统数据(通过专门的烧写工具将编译后的映象文件download到Nand Flash中,工具由IC厂商提供),包括boot.img、system.img、recovery.img等,因此Nand Flash即是上文所说的手机上的“硬盘”。图1最右部分(图中绿色框图部分)是Nand Flash存储区更详细的划分,我们将主要关注system分区(蓝色框图),因为OTA升级主要是对这部分系统数据的重写(当然boot分区也可升级)。除此之外,蓝黑色区域标示的misc分区也应值得注意,它在OTA升级中发挥着重要的作用。
OK,一言以蔽之,所谓OTA就是将升级包(zip压缩包)写入到系统存储区,因此我们需要考虑两个问题,1.升级包是如何生成的?2.升级包是如何写入到system分区的?

3.2、OTA制作代码流程图

3.3、整包的制作过程代码追踪
包有整包与差分包之分。顾名思义,所谓整包即包含整个system分区中的数据文件;而差分包则仅包含两个版本之间改动的部分。利用整包升级好比对电脑进行重作系统,格式分系统分区,并将新系统数据写入分区;而利用差分包升级不会格式化system分区,只是对其中部分存储段的内容进行重写。除升级包之外,制作过程中还会涉及到另一种zip包,代码中称之为target-files zipfile(out/target/product/(项目名)/obj/PACKAGING/target_files_intermediates/ (项目名)-target_files-eng. (用户名).zip),我称之为差分资源包。首先阐述下整包的制作过程。
系统经过整编后,执行make otapackage命令,即可完成整包的制作,而此命令可分为两个阶段进行。首先执行./build/core/Makefile中的代码:

1.   # -----------------------------------------------------------------
2.  # OTA update package
3.
4.  name := $(TARGET_PRODUCT)
5.  ifeq ($(TARGET_BUILD_TYPE),debug)
6.    name := $(name)_debug
7.  endif
8.  name := $(name)-ota-$(FILE_NAME_TAG)
9.
10. INTERNAL_OTA_PACKAGE_TARGET := $(PRODUCT_OUT)/$(name).zip
11.
12. $(INTERNAL_OTA_PACKAGE_TARGET): KEY_CERT_PAIR := $(DEFAULT_KEY_CERT_PAIR)
13.
14. $(INTERNAL_OTA_PACKAGE_TARGET): $(BUILT_TARGET_FILES_PACKAGE) $(OTATOOLS)
15.         @echo "Package OTA: $@"
16.         $(hide) ./build/tools/releasetools/ota_from_target_files -v \
17.            -n \
18.            -p $(HOST_OUT) \
19.            -k $(KEY_CERT_PAIR) \
20.            $(ota_extra_flag) \
21.            $(BUILT_TARGET_FILES_PACKAGE) $@
22. .PHONY: otapackage
23. otapackage: $(INTERNAL_OTA_PACKAGE_TARGET)
24. # -----------------------------------------------------------------  
        代码段1 make otapackage  目标代码生成差分资源包这段代码作用在于将系统资源(包括system、recovery、boot等目录)重新打包,生成差分资源包(即target-files zipfile,下文将统一使用“差分资源包”这一概念)。我们可以看下差分资源包中的文件结构,如下:

                图2 target-files zipfile目录结构

其中,OTA目录值得关注,因为在此目录下存在着一个至关重要的文件:OTA/bin/updater(后文会有详述)。生成的差分资源包被传递给./build/tools/releasetools/ota_from_target_files执行第二阶段的操作:制作升级包。

图3 ./build/tools/releasetools目录下的文件
图3是./build/tools/releasetools目录下所包含的文件,这组文件是Google提供的用来制作升级包的代码工具,核心文件为:ota_from_target_files和img_from_target_files。其中,前者用来制作recovery模式下的升级包;后者则用来制作fastboot下的升级包(fastboot貌似是一种更底层的刷机操作,未过多研究,不再详述)。其他文件则是为此二者提供服务的,比如,common.py中包含有制作升级包所需操作的代码;edify_generator.py则用于生成recovery模式下升级的脚本文件:<升级包>.zip/ META-INF/com/google/android/updater-script。
文件ota_from_target_files是本文所关注的重点,其中定义了两个主要的方法:WriteFullOTAPackage和WriteIncrementalOTAPackage。前者用于生成整包,后者用来生成差分包。接着上文,当Makefile调用ota_from_target_files,并将差分资源包传递进来时,会执行WriteFullOTAPackage。此方法完成的工作包括:(1)将system目录,boot.img等文件添加到整包中;(2)生成升级包中的脚本文件:<升级包>.zip/META-INF/com/google/android/updater-script;(3)将上文提到的可执行文件:OTA/bin/updater添加到升级包中:META-INF/com/google/android/updater-script。摘取部分代码片段如下:

1.   script.FormatPartition("/system")
2.    script. FormatPartition ("/system")
3.    script.UnpackPackageDir("recovery", "/system")
4.    script.UnpackPackageDir("system", "/system")
5.
6.    (symlinks, retouch_files) = CopySystemFiles(input_zip, output_zip)
7.    script.MakeSymlinks(symlinks)
8.    if OPTIONS.aslr_mode:
9.      script.RetouchBinaries(retouch_files)
10.   else:
11.     script.UndoRetouchBinaries(retouch_files)  
代码2 WriteFullOTAPackage代码片段生成全包

其中的script为edify_generator对象,其FormatPartition、UnpackPackageDir等方法分别是向脚本文件update-script中写入格式化分区、解压包等指令。

1.   def AddToZip(self, input_zip, output_zip, input_path=None):
2.      """Write the accumulated script to the output_zip file.  input_zip
3.      is used as the source for the 'updater' binary needed to run
4.      script.  If input_path is not None, it will be used as a local
5.      path for the binary instead of input_zip."""
6.
7.      self.UnmountAll()
8.
9.      common.ZipWriteStr(output_zip, "META-INF/com/google/android/updater-script",
10.                        "\n".join(self.script) + "\n")
11.
12.     if input_path is None:
13.       data = input_zip.read("OTA/bin/updater")
14.     else:
15.       data = open(os.path.join(input_path, "updater")).read()
16.     common.ZipWriteStr(output_zip, "META-INF/com/google/android/update-binary",
17.                        data, perms=0755)  
     代码段3  edify_generator中的AddToZip方法

WriteFullOTAPackage执行的最后会调用此方法。将资源差分包中OTA/bin/updater文件copy到升级包中META-INF/com/google/android/update-binary。此文件是OTA升级的关键,其将在recovery模式下被执行,用来将代码段2中生成的指令转换为相应的函数去执行,从而完成对系统数据的重写。

3.4、差分包的制作

生成差分包调用的是文件./build/tools/releasetools/ota_from_target_files中的WriteIncrementalOTA方法,调用时需要将两个版本的差分资源包作为参数传进来,形如:

./build/tools/releasetools/ota_from_target_files –n –i ota_v1.zip ota_v2.zip update.zip
其中,参数n表示忽略时间戳;i表示生成增量包(即差分包);ota_v1.zip与ota_v2.zip分别代表前后两个版本的差分资源包;而update.zip则表示最终生成的差分包。
WriteIncrementalOTA函数会计算输入的两个差分资源包中版本的差异,并将其写入到差分包中;同时,将updater及生成脚本文件udpate-script添加到升级包中。
制作完升级包后,之后便是将其写入到相应存储区中,这部分工作是在recovery模式下完成的。之前的几篇笔记亦有描述,recovery模式下通过创建一个新的进程读取并执行脚本文件META-INF/com/google/android/updater-script。见如下代码:

1.   const char** args = (const char**)malloc(sizeof(char*) * 5);
2.  args[0] = binary;
3.  args[1] = EXPAND(RECOVERY_API_VERSION);   // defined in Android.mk
4.  char* temp = (char*)malloc(10);
5.  sprintf(temp, "%d", pipefd[1]);
6.  args[2] = temp;
7.  args[3] = (char*)path;
8.  args[4] = NULL;
9.
10. pid_t pid = fork();
11. if (pid == 0) {
12.     close(pipefd[0]);
13.     execv(binary, (char* const*)args);
14.     _exit(-1);
15. }
16. close(pipefd[1]);  
    代码段4 创建新进程安装升级包

分析代码之前,首先介绍Linux中函数fork与execv的用法。
pid_t fork( void)
创建新的进程,fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
  1)在父进程中,fork返回新创建子进程的进程ID;
  2)在子进程中,fork返回0;
  3)如果出现错误,fork返回一个负值;
在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程(http://os.chinaunix.net/a2012/0203/1306/000001306508.shtml)。
int execv(const char *progname, char *const argv[])
execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变。
progname: 被执行的应用程序。
argv: 传递给应用程序的参数列表, 注意,这个数组的第一个参数应该是应用程序名字本身,并且最后一个参数应该为NULL,不参将多个参数合并为一个参数放入数组。
代码4见于bootable/recovery/install.c的try_update_binary函数中,是OTA升级的核心代码之一。通过对fork及execv函数的介绍可知,代码4创建了一个新的进程并在新进程中运行升级包中的META-INF/com/google/android/updater-binary文件(参数binary已在此前赋值),此文件将按照META-INF/com/google/android/updater-script中的指令将升级包里的数据写入到存储区中。OK,我们来看下META-INF/com/google/android/updater-binary文件的来历。
在源代码的./bootable/recovery/updater目录下,存在着如下几个文件:

图4 ./bootable/recovery/updater目录
通过查看Android.mk代码可知,文件install.c、updater.c将会被编译为可执行文件updater存放到目录out/target/product//obj/EXECUTABLES/
updater_intermediates/中;而在生成差分资源包(target-files zipfile)时,会将此文件添加到压缩包中。

1.   built_ota_tools := \
2.      $(call intermediates-dir-for,EXECUTABLES,applypatch)/applypatch \
3.      $(call intermediates-dir-for,EXECUTABLES,applypatch_static)/applypatch_static \
4.      $(call intermediates-dir-for,EXECUTABLES,check_prereq)/check_prereq \
5.      $(call intermediates-dir-for,EXECUTABLES,sqlite3)/sqlite3 \
6.      $(call intermediates-dir-for,EXECUTABLES,updater)/updater  
     代码段5 Makefile中定义的变量built_ota_tools
1.   $(hide) mkdir -p $(zip_root)/OTA/bin
2.      $(hide) $(ACP) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(zip_root)/OTA/
3.      $(hide) $(ACP) $(PRIVATE_OTA_TOOLS) $(zip_root)/OTA/bin/  
    代码段6 复制built_ota_tools工具到差分资源包

如代码段5,Makefile中定义了执行OTA所需要的一组工具(built_ota_tools),其中便包括由图4中文件编译而成的文件updater;而在生成差分资源包时,会将这组工具拷贝到差分资源包的OTA/bin目录中(见代码段6);在生成升级包时(无论是执行WriteFullOTAPackage还是WriteIncrementalOTAPackage),最后都会调用edify_generator的AddToZip方法,将updater添加到升级包中(更名为"META-INF/com/google/android/update-binary");最终在recovery模式下被执行,这便是其来龙去脉。而关于updater的执行,也大致的描述下吧。
由前文可知,updater主要由bootable/recovery/updater目录下的install.c和updater.c编译而成,主函数位于updater.c。其中,在install.c中定义了读写系统存储区的操作函数(这才是重写系统数据的真正代码)并将这些函数与updater-script中的指令映射起来。而在updater.c会首先装载install.c定义的函数,之后便解析升级脚本updater-script,执行其对应的操作命令。与此同时,执行updater的进程还会与父进程通信,通知父进程进行UI的相关操作(代码见bootable/recovery/install.c中的try_update_binary函数)。

参考文档:

1、OTA制作及升级过程笔记
http://blog.csdn.net/teliduxing1029/article/details/51536560#comments

2、OTA本质与实现流程分析
http://blog.csdn.net/bi511304183/article/details/9340175

OTA--卡刷全包、差分升级包制作、分析(代码摘自Google)---2相关推荐

  1. 从ota卡刷包recovery-from-boot.p生成recovery.img

    如果手机官方没有提供线刷包,和无法通过手机里面提取recovery情况下可以尝试提供卡刷包来生成官方recovery.img,当然你的OTA卡刷包里面必须要有boot.img.recovery-fro ...

  2. 魔百盒CM201-1、CM211-1朝歌ZG_支持UWE5621WiFi驱动_免拆卡刷固件包

    魔百盒CM201-1.CM211-1朝歌ZG_支持UWE5621WiFi驱动_免拆卡刷固件包 图片 刷机方法: 把下载的刷机包文件解压一次,复制到U盘根目录!update.zip升级包不能解压,原原本 ...

  3. 魔百盒M401A_晶晨S905L3A_2+16G_安卓9_原厂卡刷固件包及详细教程

    魔百盒M401A_晶晨S905L3A_2+16G_安卓9_原厂卡刷固件包及详细教程 固件特点: 1.采用江苏版401原厂卡刷包制作: 2.当贝桌面纯净版: 3.适用于晶晨S905L3A: 4.使用原机 ...

  4. EC6108V9/EC6108V9U/EC6108V92/EC6108V97_Hi3798MV100_当贝桌面_通刷_卡刷固件包

    EC6108V9/EC6108V9U/EC6108V92/EC6108V97_Hi3798MV100_当贝桌面_通刷_卡刷固件包-内有教程 特点: 1.适用于对应型号的电视盒子刷机: 2.开放原厂固件 ...

  5. CM201-2-CH-Hi3798MV300/MV310-当贝纯净桌面卡刷固件包

    CM201-2-CH-Hi3798MV300/MV310-当贝纯净桌面卡刷固件包-内有教程 特点: 1.适用于对应型号的电视盒子刷机: 2.开放原厂固件屏蔽的市场安装和u盘安装apk: 3.修改dns ...

  6. MG100-M101-UNT400B-MG101等_Hi3798MV100_当贝纯净桌面-卡刷固件包

    MG100-M101-UNT400B-MG101等_Hi3798MV100_支持RTL8188-RTL8723无线-当贝纯净桌面-卡刷固件包 特点: 1.适用于对应型号的电视盒子刷机: 2.开放原厂固 ...

  7. CM211-2-CH-通刷Hi3798MV300/MV310-当贝纯净桌面-卡刷固件包

    CM211-2-CH-通刷Hi3798MV300/MV310-当贝纯净桌面-卡刷固件包-内有教程 特点: 1.适用于对应型号的电视盒子刷机: 2.开放原厂固件屏蔽的市场安装和u盘安装apk: 3.修改 ...

  8. 海信IP202H-晨星9385芯片-9.0-免拆卡刷固件包

    海信IP202H-晨星9385芯片-9.0-免拆卡刷固件包 特点: 1.适用于对应型号的电视盒子刷机: 2.开放原厂固件屏蔽的市场安装和u盘安装apk: 3.修改dns,三网通用: 4.大量精简内置的 ...

  9. 浙江咪咕MGV3200_KLH_国科GK6323_2+8_免拆机卡刷固件包

    浙江咪咕MGV3200_KLH_国科GK6323_2+8_免拆机卡刷固件包 特点: 1.适用于对应型号的电视盒子刷机: 2.开放原厂固件屏蔽的市场安装和u盘安装apk: 3.修改dns,三网通用: 4 ...

最新文章

  1. 简述电子计算机的用途和特点_计算机基础试题及答案
  2. DB Query Analyzer 中断SQL语句的执行
  3. stylus之方法(Functions)
  4. DOM4J介绍与代码示例【转载】
  5. mysql查询所有姓王的信息_MySQL的查询练习
  6. Illustrator 教程,如何在 Illustrator 中描摹对象?
  7. 基于51单片机超声波测距仪设计倒车雷达防撞报警器
  8. 学习笔记-OS - Exploits
  9. 计算机策略组无法打开怎么办,Win10系统gpedit.msc组策略打不开怎么解决
  10. 常用的端口号(port number)
  11. win凭据添加计算机名,手动添加Windows凭据,彻底解决Win7系统打印共享-win7添加打印机...
  12. 开源项目推荐:我个人中意的Python/C++/.Net数学库(★精品收藏★)
  13. Cocos Creator 判断Touch位置在节点(Node)内
  14. 带一张阿拉旅游卡,随时出发
  15. DIN EN ISO 4589-2塑料 用氧指数法测定燃烧行为 第2 部分:室温试验
  16. WEIXIN day_08(8.25) 学子影院项目实践4
  17. 比 Hadoop 快至少 10 倍的物联网大数据平台,我把它开源了
  18. 利用SVD求得两个对应点集合的旋转矩阵R和转移矩阵t的数学推导
  19. java项目如何部署服务器-----如何传输文件到阿里云服务器(三)
  20. 产品价格及库存属性修改

热门文章

  1. 决策树(信息熵、信息增溢、GINI)的计算
  2. Linux Mint18分区方案
  3. php filter_sanitize_number_int,php – 我正确使用FILTER_VALIDATE_INT FILTER_SANITIZE_NUMBER_INT吗?...
  4. Dockerfile 构建镜像以及镜像优化的方法
  5. PW5410A原厂低噪声DC-DC升压开关电容倍压器
  6. excel如何把多张表合并成一个表_如何将多个excel表格合并成一个_excel多表合并到一种表格的方法...
  7. 【FXCG】展望2022人民币兑美元汇率走向何方
  8. ProE与UG的比较
  9. 戴文的Linux内核专题:03驱动程序
  10. QT 添加资源.qrc文件(My Sources File 图片 音频 支持翻译的.qm文件)