Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size

Android A/B System OTA分析(六)如何获取 payload 的 offset 和 size

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

Android A/B 系统基础入门系列《Android A/B 系统》已完结,文章列表:

更多关于 Android OTA 升级相关文章,请参考《Android OTA 升级系列专栏文章导读》

上一篇《Android A/B System OTA分析(五)客户端升级的参数》提到升级时 offset 和 size 参数分别用于升级时设置远程文件中 payload 数据的起始地址和长度,但并没有提到如何获得这个 offset 和 size 值。本篇详细说明如何计算和获取这两个参数。

我写东西通常想把来龙去脉都写清楚,因此也会很繁琐,以下是对本文快速导航:

  • 如果你只想知道 Android O 开始,脚本中是如何计算 offset 和 size 参数的,请转到 2.1 节。
  • 如果你只想知道命令行如何手工获取 offset 和 size 参数,请转到第 2.2 节。
  • 如果你想找一个单独的脚本工具计算 offset 和 size,请转到第 3.3 节

1. zip 文件的格式

要想知道压缩包中每个文件的 offset 和 size 是如何计算的,就先需要了解下 zip 文件的格式。

对于这种要了解标准或文件格式的情况,我一般推荐阅读官方文档。官方文档虽然枯燥,但是是第一手信息。再配上网上其它的分析文章,这样阅读理解起来会比较容易,也不容易出现错误。

维基百科页面《ZIP (file format) 》提供了多个 zip 文件格式的历史版本链接, 目前最新的版本是 v6.3.9(文档日期 2020/07/15),这里使用 v6.3.2 版本的文档作为参考(文档日期 2007/09/28):

APPNOTE.TXT - .ZIP File Format Specification》: https://pkware.cachefly.net/webdocs/APPNOTE/APPNOTE-6.3.2.TXT

关于 zip 文件的历史,有兴趣的也请自行参考维基百科:《ZIP (file format)

在 v6.3.2 版文档的第 V 节详细描述了 zip 文件的格式。

1.1 zip 文件的总体格式

Overall .ZIP file format:

[local file header 1]
[file data 1]
[data descriptor 1]
. 
.
.
[local file header n]
[file data n]
[data descriptor n]
[archive decryption header] 
[archive extra data record] 
[central directory]
[zip64 end of central directory record]
[zip64 end of central directory locator] 
[end of central directory record]

总体来说,zip 文件由多个文件组成,每个文件由 “loacal file header”, “file data” 和 “data descriptor” 3 部分组成,多个文件时各文件数据依次排列。

在文件结束后有一些其它数据,由于我们只关心每个文件的 offset 和 size,所以可以暂时不用考虑文件末尾的那些数据,虽然可能也很重要。

1.2 local file header

zip 文件中,每个文件的第一部分就是 local file header,用于描述文件的各种属性。

Local file header:

local file header signature     4 bytes  (0x04034b50)
version needed to extract       2 bytes
general purpose bit flag        2 bytes
compression method              2 bytes
last mod file time              2 bytes
last mod file date              2 bytes
crc-32                          4 bytes
compressed size                 4 bytes
uncompressed size               4 bytes
file name length                2 bytes
extra field length              2 bytes

file name (variable size)
extra field (variable size)

local file header 中,前面的是定长部分的数据,一共 30 bytes;后面还有两个变长的部分 file nameextra field,这两部分的具体长度由定长部分的 file name lengthextra filed length 指定。

因此 len(local file header) = 30 + len(file name) + len(extra filed)

1.3 file data

紧挨着 local file header 的是文件数据 file data,根据具体的情况,这里的数据可能是压缩的,也可能是没有压缩的,具体长度由 local file header 中的 compressed size 指定。

1.4 data descriptor

file data 之后是 data descriptor:

Data descriptor:

crc-32                          4 bytes
compressed size                 4 bytes
uncompressed size               4 bytes

这部分数据并不是必须的,只有当 local file header 结构中 general purpose bit flag 的 bit 3 被设置以后才存在,其内容也是用来指定文件数据长度的。

为什么会出现这种情况呢? 这是因为有些情况下,一开始是不知道文件数据大小的。例如,用录像机录像时,其数据压缩存储,一开始录制的时候并不能确定最终文件多大,但这些数据又需要不断写入存储介质,所以就在开始的时候设置一个标志位,表示其大小存储在数据结束的地方。

1.5 offset 和 size 的计算

