当前位置: 首页 > news >正文

Android OTA 相关工具(一) 虚拟 A/B 之 snapshotctl

Android 虚拟 A/B 分区推出快三年了,不论是 google 还是百度结果,除了源代码之外,竟然没有人提到这个 Android Virtual A/B 的调试工具 ,着实让人感觉意外。

所以我相信还有不少人不知道 Android OTA 到底都有哪些调试工具,这些工具又该如何使用?所以决定开一个专栏,专门介绍 Android OTA 相关的各种工具。

本文为洛奇看世界(guyongqiangx)原创,转载请注明出处。
文章链接:https://blog.csdn.net/guyongqiangx/article/details/129122159

有下图为证,到目前位置,百度结果还没有 snapshotctl 相关内容:

百度搜索 snapshotctl 工具的结果

对于 snapshotctl,除了 Android 自家的开发者之外,肯定有下游开发者用过,但没有人分享过这个工具,因此本篇算是全网对 snapshotctl 介绍的第一篇,我相信还有不少人连这个工具都没有听说过。

本文基于 Android 代码版本: android-11.0.0_r21,但后续版本也大同小异

在线代码:http://aospxref.com/android-11.0.0_r21/

其实 snapshotctl 的工具使用并不复杂,源码也还算简单,代码位于:

system/core/fs_mgr/libsnapshot/snapshotctl.cpp

这里不再详细分析代码,主要演示 snapshotct 工具的使用。

1. snapshotctl 的功能

在早期版本(android-11.0.0_r21)中,snapshotctl 支持 dump 和 map 操作,后面又增加了 unmap 操作。

snapshotctl 的帮助信息:

console:/ # snapshotctl -h                                                     
snapshotctl: Control snapshots.
Usage: snapshotctl [action] [flags]
Actions:dumpPrint snapshot states.mergeDeprecated.mapMap all partitions at /dev/block/mapper
64|console:/ # 

2. dump 操作

dump 操作是 snapshtctl 最有用的操作,可以输出系统升级中的各种状态。

以下是我的一块板子上运行 snapshotctl dump 的输出:

console:/ # snapshotctl dump                                                   
snapshotctl W 10-10 21:43:54  3770  3770 snapshot.cpp:247] Cannot read /metadata/ota/snapshot-boot: No such file or directory
Update state: initiated
Compression: 0
Current slot: _a
Boot indicator: booting from unknown slot
Rollback indicator: No such file or directory
Forward merge indicator: No such file or directory
Source build fingerprint: google/inuvik/inuvik:11/RVC/eng.rocky.20221010.210616:userdebug/dev-keys
Snapshot: system_bstate: CREATEDdevice size (bytes): 1263079424snapshot size (bytes): 1263079424cow partition size (bytes): 119177216cow file size (bytes): 949866496allocated sectors: 0metadata sectors: 0compression: none
Snapshot: vendor_bstate: CREATEDdevice size (bytes): 80506880snapshot size (bytes): 80506880cow partition size (bytes): 0cow file size (bytes): 978944allocated sectors: 0metadata sectors: 0compression: none
console:/ # 

3. map 操作

如果升级中出现了问题,可以通过 snapshotctl map 操作把系统中的各种 base, cow 和 cow-img 等文件都映射成设备方便检查。

以下是一个映射示例:

console:/ # snapshotctl map
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2525] Successfully unmapped snapshot system_b
snapshotctl I 10-11 19:59:53  6127  6127 fs_mgr_dm_linear.cpp:247] [libfs_mgr]Created logical partition system_b-base on device /dev/block/dm-4
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:638] Mapped system_b-cow-img to /dev/block/dm-5
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2596] Mapped COW device for system_b at /dev/block/dm-6
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2490] Mapped system_b as snapshot device at /dev/block/dm-7
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2525] Successfully unmapped snapshot vendor_b
snapshotctl I 10-11 19:59:53  61[10577.688566] audit: rate limit exceeded
27  6127 fs_mgr_dm_linear.cpp:247] [libfs_mgr]Created logical partition vendor_b-base on device /dev/block/dm-8
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:638] Mapped vendor_b-cow-img to /dev/block/dm-9
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2556] Mapped COW image for vendor_b at vendor_b-cow-img
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2490] Mapped vendor_b as snapshot device at /dev/block/dm-10
snapshotctl I 10-11 19:59:53  6127  6127 snapshot.cpp:2741] MapAllSnapshots succeeded.
console:/ # 

上面的 map 操作映射了下面的文件:

console:/ # ls -lh data/gsi/ota/
total 454M
-rw------- 1 root root   26 2022-10-11 00:00 system_b-cow-img.img
-rw------- 1 root root 906M 2022-10-11 00:00 system_b-cow-img.img.0000
-rw------- 1 root root   26 2022-10-11 00:00 vendor_b-cow-img.img
-rw------- 1 root root 956K 2022-10-11 00:00 vendor_b-cow-img.img.0000

