Android OTA 相关工具(八) 使用 lpadd 添加镜像到 super.img

文章目录

    • 1. lpadd 的编译
    • 2. lpadd 的帮助信息
    • 3. lpadd 的用法
      • 3.1 准备工作
        • empty 的 super 设备镜像
        • raw 格式的 super 设备镜像
        • sparse 格式的 super 设备镜像
      • 3.1 lpadd 分区操作示例
    • 4. 其它

我一直以为没有人会使用 lpadd 工具,就像我以为没有人会去使用 lpmake 手动生成 super.img 一样。

然鹅,真的有小伙伴使用 lpadd 和 lpmake 去学习和了解 super.img。

lpadd not found

话说 lpmake 和 lpadd 还真是一个学习 super.img 的好工具,要是再有一个 lpdelete/remove 就更好了。当然,这些都是非常低频甚至几乎不会用到的小工具,以至于在上一篇提到的 lpunpack 中有 bug 也一直没有修复。

其实 lpmake 在官方代码的 README.md 中介绍的命令也是有 bug 的。

前几篇分别介绍了 lpdump, lpmake 和 lpunpack,本篇介绍 lpadd。

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

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

  • 《Android OTA 相关工具(一) 虚拟 A/B 之 snapshotctl》
  • 《Android OTA 相关工具(二) 动态分区之 dmctl》
  • 《Android OTA 相关工具(三) A/B 系统之 bootctl 工具》
  • 《Android OTA 相关工具(四) 查看 payload 文件信息》
  • 《Android OTA 相关工具(五) 使用 lpdump 查看动态分区》
  • 《Android OTA 相关工具(六) 使用 lpmake 打包生成 super.img》
  • 《Android OTA 相关工具(七) 使用 lpunpack 解包 super.img》
  • 《Android OTA 相关工具(八) 使用 lpadd 添加镜像到 super.img》

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

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

1. lpadd 的编译

lpadd 工具从 Android 11® 后引入的逻辑分区工具,源码位于 system/extras/partition_tools 目录下,默认不会编译 lpadd。

由于 lpadd 只支持在 host 上运行,所以如果需要编译 lpadd,需要将其添加到 PRODUCT_HOST_PACKAGES 中:

PRODUCT_HOST_PACKAGES += lpadd

我这里使用 Android 参考设备 panther 进行编译,修改如下:

android-13.0.0_r41$ repo diff device/google/pantah/device-panther.mk 
project device/google/pantah/
diff --git a/device-panther.mk b/device-panther.mk
index 3c61c6d..e9e2f6c 100644
--- a/device-panther.mk
+++ b/device-panther.mk
@@ -143,6 +143,8 @@ PRODUCT_PROPERTY_OVERRIDES += \PRODUCT_PACKAGES += \libspatialaudio+PRODUCT_HOST_PACKAGES += lpadd 
+# Bluetooth hci_inject test toolPRODUCT_PACKAGES_DEBUG += \hci_inject

进行以上修改后,再编译。

除了这种办法外,也可以直接在根目录下使用 mmm 编译 lpadd 所在的 partition_tools 模块:

android-13.0.0_r41$ mmm system/extras/partition_tools
android-13.0.0_r41$ which lpadd
/local/public/users/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpadd

编译 Android 后输出到 out/host/linux-x86/bin/lpadd ,第一次编译以后,通过 source 和 lunch 操作设置 Android 编译环境后就可以引用。

例如:

$ source build/envsetup.sh 
$ lunch aosp_panther-userdebug
$ which lpadd 
/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpadd

当然,也可以将 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 lpadd 
/public/rocky/android-13.0.0_r41/out/host/linux-x86/bin/lpadd

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

2. lpadd 的帮助信息

lpadd 工具自带的帮助信息:

android-13.0.0_r41$ lpadd -h
lpadd - command-line tool for adding partitions to a super.imgUsage:lpadd [options] SUPER PARTNAME PARTGROUP [IMAGE]SUPER                         Path to the super image. It can be sparsed orunsparsed. If sparsed, it will be unsparsedtemporarily and re-sparsed over the originalfile. This will consume extra space during theexecution of lpadd.PARTNAME                      Name of the partition to add.PARTGROUP                     Name of the partition group to use. If thepartition can be updated over OTA, the groupshould match its updatable group.IMAGE                         If specified, the contents of the given imagewill be added to the super image. If the imageis sparsed, it will be temporarily unsparsed.If no image is specified, the partition willbe zero-sized.Extra options:--readonly                    The partition should be mapped read-only.--replace                     The partition contents should be replaced withthe input image.

除了上面的 help 信息,Android 源码中自带的文档 system/extras/partition_tools/README.md 也包含了对 lpadd 的一些解释说明,如下:

official document for lpadd

