我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img

我在 《Android 动态分区详解(二) 核心模块和相关工具介绍》 介绍过 lpmake 工具,这款工具用于将多个分区镜像打包生成一个 Android 专用的动态分区镜像,一般称为 super.img。Android 编译时,系统会自动调用 lpmake 并传入相关参数来生成 super.img,不需要我们手动操作。但难免还是有朋友想深入研究下 super.img,希望自己手动生成 super.img。所以这里专门开一篇详解介绍下 lpmake 工具。

本文基于 android-13.0.0_r41 编译生成的 lpmake 介绍该工具的使用,但也适用于 Android 10(Q) 开始的其它 Android 版本。

《Android OTA 相关工具》系列,目前已有文章列表:

本文为洛奇看世界(guyongqiangx)原创,转载请注明出处。

文章链接:https://blog.csdn.net/guyongqiangx/article/details/132581720

1. lpmake 的编译

lpmake 工具从 Android Q 版代码开始引入,源码位于 system/extras/partition_tools 目录下,默认编译 Android 后输出到 out/host/linux-x86/bin/lpmake ,第一次编译以后,通过 source 和 lunch 操作设置 Android 编译环境后就可以引用。

例如:

$ source build/envsetup.sh $ lunch aosp_panther-userdebug$ which lpmake/local/public/users/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpmake$ lpmake -hlpmake: option requires an argument -- 'h'Must specify --device OR --device-size.

当然,也可以将 out/host/linux-x86/bin 添加到当前目录下使用:

$ echo $PATH/home/rocky/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin$ export PATH=${PWD}/out/host/linux-x86/bin:$PATH$ echo $PATH/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin:/home/rocky/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin$ which lpmake/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpmake$ lpmake -hlpmake: option requires an argument -- 'h'Must specify --device OR --device-size.

两种方式都差不多,不过个人推荐前者。

2. lpmake 的帮助信息

关于一个工具,最好的文档就是自己的帮助手册,我这里顺手将 lpmake 的 help 命令输出贴在这里。

android-13.0.0_r41$ lpmake helplpmake - command-line tool for creating Android Logical Partition images.Usage:  lpmake [options]Required options:  -d,--device-size=[SIZE|auto]  Size of the block device for logical partitions.    Can be set to auto to automatically calculate the    minimum size, the sum of partition sizes plus    metadata-size times the number of partitions.  -m,--metadata-size=SIZE       Maximum size to reserve for partition metadata.  -s,--metadata-slots=COUNT     Number of slots to store metadata copies.  -p,--partition=DATA           Add a partition given the data, see below.  -o,--output=FILE              Output file.Optional:  -b,--block-size=SIZE          Physical block size, defaults to 4096.  -a,--alignment=N              Optimal partition alignment in bytes.  -O,--alignment-offset=N       Alignment offset in bytes to device parent.  -S,--sparse                   Output a sparse image for fastboot.  -i,--image=PARTITION=FILE     If building a sparse image for fastboot, include    the given file (or sparse file) as initial data for    the named partition.  -g,--group=GROUP:SIZE         Define a named partition group with the given    maximum size.  -D,--device=DATA              Add a block device that the super partition    spans over. If specified, then -d/--device-size    and alignments must not be specified. The format    for DATA is listed below.  -n,--super-name=NAME          Specify the name of the block device that will    house the super partition.  -x,--auto-slot-suffixing      Mark the block device and partition names needing    slot suffixes before being used.  -F,--force-full-image         Force a full image to be written even if no    partition images were specified. Normally, this    would produce a minimal super_empty.img which    cannot be flashed; force-full-image will produce    a flashable image.  --virtual-ab                  Add the VIRTUAL_AB_DEVICE flag to the metadata    header. Note that the resulting super.img will    require a liblp capable of parsing a v1.2 header.Partition data format:  <name>:<attributes>:<size>[:group]  Attrs must be 'none' or 'readonly'.Device data format:  <partition_name>:<size>[:<alignment>:<alignment_offset>]  The partition name is the basename of the /dev/block/by-name/ path of the  block device. The size is the device size in bytes. The alignment and  alignment offset parameters are the same as -a/--alignment and   -O/--alignment-offset.

虽然上面的 help 信息包含了所有的选项说明,但我相信读到这里的小伙伴只有少部分真正去阅读了工具选项和说明。主要有几点:

  1. 说明是英文的,一看英文就反感。没说你,我自己就是这样。
  2. 选项很枯燥,看了也不知道怎么用
  3. 喜欢手把手的那种详细说明文档

但我还是十分建议你花 5 分钟去仔细阅读一下工具所有选项以及相应的说明,主要理由有以下几点:

  1. 不喜欢看英文的文档,那是因为你看得太少了,需要多看
  2. 选项很枯燥,看了也不知道怎么用,还是因为看得太少了
  3. 不要寄希望与别人的手把手文档,有当然好,没有就上帮助文档,这才是必由之路。