由于我们这里只关心 offset 和 size 的计算,所以 zip 文件后面的那些数据暂时不管了。

只需要拿到每个文件在 zip 包中的 local file header 数据就可以计算得到 offset 和 size 数值。

文件数据的起始位置(offset):

offset(data) = offset(local file header) + size(local file header) 
             = offset(local file header) + 30 + len(file name) + len(extra filed)

文件数据的大小(size):

# 压缩后数据大小
size = comressed size

# 原始数据大小
size = uncompressed size

最后,一张图描述 zip 文件的主要结构,方便参考:
zip文件的结构

1.6 关于 encryption header

APPNOTE.TXT - .ZIP File Format Specification Version, 6.3.3 开始,zip 文件新增了一个 encryption header,位于 local file header 之后, file data 之前,如下所示:

Overall .ZIP file format:

[local file header 1]
[encryption header 1]
[file data 1]
[data descriptor 1]
. 
.
.
[local file header n]
[encryption header n]
[file data n]
[data descriptor n]
[archive decryption header] 
[archive extra data record] 
[central directory header 1]
.
.
.
[central directory header n]
[zip64 end of central directory record]
[zip64 end of central directory locator] 
[end of central directory record]

这里的 encryption header 只有在压缩包的数据被加密的情况下才会出现,由于 Android 的 update.zip 包并未加密,不会出现 encryption header,因此接下来的讨论都默认没有 encryption header

2. 获取 offset 和 size 的三种方式

上一节介绍了 zip 文件的结构,接下来就可以根据这个结构去获取 offset 和 size 数据。

2.1 Android O 开始自动生成 offset 和 size 数据

1. metadata 示例

从 Android 8.0 (O) 开始,制作升级包时,会自动计算 payload 的 offset 和 size 并输出到 zip 包的 META-INF/com/android/metadata 文件中,像下面这样:

$ cat META-INF/com/android/metadata
ota-required-cache=0
ota-streaming-property-files=payload.bin:738:271041806,payload_properties.txt:271042602:154,care_map.txt:474:217,metadata:69:357
ota-type=AB
post-build=bcm/b604usff/b604usff:8.0.0/OPR6.170623.021/rg935701131615:userdebug/test-keys
post-build-incremental=eng.rg9357.20220113.161532
post-timestamp=1642061732
pre-device=b604usff

这里的 ota-streaming-property-files 键值对就记录了多个文件的 offset 和 size 值,包括:

  • payload.bin, offset: 738, size: 271041806
  • payload_propterites.txt, offset: 271042602, size: 154
  • care_map.txt, offset: 474, size: 217
  • metadata, offset: 6957, size: 357
2. metadata 生成的代码分析

这里涉及的Android代码:android-8.0.0_r12(BUILD_ID=OPR6.170623.021)

生成 offset 和 size 数据的代码位于脚本 ota_from_target_files 中,见下面的代码片段:

  • 计算多个文件的 offset 和 size

