正确的刷机观

 

         前面几个blog贴了很多网址,虽然也有自己总结的东西,并以刷机角度去总结分析,但是没有新东西究竟意义不大,一想到这就感觉该系列blog低了逼格。的确做了不同的工作,而这略为不同的工作,虽然没有专利限制,但也算方案。为增加blog分量,这里就随意介绍下,没有源码,没有截图,只有思想,别人碰到后也自然想到,无技术难点。

正确的刷机观

本blog以分区表改变情况,做升级方案分析,以升级方式划分各节。

先来看看分区表文件gpt_main0.bin

正确的刷机观

没有源码的话也是能看出dtbo_a起始地址0x000E1000结束地址0x000E4FFF。同时GPT(分区表)里面包括AB系统的活动分区、正常启动次数等信息,还有sectool签名、时间戳信息,不可直接修改编辑。一般GPT的最后分区是userdata,并且分区大小为-1,驱动会识别emmc大小,重写GPT,让userdata使用所有剩余空间。

 

  1. QFIL升级

提供全部镜像,直接全部擦写,没啥好说。

下面是xml文件label="PrimaryGPT"内容,详细解释可见升级方式QFIL部分。

<program SECTOR_SIZE_IN_BYTES="512" file_sector_offset="0" filename="gpt_main0.bin" label="PrimaryGPT" num_partition_sectors="34" physical_partition_number="0" size_in_KB="17.0" sparse="false" start_byte_hex="0x0" start_sector="0" />

 

         NV(MP的数据和无线调试参数)备份,

         方法1,有tool->QCN backup按键。

方法2,有partition Manager选择modemst1modemst2fsg分区read

         方法3configuration->FireHose configuration->Auto backup Restore QCN (读取后重写入)/Auto preserve(不动这几个分区)

 

  1. fastboot 升级

fastboot flash partition gpt_both0.bin刷完后分区表的信息即时替换,需要立即刷入其它所有镜像,不刷重启后由于起始位置改动,无法获取aboot、boot甚至sbl1的信息,设备无法开机,恢复只能靠硬件进入紧急下载。

假如NV所使用分区起始位置不动,刷写过程中也不擦除,NV数据是可以保留的。

假如NV所使用分区起始位置改动,由于fastboot不支持读分区,故NV无法通过fastboot备份。

正确的刷机观

         起始位置、结束位置没动的modem和NV分区,其数据是可以保留的。手绘省时,会意即可。

 

再就是,userdata分区数据copy到其它设备后,用户数据依然有效,没有密码甚至可以直接挂载。其它分区的用户数据影响较小,若要想用户数据尽量完整可用,copy前后设备的版本最好一致,提供的userdata使用空间必须大于copy的。为防止用户数据被copy窃取,应该要求用户设置开机密码。

 

  1. OTA升级

 

3.1 nonAB的OTA升级情况

nonAB升级流程是recovery调用OTA包中的update-binary二进制执行程序,解析updater-script脚本,按该脚本流程升级。

官网https://source.android.com/devices/tech/ota/nonab

详细了解nonAB的OTA升级流程的看下面这系列的blog比较好

https://blog.****.net/huangyabin001/article/details/43731545

 

google源生代码的updater(即update-binary二进制执行程序,源码位置bootable\recovery\updater)是不带修改GPT的,方案商有修改GPT方案,提供GPT修改库。

假如GPT只是签名和时间戳信息改动,可以对比关键分区的起始位置、结束位置来确定是否替换GPT。

假如GPT中NV所使用分区起始位置和结束位置不动,升级过程中不擦除,NV数据也是可以保留。

假如改动很大,需要备份NV,可以在bootable\recovery\updater源码中添加函数,复制NV分区数据至tmp目录,替换GPT后再写入。

 

NOTE:

OTA升级按需求还可以添加sparse库,并在updater/install.cpp源码中编写函数,就可以支持sparse格式镜像的刷写,这种方法可加快文件系统格式镜像的刷写。sparse格式实际是文件系统一种压缩格式,无法用diff工具差分对比,在制作差分包时该类文件应该直接刷写。python源码有指定后缀类型不做diff。

脚本在android 7.1往android 4.4降级时,由于库的不兼容(准确来讲,新版本往旧版本升级时,旧版本是无法知道新版本改动的),导致getprop无法读取设备属性。这时流程上可以使用源码提供的file_getprop接口,通过挂载system再读build.prop文件里面的属性。

 

可以看到nonAB的这种OTA升级模式,在升级过程中SELinux给予updater-binary权限很大,包括可读写方式挂载system/vendor、可读写分区、可修改GPT等。同时update-binary执行程序的库可自己加,接口可自己写,流程updater-script可自己定,具有极高的功能*和流程*。之前很多**刷机都是通过recovery的OTA升级来完成,因此OTA包的签名需要保护好。

 

3.2 AB的OTA升级情况

AB系统升级是调用system/bin/update_engine,解压payload.bin文件,刷写到另外一个slot,和上面nonAB方式明显不同,无法使用自己的升级程序,无法按照自己定义流程来升级。就这两点对于AB系统来说,意味着更安全。同时利用两个slot,可以后台升级,可以断点续传,可以保证稳定性等等。

update_engine的确有足够权限去刷写非AB的分区,修改GPT。但你无法修改已经在系统里面的update_engine执行程序,无法控制流程,同时你在改GPT后,你的程序读写所有起始位置变了的分区都会有问题。

当然你可以微改,能改多少可以慢慢验证。但这里没有研究。

 

         AB系统的GPT修改通用的方式是什么呢?

显然你需要进入和recovery一样的干净的升级环境;需要按自己流程刷写设备;当然跑自己的升级程序最好不过。

正确的刷机观

达叔:“没错!”,最简单方式是使用nonAB的OTA升级包与升级流程。

那么流程基本就是替换recovery,替换GPT,刷写新系统。总共是三步两个OTA包一个GPT。这个新系统*度很高,AB or nonAB,GPT自定,版本自定等等。

如果对nonAB的OTA升级比较熟,可以将替换GPT和刷写新系统变成一步,GPT可放入后刷的nonAB的OTA包中。如果aboot和misc作用比较熟,第一个AB格式的OTA包升级完成后,替换recovery同时改写下aboot和misc分区,实现重启立即进入recovery升级第二个nonAB格式的OTA包。那整个流程,操作就变成一步。加上AB的OTA包与nonAB的OTA包差异很大,完全可以放一个包中。最后,可以一个包一个操作,实现改GPT式全刷写。

调试时注意:nonAB的recovery在AB的分区下跑(无cache/recovery等分区),需要修改recovery的挂载表和日志位置。且执行程序update-binary需要3.1中提到的sparse支持,GPT修改,NV备份等能力。再然后就是updater-script不能用源生的,需要自己编写。最后要点是本方案仅供讨论,挂掉自负,哈哈哈。

 

这种OTA改GPT需求比较扯淡,实际用到比较少,加上文笔新奇,只有文字,当然传得少也好。

下篇blog比较有用,新玩意,也算是趋势,而且有图。