news 2026/9/29 16:11:16

安卓系统镜像解包打包全链路:simg2img、make_ext4fs 与 mkuserimg.sh 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
安卓系统镜像解包打包全链路:simg2img、make_ext4fs 与 mkuserimg.sh 实战

简介:这份资源是面向Android系统开发者、ROM制作人和设备调试者的已编译工具集,用于解决系统镜像解包、打包与格式转换等操作需求。包内共4个文件,包含make_ext4fs、simg2img、img2simg三个可执行程序及一个mkuserimg.sh脚本,压缩包约136KB,体积轻便,解压后可直接在命令行调用。其中img2simg与simg2img负责稀疏镜像与标准镜像的双向转换,make_ext4fs用于生成ext4文件系统镜像,mkuserimg.sh则整合内核、根文件系统等组件生成完整用户镜像。已有2942人学习下载,说明该工具集在镜像处理场景中具有实际参考价值。借助这套工具,读者可快速完成分区镜像的转换、文件系统构建与用户镜像打包,理解Android系统内部结构,并为定制系统与调试问题提供可复用的命令行方案。

1. 安卓系统镜像解包打包:从 img 到 ext4 再回到 img 的完整链路

手里拿到一个安卓设备的固件包,解压出来一堆.img文件,想改里面的东西——换个开机动画、删几个预装应用、调一下build.prop——结果发现这些 img 根本不是能直接挂载的格式。这是做安卓系统裁剪、机顶盒定制、行车记录仪固件改造时最常撞上的第一堵墙。img2simg、make_ext4fs、mkuserimg.sh、simg2img这四个工具,就是拆墙的整套家伙事。它们解决的核心问题只有一个:安卓的system.img、vendor.img这类分区镜像,在 sparse 格式和 ext4 格式之间来回转换,并且能重新打包成设备能识别的镜像。适合谁?做 ROM 定制的、搞机顶盒系统裁剪的、折腾开发板安卓移植的,以及任何需要修改安卓分区内容再刷回去的人。这套工具集已经编译好,意味着你不需要从 AOSP 源码树里单独编它们,拿到就能用。

2. 四个工具各管什么:先搞清楚 sparse 和 ext4 的区别

2.1 为什么安卓镜像不能直接 mount

安卓的system.img在出厂时通常是sparse 格式(也叫 Android sparse image)。这种格式不是文件系统的真实布局,而是一种压缩表示——它把连续的零数据块用简短的头部描述代替,目的是让镜像文件更小、刷机时写入更快。你直接mount -o loop system.img /mnt会失败,因为内核的 loop 设备不认识 sparse 头部。

要修改里面的内容,必须先把 sparse 转成raw ext4 格式,这时候它才是一个真正的 ext4 文件系统镜像,可以挂载、可以读写。改完之后,再转回 sparse 格式,或者直接打包成设备能刷的镜像。

四个工具的分工是这样的:

工具方向作用
simg2imgsparse → raw把 sparse 镜像转成 raw ext4 镜像
img2simgraw → sparse把 raw 镜像转回 sparse 格式
make_ext4fs目录 → ext4从一个目录生成 ext4 文件系统镜像
mkuserimg.sh目录 → img封装脚本,调用 make_ext4fs 并处理权限、selinux 等

实际工作流通常是:simg2img解开 → mount 修改 → 用make_ext4fs或mkuserimg.sh重新打包 → 必要时img2simg转回 sparse。

2.2 simg2img 和 img2simg 的最小用法

先确认工具可执行:

chmod +x simg2img img2simg make_ext4fs mkuserimg.sh ./simg2img --help

如果输出用法说明,说明工具链没问题。接下来做转换:

# sparse 转 raw,得到可挂载的 ext4 镜像 ./simg2img system.img system_raw.img # 查看转换后的文件类型 file system_raw.img # 期望输出:Linux rev 1.0 ext4 filesystem data ... # 挂载查看内容 mkdir -p /mnt/system sudo mount -o loop system_raw.img /mnt/system ls /mnt/system

simg2img的输入是 sparse 格式,输出是 raw 格式。转换后的文件通常比原文件大很多,因为零数据块被展开了。这是正常的,不用担心。

反过来,改完之后如果要转回 sparse:

# raw 转 sparse ./img2simg system_raw.img system_new.img # 验证 file system_new.img # 期望输出:Android sparse image ...

注意:img2simg默认的 sparse 头部版本和块大小可能和原厂不一致。有些设备对 sparse 格式有严格要求,如果刷回去不认,需要加参数调整。

2.3 make_ext4fs 的关键参数怎么设

make_ext4fs是从一个目录直接生成 ext4 镜像的工具。它的基本用法:

./make_ext4fs -l 2048M -s -a system system_new.img /path/to/system_dir

