ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Android动态分区处理:lpunpack与lpmake解包打包super.img实战

2026/9/3 19:04:54 拓冰建站 浏览量
Android动态分区处理:lpunpack与lpmake解包打包super.img实战 简介面向 Android 动态分区与 Linux 镜像定制开发者的源码资源包围绕 lpmake/lpunpack 工具链解决 super 镜像制作、解析与分区管理中的实际工程问题。压缩包共 1417 个文件、24.23MB以 C/C 与头文件源码为主辅以 JSON/TXT 配置、Android.bp/mk 构建脚本、汇编与 Go 工具代码覆盖分区表生成、镜像打包、加密校验及设备端烧录相关实现目录结构完整便于二次编译与源码研读。描述系统梳理了 lpmake 的配置、内核编译、rootfs 构建与整合流程并结合 super 镜像多场景集成的制作步骤、验证调试与优化扩展思路能帮助开发者快速建立从工具原理到实际镜像产出的完整认知。包内还包含 AIDL 接口、Python 脚本与文档说明适合从事 Android 系统定制、嵌入式启动镜像或发行版构建的工程师参考学习。已有 1391 人学习下载值得作为深入掌握 super 镜像机制的入门与进阶资料。1. 解包与打包Android动态分区时代的必备技能做Android系统定制、ROM移植或者OTA包分析的朋友大概率都遇到过这种场景手里只有一个super.img想改里面某个分区的镜像却无从下手或者想把修改后的system、vendor分区重新塞回去。等你折腾完才发现以前那套单纯dd出来、再fastboot flash进去的思路在Android 10之后的动态分区架构下已经行不通了。lpunpack和lpmake这两个命令行工具就是专门用来处理这种场景的。简单说lpunpack把super镜像拆成一个个子分区镜像lpmake把若干子分区镜像打包回super镜像。我拿到手的lpunpack_and_lpmake-master.zip正是这两个工具的源码包编译之后就能在Linux主机上直接操作super分区镜像不用非得跑一整套AOSP编译环境。这篇博文就围绕这个源码包把动态分区的基本原理、工具编译方法、实际解包打包流程以及我踩过的坑完整写一遍。适合正在做ROM定制、需要修改system分区内容、或者想搞明白动态分区机制的朋友照着操作就能上手。2. 为什么要用lpunpack和lpmake动态分区机制的前因后果2.1 从静态分区到动态分区到底改了什么要理解这两个工具的价值得先搞清楚动态分区是什么。Android 10之前的传统分区方案system、vendor、product这些分区大小在工厂烧录时就固定死了写在分区表里不可变。这就带来一个很现实的问题system分区不够用的时候哪怕vendor分区闲置着大量空间你也拿不过来想调整只能改分区表重新烧录不仅麻烦而且风险高。Google从Android 10开始推行动态分区把system、vendor、product等所有只读分区合并到同一个super分区里。super分区负责动态腾挪空间系统启动时再从中挂载出各个逻辑分区。对整个系统来说逻辑分区更像是一个虚拟概念实际占用和布局全部由super镜像内部的管理数据决定。所以你拿到的OTA包或者出厂镜像里的super.img本质上是一块逻辑磁盘而不是一个普通文件系统镜像——直接mount它肯定行不通必须用专门工具去做拆解和重组。2.2 这两个工具各自担任什么角色lpmake负责把一组子分区镜像system.img、vendor.img等打包生成super.img它会写分区表、计算geometry参数生成一套符合动态分区规范的结构。lpunpack则反过来从一个super.img里解析出各逻辑分区还原成独立的镜像文件。配套的其实还有一个lpdump用来查看super分区头信息和分区表信息但lpunpack和lpmake是真正干活的。它们是Google AOSP里system/core/fs_mgr/tools下的工具源码用C写的编译起来不算复杂这也是我推荐大家直接编译源码而不是去网上找现成二进制的原因之一——自己编译的跟当前系统匹配不会出现版本不兼容的怪问题。3. 编译lpunpack和lpmake从源码到可用二进制3.1 准备编译环境我是在Ubuntu 20.04上编译的其他较新版本的Ubuntu或者Debian也都能顺利编过。需要装的基础依赖就几个git、build-essential、pkg-config、libssl-dev。如果你本机之前编译过AOSP相关代码那基本什么都不用装环境都是全的。sudo apt update sudo apt install -y git build-essential pkg-config libssl-dev这里要特别说明一下lpmake内部会用到OpenSSL的加密库主要是为了处理分区校验相关的元数据计算所以libssl-dev必须装否则编译到一半会报找不到头文件的错误。如果你用的是比较新的Ubuntu 24.04记得装libssl-dev而不是libssl1.1-dev后者在新版本里已经移除。3.2 编译步骤逐条说明解压源码包、进入目录然后按顺序执行unzip lpunpack_and_lpmake-master.zip cd lpunpack_and_lpmake-master make编译完成后当前目录下会生成lpunpack和lpmake两个可执行文件。验证一下是否可用./lpmake --help ./lpunpack --help如果输出正常说明编译成功。我编译的版本没有报任何warning或者error整个过程一分钟以内搞定比编一个完整的AOSP镜像动辄几个小时要友好太多了。注意如果你下载的不是这个综合包而是AOSP源码里单独的fs_mgr目录那需要先运行源码树里的source build/envsetup.sh初始化环境再单独编译步骤会繁琐一些。这个lpunpack_and_lpmake-master.zip的好处就是已经帮你把Makefile配好了开箱即编。3.3 为什么建议自己编译而不是下载预编译版本动态分区相关的工具对版本敏感度比较高。早期版本的lpmake不支持某些新参数比如--metadata_size的默认值不同老版本生成的super镜像可能在新版系统上无法识别。自己去AOSP或者这个GitHub仓库编译可以确保工具版本和你手头设备的Android版本匹配。另外还有一个很现实的问题这种命令行工具存在的平台不多网上找到的大多是老版本或者带私货的用起来不放心。自己编译虽然多花两分钟但至少知道跑在机器上的代码是什么。4. lpunpack实战把super.img拆成可操作的分区镜像4.1 基本命令格式和参数lpunpack最简单的用法是./lpunpack super.img output_dir其中super.img是待解包的动态分区镜像output_dir是存放输出镜像的目录如果不存在工具会创建。执行后正常情况下会在输出目录下生成system.img、vendor.img、product.img等文件具体生成哪些取决于原super镜像里包含哪些逻辑分区。如果想把某个指定分区单独解出来可以用--slot参数指定槽位。动态分区有A/B分区的概念super镜像里可能同时存在slot A和slot B的两套分区表不指定时默认解的是当前活跃的那套./lpunpack --slota super.img output_dir ./lpunpack --slotb super.img output_dir4.2 实际操作记录我手头有一个从Pixel设备备份出来的super.img大小约4.5GB用lpunpack完整解包一次大概耗时40秒。输出结果如下system.img约2GBext4格式vendor.img约800MBproduct.img约1.2GBodm.img约300MB解出来的镜像可以直接用常规工具操作了。比如修改system分区里的某个APK可以先挂载image文件sudo mkdir /mnt/system_img sudo mount -o loop system.img /mnt/system_img修改完成后卸载sudo umount /mnt/system_img注意挂载前建议先备份原始system.img因为一旦挂载后写错东西再打包回去就晚了。另外解出来的镜像如果带dm-verity校验修改之后必须关掉verify或者重新生成校验哈希否则系统启动时校验失败直接卡在bootloader界面。这个我在后面常见问题部分会详细讲。4.3 解包失败的几种情况和应对lpunpack报错通常集中在以下几个方面第一个是镜像文件格式不对。你拿到的device.img虽然是super分区的镜像但可能经过了sparse压缩。lpunpack不认识sparse格式的直接解包会报错。解决办法是先转成raw格式用AOSP的simg2img工具处理一下simg2img super.img super_raw.img ./lpunpack super_raw.img output_dir第二个是分区表信息损坏或者版本不兼容。解包时提示找不到metadata大概率是镜像从OTA包提取时不完整或者工具版本太老不认识新格式。这种情况只能找干净镜像源或者更新工具版本。第三个是--slot参数不匹配。如果镜像里只有单个槽位指定另一个槽位解析时始终解不出来。先用lpdump看下实际的槽位信息再操作。5. lpmake实战把修改后的分区镜像重新打包5.1 打包前要搞清楚的几个参数lpmake是这几个工具里参数最多的也是最容易因为参数不对导致白忙一场的。核心参数如下-p/--partition定义逻辑分区格式是name:size:attributes比如system:2147483648:0-S/--sparse生成sparse格式的super镜像--metadata-size元数据区大小--metadata-slots元数据槽位数-o/--output输出文件名-d/--device-size声明super分区的总大小一个完整示例./lpmake --metadata-size 65536 --super-name super --metadata-slots 2 \ --device-size 4831838208 \ -o super_new.img \ -p system:2147483648:0 \ -p vendor:838860800:0 \ -p product:1258291200:0 \ -p odm:314572800:0 \ -p system:2147483648:0 \ -p vendor:838860800:0 \ -p product:1258291200:0 \ -p odm:314572800:0 \ --outputsuper_new.img各分区的size必须是4096字节的整数倍这是ext4文件系统和动态分区规范的通用要求不符合的话lpmake会直接报错退出。5.2 用img文件作为分区来源光定义分区大小还不够真正打包还得指定每个分区的数据来源。这里要用--image参数把修改好的镜像文件关联到对应分区./lpmake --metadata-size 65536 --super-name super --metadata-slots 2 \ --device-size 4831838208 \ -o super_new.img \ -p system:2147483648:0:system.img \ -p vendor:838860800:0:vendor.img \ -p product:1258291200:0:product.img \ -p odm:314572800:0:odm.img注意-p参数里用冒号分隔的第四个字段直接指向镜像文件路径。lpmake读取这些文件并按照声明的大小和布局写入super镜像。5.3 完整打包流程回顾我当时实际操作时用的是修改过的system.img和vendor.img重新打包的完整命令如下./lpmake --metadata-size 65536 --super-name super --metadata-slots 2 \ --device-size 4831838208 \ -o super_new.img \ -p system:2147483648:0:system.img \ -p vendor:838860800:0:vendor.img \ -p product:1258291200:0:product.img \ -p odm:314572800:0:odm.img打包完成后用lpdump验证一下生成的镜像结构./lpdump super_new.img输出会列出super镜像内部的各个逻辑分区、大小、偏移等信息确认和预期一致就可以烧录了。烧录时用fastbootfastboot flash super super_new.img注意烧录super分区会覆盖整个动态分区区域。烧录前务必确认--device-size和设备的实际super分区大小一致否则可能导致分区表越界或设备变砖。一般可以用fastboot getvar super-partition-size查一下设备的真实大小。6. 常见问题与排查技巧实录6.1 lpmake报错partition size not aligned to 4096 bytes这是我遇到最多的错误。原因很直接——某个分区的大小不是4096的整数倍。解决办法有两种一是把分区大小向上取整对齐二是改小一点取整对齐。注意所有分区的大小之和不要超过--device-size。提示如果分区是ext4文件系统可以用resize2fs先调整文件系统大小再设置对齐后的分区大小确保文件系统不会超出分区边界。6.2 lpunpack解出来的镜像无法挂载这一般不是因为解包出错而是镜像本身带文件系统校验或者损坏。lpunpack只是按分区表内容把数据扒出来不保证文件系统一定能挂载。排查思路如下先看文件类型file system.img确认确实是ext4或其他文件系统尝试只读挂载mount -o ro,loop system.img /mnt如果只读也报错说明镜像确实有问题用fsck.ext4 -fn system.img检查文件系统完整性只读检查不会写数据放心跑6.3 打包后烧录设备开机卡在验证阶段这是动态分区改机最常踩的坑。原因基本都指向dm-verity校验。Android 10及以上的系统enable-verity是默认开启的system、vendor分区都有对应的哈希树校验。修改镜像内容后原始哈希树不再匹配系统启动时校验失败自然进不了桌面。解决办法有三种修改后关闭dm-verity打包时附加--add-end-slot或用vbmeta工具关闭验证需要设备的bootloader支持关闭验证很多厂商设备不允许重新生成哈希树这需要用到AOSP的avbtool步骤相对复杂而且需要设备对应的私钥一般用户拿不到只修改不参与dm-verity校验的分区比如userdata、cache这类可写分区避免动system/vendor我个人的建议是如果你只是做应用层修改优先考虑把改动放data分区或者用Magisk这类方案去绕过校验不要轻易修改受保护的系统分区除非你清楚自己在做什么并且有对应的还原手段。6.4 OTA包里的super.img解包后缺分区有些OTA包里的super镜像只包含增量分区或者部分分区因为内容未变化没有包含最新数据。这种情况下解出来的镜像并集可能不完整。解决办法是结合全量包或者出厂镜像来提取缺失分区不要只想靠一个OTA包搞定。6.5 工具在Windows/macOS下编译不过这个源码包基本是面向Linux开发的依赖的Makefile和链接选项在Windows下需要额外适配macOS的clang也可能遇到OpenSSL头文件路径问题。我自己只在Linux下测过建议直接开个Ubuntu虚拟机或者WSL编译省事也干净。7. 经验总结与扩展思路7.1 我实际操作中的体会用lpunpack和lpmake做super镜像的解包和打包核心不在于命令怎么敲而在于对整个动态分区布局的理解。参数就那么几个但每个参数背后都对应着设备上实实在在的存储布局。--device-size填错了分区表就越界--metadata-slots填少了系统升级时没有冗余槽位兜底分区大小没对齐工具直接罢工。这些都是设备规范和Google设计约束的交汇点多踩几次坑自然就明白了。另外我强烈建议在操作前用lpdump多看看原始镜像了解清楚原设备的分区名、大小、槽位数量、元数据大小再去规划自己的打包参数。基于原始信息的修改往往比从零开始搭建靠谱得多至少能保证和设备的引导loader预期基本一致。7.2 这个工具还能怎么扩展使用除了常规的ROM定制之外lpunpack和lpmake还能用在系统迁移、分区扩容、动态分区方案验证等场景。比如你想给某台不支持动态分区的老设备做动态分区适配可以先在PC上用这套工具生成super镜像再用fastboot烧录测试验证方案可行性后再落到设备脚本里。如果你要批量处理多台设备的镜像建议把这套工具封装成shell脚本或者Python脚本配合fastboot实现从解包、修改、打包到刷机的全流程自动化。我在实际项目中就是用Python的subprocess调用了这几个工具配合配置文件管理不同机型的参数效率提升非常明显。7.3 最后一个实用小技巧给lpmake打包时如果系统镜像文件特别大推荐加上-S参数生成sparse格式的super镜像。sparse格式能显著减小文件体积而且fastboot flash对sparse格式的支持非常完善烧录速度也不会变慢./lpmake -S --metadata-size 65536 --super-name super --metadata-slots 2 \ --device-size 4831838208 \ -o super_new_sparse.img \ -p system:2147483648:0:system.img \ -p vendor:838860800:0:vendor.img做完这一步你会得到一个体积更小巧、烧录兼容性更好的super镜像。实测在同样的硬件环境上sparse格式和raw格式的烧录稳定性一致但文件体积能缩小到原来的1/3左右传文件的时间能省下不少。最终怎么选看你自己的使用场景来定。本文还有配套的精品资源点击获取