从第 971 行开始,定义了函数 ComputeStreamingMetadata 用于提取指定压缩包的 offset 和 size 信息

  def ComputeStreamingMetadata(zip_file, reserve_space=False,
                               expected_length=None):
    """Compute the streaming metadata for a given zip.

    When 'reserve_space' is True, we reserve extra space for the offset and
    length of the metadata entry itself, although we don't know the final
    values until the package gets signed. This function will be called again
    after signing. We then write the actual values and pad the string to the
    length we set earlier. Note that we can't use the actual length of the
    metadata entry in the second run. Otherwise the offsets for other entries
    will be changing again.
    """

    #
    # 根据文件名 name, 获取对应文件的 offset 和 size 并用这样的格式输出: 'filename:offset:size'
    # 如: payload.bin:738:271041806
    #
    def ComputeEntryOffsetSize(name):
      """Compute the zip entry offset and size."""
      # 提取文件名 name 对应的 zipinfo 对象
      info = zip_file.getinfo(name)
      # 根据 zipinfo 对象的 header_offset 和 FileHeader 长度, 得到文件数据的 offset
      offset = info.header_offset + len(info.FileHeader())
      # 使用 zipinfo 对象的 file_size 作为 size (这里的 file_size 是文件压缩前的大小,压缩后的大小为 compress_size)
      size = info.file_size
      return '%s:%d:%d' % (os.path.basename(name), offset, size)

    #
    # 获取以下文件的 offset 和 size 数据:
    # 1. payload.bin
    # 2. payload_properties.txt
    # 3. care_map.txt
    # 4. compatibility.zip
    # 5. metadata
    #
    # payload.bin and payload_properties.txt must exist.
    offsets = [ComputeEntryOffsetSize('payload.bin'),
               ComputeEntryOffsetSize('payload_properties.txt')]

    # care_map.txt is available only if dm-verity is enabled.
    if 'care_map.txt' in zip_file.namelist():
      offsets.append(ComputeEntryOffsetSize('care_map.txt'))

    if 'compatibility.zip' in zip_file.namelist():
      offsets.append(ComputeEntryOffsetSize('compatibility.zip'))

    #
    # 计算 'META-INF/com/android/metadata' 文件的 offset 和 size 时,预留了格式: 'metadata:          ' (10个空格)
    #
    # 'META-INF/com/android/metadata' is required. We don't know its actual
    # offset and length (as well as the values for other entries). So we
    # reserve 10-byte as a placeholder, which is to cover the space for metadata
    # entry ('xx:xxx', since it's ZIP_STORED which should appear at the
    # beginning of the zip), as well as the possible value changes in other
    # entries.
    if reserve_space:
      offsets.append('metadata:' + ' ' * 10)
    else:
      offsets.append(ComputeEntryOffsetSize(METADATA_NAME))

    # 将所有文件的 'name:offset:size' 数据用逗号连接成一个字符串返回
    value = ','.join(offsets)
    if expected_length is not None:
      assert len(value) <= expected_length, \
          'Insufficient reserved space: reserved=%d, actual=%d' % (
              expected_length, len(value))
      value += ' ' * (expected_length - len(value))
    return value
  • 将获取的 offset 和 size 写入 metadata 文件

第 1213 行代码开始,计算输出的 zip 文件的 offset 和 size 信息写入 metadata 文件的 ota-streaming-property-files 键值对中。但这里 metadata 文件自身的 offset 和 size 并没有计算。

  # Write the current metadata entry with placeholders.
  metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
      output_zip, reserve_space=True)
  WriteMetadata(metadata, output_zip)
  • 用 metadata 自己的 offset 和 size 更新 ota-streaming-property-files

第 1231 行代码开始,重新计算 metadata 自己的 offset 和 size,并更新。

  # Open the signed zip. Compute the final metadata that's needed for streaming.
  prelim_zip = zipfile.ZipFile(prelim_signing, "r",
                               compression=zipfile.ZIP_DEFLATED)
  expected_length = len(metadata['ota-streaming-property-files'])
  metadata['ota-streaming-property-files'] = ComputeStreamingMetadata(
      prelim_zip, reserve_space=False, expected_length=expected_length)

  ...

  # Now write the final metadata entry.
  WriteMetadata(metadata, output_zip)

2.2 使用 zipinfo 手工计算

linux 命令行工具 zipinfo 可以用来提取 zip 文件的信息。

1. 安装 zipinfo

这个工具默认情况下没有安装,ubuntu 上可以通过以下命令安装:

sudo apt install unzip
2. 使用 zipinfo 解析 update.zip 文件
  • zipinfo 帮助信息

可以通过 zipinfo 查看简略的帮助信息,或者通过 man zipinfo 查看详尽的内容

$ zipinfo
ZipInfo 3.00 of 20 April 2009, by Greg Roelofs and the Info-ZIP group.

List name, date/time, attribute, size, compression method, etc., about files
in list (excluding those in xlist) contained in the specified .zip archive(s).
"file[.zip]" may be a wildcard name containing *, ?, [] (e.g., "[a-j]*.zip").

   usage:  zipinfo [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]
      or:  unzip -Z [-12smlvChMtTz] file[.zip] [list...] [-x xlist...]

main listing-format options:             -s  short Unix "ls -l" format (def.)
  -1  filenames ONLY, one per line       -m  medium Unix "ls -l" format
  -2  just filenames but allow -h/-t/-z  -l  long Unix "ls -l" format
                                         -v  verbose, multi-page format
miscellaneous options:
  -h  print header line       -t  print totals for listed files or for all
  -z  print zipfile comment  ⚌-T⚌ print file times in sortable decimal format
 ⚌-C⚌ be case-insensitive   zipinfo  -x  exclude filenames that follow from listing
  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
  -I CHARSET  specify a character encoding for UNIX and other archives

$ man zipinfo
  • 不带参数, 列举 update.zip 中的文件
