前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AB升级(5):payload结构解析

AB升级(5):payload结构解析

原创
作者头像
小胡子
发布2022-05-30 20:52:47
2.4K1
发布2022-05-30 20:52:47
举报
文章被收录于专栏:小胡子专栏小胡子专栏

在进一步分析升级流程之前,我们先来看下AB升级情况下的OTA包的结构。

OTA包的结构

代码语言:txt
复制
├── care_map.pb
├── META-INF
│   └── com
│       └── android
│           ├── metadata 
│           └── otacert  // release key的公钥,用来对ota包做签名验证
├── payload.bin
└── payload_properties.txt

payload_properties.txt

包含了payload的一些元信息,如文件的hash值,大小等。

代码语言:txt
复制
FILE_HASH=clGjz1kJ/Toxcax0Ap8d2cCVupI1xoBBXgqOzNK+IeQ=
FILE_SIZE=1345770359
METADATA_HASH=EG0gbI1eQ5PCQhcOovjiP8zK1H14T6CL8znOwAnQRnE=
METADATA_SIZE=98416

metadata

包含了待升级固件的信息,如版本号,编译的时间等

代码语言:txt
复制
ota-property-files=payload_metadata.bin:1808:98683,payload.bin:1808:1345770359,payload_properties.txt:1345772225:155,care_map.pb:677:1084,metadata:69:561            
ota-required-cache=0
ota-streaming-property-files=payload.bin:1808:1345770359,payload_properties.txt:1345772225:155,care_map.pb:677:1084,metadata:69:561              
ota-type=AB
post-build=xxx
post-build-incremental=1640652245
post-sdk-level=30
post-security-patch-level=2021-10-05
post-timestamp=1640652162
pre-device=xxx

payload.bin

包含待升级的镜像信息

payload.bin的结构

payload随着AB分区和update engine引入,其中payload的数据定义在

update_metadata.proto中,这个是protobuf格式的源文件。protobuf是Google推出的跨语言的序列化工具,可以将对象转换成字节流保存,并可以通过Java,C++,C#,Python等方式读写。

delta_update_file

delta_update_file这个结构体是payload.bin的数据结构,解结构体表述如下:

代码语言:txt
复制
system/update_engine/update_metadata.proto

struct delta_update_file {
  char magic[4] = "CrAU";
  uint64 file_format_version;  // payload major version
  uint64 manifest_size;  // Size of protobuf DeltaArchiveManifest

  // Only present if format_version >= 2:
  uint32 metadata_signature_size;

  // The DeltaArchiveManifest protobuf serialized, not compressed.
  char manifest[manifest_size];

  // The signature of the metadata (from the beginning of the payload up to
  // this location, not including the signature itself). This is a serialized
  // Signatures message.
  char metadata_signature_message[metadata_signature_size];

  // Data blobs for files, no specific format. The specific offset
  // and length of each data blob is recorded in the DeltaArchiveManifest.
  struct {
    char data[];
  } blobs[];

  // The signature of the entire payload, everything up to this location,
  // except that metadata_signature_message is skipped to simplify signing
  // process. These two are not signed:
  uint64 payload_signatures_message_size;
  // This is a serialized Signatures message.
  char payload_signatures_message[payload_signatures_message_size];
};

将结构体转化为图片分解后如下:

delta_update_file结构解析
delta_update_file结构解析

这个图片能比较清晰的看到delta_update_file主要分为四个部分

  • Header 主要是文件格式以及后面的protobuf的长度,签名长度进行描述
  • protofuf DeltaArchiveManifest这个结构代表的数据,是payload.bin转给你的核心数据,存储了分区的信息。
  • blob[] 对应于InstallOperation的数据,至于这个数据有多长,如何操作等信息都存放在DeltaArchiveManifest中
  • signature 存储包括元数据的签名和payload的签名

Manifest的数据结构