说到底,自带的帮助文档是第一手的资料,阅读第一手的资料,有助于你提高自己的学习能力。

3. lpmake 的用法

除了帮助文档,看看 Android 里具体如何使用 lpmake 工具,对学习理解也有很大帮助。实在理解不了帮助文档,那照着别人的用法依葫芦画瓢总比较容易一点。

3.1 示例 1

这里说说 Android 编译中对 lpmake 的调用。

Android 编译时,build_super_image.py 脚本会准备命令并调用 lpmake 生成 super.img,直接在 Android 编译的 log 中搜索 lpmake 就可以看到详细的命令。

这里以 Android 13 中编译参考设备 panther 为例,看看 build_super_image.py 是如何调用 lpmake 的:

$ source build/envsetup.sh $ lunch aosp_panther-userdebug$ make dist -j80 2>&1 | tee make-dist.log$ grep -ni lpmake make-dist.log56:2023-08-30 02:26:10 - common.py - INFO    :   Running: "/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpmake --metadata-size 65536 --super-name super --metadata-slots 3 --virtual-ab --device super:8531214336 --group google_dynamic_partitions_a:8527020032 --group google_dynamic_partitions_b:8527020032 --partition system_a:readonly:886816768:google_dynamic_partitions_a --image system_a=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/system.img --partition system_b:readonly:27312128:google_dynamic_partitions_b --image system_b=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/system_other.img --partition system_dlkm_a:readonly:348160:google_dynamic_partitions_a --image system_dlkm_a=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/system_dlkm.img --partition system_dlkm_b:readonly:0:google_dynamic_partitions_b --partition system_ext_a:readonly:301395968:google_dynamic_partitions_a --image system_ext_a=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/system_ext.img --partition system_ext_b:readonly:0:google_dynamic_partitions_b --partition product_a:readonly:368046080:google_dynamic_partitions_a --image product_a=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/product.img --partition product_b:readonly:0:google_dynamic_partitions_b --partition vendor_a:readonly:621752320:google_dynamic_partitions_a --image vendor_a=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/vendor.img --partition vendor_b:readonly:0:google_dynamic_partitions_b --partition vendor_dlkm_a:readonly:43040768:google_dynamic_partitions_a --image vendor_dlkm_a=out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/vendor_dlkm.img --partition vendor_dlkm_b:readonly:0:google_dynamic_partitions_b --sparse --output out/target/product/panther/obj/PACKAGING/super.img_intermediates/super.img"

这里因为分区很多,所以 lpmake 的命令参数非常长,手动对这个 lpmake 命令整理一下会清楚很多:

/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpmake \--metadata-size 65536 \--super-name super \--metadata-slots 3 \--virtual-ab \--device super:8531214336 \--group google_dynamic_partitions_a:8527020032 \--group google_dynamic_partitions_b:8527020032 \--partition system_a:readonly:886816768:google_dynamic_partitions_a \--image system_a=out/target/product/panther/system.img \--partition system_b:readonly:27312128:google_dynamic_partitions_b \--image system_b=out/target/product/panther/system_other.img \--partition system_dlkm_a:readonly:348160:google_dynamic_partitions_a \--image system_dlkm_a=out/target/product/panther/system_dlkm.img \--partition system_dlkm_b:readonly:0:google_dynamic_partitions_b \--partition system_ext_a:readonly:301395968:google_dynamic_partitions_a \--image system_ext_a=out/target/product/panther/system_ext.img \--partition system_ext_b:readonly:0:google_dynamic_partitions_b \--partition product_a:readonly:368046080:google_dynamic_partitions_a \--image product_a=out/target/product/panther/product.img \--partition product_b:readonly:0:google_dynamic_partitions_b \--partition vendor_a:readonly:621752320:google_dynamic_partitions_a \--image vendor_a=out/target/product/panther/vendor.img \--partition vendor_b:readonly:0:google_dynamic_partitions_b \--partition vendor_dlkm_a:readonly:43040768:google_dynamic_partitions_a \--image vendor_dlkm_a=out/target/product/panther/vendor_dlkm.img \--partition vendor_dlkm_b:readonly:0:google_dynamic_partitions_b \--sparse \--output out/target/product/panther/super.img

这里我把 --image 的路径进行了简化,将类似下面这样的完整路径:

out/target/product/panther/obj/PACKAGING/target_files_intermediates/aosp_panther-target_files-eng.rocky/IMAGES/system.img

使用另外一个比较简短的路径替代:

out/target/product/panther/system.img

