深入Super.img:用lpunpack拆解与lpmake命令手动打包Android动态分区镜像

张开发
2026/4/17 14:10:06 15 分钟阅读

分享文章

深入Super.img:用lpunpack拆解与lpmake命令手动打包Android动态分区镜像
深入Super.img用lpunpack拆解与lpmake命令手动打包Android动态分区镜像如果你曾经尝试过修改Android系统镜像可能会对super.img这个神秘的容器感到好奇。不同于传统的system.img或vendor.imgsuper.img是一个包含了多个子分区的复合镜像它代表了Android从静态分区向动态分区架构的重大转变。本文将带你深入这个技术细节掌握手动拆解和重组super.img的核心技能。1. 动态分区Android存储架构的进化Android的动态分区Dynamic Partitions设计始于Android 10Q并在Android 11R中成为主流。它解决了传统分区方案中几个关键痛点固定分区大小的限制在传统方案中system、vendor等分区大小在编译时就被固定无法根据实际需求动态调整OTA更新困难当系统需要增加新功能时可能需要重新调整分区布局存储空间浪费每个分区需要预留额外空间导致整体存储利用率低下动态分区通过引入super分区概念将多个逻辑分区如system、vendor、product合并到一个物理分区中。这种设计带来了几个显著优势特性传统分区动态分区分区大小固定不变可动态调整存储利用率较低需预留空间较高共享空间池OTA灵活性受限更灵活管理复杂度简单需要额外元数据管理在底层实现上动态分区利用了Linux内核的device-mapper框架特别是dm-linear目标。启动时bootloader会加载super分区init进程则负责解析其中的元数据并创建对应的虚拟块设备。2. 工具链准备获取lpunpack和lpmake要操作super.img我们需要两个关键工具lpunpack用于解包和lpmake用于打包。虽然这些工具是AOSP的一部分但它们默认不会被编译需要手动构建。2.1 从源码编译工具假设你已经配置好了Android编译环境以下是获取这些工具的步骤# 进入AOSP根目录 source build/envsetup.sh lunch aosp_arm64-eng # 或选择你的目标设备 # 单独编译分区工具 make lpunpack lpmake编译完成后工具会出现在以下路径out/host/linux-x86/bin/lpunpackout/host/linux-x86/bin/lpmake提示如果你不想编译整个AOSP也可以只初始化构建环境并单独编译这些工具。2.2 验证工具可用性使用--help参数检查工具是否正常工作out/host/linux-x86/bin/lpunpack --help out/host/linux-x86/bin/lpmake --help你应该能看到各自的用法说明。如果遇到权限问题记得给这些二进制文件添加可执行权限。3. 解构super.img使用lpunpack深入分析有了lpunpack我们就可以开始解剖super.img了。这个镜像通常位于设备的/dev/block/by-name/super或刷机包的super.img中。3.1 基本解包命令解包super.img的基本命令格式如下lpunpack super.img output_dir/这个命令会将super.img中的所有子分区提取到指定的输出目录。例如mkdir unpacked lpunpack super.img unpacked/解包完成后你会在输出目录中看到类似这样的文件结构unpacked/ ├── system.img ├── vendor.img ├── product.img └── system_ext.img3.2 高级解包选项lpunpack还提供了一些有用的选项-p partition只解包指定的分区-v详细输出模式-s处理稀疏镜像例如只解包system分区lpunpack -p system super.img unpacked/3.3 分析解包结果解包后你可以使用标准工具进一步分析各个子镜像# 检查system.img文件系统类型 file unpacked/system.img # 挂载system.img进行检查 mkdir system_mount sudo mount -o loop unpacked/system.img system_mount对于Android 10的镜像你可能会发现它们是erofs文件系统而不是传统的ext4sudo mount -t erofs -o loop unpacked/system.img system_mount4. 重组super.img掌握lpmake的艺术解包只是第一步真正的技术在于如何修改后重新打包。这就是lpmake的用武之地。4.1 lpmake命令结构lpmake的基本语法如下lpmake --metadata-size size \ --metadata-slots count \ --device device_name:size \ --group group_name:size \ --partition name:attr:size:group \ --image namefile \ --sparse \ --output output.img让我们分解这些关键参数--metadata-size元数据区域大小通常65536字节--metadata-slots元数据副本数量通常2或3--device指定super分区设备名和总大小--group定义分区组及其可用空间--partition定义单个分区的属性--image关联分区名和实际镜像文件--sparse生成稀疏镜像--output指定输出文件4.2 实际打包示例假设我们要打包包含system和vendor分区的super.img命令可能如下lpmake --metadata-size 65536 \ --metadata-slots 2 \ --device super:4294967296 \ --group main:3221225472 \ --partition system:readonly:1610612736:main \ --image systemsystem.img \ --partition vendor:readonly:1073741824:main \ --image vendorvendor.img \ --sparse \ --output new_super.img4.3 参数详解**分区属性attr**可以包含以下标志的组合readonly分区只读none无特殊属性slotselect支持A/B分区的槽选择分区组概念允许你将多个分区组织在一起共享存储空间。这在A/B系统更新中特别有用。元数据管理是动态分区的核心。--metadata-slots指定了元数据的副本数量这提高了系统的可靠性。通常建议使用2或3个副本。5. 实战技巧与常见问题5.1 确定分区大小获取正确分区大小的方法从原super.img的元数据中提取使用lpdump工具如果可用查看原始配置根据实际镜像文件大小计算# 获取system.img的实际大小字节 stat -c %s system.img5.2 处理稀疏镜像Android系统镜像通常使用稀疏格式节省空间。如果你处理的是稀疏镜像解包时添加-s参数打包时添加--sparse参数可以使用img2simg和simg2img工具转换格式5.3 调试技巧当lpmake失败时可以增加-v参数获取详细输出检查元数据大小是否足够通常65536字节确保分区大小总和不超过组大小验证输入镜像的完整性5.4 AVB2.0验证考虑如果你修改了分区内容可能需要处理AVBAndroid Verified Boot验证更新vbmeta签名调整hashtree描述符可能需要禁用验证进行测试# 使用avbtool更新hashtree avbtool add_hashtree_footer --image system.img \ --partition_name system \ --partition_size 1610612736 \ --algorithm SHA256_RSA2048 \ --key testkey.pem \ --salt deadbeef6. 高级应用场景掌握了这些基础知识后你可以尝试更高级的操作6.1 自定义分区布局创建完全自定义的动态分区布局lpmake --metadata-size 65536 \ --metadata-slots 2 \ --device super:6442450944 \ --group custom:5368709120 \ --partition my_system:readonly:3221225472:custom \ --image my_systemcustom_system.img \ --partition my_vendor:readonly:1073741824:custom \ --image my_vendorcustom_vendor.img \ --output custom_super.img6.2 合并多个更新包在OTA场景中可能需要合并多个更新包的分区解包两个版本的super.img选择性替换需要更新的分区重新打包为新的super.img6.3 开发调试技巧对于系统开发者可以快速验证分区大小调整的影响测试不同的文件系统组合调试init阶段的挂载问题# 在模拟器上测试自定义super.img emulator -partition-size 4096 -superimage custom_super.img7. 底层原理深入要真正掌握动态分区需要理解其底层实现机制。7.1 元数据结构super.img的元数据使用protobuf格式存储主要包含分区列表名称、大小、属性组定义名称、最大大小、分区列表区块分配信息校验和数据7.2 设备映射器交互启动时init进程会读取super分区的元数据验证元数据的完整性和有效性通过device-mapper创建设备节点为每个逻辑分区建立映射关系这个过程可以在first_stage_mount的日志中观察到。7.3 与dm-verity的集成动态分区与Android的验证启动AVB紧密集成vbmeta包含vbmeta_system的描述符vbmeta_system包含super分区中各子分区的描述符每个子分区可以独立进行hashtree验证这种分层验证机制既保持了安全性又提供了灵活性。

更多文章