如果 super 空间有分配用于升级也会被映射,具体我还没有详细检查。

一旦映射了分区,就可以通过其它工具对升级的镜像进行检查了,例如使用 dmctl 工具查看映射的状态,如下:

console:/ # dmctl 
usage: dmctl <command> [command options]dmctl -f file
commands:create <dm-name> [-ro] <targets...>delete <dm-name>list <devices | targets> [-v]getpath <dm-name>getuuid <dm-name>info <dm-name>status <dm-name>resume <dm-name>suspend <dm-name>table <dm-name>help-f file reads command and all parameters from named fileTarget syntax:<target_type> <start_sector> <num_sectors> [target_data]
234|console:/ # dmctl table
Invalid arguments, see 'dmctl help'
234|console:/ # su
console:/ # dmctl list devices
Available Device Mapper Devices:
userdata             : 252:3
system_b             : 252:7
vendor_b             : 252:10
vendor_b-base        : 252:8
system_a             : 252:0
vendor_b-cow-img     : 252:9
vendor_a             : 252:1
system_b-base        : 252:4
system_b-cow-img     : 252:5
system_b-cow         : 252:6
scratch              : 252:2
console:/ # 
console:/ # dmctl info vendor_b-base
device        : vendor_b-base
active        : true
access        : rw 
activeTable   : true
inactiveTable : false
bufferFull    : false
console:/ # 
console:/ # dmctl info vendor_b-cow-img
device        : vendor_b-cow-img
active        : true
access        : rw 
activeTable   : true
inactiveTable : false
bufferFull    : false
console:/ # 
console:/ # 
console:/ # dmctl table vendor_b-cow-img
Targets in the device-mapper table for vendor_b-cow-img:
0-1912: linear, 259:4 6107136
console:/ # 
console:/ # dmctl table system_b-cow
Targets in the device-mapper table for system_b-cow:
0-888: linear, 259:3 2469000
888-232768: linear, 259:3 2627128
232768-2087976: linear, 252:5 0
console:/ #
console:/ # dmctl table system_b-cow-img
Targets in the device-mapper table for system_b-cow-img:
0-4096: linear, 259:4 569344
4096-8192: linear, 259:4 675840
8192-12288: linear, 259:4 1134592
12288-16384: linear, 259:4 1155072
16384-20480: linear, 259:4 1179648
20480-28672: linear, 259:4 1187840
28672-65536: linear, 259:4 1200128
65536-69632: linear, 259:4 1253376
69632-73728: linear, 259:4 1269760
73728-77824: linear, 259:4 1302528
77824-86016: linear, 259:4 1318912
86016-102400: linear, 259:4 1351680
102400-106496: linear, 259:4 1376256
106496-118784: linear, 259:4 1384448
118784-131072: linear, 259:4 1466368
131072-155648: linear, 259:4 1482752
155648-159744: linear, 259:4 1515520
159744-163840: linear, 259:4 1699840
163840-172032: linear, 259:4 1712128
172032-176128: linear, 259:4 1773568
176128-184320: linear, 259:4 1867776
184320-192512: linear, 259:4 2097152
192512-196608: linear, 259:4 2109440
196608-204800: linear, 259:4 2134016
204800-208896: linear, 259:4 2158592
208896-212992: linear, 259:4 2170880
212992-217088: linear, 259:4 2187264
217088-221184: linear, 259:4 2215936
221184-225280: linear, 259:4 2244608
225280-249856: linear, 259:4 2310144
249856-253952: linear, 259:4 2355200
253952-294912: linear, 259:4 2449408
294912-311296: linear, 259:4 2912256
311296-323584: linear, 259:4 4030464
323584-372736: linear, 259:4 4050944
372736-376832: linear, 259:4 4149248
376832-385024: linear, 259:4 4165632
385024-389120: linear, 259:4 4325376
389120-516096: linear, 259:4 4620288
516096-557056: linear, 259:4 4751360
557056-565248: linear, 259:4 4796416
565248-1855208: linear, 259:4 4812800
console:/ # 

4. unmap 操作

可以通过 snapshotctl unmap 将前面映射的分区卸载。

console:/ # snapshotctl unmap                                                  
snapshotctl I 10-11 19:59:48  6120  6120 snapshot.cpp:2525] Successfully unmapped snapshot system_b
snapshotctl I 10-11 19:59:48  6120  6120 snapshot.cpp:2525] Successfully unmapped snapshot vendor_b
console:/ # 

5. merge 操作

目前 snapshotctl 工具中的 merge 操作已经取消。

console:/ # snapshotctl merge
snapshotctl W 10-11 19:43:10  5986  5986 snapshotctl.cpp:66] Deprecated. Call update_engine_client --merge instead.
70|console:/ # 