$ zipinfo update.zip
Archive:  update.zip
Zip file size: 271045893 bytes, number of entries: 5
-rw----     1.0 fat      357 bx stor 09-Jan-01 00:00 META-INF/com/android/metadata
-rw----     1.0 fat      217 bx stor 09-Jan-01 00:00 care_map.txt
-rw----     1.0 fat 271041806 bx stor 09-Jan-01 00:00 payload.bin
-rw----     1.0 fat      154 bx stor 09-Jan-01 00:00 payload_properties.txt
-rw----     2.0 fat     1675 bl defN 09-Jan-01 00:00 META-INF/com/android/otacert
5 files, 271044209 bytes uncompressed, 271043477 bytes compressed:  0.0%
  • -v 选项解析 zip 文件详信息
$ zipinfo -v update.zip
Archive:  update.zip
The zipfile comment is 1738 bytes long and contains the following text:
======================== zipfile comment begins ==========================
signed by SignApk
========================= zipfile comment ends ===========================

End-of-central-directory record:
-------------------------------

  Zip archive file size:                 271045893 (000000001027D505h)
  Actual end-cent-dir record offset:     271044133 (000000001027CE25h)
  Expected end-cent-dir record offset:   271044133 (000000001027CE25h)
  (based on the length of the central directory and its expected offset)

  This zipfile constitutes the sole disk of a single-part archive; its
  central directory contains 5 entries.
  The central directory is 360 (0000000000000168h) bytes long,
  and its (expected) offset in bytes from the beginning of the zipfile
  is 271043773 (000000001027CCBDh).