上面这个 lpmake 命令的参数重点:

  • --metadata-size 65536

    指定单个 metadata 数据的大小,通常为 64K,即 65536。

  • --super-name super

    指定了 super 设备的设备名称。

  • --metadata-slots 3

    每一个 metadata 的 slot 数量,关于这个数值为什么是 3,而不是 2 在 《Android 动态分区详解(一) 5 张图让你搞懂动态分区原理》有过疑惑,后面看情况是不是要单独写一点东西来说明分析这个。

  • --virtual-ab

    用于设置 metadata 头部的 VIRTUAL_AB_DEVICE 标识,解析这个标识需要 liblp 能够解析 v1.2 版本的 metadata header 数据。

  • --device super:8531214336

    指定 super 设备的大小,可以指定具体的大小数值,也可以通过 --device super:auto 自动计算所需的最小 size。

  • --group google_dynamic_partitions_a:8527020032

    设备 super 内的分组信息,使用 GROUP:SIZE 格式指定具体的 group 名称,以及最大大小。

  • --partition system_a:readonly:886816768:google_dynamic_partitions_a

    设备 super 内的分区信息,使用 ::[:group] 格式指定分区名称,属性,大小,以及所属分组名称。

  • --image system_a=out/target/product/panther/system.img

    指定分区需要写入的 image 路径。

  • --sparse

    指定生成的 super.img 是否是 sparse 格式,如果指定则输出 sparse 格式的 super 镜像。

  • --output out/target/product/panther/super.img

    指定输出的 super 镜像文件路径和文件名。

根据前面的提示,以下参数是必须的:

--device-size=[SIZE|auto]--metadata-size=SIZE--metadata-slots=COUNT--partition=DATA--output=FILE

主要就是用于生成 super 头部的 metadata,缺少任何一个都会影响 metadata 数据的生成,所以是必须的。

上面的命令中,Android 参考设备 panther 上面的分区比较多,分区信息通过 --partition 指定,具体包含的镜像通过 --image 指定。

至于 --group 以及 --image 参数都不是必须的。理论上你可以不用再 super 上创建分组,在制作 super 时也可以不用传入具体分区的镜像数据,这样生成的 super 就是一个只有 metadata 描述数据,而没有任何分区镜像数据的空的 super.img,相当于 Android 编译生成的 super_empty.img

3.2 示例 2

另外,文章《Android 动态分区详解(二) 核心模块和相关工具介绍》 中也介绍过 lpmake 工具的另外一个例子,可以参考上面的参数执行分析这个命令:

lpmake --metadata-size 65536 --super-name super --metadata-slots 3 \    --device super:3028287488 \--group bcm_ref_a:1509949440 --group bcm_ref_b:1509949440 \--partition system_a:readonly:1077702656:bcm_ref_a \--image system_a=out/target/product/inuvik/system.img \--partition system_b:readonly:0:bcm_ref_b \--partition vendor_a:readonly:104992768:bcm_ref_a \--image vendor_a=out/target/product/inuvik/vendor.img \--partition vendor_b:readonly:0:bcm_ref_b \--sparse --output out/target/product/inuvik/super.img

3.3 示例 3

这里再提供一个 Android 文档中介绍 lpmake 时使用的例子:

lpmake --device-size 10240000000 \       --metadata-size 65536     \       --metadata-slots 2        \       -o /tmp/super.img         \       -p "cache:2da85788-f0e1-4fda-9ee7-e5177eab184b:none:67108864" \       -i "cache=out/target/hikey960/cache.img"

这个例子中,创建了一个 10GB 的 super 动态分区,里面只包含了一个 64M 大小的 “cache” 分区。

现在,你可以手动自己使用 lpmake 来生成 super.img 了吗?

4. 几个思考题

到这里差不多应该结束了,给大家留三个思考题:

问题1system.imgsystem_other.img

仔细观察上面第 3 节生成参考设备 panther 的 super.img 的命令中,system_a 分区和 system_b 分区传入的镜像文件竟然不一样:

/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpmake \--metadata-size 65536 \--super-name super \--metadata-slots 3 \--virtual-ab \--device super:8531214336 \--group google_dynamic_partitions_a:8527020032 \--group google_dynamic_partitions_b:8527020032 \--partition system_a:readonly:886816768:google_dynamic_partitions_a \--image system_a=out/target/product/panther/system.img \--partition system_b:readonly:27312128:google_dynamic_partitions_b \--image system_b=out/target/product/panther/system_other.img \...--sparse \--output out/target/product/panther/super.img

其中:

  • system_a 的 image 为: out/target/product/panther/system.img
  • system_b 的 image 为: out/target/product/panther/system_other.img

按照我的理解是 system_asystem_b 分区,制作镜像时可以提供一样的文件,或者像其他分区一样,system_b 不提供任何文件,仅保留一个空分区记录。

但为什么这里会传递 system_other.imgsystem_b 分区呢?

镜像文件 system_other.imgsystem.img 有什么区别?

问题 2:按照我上面的方法,研究下 super_empty.img 是如何生成的?

问题 3:为什么我 OTA 讨论群里的这位群友反馈他生成的 super.img 只有几十 K?
在这里插入图片描述
在这里插入图片描述

5. 其它

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

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

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

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

来源地址:https://blog.csdn.net/guyongqiangx/article/details/132581720

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录