这里的提示指出,如果需要进行 merge,可以通过命令:" update_engine_client --merge" 来进行。

所以,如果虚拟分区升级出现问题,可以先通过 snapshotctl dump 查看一些基本信息,然后通过 snapshotctl map 将所有虚拟分区设备映射出来进行检查,具体有哪些检查的手段,这个看每个人自己的工具储备了,也可以多关注我的博客"洛奇看世界(https://blog.csdn.net/guyongqiangx)",后面陆续为您分享更多 OTA 工具,包括一些洛奇自己开发的工具。

6. 其它

到目前为止,我写过 Android OTA 升级相关的话题包括:

  • 基础入门:《Android A/B 系统》系列
  • 核心模块:《Android Update Engine 分析》 系列
  • 动态分区:《Android 动态分区》 系列
  • 虚拟 A/B:《Android 虚拟 A/B 分区》系列
  • 升级工具:《Android OTA 相关工具》系列

更多这些关于 Android OTA 升级相关文章的内容,请参考《Android OTA 升级系列专栏文章导读》。

如果您已经订阅了动态分区和虚拟分区付费专栏,请务必加我微信,备注订阅账号,拉您进“动态分区 & 虚拟分区专栏 VIP 答疑群”。我会在方便的时候,回答大家关于 A/B 系统、动态分区、虚拟分区、各种 OTA 升级和签名的问题。

除此之外,我有一个 Android OTA 升级讨论群,里面现在有 400+ 朋友,主要讨论手机,车机,电视,机顶盒,平板等各种设备的 OTA 升级话题,如果您从事 OTA 升级工作,欢迎加群一起交流,请在加我微信时注明“Android OTA 讨论组”。此群仅限 Android OTA 开发者参与~

公众号“洛奇看世界”后台回复“wx”获取个人微信。

相关文章:

Android OTA 相关工具(一) 虚拟 A/B 之 snapshotctl

Android 虚拟 A/B 分区推出快三年了&#xff0c;不论是 google 还是百度结果&#xff0c;除了源代码之外&#xff0c;竟然没有人提到这个 Android Virtual A/B 的调试工具 &#xff0c;着实让人感觉意外。 所以我相信还有不少人不知道 Android OTA 到底都有哪些调试工具&#…...

QT for Android BLE Bluetooch QT BLE

小白式的介绍&#xff0c;很详细了&#xff0c;很多主要内容写在程序的注释里&#xff0c;慢慢看 下面是我的源码 https://download.csdn.net/download/qq_27620407/87464307 源码打不开的话可以试试下图的操作&#xff0c;之后电机确定&#xff0c;可能是加图标搞的&#xff0…...

【蓝桥集训】第四天——双指针

作者&#xff1a;指针不指南吗 专栏&#xff1a;Acwing 蓝桥集训每日一题 &#x1f43e;或许会很慢&#xff0c;但是不可以停下&#x1f43e; 文章目录1.字符串删减2.最长连续不重复子序列3.数组元素的目标和1.字符串删减 给定一个由 n 个小写字母构成的字符串。 现在&#xff…...

List<Map<String, Object>>的数据结构的添加和删除实例

对List<Map<String, Object>>的数据结构的添加和删除实例添加//初始化List<Map<String, Object>> products new ArrayList<Map<String,Object>>();//也可以这样初始化List<Map<String, Object>> products null//初始Map<…...

5.2 线程实际案例练习

文章目录1.概述2.实现方案一&#xff1a;继承Thread2.1 代码实现2.2 代码分析3.实现方案二&#xff1a;实现Runnable接口3.1 代码实现3.2 代码分析4.实现方案三&#xff1a;构建线程池4.1 代码实现4.2 代码分析1.概述 接下来我们通过一个售票案例的实际操作来深入理解线程的相…...

stm32f407探索者开发板(十七)——串口寄存器库函数配置方法

文章目录一、STM32串口常用寄存器和库函数1.1 常用的串口寄存器1.2 串口相关的库函数1.3 状态寄存器&#xff08;USART_ SR&#xff09;1.4 数据寄存器&#xff08;USART_ DR&#xff09;1.5 波特率寄存器&#xff08;USART_BRR&#xff09;二、串口配置一般步骤一、STM32串口常…...

山西省2023年软考报名3月14日开始

根据2023年上半年计算机技术与软件专业技术资格(水平)考试工作计划&#xff0c;可以得知&#xff0c;全国考务管理服务平台将于2023年3月13日开放&#xff0c;各地开始组织报名&#xff0c;如山西已发布2023上半年报名简章&#xff0c;从3月14号开始报名。 软考报名官网 大部…...

进程章节总结性实验

