文章目录
- 1. payload_info.py 的使用
- 1. 环境
- 2. 帮助信息
- 2. 查看 payload 文件信息
- 1. 不带选项查看
- 2. 使用 stats 选项查看
- 3. 使用 signagures 选项
- 4. 使用 list_ops 选项查看
- 3. 其它
一直以来,很多人都表达过很想去研究一下 Android OTA 的 payload 文件,看看里面到底有什么,想对其进行一番研究操作,但又觉得 payload 文件很复杂,最终望而却步。
在很久很久的以前上古时代,确切说是 Android 7.1 刚引进 A/B 系统的时候,基本没有什么用于分析 A/B 系统和 payload 的工具,我根据 update_metadata.proto 文件画过一张 payload.bin 的文件结构图,如下(可以点击图片看大图):
图 1. Android 7.1 的 payload.bin 文件结构图
从 Anroid 7.1 到如今的 Android 13 系统,update_metadata.proto 文件几经变化,但大体结构仍然不变。
从 Android 10(Q) 的动态分区开始,update_engine 的代码中新增了一个名为 payload_info.py 的脚本,专门用于解析 payload.bin 文件并显示相关信息。
有了这个工具,我觉得你应该不需要再对 payload.bin 文件内容发愁了。
更多关于 Android OTA 升级相关文章的列表和内容,请参考《Android OTA 升级系列专栏文章导读》
如果您已经订阅了收费专栏,请务必加我微信,拉你进相应专栏的答疑群。
本文基于 Android 11® 上的 payload_info.py 工具介绍其用法。
1. payload_info.py 的使用
1. 环境
payload_info.py 脚本位于 system/update_engine/scripts
目录下,payload_info.py 的脚本内容很简单,就是通过 payload 的 proto 结构数据查看 payload.bin 文件的信息。
payload_info.py 脚本的功能依赖于这个目录下的一些其它脚本,所以最简单的办法是直接在这个目录下进行操作,或者把脚本目录 export 到环境变量 PATH 中即可。
export PATH=system/update_engine/scripts:$PATH
虽然如此,但我通常还是建议你像我下面这样使用:
# 执行 build/envsetup.sh 设置代码编译相关的环境
$ source build/envsetup.sh# 选择你感兴趣的编译配置,我这里直接用数字 46 指定,你也可以使用名称指定,如 'lunch aosp_arm64-eng'
$ lunch 46# 把 payload_info.py 变量加入到 PATH 环境变量中
$ export PATH=system/update_engine/scripts:$PATH
设置好环境以后,就可以使用 payload_info.py 工具了。
2. 帮助信息
$ payload_info.py --help
usage: payload_info.py [-h] [--list_ops] [--stats] [--signatures] payload_fileShow information about an update payload.positional arguments:payload_file The update payload file.optional arguments:-h, --help show this help message and exit--list_ops List the install operations and their extents.--stats Show information about overall input/output.--signatures Show signatures stored in the payload.
从这里可以看到,payload_info.py 支持的选项比较直观和简单,十分便于使用。
2. 查看 payload 文件信息
在这里,我查看一个 out/update 目录下差分包的 payload.bin 文件:
$ tree out/update
out/update
├── care_map.pb
├── META-INF
│ └── com
│ └── android
│ ├── metadata
│ └── otacert
├── payload.bin
└── payload_properties.txt3 directories, 5 files
1. 不带选项查看
$ payload_info.py out/update/payload.bin
Payload version: 2
Manifest length: 53885
Number of partitions: 6Number of "boot" ops: 67Number of "system" ops: 790Number of "vendor" ops: 42Number of "dtbo" ops: 4Number of "vbmeta" ops: 1Number of "vendor_boot" ops: 23Timestamp for boot: Timestamp for system: Timestamp for vendor: Timestamp for dtbo: Timestamp for vbmeta: Timestamp for vendor_boot: COW Size for boot: 0COW Size for system: 0COW Size for vendor: 0COW Size for dtbo: 0COW Size for vbmeta: 0COW Size for vendor_boot: 0
Block size: 4096
Minor version: 7
从这里可以看到,这个 payload.bin 中一共操作了 6 个分区,分别是 boot, system, vendor, dtbo, vbmeta 和 vendor_boot。每个分区又有自己的 install operations。
2. 使用 stats 选项查看
$ payload_info.py --stats out/update/payload.bin
Payload version: 2
Manifest length: 53885
Number of partitions: 6Number of "boot" ops: 67Number of "system" ops: 790Number of "vendor" ops: 42Number of "dtbo" ops: 4Number of "vbmeta" ops: 1Number of "vendor_boot" ops: 23Timestamp for boot: Timestamp for system: Timestamp for vendor: Timestamp for dtbo: Timestamp for vbmeta: Timestamp for vendor_boot: COW Size for boot: 0COW Size for system: 0COW Size for vendor: 0COW Size for dtbo: 0COW Size for vbmeta: 0COW Size for vendor_boot: 0
Block size: 4096
Minor version: 7
Blocks read: 1059987
Blocks written: 354408
Seeks when writing: 100
使用 stats 选项和不带选项输出的结果差不多,但会多出以下 IO 操作相关的部分:
Blocks read: 1059987
Blocks written: 354408
Seeks when writing: 100
3. 使用 signagures 选项
顾名思义,signatures 选项就是用来查看 signature 信息的:
$ payload_info.py --signatures out/update/payload.bin
Payload version: 2
Manifest length: 53885
Number of partitions: 6Number of "boot" ops: 67Number of "system" ops: 790Number of "vendor" ops: 42Number of "dtbo" ops: 4Number of "vbmeta" ops: 1Number of "vendor_boot" ops: 23Timestamp for boot: Timestamp for system: Timestamp for vendor: Timestamp for dtbo: Timestamp for vbmeta: Timestamp for vendor_boot: COW Size for boot: 0COW Size for system: 0COW Size for vendor: 0COW Size for dtbo: 0COW Size for vbmeta: 0COW Size for vendor_boot: 0
Block size: 4096
Minor version: 7
Metadata signatures blob: file_offset=53909 (267 bytes)
Metadata signatures: (1 entries)version=None, hex_data: (256 bytes)1a 53 e6 68 fb 26 26 bb c4 58 2f 1c fc a8 59 2d | .S.h.&&..X/...Y-e9 e8 2a a5 f4 29 94 92 9d b8 0a 85 03 0f 90 35 | ..*..).........51f d7 a6 0f ba fc 9b ce f7 e4 d6 70 9b f8 b6 76 | ...........p...v19 2c a8 6f bf f8 cc c9 48 51 4b 67 91 03 73 91 | .,.o....HQKg..s.c4 cf 58 df 84 02 d6 d4 c4 6f 38 b7 70 ad ea 81 | ..X......o8.p...e3 a5 36 1d f1 b7 49 2f b0 18 56 ba 5b 96 ee d5 | ..6...I/..V.[...9f 30 1b 41 d7 36 9f b7 f3 d2 9d c5 57 c3 a8 93 | .0.A.6......W...ca 3d ab 77 84 3b 4a 39 c5 05 c1 37 0a 99 6b 16 | .=.w.;J9...7..k.db 5a 6e df a1 3a c1 6e 12 c4 47 76 88 19 28 6f | .Zn..:.n..Gv..(o55 79 28 8f 86 ab 5e 5d 38 b6 14 a2 2d 80 93 e9 | Uy(...^]8...-...07 11 50 f6 54 be a8 80 0c 14 40 36 15 37 85 e1 | ..P.T.....@6.7..d8 74 4e ac 03 7b 43 66 3a c1 0b bc 07 7b 63 03 | .tN..{Cf:....{c.bb e9 5d 2a 49 57 c5 3d 81 97 a2 83 87 01 0b 8c | ..]*IW.=........bc 5c a2 b3 26 a1 8a 7d 42 25 14 7a 76 c6 01 54 | .\..&..}B%.zv..T12 a5 0e f3 60 9e 3d 1c d8 fa c2 7c bc a8 f2 01 | ....`.=....|....ee c0 3b 5a 3b ac a4 c6 89 09 c6 78 a0 9d 00 34 | ..;Z;......x...4
Payload signatures blob: blob_offset=9939442 (267 bytes)
Payload signatures: (1 entries)version=None, hex_data: (256 bytes)82 48 48 29 0d 04 9f 64 41 0e e2 bb da ad 14 eb | .HH)...dA.......a2 43 fd 7b ff c5 bd 58 b7 c8 af 02 b7 48 eb 30 | .C.{...X.....H.08a 56 c7 6f fb 31 2d 77 e1 37 bc c4 b5 c6 8b a9 | .V.o.1-w.7......0e 79 73 8e 64 a9 10 63 8f c0 93 dd 2d da 0d 74 | .ys.d..c....-..td6 28 1c da d2 4d 8e 29 5b f7 08 9d 56 80 0b 7b | .(...M.)[...V..{c8 ea 4e 8a 76 d9 ae 0d d3 1c 7d a7 8f d4 48 04 | ..N.v.....}...H.f4 d0 e0 b7 37 d1 0a 1e 92 d0 14 bb 34 4a c5 e4 | ....7.......4J..8b bf 8e 9d 1e a1 df 59 75 0a 77 10 0f bf 59 e5 | .......Yu.w...Y.05 33 b6 48 65 03 ed 9f 73 62 34 34 ca 8f 2d 21 | .3.He...sb44..-!cd d6 31 2f 22 93 69 9e fa 70 a1 9d 5b cf eb a3 | ..1/".i..p..[...f9 b7 ca c1 67 45 52 c2 1a 64 ad 22 32 46 0a 56 | ....gER..d."2F.V83 56 87 12 dc 71 55 08 0e 2b ec 92 ad 65 99 6e | .V...qU..+...e.nbf d9 e0 ad dc 45 48 3a 08 91 b6 ed 44 c6 f6 dc | .....EH:....D...c6 56 47 b7 d0 90 a6 63 c7 87 c8 51 2e 6c 79 16 | .VG....c...Q.ly.c4 11 36 ff 93 da f3 00 2c bc 0c 7a cc d1 53 d4 | ..6.....,..z..S.e6 d5 05 16 7b 23 ba 67 0c c5 40 6a ed 63 6c ff | ....{#.g..@j.cl.
从上面的输出可以看到 payload.bin 文件中 metadata 数据以及整个 payload 文件的 signagrue 签名内容信息。
4. 使用 list_ops 选项查看
使用 list_ops
选项可以查看 payload.bin 中包含的所有的 install operation 以及相关的 extent 信息
$ payload_info.py --list_ops out/update/payload.bin
Payload version: 2
Manifest length: 53885
Number of partitions: 6Number of "boot" ops: 67Number of "system" ops: 790Number of "vendor" ops: 42Number of "dtbo" ops: 4Number of "vbmeta" ops: 1Number of "vendor_boot" ops: 23Timestamp for boot: Timestamp for system: Timestamp for vendor: Timestamp for dtbo: Timestamp for vbmeta: Timestamp for vendor_boot: COW Size for boot: 0COW Size for system: 0COW Size for vendor: 0COW Size for dtbo: 0COW Size for vbmeta: 0COW Size for vendor_boot: 0
Block size: 4096
Minor version: 7boot install operations:0: SOURCE_COPYSource: 1 extent (512 blocks)(0,512)Destination: 1 extent (512 blocks)(0,512)...65: ZERODestination: 1 extent (281 blocks)(18150,281)66: SOURCE_COPYSource: 1 extent (1 block)(18431,1)Destination: 1 extent (1 block)(18431,1)
system install operations:0: BROTLI_BSDIFFData offset: 170Data length: 1447872Source: 16 extents (512 blocks)(0,2) (3,1) (28,2) (32768,4) (65536,2) (65551,8) (85061,1) (98304,25)(131072,23) (163840,25) (196608,23) (229376,25) (262144,23) (294912,15)(302569,1) (303478,332)Destination: 14 extents (512 blocks)(0,2) (32768,2) (65551,8) (98304,2) (98308,21) (131074,21) (163840,2)(163844,21) (196610,21) (229376,2) (229380,21) (262146,21) (294912,15)(305874,353)1: SOURCE_COPYSource: 3 extents (23 blocks)(2,1) (2,1) (4,21)Destination: 1 extent (23 blocks)(2,23)2: BROTLI_BSDIFFData offset: 1448042Data length: 81Source: 1 extent (1 block)(25,1)Destination: 1 extent (1 block)(25,1)...788: ZERODestination: 1 extent (75 blocks)(308293,75)789: REPLACE_BZData offset: 9938147Data length: 74Destination: 1 extent (1 block)(308368,1)
vendor install operations:0: SOURCE_COPYSource: 6 extents (512 blocks)(0,15) (6,1) (16,33) (48,1) (48,1) (51,461)Destination: 1 extent (512 blocks)(0,512)...41: SOURCE_COPYSource: 1 extent (1 block)(19654,1)Destination: 1 extent (1 block)(19654,1)
dtbo install operations:0: SOURCE_COPYSource: 1 extent (1 block)(0,1)Destination: 1 extent (1 block)(0,1)1: BROTLI_BSDIFFData offset: 9938221Data length: 182Source: 2 extents (3 blocks)(0,2) (255,1)Destination: 1 extent (1 block)(1,1)2: ZERODestination: 1 extent (253 blocks)(2,253)3: SOURCE_COPYSource: 1 extent (1 block)(255,1)Destination: 1 extent (1 block)(255,1)
vbmeta install operations:0: BROTLI_BSDIFFData offset: 9938403Data length: 868Source: 1 extent (1 block)(0,1)Destination: 1 extent (1 block)(0,1)
vendor_boot install operations:0: SOURCE_COPYSource: 1 extent (512 blocks)(0,512)Destination: 1 extent (512 blocks)(0,512)...21: ZERODestination: 1 extent (432 blocks)(9807,432)22: SOURCE_COPYSource: 1 extent (1 block)(10239,1)Destination: 1 extent (1 block)(10239,1)
具体的详细操作,以及相应的 extents 都一目了然。
也可以对 list_ops 的输出进一步操作,比如对各种操作进行分类统计。
3. 其它
到目前为止,我写过 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”获取个人微信。