代码语言:txt
复制
message DeltaArchiveManifest {
  // Only present in major version = 1. List of install operations for the
  // kernel and rootfs partitions. For major version = 2 see the |partitions|
  // field.
  repeated InstallOperation install_operations = 1;
  repeated InstallOperation kernel_install_operations = 2;

  // (At time of writing) usually 4096
  optional uint32 block_size = 3 [default = 4096];

  // If signatures are present, the offset into the blobs, generally
  // tacked onto the end of the file, and the length. We use an offset
  // rather than a bool to allow for more flexibility in future file formats.
  // If either is absent, it means signatures aren't supported in this
  // file.
  optional uint64 signatures_offset = 4;
  optional uint64 signatures_size = 5;

  // Only present in major version = 1. Partition metadata used to validate the
  // update. For major version = 2 see the |partitions| field.
  optional PartitionInfo old_kernel_info = 6;
  optional PartitionInfo new_kernel_info = 7;
  optional PartitionInfo old_rootfs_info = 8;
  optional PartitionInfo new_rootfs_info = 9;

  // old_image_info will only be present for delta images.
  optional ImageInfo old_image_info = 10;

  optional ImageInfo new_image_info = 11;

  // The minor version, also referred as "delta version", of the payload.
  // Minor version 0 is full payload, everything else is delta payload.
  optional uint32 minor_version = 12 [default = 0];

  // Only present in major version >= 2. List of partitions that will be
  // updated, in the order they will be updated. This field replaces the
  // |install_operations|, |kernel_install_operations| and the
  // |{old,new}_{kernel,rootfs}_info| fields used in major version = 1. This
  // array can have more than two partitions if needed, and they are identified
  // by the partition name.
  repeated PartitionUpdate partitions = 13;

  // The maximum timestamp of the OS allowed to apply this payload.
  // Can be used to prevent downgrading the OS.
  optional int64 max_timestamp = 14;

  // Metadata related to all dynamic partitions.
  optional DynamicPartitionMetadata dynamic_partition_metadata = 15;
}

DeltaArchiveManifest中嵌套的数据结构较多,使用框架图来表示更加的直观

payload数据结构
payload数据结构

这里requried指定的成员一定存在;optional指定的成员属于可选项,有可能不存在;而repeated指示的成员我们可以看成是一个数组

payload.bin解压缩

payload.bin可以理解为压缩文件,可以通过https://github.com/vm03/payload_dumper中的脚本进行解压缩。

使用环境说明

1.需要使用Python3的环境执行

2.pip3 install bsdiff4

环境配置完之后,使用payload_dumper.py脚本执行

代码语言:txt
复制
python3 payload_dumper.py -h
usage: payload_dumper.py [-h] [--out OUT] [--diff] [--old OLD]
                         [--images IMAGES]
                         payloadfile

OTA payload dumper

positional arguments:
  payloadfile      payload file name

optional arguments:
  -h, --help       show this help message and exit
  --out OUT        output directory (defaul: output)
  --diff           extract differential OTA, you need put original images to
                   old dir
  --old OLD        directory with original images for differential OTA
                   (defaul: old)
  --images IMAGES  images to extract (default: empty)

执行完之后

代码语言:txt
复制
python3 payload_dumper.py '/work/update/payload.bin' 
Processing boot partition................Done
Processing system partition................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Done
Processing vendor partition...........................................................................................................................................................Done
Processing preloader partition.Done
Processing md1img partition............Done
Processing md1dsp partition....Done
Processing spmfw partition.Done
Processing scp partition.Done
Processing sspm partition.Done
Processing gz partition.Done
Processing lk partition.Done
Processing dtbo partition.Done
Processing tee partition.Done
Processing vbmeta partition.Done
Processing vbmeta_system partition.Done
Processing vbmeta_vendor partition.Done
Processing product partition................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Done

如果不指定参数,则默认在脚本当前目录下生产解压缩的文件

代码语言:txt
复制
├── output
│   ├── boot.img
│   ├── dtbo.img
│   ├── gz.img
│   ├── lk.img
│   ├── md1dsp.img
│   ├── md1img.img
│   ├── preloader.img
│   ├── product.img
│   ├── scp.img
│   ├── spmfw.img
│   ├── sspm.img
│   ├── system.img
│   ├── tee.img
│   ├── vbmeta.img
│   ├── vbmeta_system.img
│   ├── vbmeta_vendor.img
│   └── vendor.img
├── payload_dumper.py

参考链接

1 https://www.cxyzjd.com/article/u011391629/100122248#OTA_Package_Format_107

2 https://blog.csdn.net/guyongqiangx/article/details/82805813

3 https://github.com/vm03/payload_dumper

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • OTA包的结构
  • payload.bin的结构
  • payload.bin解压缩
  • 参考链接
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档