关于Android9.0 断电后升级问题排查分析

深入解析Android OTA升级:从架构原理到实战调试 系统升级是移动设备维护与功能演进的核心机制,其本质是通过安全可靠的方式更新设备固件。在Android生态中,OTA(Over-The-Air)技术实现了这一过程的远程自动化,其底层原理涉及Bootloader引导、分区管理、安全校验与差分算法等多个技术模块的协同。从技术价值看,OTA不仅保障了系统安全性与功能迭代,还通过A/B分区、动态分区等机制极大提升了升级过程的可靠性与用户体验。在应用场景上,无论是手机厂商的系统推送、第三方ROM定制,还是物联网设备的固件更新,都深度依赖OTA技术栈。本文将聚焦Andr 阅读详情

最近遇到一个项目Android 9.0的,很多机器出现了开机dm-verify error的错误,排查了很久,做了大量的测试,在此坐下记录分析流程

1.问题复现

2.问题排查

3.问题解决

 

一.问题复现

起初的信息并不全,升级的log也是全部跑完了,正好过年期间看了下updaer断电后升级的机制,年后重新看这个问题,发现升级的log其实都是retry的,也就是升级中间关机过

测试了下发现差分包升级过程中强制关机,问题必现

 

二.问题排查

实际测试发现整包升级没有该问题,那就看下差分包于整包实际的区别,两方面排查

 

驱动部分

1.之前遇到过开机起不来 大部分是preloader或者lk升级问题,把整包的驱动部分全部替换到差分包里,测试失败

2.再次操作升级包,把升级驱动部分提前,放在升级system和vendor前面,测试失败

 

system损坏

如果驱动部分一样了还是不行,那不用说了,就是system升坏了

其实发现system有问题也是老老实实自己按步骤测试出来的

1.按照复现路径测试

2.升级失败后单刷问题,一直到刷system才真正起来,说明system升挂了

3.回读出system与正常target做对比,发现transfer.list里面从恢复处开始,后面执行new的文件不一致了,为了排除是偶然因素,开始尝试从不同处中断

4.是从百分之40 差不多system 的transfer.list走了1000行 后面执行new的部分 数据跟target包里的都不一样

5.后面从60% 80% 一层层中断,结果就是 留下最后那个需要new的文件不一样

6.最后一次是85%左右,system升级完成了,开始升级vendor,我中断后起来继续升级就报错了,因为升vendor用了很多cache的空间,实际对比vendor也确实有很多不一样的, 单刷也正常开机了

 

结论就是恢复升级后执行new的部分写入流程有问题

 

三.问题解决

解决问题中间一个朋友给了一份谷歌的patch

updater: Fix an issue when resuming an update.

We cannot skip "new" commands while resuming an update with
last_command_file, because they read in the data sequentially from the
package.

Bug: 69858743
Test: Interrupt an update that has new commands. Check the update log.
Change-Id: I05fb67246f5ea3ba2a0f78f10255c0d9b0bc2f5a
diff --git a/updater/blockimg.cpp b/updater/blockimg.cpp
index d767d44..7b98f7f 100644
--- a/updater/blockimg.cpp
+++ b/updater/blockimg.cpp
@@ -1730,8 +1730,12 @@
       continue;
     }
 
