简介:这份资源是面向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 格式,或者直接打包成设备能刷的镜像。
四个工具的分工是这样的:
| 工具 | 方向 | 作用 |
|---|---|---|
simg2img | sparse → raw | 把 sparse 镜像转成 raw ext4 镜像 |
img2simg | raw → 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/systemsimg2img的输入是 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_binarySELinux 上下文:安卓 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 拒绝的大量时间。希望帮到你。
本文还有配套的精品资源,点击获取