参数逐个说清楚:

  • -l 2048M:指定镜像大小。这个值必须大于目录实际内容大小,否则会报错。一般设成比原分区略大或相等。如果不知道原分区大小,可以用du -sh /path/to/system_dir看实际占用,然后留 10% 余量。
  • -s:生成 sparse 格式。不加这个参数生成的是 raw ext4。如果你后面还要用img2simg,这里就不加-s。
  • -a system:指定挂载点名称。这个参数影响镜像内部的挂载信息,一般填分区名,比如system、vendor、userdata。
  • 最后一个参数是输出文件名,再后面是源目录。

常见翻车点:-l设小了,打包到一半报 “No space left on device”。解决办法是先du -sb看目录字节数,再往上取整。

2.4 mkuserimg.sh 帮你处理了哪些脏活

mkuserimg.sh是一个 shell 封装脚本,内部调用make_ext4fs,但它额外处理了几件事:

./mkuserimg.sh -s /path/to/system_dir system_new.img ext4 system 2048M

参数顺序是:-s(生成 sparse)、源目录、输出文件、文件系统类型、挂载点、分区大小。

它比直接调make_ext4fs多做的事包括:设置正确的文件权限和 SELinux 上下文标签、处理file_contexts文件、确保lost+found目录存在。如果你直接make_ext4fs打包出来的镜像刷进去后出现权限拒绝或 SELinux 报错,大概率就是少了这些处理。

提示:不同安卓版本的mkuserimg.sh参数顺序可能不同。拿到工具后先cat mkuserimg.sh看一眼内部实现,确认参数顺序再执行。

3. 完整实操:改一个 system.img 并重新打包刷回

3.1 从固件包里定位并解开 system.img

假设你拿到一个固件包,解压后目录结构是这样的:

firmware/ ├── system.img ├── vendor.img ├── boot.img └── ...

先确认system.img是不是 sparse 格式:

file system.img # 输出可能是:Android sparse image, version: 1.0, ... # 也可能是:Linux rev 1.0 ext4 filesystem data ...

如果是 sparse,用simg2img转换:

./simg2img system.img system_raw.img

如果是 raw ext4,跳过这步。然后挂载:

sudo mkdir -p /mnt/android_system sudo mount -o loop,rw system_raw.img /mnt/android_system

-o rw表示以读写方式挂载,这样你可以直接修改内容。如果只想查看,不加rw也行。

3.2 修改内容时的权限和 SELinux 坑

挂载之后,你可以删应用、改配置。但有几个坑必须提前知道:

权限问题:安卓系统目录里的文件权限和普通 Linux 不一样。比如/system/bin下的可执行文件通常是755,/system/etc下的配置文件可能是644。如果你用cp覆盖文件,默认权限可能不对,导致刷进去后服务起不来。改完之后用chmod和chown修正:

# 示例:确保文件权限正确 sudo chmod 755 /mnt/android_system/bin/some_binary sudo chown root:root /mnt/android_system/bin/some_binary

SELinux 上下文:安卓 5.0 以后 SELinux 是 enforcing 模式,每个文件都有安全上下文标签。如果你新增了文件但没有打标签,开机后 init 进程会拒绝访问。查看当前标签:

ls -Z /mnt/android_system/bin/

如果新增文件需要打标签,用chcon:

sudo chcon u:object_r:system_file:s0 /mnt/android_system/bin/new_file

但更稳妥的做法是:修改完后,用mkuserimg.sh重新打包,它会根据file_contexts自动处理标签。前提是你的工具目录里有对应设备的file_contexts文件。

3.3 用 mkuserimg.sh 重新打包并验证

修改完成后,先卸载:

sudo umount /mnt/android_system

然后打包。假设你要生成 sparse 格式的镜像:

./mkuserimg.sh -s /path/to/modified_system system_new.img ext4 system 2048M

如果mkuserimg.sh报错找不到make_ext4fs,检查脚本里的路径变量,或者把make_ext4fs放到 PATH 里:

export PATH=$PATH:/path/to/tools

打包完成后验证:

# 确认是 sparse 格式 file system_new.img # 转回 raw 再挂载检查内容是否完整 ./simg2img system_new.img system_check.img sudo mount -o loop system_check.img /mnt/check ls /mnt/check sudo umount /mnt/check

如果挂载后能看到你修改的内容,说明打包成功。

3.4 刷回设备前的最后检查

刷机有风险,刷前先确认几件事:

  • 镜像大小是否超过分区大小。用ls -l system_new.img看文件大小,对比设备分区表里system分区的大小。超过的话刷进去会失败甚至变砖。
  • sparse 格式版本是否匹配。有些老设备只认 sparse v1,新工具默认可能生成 v2。如果刷不进去,试试img2simg的兼容参数。
  • 是否有回滚方案。刷之前把原厂system.img备份好,最好确认设备有 fastboot 或 recovery 模式可以救回来。

4. 避坑指南:五个让新手翻车的典型场景

4.1 挂载报 “wrong fs type” 或 “bad option”

现象:mount -o loop system.img /mnt报错,提示文件系统类型不对。

原因:system.img还是 sparse 格式,没有转成 raw ext4。内核的 loop 设备不认识 sparse 头部。