按照 Android 官方文档的说法,在我看来有以下重点:

  • lpadd 可以用来往 super.img 中添加分区镜像文件,或者往 super_empty.img 中添加分区。有利于在各种分开或者混合编译的情况,例如 radio.img 和 system.img 由不同的部门或公司管理的不同的代码编译,但都希望最后添加到一个 super.img 中。
  • 增加的分区名字 PART_NAME 必须是还没有存在的。
  • 不能往 super_empty.img 中添加分区镜像文件。
  • lpadd 会消耗大量 TMPDIR 空间,所以如果默认的 TMPDIR 不够空间的话,通过命令行变量 TMPDIR 临时指定一个位置。

3. lpadd 的用法

3.1 准备工作

为了方便演示,我这里手动生成了 3 个名为 rocky 的 super 设备镜像,分别是:

  • empty 的 super 设备镜像: rocky_empty.img
  • raw 格式的 super 设备镜像: rocky_raw.img
  • sparse 格式的 super 设备镜像: rocky_sparse.img

super 设备的大小为 10G (10000M):

  • 包含 2 个大小为 4G(4000M)的 “guyognqiangx_a”, “guyongqiangx_b” 以及默认 “default” 分组 group
  • 分组 “guyognqiangx_a” 和 “guyongqiangx_b” 分别包含大小为 20M 的 “boot_a” 和 “boot_b”
  • 默认分组 “default” 包含一个大小为 100M 的 “radio” 分组

另外,我是基于 android-13.0.0_r41 上编译谷歌的 panther 设备进行这个实验的,如果下载代码和编译 panther,请参考手把手文章《如何下载和编译 Android 源码?》

因为制作 raw 格式和 sparse 格式镜像时,指定的分区需要先转换成 sparse 格式,所以我这里把 radio.img 和 system.img 转换成了 sparse 格式的 sradio.img 和 ssystem.img:

$ img2simg out/target/product/panther/radio.img sradio.img 
$ img2simg out/target/product/panther/system.img ssystem.img 
$ ls -lh out/target/product/panther/{radio,system}.img {sradio,ssystem}.img
-rw-r--r-- 1 rocky users  77M Aug 16 00:29 out/target/product/panther/radio.img
-rw-r--r-- 1 rocky users 846M Aug 16 00:58 out/target/product/panther/system.img
-rw-r--r-- 1 rocky users  68M Sep  2 09:36 sradio.img
-rw-r--r-- 1 rocky users 843M Sep  2 09:36 ssystem.img

empty 的 super 设备镜像

不包含任何分区镜像

$ lpmake --device-size 10485760000 \--metadata-size 65536     \--metadata-slots 2        \-g guyongqiangx_a:4194304000 \-g guyongqiangx_b:4194304000 \-p "radio:readonly:104857600" \-p "boot_a:none:2197520:guyongqiangx_a" \-p "boot_b:none:2197520:guyongqiangx_b" \-o rocky_empty.img

raw 格式的 super 设备镜像

“default” 组内的 “radio” 分区使用镜像 “sradio.img”

$ lpmake --device-size 10485760000 \--metadata-size 65536     \--metadata-slots 2        \-g guyongqiangx_a:4194304000 \-g guyongqiangx_b:4194304000 \-p "radio:readonly:104857600" \-i "radio=sradio.img" \-p "boot_a:none:2197520:guyongqiangx_a" \-p "boot_b:none:2197520:guyongqiangx_b" \-o rocky_raw.img

sparse 格式的 super 设备镜像

  • “default” 组内的 “radio” 分区使用镜像 “sradio.img”
  • “guyongqiangx_a” 组内的 “system_a” 分区使用镜像 “ssystem.img”
  • 使用 “-S” 指定输出 sparse 格式的镜像
$ lpmake --device-size 10485760000 \--metadata-size 65536     \--metadata-slots 2        \-g guyongqiangx_a:4194304000 \-g guyongqiangx_b:4194304000 \-p "radio:readonly:104857600" \-i "radio=sradio.img" \-p "system_a:readonly:1048576000:guyongqiangx_a" \-i "system_a=ssystem.img" \-p "boot_a:none:2197520:guyongqiangx_a" \-p "boot_b:none:2197520:guyongqiangx_b" \-S -o rocky_sparse.img

三种格式的分区镜像添加完成以后,可以使用 lpdump 查看分区镜像情况。

后续操作主要使用 raw 格式的分区镜像 rocky_raw.img。

3.1 lpadd 分区操作示例

建议: 在下面的各个 lpmake 和 lpadd 的步骤完成后,建议再使用 lpdump 或 lpunpack 来检查 lpadd 的结果,以加深对 lpadd 和 super 动态分区设备的理解。

rocky_raw.img 的 “guyongqiangx_a” 组内添加新分区 "vendor_a"和镜像:

$ lpadd rocky_raw.img vendor_a guyongqiangx_a out/target/product/panther/vendor.img

在 “guyognqiangx_a” 分组内添加 readonly 的分区 “radio_a”

$ lpadd rocky_raw.img --readonly radio_a guyongqiangx_a

在上一步的基础上,直接给 radio_a 分区添加镜像失败,需要使用 “–replace” 选项添加分区镜像:

$ lpadd rocky_raw.img radio_a guyongqiangx_a out/target/product/panther/radio.img
[liblp]Attempting to create duplication partition with name: radio_a
Could not add partition: radio_a
$ lpadd rocky_raw.img --replace radio_a guyongqiangx_a out/target/product/panther/radio.img
Writing data for partition radio_a...
Done.

因为默认使用 lpadd 时默认是向 super 设备添加新分区,如果分区已经存在,需要更新分区镜像,则需要使用 “–replace” 选项。

将 radio_a 分区镜像从原来的 radio.img 替换为 bootloader.img:

$ lpadd rocky_raw.img --replace radio_a guyongqiangx_a out/target/product/panther/bootloader.img
Writing data for partition radio_a...
Done.

直接给 empty 的 super 设备添加分区和镜像会失败:

$ lpadd rocky_empty.img radio_a guyongqiangx_a out/target/product/panther/radio.img
Cannot add a partition image to an empty super file.

但是可以给 empty 的 super 设备添加分区:

$ lpadd rocky_empty.img radio_a guyongqiangx_a
Done.

对于逻辑分区的管理,再添加一个 lpdelete 或者 lpremove 来从 super 设备移除分区就完美了,因为这样整个分区的增删改查操作就都具备了,可惜没有~

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”获取个人微信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/117039.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netty源码NioEventLoop解析

带着问题源码 Netty 的 NioEventLoop 是如何实现的?它为什么能够保证 Channel 的操作是线程安全的?Netty 如何解决 JDK epoll 空轮询 Bug?NioEventLoop 是如何实现无锁化的? 一、作用与设计原理 Netty的NioEventLoop并不是一个存…

无涯教程-Android - 应用组件

应用程序组件是Android应用程序的基本组成部分,这些组件需要在应用程序清单文件 AndroidManifest.xml 注册,该文件描述了应用程序的每个组件以及它们如何交互。 Android应用程序可以使用以下四个主要组件- Sr.NoComponents & 描述1 Activities 它们…

2023-9-2 Kruskal算法求最小生成树

题目链接&#xff1a;Kruskal算法求最小生成树 #include <iostream> #include <algorithm>using namespace std;const int N 200010;// 与并查集中的p含义相同 int p[N];struct Edge {int a, b, w;bool operator< (const Edge & W)const{return w < W.w…

浅析Linux SCSI子系统:错误恢复

文章目录 概述SCSI错误恢复处理添加错误恢复命令错误恢复线程scsi_eh_ready_devs IO超时处理相关参考 概述 IO路径是一个漫长的过程&#xff0c;从SCSI命令请求下发到请求完成返回&#xff0c;中间的任何一个环节出现问题都会导致IO请求的失败。从SCSI子系统到低层驱动&#x…

【快手小玩法-弹幕游戏】开发者功能测试报告提交模板

背景 快手有明确的要求&#xff0c;准入和准出更加严格&#xff0c;要求有明确的测试报告。格式如下&#xff1a; *本文参考字节wiki&#xff1a;CP侧测试报告模板(复制填写轻雀文档) 其他文章推荐&#xff1a;【抖音小玩法-弹幕游戏】开发者功能测试报告提交模板 一、前言…

Java后端开发面试题——集合篇

ArrayList底层的实现原理是什么 底层数据结构 ArrayList底层是用动态的数组实现的 初始容量 ArrayList初始容量为0&#xff0c;当第一次添加数据的时候才会初始化容量为10 扩容逻辑 ArrayList在进行扩容的时候是原来容量的1.5倍&#xff0c;每次扩容都需要拷贝数组 添加逻…

MMSegmentation训练自己的语义分割数据集

全流程&#xff0c;训练语义分割数据集 数据标注json转mask 运行源码MMSegmentation模型选择运行部分 数据标注 # 安装 pip install labelme # 启动labelme labelme然后 ctrl N 开启多边形标注即可&#xff0c;命名类为person 之后会保存到同目录下json文件&#xff1a; js…

WordPress(6)网站侧边栏倒计时进度小工具

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 效果图在这里插入图片描述一、添加位置二、主题style.css文件中添加美化1.引入库2.添加自定义的HTML模块效果图 提示:以下是本篇文章正文内容,下面案例可供参考 一、添加位置 在主题中 child.js…

【1++的数据结构】之AVL树