进程实验课笔记 本节需要有linux基础&#xff0c;懂基本的linux命令操作即可。 Ubuntu镜像下载 https://note.youdao.com/s/VxvU3eVC ubuntu安装 https://www.bilibili.com/video/BV1j44y1S7c2/?spm_id_from333.999.0.0 实验环境ubuntu22版本&#xff0c;那个linux环境都可以…...

【MyBatis】MyBatis的缓存

10、MyBatis的缓存 10.1、MyBatis的一级缓存 一级缓存是SqlSession级别的&#xff0c;通过同一个SqlSession查询的数据会被缓存&#xff0c;下次查询相同的数据&#xff0c;就会从缓存中直接获取&#xff0c;不会从数据库重新访问 使一级缓存失效的四种情况&#xff1a; 不…...

MyBatis基本使用

一、简介 MyBatis 中文文档 https://mybatis.org/mybatis-3/zh/index.html 1.什么是 MyBatis 概述&#xff1a;MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBa…...

如何运行YOLOv6的代码实现目标识别?

YOLOv6是由美团视觉团队开发的1.环境配置我们先把YOLOv6的代码clone下来git clone https://github.com/meituan/YOLOv6.git安装一些必要的包pip install pycocotools2.0作者要求pytorch的版本是1.8.0,我的环境是1.7.0&#xff0c;也是可以正常运行的pip install -r requirement…...

新品BCM6755A1KFEBG/MT7921LE/MT7921AU WiFi芯片

博通在WiFi市场具有相当的实力。在WiFi6上有下面这几个解决方案&#xff1a;型号&#xff1a;BCM6755 BCM6755A1KFEBG类型&#xff1a;四核1.5GHz CPU封装&#xff1a;BGA批次&#xff1a;新BCM6755和BCM6750还是A7架构&#xff0c;更多的用在中低端型号上。BCM6755和BCM6750 C…...

析构函数、拷贝构造

1、析构函数析构函数的定义方式函数名和类名相同&#xff0c;在类名前加~&#xff0c;没有返回值类型&#xff0c;没有函数形参&#xff08;不能重载&#xff09;当对象生命周期结束的时候&#xff0c;系统会自动调用析构函数先调用析构函数&#xff0c;再释放对象的空间析构函…...

光学镜头是制作过程阶段理解

光学镜头是由多组镜片组合而成&#xff0c;它是摄影机投影一及显微镜上必不可少的部件。那么光学镜头是如何制造的呢&#xff1f;光学镜头的制作分为以下四个阶段&#xff1a;第一、首先将一大块光学玻璃用钻石锯片进行切片&#xff0c;然后用钻头在每一块玻璃切片上钻出多块冰…...

实验室设计|实验室设计要点SICOLAB

一、实验室设计规划要素1、实验室布局&#xff1a;实验室的布局要符合实验室工作流程&#xff0c;可以将实验室划分为干净区和污染区&#xff0c;以确保实验室的卫生和实验的准确性。2、设备选购&#xff1a;根据实验需要选择适当的设备&#xff0c;并确保设备的质量和性能符合…...

I.MX6ULL_Linux_系统篇(16) uboot分析-启动流程

原文链接&#xff1a;I.MX6ULL_系统篇(16) uboot分析-启动流程 – WSY Personal Blog (cpolar.cn) 前面我们详细的分析了 uboot 的顶层 Makefile&#xff0c;了解了 uboot 的编译流程。本章我们来详细的分析一下 uboot 的启动流程&#xff0c;理清 uboot 是如何启动的。通过对 …...

【C#】async关键字修饰后有无await的影响

文章目录测试总结拓展&#xff1a;js的async await问题参考测试 来自微软官网的说法&#xff1a; 异步方法通常包含 await 运算符的一个或多个匹配项&#xff0c;但缺少 await 表达式不会导致编译器错误。 如果异步方法未使用 await 运算符标记悬挂点&#xff0c;则该方法将作…...

Interspeech2022 | 一种基于元辅助学习的低资源口语语义理解方法

中国移动研究院首席科学家冯俊兰博士带领人工智能与智慧运营中心语音团队共同撰写的文章《Meta Auxiliary Learning for Low-resource Spoken Language Understanding》被语音国际顶会Interspeech2022接收。 关于Interspeech Interspeech 是国际最大且最全面关于言语科学与技…...

File类的用法和InputStream,OutputStream的用法

这里写自定义目录标题一、File类1.构造方法2.普通方法二、InputStream1.方法2.FileInputStream3.Scanner类的应用三、OutputStream1.方法2.FileOutputStream3.PrintWriter类的应用一、File类 1.构造方法 签名说明File(File parent, Stringchild)根据父目录 孩子文件路径&…...

Java多线程——Thread类的基本用法

一.线程的创建继承Thread类//继承Thread类class MyThread extends Thread{Overridepublic void run() {System.out.println("线程运行的代码");} } public class Demo1 {public static void main(String[] args) {MyThread t new MyThread();t.start();//启动线程&a…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...