Central directory entry #1:
---------------------------

  META-INF/com/android/metadata

  offset of local header from start of archive:   0
                                                  (0000000000000000h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         982fa5b5
  compressed size:                                357 bytes
  uncompressed size:                              357 bytes
  length of filename:                             29 characters
  length of extra field:                          10 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xcafe (unknown) and 0 data bytes.
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #2:
---------------------------

  care_map.txt

  offset of local header from start of archive:   426
                                                  (00000000000001AAh) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         03053f05
  compressed size:                                217 bytes
  uncompressed size:                              217 bytes
  length of filename:                             12 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #3:
---------------------------

  payload.bin

  offset of local header from start of archive:   691
                                                  (00000000000002B3h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         eba210d4
  compressed size:                                271041806 bytes
  uncompressed size:                              271041806 bytes
  length of filename:                             11 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #4:
---------------------------

  payload_properties.txt

  offset of local header from start of archive:   271042544
                                                  (000000001027C7F0h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         21aa275c
  compressed size:                                154 bytes
  uncompressed size:                              154 bytes
  length of filename:                             22 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

Central directory entry #5:
---------------------------

  META-INF/com/android/otacert

  offset of local header from start of archive:   271042756
                                                  (000000001027C8C4h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   2.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   2.0
  compression method:                             deflated
  compression sub-type (deflation):               normal
  file security status:                           not encrypted
  extended local header:                          yes
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         c3fc0954
  compressed size:                                943 bytes
  uncompressed size:                              1675 bytes
  length of filename:                             28 characters
  length of extra field:                          0 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  There is no file comment.

上面执行命令 zipinfo -v update.zip,会打印了 update.zip 包中所有文件的详细信息。

如果只想查看单个文件的信息,可以在后面添加想查看的文件名,如: zipinfo -v update.zip payload.bin:

$ zipinfo -v update.zip payload.bin
Archive:  update.zip
The zipfile comment is 1738 bytes long and contains the following text:
======================== zipfile comment begins ==========================
signed by SignApk
========================= zipfile comment ends ===========================

End-of-central-directory record:
-------------------------------

  Zip archive file size:                 271045893 (000000001027D505h)
  Actual end-cent-dir record offset:     271044133 (000000001027CE25h)
  Expected end-cent-dir record offset:   271044133 (000000001027CE25h)
  (based on the length of the central directory and its expected offset)

  This zipfile constitutes the sole disk of a single-part archive; its
  central directory contains 5 entries.
  The central directory is 360 (0000000000000168h) bytes long,
  and its (expected) offset in bytes from the beginning of the zipfile
  is 271043773 (000000001027CCBDh).


Central directory entry #3:
---------------------------

  payload.bin

  offset of local header from start of archive:   691
                                                  (00000000000002B3h) bytes
  file system or operating system of origin:      MS-DOS, OS/2 or NT FAT
  version of encoding software:                   1.0
  minimum file system compatibility required:     MS-DOS, OS/2 or NT FAT
  minimum software version required to extract:   1.0
  compression method:                             none (stored)
  file security status:                           not encrypted
  extended local header:                          no
  file last modified on (DOS date/time):          2009 Jan 1 00:00:00
  32-bit CRC value (hex):                         eba210d4
  compressed size:                                271041806 bytes
  uncompressed size:                              271041806 bytes
  length of filename:                             11 characters
  length of extra field:                          6 bytes
  length of file comment:                         0 characters
  disk number on which file begins:               disk 1
  apparent file type:                             binary
  non-MSDOS external file attributes:             000000 hex
  MS-DOS file attributes (00 hex):                none

  The central-directory extra field contains:
  - A subfield with ID 0xd935 (unknown) and 2 data bytes:
    00 00.

  There is no file comment.

这里就只显示了 payload.bin 文件的详细信息。

3. 从 zipinfo 结果中手工计算 offset 和 size

zipinfo -v update.zip payload.bin
从上面的解析可以得到以下的信息:

  • payload.bin 文件的 local file header 的偏移为 691 bytes
  • filenameextra field 的长度分别为 11 bytes 和 6 bytes
  • compressed sizeuncompressed size 大小一样,都是 271041806 bytes

因此,payload.bin 文件的数据在 update.zip 包中的偏移量:

offset(data) = offset(local file header) + size(local file header) 
             = offset(local file header) + 30 + len(file name) + len(extra filed)
             = 691 + 30 + 11 + 6
             = 738

另外,这里compressed sizeuncompressed size 大小一样,都是 271041806 bytes 说明 payload.bin 文件并没有被压缩,只是打包到了 zip 文件而已,在数据被压缩的情况下,则其在压缩包中的大小应该是 compressed size

在前面的 python 代码中,其 zipinfo.file_size 就是这里的 uncompressed size,否则应该使用 compressed size 数据。

所以,我觉得脚本中应该使用 zipinfo.compress_size 作为 size 大小最为合适,offset ~ compress_size 才是 payload.bin 在 zip 包中的具体数据。

2.3 使用 python 脚本计算

简单修改一下 Android O 脚本中的代码,就可以生成一个计算 offset 和 size 的工具 zip_info.py

#!/usr/bin/env python3

import os
import zipfile


def show_zipfile(filename):
    zf = zipfile.ZipFile(filename, 'r')
    print('{}:\n'.format(filename))
    print('{:>25s}  {:>15s}  {:>15s}  {:>15s}'.format("name", "offset", "size", "compress_size"))
    print('{:>25s}  {:>15s}  {:>15s}  {:>15s}'.format('-' * 25, '-' * 15, '-' * 15, '-' * 15))
    for x in zf.namelist():
        info = zf.getinfo(x)
        offset = info.header_offset + len(info.FileHeader())
        size = info.file_size
        compress_size = info.compress_size
        print('{:>25s}  {:>15d}  {:>15d}  {:>15d}'.format(os.path.basename(x), offset, size, compress_size))
    zf.close()


if __name__ == "__main__":
    filename = 'update.zip'
    show_zipfile(filename)

计算当前目录下 “update.zip” 压缩包内各文件的 offset 和 size:

$ python3 zip_info.py
update.zip:

                     name           offset             size    compress_size
-------------------------  ---------------  ---------------  ---------------
                 metadata               69              357              357
             care_map.txt              474              217              217
              payload.bin              738        271041806        271041806
   payload_properties.txt        271042602              154              154
                  otacert        271042814             1675              943

3. 总结

  1. 从 Android 8.0 (O) 开始,制作升级包时会同时将 offset 和 size 信息输出到 META-INF/com/android/metadata 文件中。

  2. 通过 zipinfo 工具,使用命令 zipinfo -v update.zip payload.bin 获取 payload.bin 文件的详细信息,然后通过下面的方式计算 offset:

    offset(data) = offset(local file header) + size(local file header) 
                 = offset(local file header) + 30 + len(file name) + len(extra filed)
    

    具体的分析请参考 2.2 节。

  3. 使用这里提供的 python3 工具计算 update.zip 包内各数据的 offset 和 size 信息

    具体的代码和样例输出,参考 2.3 节。

4. 其它

到目前为止,我写过 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”获取个人微信。

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洛奇看世界

一分也是爱~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值