&#x1f44d;作者主页&#xff1a;进击的1 &#x1f929; 专栏链接&#xff1a;【1的数据结构】 文章目录 一&#xff0c;什么是AVL树二&#xff0c;AVL树的插入三&#xff0c;AVL树的旋转3.1 向左旋转3.2 向右旋转3.3 左右双旋3.4 右左双旋 四&#xff0c;验证AVL树是否平衡 …

Data truncation: Out of range value for column ‘id‘ at row 1

错误信息&#xff1a;Data truncation: Out of range value for column id at row 1 数据截断&#xff1a;第1行“id”列的值超出范围 很多人会回复&#xff1a;数据库 类型由int改为 bigInt 我看了表结构 可以放的下的。 是 bigint(20) 没有问题啊。 默认的 bigint 类型…

C语言面试题值反转字符串

知识捡漏本 1.C语言优先级 &#xff1a;左高于高于 右 2.定义宏函数product&#xff0c;调用product后&#xff0c;里面的i和i都是加两次1&#xff0c;i就是两个加2后的i相乘&#xff0c;i是开始的i和1后的i相乘。 3.用i (j4,k 8,m 16);这种定义方法&#xff0c;最终i和最后一…

dji uav建图导航系列()ROS中创建dji_sdk节点包(一)项目结构

文章目录 1、整体项目结构1.1、 目录launch1.2、文件CMakeLists.txt1.3、文件package.xml1.4、目录include1.4、目录srv在ROS框架下创建一个无人机的节点dji_sdk,实现必需的订阅(控制指令)、发布(无人机里程计)、服务(无人机起飞降落、控制权得很)功能,就能实现一个类似…

全球免费编程教育网站:Code.org

全球免费编程教育网站&#xff1a;Code.org 官网地址注册使用 你还在为小朋友的编程教育而发愁吗&#xff1f; 你还在为小朋友放假无聊而头疼吗&#xff1f; 他来了他来了&#xff0c;全球免费编程教育网站来了。 2013年成立的Code.org是一个非营利组织。 它致力于为年轻女子、…

【RISC-V】RISC-V寄存器

一、通用寄存器 32位RISC-V体系结构提供32个32位的整型通用寄存器寄存器别名全称说明X0zero零寄存器可做源寄存器(rs)或目标寄存器(rd)X1ra链接寄存器保存函数返回地址X2sp栈指针寄存器指向栈的地址X3gp全局寄存器用于链接器松弛优化X4tp线程寄存器常用于在OS中保存指向进程控…

Qt/C++编写视频监控系统81-Onvif报警抓图和录像并回放

一、前言 视频监控系统中的图文警情模块&#xff0c;是通过Onvif协议的事件订阅拿到的&#xff0c;通过事件订阅后&#xff0c;设备的各种报警事件比如入侵报警/遮挡报警/越界报警/开关量报警等&#xff0c;触发后都会主动往订阅者发送&#xff0c;而且一般都是会发送两次&…

Node.js crypto模块 加密算法

背景 微信小程序调用飞蛾热敏纸打印机&#xff0c;需要进行参数sig签名校验&#xff0c;使用的是sha1进行加密 // 通过crypto.createHash()函数&#xff0c;创建一个hash实例&#xff0c;但是需要调用md5&#xff0c;sha1&#xff0c;sha256&#xff0c;sha512算法来实现实例的…

企业架构LNMP学习笔记7

PHP介绍&#xff1a; HTML&#xff1a;超文本标记语言 http: 超文本传输协议 端口80 浏览器将html代码解析成web页面。 PHP&#xff1a;超文本预处理器。后端语言开发&#xff0c;页面上需要动态改变修改的&#xff0c;需要连接数据库查询数据&#xff0c;转为html。 主要…

流媒体弱网优化之路(BBR应用)——GCC与BBR的算法思想分析

流媒体弱网优化之路(WebRTC)——GCC与BBR的算法思想分析 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标&#xff1a;可以让大家熟悉各类Qos能力、带宽估计能力&#xff0c;提供每个环节关键参数调节接口并实现一个json全配置&…

WebSocket(一)

一.什么是WebSocket 【1】WebSocket是一种协议&#xff0c;设计用于提供低延迟&#xff0c;全双工和长期运行的连接。 全双工&#xff1a;通信的两个参与方可以同时发送和接收数据&#xff0c;不需要等待对方的响应或传输完成。 【2】比较 传统通信&#xff08;http协议&am…

Docker 的快速使用

ubuntu安装 centos安装 安装完毕之后执行一下这条命令&#xff0c;可以避免每次使用docker命令都需要sudo权限 sudo usermod -aG docker $USER阿里云docker镜像加速 DockerHub 遇到不懂或者不会使用的命令可以使用docker --help查看文档 docker --help 如&#xff1a; dock…