-    // Skip all commands before the saved last command index when resuming an update.
-    if (params.canwrite && params.cmdindex != -1 && params.cmdindex <= saved_last_command_index) {
+    std::string cmdname = std::string(params.cmdname);
+
+    // Skip all commands before the saved last command index when resuming an update, except for
+    // "new" command. Because new commands read in the data sequentially.
+    if (params.canwrite && params.cmdindex != -1 && params.cmdindex <= saved_last_command_index &&
+        cmdname != "new") {
       LOG(INFO) << "Skipping already executed command: " << params.cmdindex
                 << ", last executed command for previous update: " << saved_last_command_index;
       continue;
@@ -1748,7 +1752,6 @@
     if (!params.canwrite && saved_last_command_index != -1 && params.cmdindex != -1 &&
         params.cmdindex <= saved_last_command_index) {
       // TODO(xunchang) check that the cmdline of the saved index is correct.
-      std::string cmdname = std::string(params.cmdname);
       if ((cmdname == "move" || cmdname == "bsdiff" || cmdname == "imgdiff") &&
           !params.target_verified) {
         LOG(WARNING) << "Previously executed command " << saved_last_command_index << ": "

合入后测试发现这个问题解决了,显然我之前看updater部分的时候漏了比较重要的信息

1.调用install_package方法中retry=1,判定为恢复升级

2.校验阶段,会解析transfer.list,move.bisdiff部分如果校验发现已经是升级后的block,则判定校验通过,对于stash部分,优先从上次保存的stash数据中读取进行校验

3.写入阶段,依然会解析transfer.list,首次升级过程中保存了last_command_index,会从中断处继续执行写入,已经写入成功的部分会被跳过

 

这里的意思是 如果单行在transfer.list 在last_command_index之前,增加了如果是new的情况 不会跳过,会再执行一次

 

优化的方案显然与我最后分析的结果大致吻合,虽然没有看代码,大致意思相当于,执行new的部分会从system.new.dat文件中按顺序读取,如果在last_command_index之前new被跳过,后面的还是从头写入了,这样就全部写错了

实际在失败的last_log里也看到有这样一句打印

new data receiver is still available after executing all commands.执行完了所有的new发现还有剩余

 

四.总结

问题是解决了 ,只不过好像啥事都没做.对于这种dm-verify error的问题,如果没有遇到过还是两方面排查

1.失败后单刷,那个能起来 就是那个失败了

2.挨个回读进行确认,确认是那个镜像的问题

3.多做测试对比,概率性问题尽量找到必现路径

创维E900V21盒子刷机实战:安卓9固件优化与鸿蒙架构解析 在嵌入式系统与智能硬件领域,固件刷写是赋予设备新生的关键技术。其原理在于通过底层引导程序(Bootloader)与设备建立通信,将经过优化的系统镜像写入存储芯片,从而替换原有操作系统。这项技术的核心价值在于突破厂商限制,释放硬件潜能,提升系统流畅度与应用兼容性。在智能电视盒子这类设备上,老旧设备常因原厂系统臃肿、功能受限而体验不佳,通过刷入定制固件可有效解决此问题。本文以创维E900V21系列盒子为例,深入探讨基于安卓9.0的深度定制固件,该固件集成了当贝桌面与乐家桌面,并优化了内存调度与GPU驱动,显著提 阅读详情

相关推荐

海信IP501H刷机全攻略:从GK6323V100C救砖到免拆升级9.0系统(附固件下载)

本文提供了海信IP501H机顶盒基于GK6323V100C芯片的详细刷机指南。内容涵盖从救砖强刷到免拆升级Android 9.0系统的完整流程,包括固件选择、短接操作、ADB调试等关键步骤与风险提示,并附有实用的疑难排解与优化建议,帮助玩家安全解锁设备潜能。

a1b2c3d的博客 797

深入理解dm-verity机制

近期做的一个项目,由于客户对安全性要求比较高,涉及到文件系统校验的问题,起初是在ramdisk中挂载rootfs后对所有重要的文件检查sha256,但是随着rootfs的逐步增大,发现校验花费的时间太长,竟然达到十几秒,于是就想改用一种方案,首先想到的是整个rootfs校验后在挂载,这样肯定是比一个文件一个文件校验要来得快些,但是项目中用的是nandflash,并不是EMMC,所以文件系统只能采用...

whuzm08的专栏 4万+

保姆级教程:海信IP501H机顶盒GK6323芯片救砖指南,从4.4.2卡刷到9.0免拆升级全流程

本文提供海信IP501H机顶盒GK6323芯片的救砖与升级全攻略,涵盖从4.4.2系统救砖到免拆升级Android 9.0的详细流程。通过短接强刷和ADB调试方案,帮助用户解决黑屏、卡LOGO等问题,并提升设备性能。教程包括工具准备、操作细节及刷机后优化设置,确保安全高效完成升级。

weixin_33743248的博客 400

android 设备写入文件,立即断电重启后,文件丢失

在android开发的过程中碰到写入文件后,立即断电重启,发现写入的文件丢失了 写入时检查了,写入是没有失败的,经过查找资料可能是如下问题引起:   Linux/Unix系统中,在文件或数据处理过程中一般先放到内存缓冲区中,等到适当的时候再写入磁盘,以提高系统的运行效率。 可能是因为断电时,文件没有写入的物理介质中导致,解决办法如下:        在write/fwrite写

Winter专栏 3316

瑞芯微RK3399K Android 10固件升级实战:从MaskRom模式到分区镜像烧写

本文详细介绍了瑞芯微RK3399K设备在Android 10固件升级过程中的实战操作,包括MaskRom模式救砖、工具链搭建、全盘与分区烧写技巧及常见错误解决方案。通过具体步骤和命令示例,帮助开发者高效完成固件升级,特别适合遇到设备变砖或需要定制分区的用户。

514

嵌入式开发实战:手把手教你为STM32 MCU实现差分OTA升级(基于BSDiff算法)

本文详细介绍了如何在STM32 MCU上实现差分OTA升级,基于BSDiff算法显著减少数据传输量。通过优化的双区Flash设计、断电安全状态机和内存高效处理,解决了嵌入式环境下的三大挑战。实战数据显示,差分升级仅需87KB传输量,比整包升级节省83%带宽,同时提升可靠性至99.6%。

weixin_30655569的博客 398

Android 中的dm-verity

Android 中的Verified Boot之dm-verity之前做了一个Verified Boot模块相关的工作,但是在网上只有找到google的文档和一个nexus的patch。虽然有patch,但在不同版本的代码上实现起来却可能有一些bug,所以特此记录一下debug这个东西的过程。之前debug的过程一直没找到问题,归根到底还是这个原理没搞清楚就下手,所以我分成原理,接口和应用来说明dm

u011280717的博客 5万+

瑞芯微平台批量固件升级实战:Topeet RK Flash工具全解析

在嵌入式开发与设备管理中,固件升级是核心环节,尤其当设备数量达到数十甚至上百台时,传统手动方式效率低下且易出错。固件升级工具通过整合底层烧写协议,将分散的手动操作标准化,其技术价值在于实现流程的工程化与自动化。从原理上看,这类工具通常基于芯片厂商提供的底层协议(如Rockchip的rkdeveloptool),通过封装和增强,支持多种升级模式。其核心应用场景覆盖研发调试、产线批量生产、现场维护等全生命周期。本文聚焦迅为Topeet RK Flash工具,深入讲解其如何通过**批量升级**和**离线部署**功

weixin_33997389的博客 479

DM-Verity整体流程

2.2.2 sudo veritysetup format A_1_6_gos0-fs_targetfs.img A_1_6_gos0-fs_targetfs.img --data-blocks 5767168 --hash-offset 23622320128 (生成文件data+hash)2.2 进入nv产出包 out_new1 在tii-a 和tii-b 生成加密 A_1_6_gos0-fs_targetfs.img。2.1 制作nv包,获得 A_1_6_gos0-fs_targetfs.img。

smj15263180896的博客 1916

Android原生SQLite实战:高并发、事务控制与生产级避坑指南

SQLite是Android本地数据存储的基础关系型数据库引擎,其核心原理基于ACID事务、B-tree索引与WAL日志模式。掌握原生SQLite不仅关乎CRUD实现,更决定App在高并发写入、跨表强一致性、动态Schema等关键场景下的稳定性与性能上限。相比Room等抽象层,原生方案提供对事务粒度、PRAGMA配置、锁机制和底层I/O的直接控制能力,适用于医疗、金融及实时监控类应用。本文聚焦真实项目中的SQLite实践——从抗压型OpenHelper设计、WAL模式调优、单线程Executor线程安全方案

weixin_34416649的博客 451

小米秋招手机测试笔试题解析:核心考点与测试思维

手机测试是移动互联网质量保障的关键环节,其核心在于理解Android系统底层原理、硬件参数、通信协议与用户场景的复杂交织。从系统架构到电池充电特性,从射频信号到OTA升级,测试工程师需要具备分层排查思维和边界条件敏感度,才能精准定位问题。掌握测试用例设计方法,覆盖冷启动、蓝牙兼容性、弱网环境等真实场景,是手机测试的基本功。本篇文章以小米2019秋招手机测试笔试题为样本,拆解笔试背后的能力模型,探讨如何从系统底层到用户场景构建完整的测试方案,帮助读者理解手机测试工程师的核心素养与面试考察要点。

weixin_30698527的博客 407

嵌入式升级包本质与安全升级实操指南

嵌入式升级包并非普通软件安装包,而是融合签名验证、差分补丁与硬件状态迁移的可信镜像。其原理涉及U-Boot启动链校验、eMMC闪存页擦写特性、Linux内核缓存刷新机制及A/B分区原子切换逻辑。技术价值在于保障生产环境零宕机升级能力,支撑IoT设备OTA、车载系统固件迭代与边缘节点批量运维等高可靠场景。本文聚焦升级包结构解析、dd命令参数优化、三重校验机制及S级风险防控,覆盖.bin/.img/.ota等典型格式,直击签名验证失败、断电变砖、版本错配等高频故障根因。

weixin_34080571的博客 330

android app断电强制保存数据到磁盘(解决断电数据丢失的问题)

在应用开发中,保存数据一般会用到SharedPreferences和Settings.system来保存数据,而有的时候,保存的数据在断电关机的时候会丢失 所以就尝试用文本读写的方式保存数据 FileOutputStream流保存数据的时候 在关机前可以将缓存数据及时写入磁盘 1.写入数据 public void saveMusicPath(String musicpath){ /* Java 示例代码 */ FileOutputStream fostream = null; try { fos

安卓兼职framework和app工程师的博客 3447

android车载面试题-1,主题语音

以上题目覆盖系统层开发、语音算法集成、车控协议对接等核心领域,建议候选人重点准备Framework层定制、车载语音全链路实现、车规级稳定性保障等方向。实际面试中可根据项目经历侧重追问具体实现细节。

Adversity reveals genius; fortune conceals it. 1018

高通Android设备FT5626触控驱动完整工程包(含手势识别、ESD防护与Flash在线升级)

专为高通平台Android 8.0+系统适配的FT5626电容式触控芯片驱动工程,提供可直接编译集成的Linux内核态源码。包含核心触摸处理模块(focaltech_core.c)、标准I2C通信层(focaltech_i2c.c)、低功耗手势识别支持(focaltech_gesture.c)、运行时ESD异常自动检测与恢复机制(focaltech_esdcheck.c)、安全Flash固件升级功能(focaltech_flash/目录下完整.c/.h实现),以及点报告校验逻辑(focaltech_poin

k9l0m1的博客 205

路畅A6车机固件V1.51刷机实战:从版本解读到完整升级流程

车载导航系统的固件升级是解决车机卡顿、导航闪退、蓝牙连接不稳定等问题的常用技术手段,其本质是通过更新底层系统镜像来重新匹配硬件与软件。一次成功的车机刷机,需要理解固件包命名中的平台码、导航模块、屏幕分辨率与内存大小等关键字段,也需要严格把控U盘格式、电源稳定性、版本兼容性等操作细节。掌握这些原理与流程,不仅能帮助车主规避变砖风险,也能让车载电子改装师傅在工程实践中少走弯路。本文以路畅A6平台GBDS导航模块256MB内存机型的V1.51固件为例,从版本解读、刷机前准备、完整升级步骤到常见问题排查,完整呈现一

weixin_29191081的博客 268

奥迪A4L升级第四代蓝牙数字钥匙:原理、安装与故障排查指南

蓝牙数字钥匙并非简单的蓝牙模块,它涉及低功耗蓝牙(BLE)、原车总线协议、云端授权与安全认证的深度融合。对于奥迪A4L这类带原厂防盗系统的车型,升级方案是否尊重原车协议决定了后续使用是否稳定。本文从数字钥匙的核心概念出发,解析BLE与车机蓝牙的差异、第四代产品的代际演进与安全特性,并结合奥迪A4L的硬件条件,介绍无损安装流程、App配置、蓝牙调试方法及日常故障排查技巧。无论是准备升级的车主,还是车联网开发工程师,都能从中理解“虚拟钥匙”从端到云的安全边界,避免因选型或安装不当导致的信号故障与安全隐患。

weixin_33858336的博客 349

SystemRDL:从寄存器描述到自动化生成的完整指南

本文详细介绍了SystemRDL如何通过“一份描述,多处生成”的理念,彻底解决芯片与FPGA设计中手动维护寄存器带来的不一致与低效问题。文章提供了从语言快速上手、核心组件讲解到使用PeakRDL工具链实现自动化代码与文档生成的完整实战指南,帮助硬件工程师构建高效、可靠的寄存器开发流程。

weixin_29243279的博客 659
上一篇: MTK 驱动部分双分区升级原理
下一篇: 七、recovery ota升级包签名生成/校验
李标标
博客等级 码龄11年 124粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值