解决:先执行./simg2img system.img system_raw.img,再挂载system_raw.img。用file命令确认转换后的格式是 ext4。

4.2 make_ext4fs 报 “No space left on device”

现象:打包到一半失败,提示空间不足。

原因:-l参数指定的镜像大小小于源目录实际内容大小。make_ext4fs需要预留 inode 和块的开销,实际可用空间比-l值略小。

解决:用du -sb /path/to/dir看目录字节数,然后-l设成这个值乘以 1.1 到 1.2。如果目录里有大量小文件,还要考虑 inode 数量,可以加-i参数调整 inode 大小。

4.3 刷进去后开机卡 logo 或无限重启

现象:镜像刷入成功,但设备开不了机。

原因:最常见的是 SELinux 上下文丢失或权限不对。其次是删除了系统关键组件,或者build.prop改错了参数。

解决:先用mkuserimg.sh重新打包,确保 SELinux 标签正确。如果还是不行,对比原厂镜像和你修改后的镜像,用diff看目录结构差异。重点检查/system/bin/init、/system/etc/init/下的 rc 文件、以及build.prop里的ro.开头属性。

4.4 img2simg 转出来的镜像刷不进去

现象:img2simg转换成功,但 fastboot 刷入时报错。

原因:sparse 头部版本或块大小不匹配。不同设备对 sparse 格式的支持程度不同。

解决:试试img2simg的-b参数指定块大小,或者直接用make_ext4fs -s生成 sparse 格式,而不是先 raw 再转。另外确认输出文件大小没有超过分区限制。

4.5 挂载后修改文件,重新打包发现修改丢失

现象:明明在挂载目录里改了文件,打包后挂载检查发现还是旧内容。

原因:可能是挂载时用了只读模式,或者修改后没有sync就卸载。还有一种可能是打包时源目录指错了。

解决:挂载时加-o rw,修改后执行sync,再umount。打包前用ls确认源目录里确实有你修改的内容。如果用的是mkuserimg.sh,确认第一个参数是修改后的目录路径。

5. 进阶技巧:用 file_contexts 和 fs_config 精确控制打包结果

前面提到mkuserimg.sh会自动处理 SELinux 标签和权限,但前提是工具目录里有正确的file_contexts和fs_config文件。这两个文件决定了镜像里每个文件的权限、所有者和安全上下文。如果你做的定制比较深,比如新增了系统服务或修改了分区布局,就需要自己维护这两个文件。

file_contexts的格式是每行一条规则:

/system/bin/init u:object_r:init_exec:s0 /system/bin/sh u:object_r:shell_exec:s0 /system/etc/init/*.rc u:object_r:system_file:s0

左边是路径,支持通配符,右边是 SELinux 上下文。打包时make_ext4fs会读取这个文件,给匹配的文件打上对应标签。

fs_config的格式是:

system/bin/init 0 0 755 system/bin/sh 0 0 755 system/etc/build.prop 0 0 644

每行是:相对路径、uid、gid、权限模式。这个文件控制文件所有者和权限位。

实际使用时,把这两个文件放在工具目录下,然后调用:

./make_ext4fs -l 2048M -s -a system -S file_contexts -C fs_config system_new.img /path/to/system_dir

参数说明:-S指定 SELinux 上下文文件,-C指定权限配置文件。这样打包出来的镜像,每个文件的权限和标签都是精确控制的,不依赖源目录的当前状态。

我自己的习惯是:每次修改系统目录后,先diff对比原厂file_contexts和fs_config,确认新增文件有没有对应的规则。如果没有,手动补上再打包。这个步骤多花五分钟,能省掉刷机后排查 SELinux 拒绝的大量时间。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 16:10:58

Unity接入华为HMS SDK实战:登录支付回调与避坑指南

简介:本资源是面向Unity开发者的华为HMS SDK接入示例工程,适合需要在华为设备上集成账号、游戏、推送等服务的移动游戏与应用开发者参考。压缩包共约2000个文件,以bin、info、class、meta、java、xml、png、jar、cs、dll等为主,涵…

作者头像 李华
网站建设 2026/9/29 16:10:53

用 lark-cli 一个月后,我把飞书 AI 操作接进了 TaoToken 统一通道

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 16:10:16

社交网络提示设计实战:采写改测存五环节的10个高效工具

上个月我们团队做了一次内容矩阵复盘,结果让我很意外:同样是追一个热点话题,五个人各自写提示词,产出的稿子风格像五家不同的号。有人写得像新闻通稿,有人写得像朋友圈碎碎念,还有人写成了产品说明书。问题…

作者头像 李华
网站建设 2026/9/29 16:09:46

MySQL InnoDB事务底层原理:隔离级别、redo log与MVCC面试要点

最近几轮技术面试里,MySQL事务几乎成了必问项。而且问得越来越细,不是“事务的四个特性是什么”这种背诵题,而是“InnoDB里一条UPDATE到底是怎么提交的”“RR隔离级别会不会出现幻读”“你们生产环境为什么用默认的RR而不是RC”,这…

作者头像 李华