简介:面向Android发烧友与ROM定制初学者的Android Kitchen V0.223定制工具包,由光头佬开发,用批处理脚本把解压、修改、打包、签名、刷写等繁琐步骤集成到菜单式操作,适合刷机玩家、ROM移植者和入门开发者。版本内置大量机型配置与插件,覆盖系统分区处理、boot.img重构、APK签名、Zipalign优化、内核模块提取、恢复模式刷机、备份与还原等关键环节,并支持扩展模块延展功能。资源共397个文件,以txt说明、c/h源码、plugin插件、jar与apk程序为主,另含busybox、zipalign等可执行工具及三星、HTC多机型适配脚本;压缩包为rar格式,约23.05MB。目前已有598人浏览学习。对希望深入理解Android系统分区、升级脚本与刷机原理的用户,它也是一份可反复拆解的实操样本;通过梳理脚本流程和内置模块,还可直接复用签名、打包、解包等脚本用于个人项目。
1. Android Kitchen 是什么:一个厨子脚本包解决 ROM 定制的整条流水线
刷过机的人应该都经历过这种场景:想精简掉系统里的垃圾应用、想换个开机动画、想改一下默认音量步进,结果打开 ROM 压缩包发现里面躺着一整个分区的镜像,无从下手。Windows 下的 ROM 定制工具大多是图形界面的“黑匣子”,你点几下按钮,它背后做了什么你完全不知道,出了问题也没法排查。而 Android Kitchen 这个小工具走的是另一条路——它是一套由 bash 脚本组成的“厨房”,把解包、定制、重新打包这一整条流水线做成菜单式的命令行操作。V0.223 这个版本是 2013 年前后非常活跃的版本系列,作者署名“光头佬”,在当年的机圈里几乎是做 ROM 定制的手工派标配。
这套工具适合两类人:一类是想把自己手机系统里的无用应用去掉、又不想用别人做好的精简包的用户;另一类是刚开始接触 ROM 制作、想搞懂 image 文件内部到底长什么样的学习者。它解决的核心问题,是让不熟悉 Linux 命令的人也能通过一个交互菜单,完成从 boot.img 解包到最终 zip 刷机包生成的全过程。本文会从工具原理讲到实战命令,最后把我在实际使用中踩过的坑和验证方法一并列出。
2. 厨房里有什么:目录结构、核心脚本和它的定制理念
2.1 解包后的目录像一个后厨工作台
把 Android Kitchen 的压缩包在 Linux 环境里解压后,你会看到一个结构非常清晰的目录树。它不像现在的图形工具那样把所有功能藏在按钮后面,而是把所有中间产物按照工作区、工具区、素材区划分好。顶层目录一般是kitchen/,里面有几个固定目录:original、working、tools、output,还有几个带数字前缀的脚本文件。这套布局从早期版本一直沿用到现在,理解它之后,你在任何一台机器上都能快速定位问题。
cd ~/kitchen ls -FSETUP.sh main.sh menu.sh tools/ original/ working/ output/ utilities/其中的逻辑很直白:original放原厂 ROM 包或者解包后的镜像文件,working是解包出来的可编辑文件系统,output存放重新打包出来的成品。tools目录里是 cmdtools、java、二进制处理程序这些第三方工具,比如unpack_bootimg、mkbootfs这些在 Android 系统编译时也会用到的程序。脚本文件menu.sh是整个厨房的交互入口,你运行它之后会看到一个数字菜单,从解包、编辑、打包到生成可刷入的 zip,全部通过菜单选择。这个设计的好处是:新手不需要记住所有命令,而熟手可以直接绕过菜单调用底层的单个脚本,灵活性反而比图形工具高。
2.2 为什么这套脚本方案能活这么久
Android Kitchen 不是第一个做 ROM 定制的工具,但它能在众多替代品里活下来,核心原因是它的架构思路对路。它把“解包”和“打包”两步做成了标准化脚本,中间的定制过程完全交给用户自由发挥。你在working目录里对文件系统做的任何修改,不管是替换 APK 还是修改build.prop,回包时都会被完整保留。这种“非侵入式定制”的理念很关键——工具只负责拆开和装回去,不负责替你决策改什么,因此它永远不会因为预设方案过时而失效。
对比同期的 DsiXda Kitchen、Cygnus ROM Kitchen 这些分支版本,Android Kitchen V0.223 的差异在于它支持更多的镜像格式和更细的打包选项。比如它对 boot.img 的 ramdisk 压缩方式支持了 gzip、lzma、lzo 等多种选择,对 system.img 的挂载方式也做了兼容处理。实践中你会发现,真正在定制 ROM 时拉胯的往往不是功能多少,而是稳定性。很多工具解包一个几百兆的 system.img 就会卡死或者解出来的文件权限错乱,而这套脚本使用标准的 Linux 工具链做底层操作,只要运行环境没问题,它的成功率非常高。这也是我至今仍在向身边做 ROM 的人推荐它的原因——有些老工具的价值不在于界面华丽,而在于它把脏活累活都干透了。
2.3 定制前必须搞清楚的镜像格式
在动手解包之前,你需要知道 Android 系统镜像的两种主要形式。一块是boot.img,它由内核(kernel)和 ramdisk(根文件系统)拼接而成,负责系统启动阶段的工作;另一块是system.img,它包含了整个 Android 系统目录,APK、jar 包、配置全在这里。老设备上system.img常用 yaffs2 文件系统格式,新一点的设备则是 ext4 的稀疏镜像(sparse image)。Kitchen 解包 system.img 时会自动识别文件系统类型,如果是 ext4 它会尝试挂载(mount)而不是直接解压,因为稀疏镜像必须通过挂载才能正确处理文件权限。
不要小看文件权限这一步。很多人在定制 ROM 时把 APK 放进了working/system/app/,回包之后刷进手机发现应用不见了,或者系统反复重启,十有八九是文件权限没有设置正确。Android 系统目录下的应用要求权限通常是 644,目录是 755,数据文件可能是 600。在 Windows 下用解压软件直接修改 zip 再回刷,出来的包几乎必出问题。Kitchen 之所以值得学,就是因为它强制你走 Linux 文件系统这一条正路,权限和属主都按规则保留。
# 查看 working/system 里一个 app 目录的权限归属 cd ~/kitchen/working/system ls -l app/drwxr-xr-x 2 root root 4096 2025-01-01 10:00 Browser -rw-r--r-- 1 root root 20480 2025-01-05 08:30 Browser.apk如果发现权限不对,直接使用 chmod 和 chown 修正,这是 Kitchen 工作流里最基本的操作。上面看到的root root表示文件的属主和属组,系统应用必须保持这个归属,厂商在定制 ROM 时也是遵循同样的规则。
3. 把厨房架起来:Windows 与 Linux 下的环境准备和第一份菜单
3.1 Windows 下用 Cygwin 还是直接上 Linux
Android Kitchen 的脚本全部是 bash 写的,Windows 本身没办法直接运行。常见的做法是在 Windows 上安装 Cygwin 模拟 Unix 环境,或者使用微软的 WSL(Windows Subsystem for Linux)。我个人的建议是:如果你只是偶尔定制一次,用 Cygwin 够用;如果你打算长期跟 ROM 打交道,干脆装一个 Ubuntu 虚拟机或者直接用 WSL2,后面的麻烦会少很多。Cygwin 的优势在于它的安装是一次性的,不需要重启切换系统,但它在处理大文件的 I/O 速度上不如原生 Linux,而且在挂载镜像时偶尔会抽风。
WSL2 比起 Cygwin 要顺畅不少,因为它是真正的 Linux 内核。在 Windows Terminal 里安装 WSL 后,直接进入 Ubuntu 发行版,然后安装 Kitchen 所需的依赖即可。这里给出一份我在 Ubuntu 22.04 上测试通过的依赖清单:
sudo apt update sudo apt install -y openjdk-8-jdk unzip zip wget \ cpio python2 bc lzma lzop bison flex \ lib32stdc++6 lib32z1默认的 Ubuntu 20.04 和 22.04 都没有预装 Java 8,而 V0.223 这个年代的 ROM 定制工具链还依赖signapk.jar来给最终 zip 签名,这个 jar 用新版本的 Java 运行会报UnsupportedClassVersionError。解决方案是安装 OpenJDK 8,并把它设置为系统默认版本。在 22.04 上可以用下面的命令切换:
sudo apt install -y openjdk-8-jdk sudo update-alternatives --config java参数说明:update-alternatives会列出系统中已安装的所有 Java 版本,输入对应数字回车即可切换到 Java 8。这一步不是可选项,因为回包后的签名是刷机包能否被 Recovery 接受的前提。有些 Recovery 校验签名很认真,签名不过直接拒绝安装。
3.2 Linux 原生环境:把 Kitchen 解压并跑通主菜单
Linux 原生环境下的准备工作要简单得多。下载 Android Kitchen V0.223 的 rar 压缩包后,先要安装解压工具。很多人直接卡在这一步,因为unrar不是系统默认安装的:
sudo apt install -y unrar mkdir -p ~/kitchen && cd ~/kitchen unrar x ~/Android_Kitchen_V0.223_By_光头佬.rar chmod +x *.sh ./menu.sh代码逻辑:第一行安装 unrar 用于解压 rar 格式的压缩包;然后创建专门的~/kitchen工作目录,避免在别处解压导致后续脚本找不到相对路径;第三行用chmod +x给所有脚本添加可执行权限;最后运行menu.sh进入交互菜单。运行后你会看到类似下面的输出:
============================================ Android Kitchen ============================================ 1) 设置工作目录 2) 解压 ROM 包 3) 解包 boot.img 4) 解包 system.img ...如果菜单没有正常显示,先检查脚本开头的#!/bin/bash是否存在,以及当前 shell 是否为 bash。Kali Linux 的默认 shell 有时候是 zsh,你需要用bash menu.sh来强制运行。这一步看起来简单,但确实有不少人在环境问题上翻车,具体原因我会在后面的避坑章里集中解释。
3.3 工作区设置与 ROM 包放置规范
Kitchen 的菜单第 1 项通常用来设置工作目录。这个步骤的意义是告诉脚本“你接下来要在哪里干活”,避免多个项目互相覆盖。如果你只做一个 ROM,直接使用默认目录即可;如果同时维护好几个设备的 ROM,每个设备设置一个独立的工作目录会舒服很多。设置完目录后,需要把原厂 ROM 包放置到指定位置。常见的做法是在original/目录下新建一个以 ROM 包名命名的子目录,然后把 zip 或者 tar 包放进去。
cd ~/kitchen/original mkdir -p my_first_rom cp /path/to/stock_rom.zip my_first_rom/ cd ~/kitchen && ./menu.sh菜单里选择解压 ROM 包后,Kitchen 会把 zip 里的boot.img、system.img、recovery.img等文件都提取出来,放到original/my_first_rom/下。这个“解压 ROM 包”和“解包镜像”是两个不同的步骤:前者是解开最外层的刷机包,后者是拆开里面的镜像文件。新手经常搞混,以为跑了一次就能直接在 working 目录里看到 APK,其实是漏了第二步。理解这两者的关系,后面才不会乱。
4. 厨房开火:从解包 system 镜像到改 build.prop 再回包
4.1 解包 boot.img 与 ramdisk 的文件结构
拿到了原厂 ROM 包,接下来的正式操作从 boot.img 开始。boot.img 的结构固定为“头部信息 + 内核代码 + ramdisk 打包文件 + 第二级引导”,Kitchen 脚本可以帮你把它完整拆开。在菜单里选择解包 boot.img 后,工具会调用unpack_bootimg将其拆成kernel文件和ramdisk目录。ramdisk 目录里边是一套完整的根文件系统,包含init.rc、default.prop、ueventd.rc这些启动时需要的配置。
# 解包后的 boot 目录内容示例 cd ~/kitchen/working/boot ls -ladrwxr-xr-x 3 root root 1024 2025-01-01 00:00 . drwxr-xr-x 2 root root 3072 2025-01-01 00:00 kernel drwxr-xr-x 9 root root 1024 2025-01-01 00:00 ramdisk定制 ROM 时,解包 boot.img 的主要目的有三个。第一个是修改default.prop(部分版本叫prop.default),比如把ro.secure改成 0,可以让 adb 在开机时直接获得 root 权限,这是很多精简包实现预置 root 的方法之一;第二个是替换开机动画相关的资源,需要修改 ramdisk 内的init.rc来改变开机时的服务执行顺序;第三个是如果你的设备要移植第三方内核,也需要在这里替换 kernel 文件。注意,改完 boot 里的任何文件后,回包时都要重新打包 ramdisk,否则文件不会生效。
4.2 解包 system.img 时遇到 sparse 和挂载失败怎么办
system.img 解包是整个定制流程里最敏感的一环。Kitchen 会先检测镜像格式,如果是 ext4 的 sparse image,它会尝试用simg2img工具转换成原生 ext4 镜像,然后再挂载到 working 目录。这里的坑在于,部分版本的 Kitchen 里simg2img是从编译工具链里复制过来的,有可能与最新的 Android 系统镜像不兼容。表现症状是解包进度走到一半提示file system not recognized或者直接报告 mount 失败。
遇到这种情况,我一般会手动执行一次挂在当前系统下的转换。你要清楚的是,Kitchen 只是一个脚本外壳,底层挂载操作的成败归根结底取决于你运行它的系统是否支持对应的文件系统。Ubuntu 默认支持 ext4,直接挂载没有问题;如果你的系统是精简版的发行版,可能需要先补装android-tools-adb和android-tools-fsutils包,这两个包里包含了 Google 官方的镜像转换工具。
sudo apt install -y android-tools-fsutils cd ~/kitchen/original/my_first_rom simg2img system.img system_raw.img file system_raw.img如果系统提示找不到simg2img命令,说明你的发行版在软件源里没有打包这个工具。退而求其次的方法是用 Python 脚本sdat2img来处理新格式的 system.new.dat 文件,不过那就是另一套流程了,Kitchen V0.223 的菜单直接处理 dat 格式的能力有限,后面避坑章我会单独讲到。总之,手动转换的思路是让 Kitchen 少干活,它解不了包你就帮它先转成它能处理的格式,排查问题时要顺着这个思路走。
4.3 修改 build.prop:定制 ROM 最有价值的单文件操作
解包完 system.img 之后,你会在working/system/下看到完整的 Android 系统文件树。其中build.prop是对系统显示信息、性能参数、默认属性影响最大的单个文件。它位于working/system/build.prop,里面以键=值格式保存了很多运行时属性。定制 ROM 时,这个文件几乎是必改的一项,改之前要先备份一份原始文件,给自己留个后悔药。
cd ~/kitchen/working/system cp build.prop build.prop.bak vim build.prop比如把设备型号改成自己想要的名字,把开机第一屏显示的版本信息改成自定义内容:
ro.product.model=MyCustomPhone ro.build.display.id=Kitchen_V0.223_2025参数说明:ro.前缀开头的属性在系统启动后是只读的,这些值会被系统服务读取并显示在“关于手机”界面上。修改后保存文件即可,不需要额外操作。但是要注意,ro.product.model这类属性影响 Google Play 的设备认证逻辑,如果改成一个不存在的型号,可能导致部分应用判定设备不兼容。所以我在实际定制时,通常会保留原始型号,只改ro.build.display.id这类不影响功能识别的字段。这个细节不算高深,但确实是在踩过坑之后才明白的。
4.4 精简系统应用的正确姿势与 APK 选择逻辑
定制 ROM 的另一个高频需求是精简掉厂商预装的应用。在 working/system 目录里,系统应用分散在app/、priv-app/、framework/这几个目录里。通用做法是先看一遍每个目录下的包名,区分哪些是核心组件、哪些是厂商添加的推广应用。改动之前做一次全量备份最重要,我习惯在精简前把整个 working/system 目录做一次 tar 打包,放到原 ROM 旁边,出错后几分钟就能还原。
cd ~/kitchen/working tar -czf ~/system_backup_$(date +%Y%m%d).tar.gz system/ cd system/app ls -l | head -20遇到不确定能不能删的应用,我的判断标准是三条:第一,包名是不是com.android.*核心系统包,这类不要动,删了大概率开机卡 Logo;第二,不在app/和priv-app/里的私有框架应用不要去碰,它们被其他应用引用,删一个可能导致一堆应用崩溃;第三,如果只是自己日常使用不需要,但不确定系统服务是否需要,那就先停用而不是删除。精简这件事最怕的不是删多了,而是你不知道为什么删多了就开不了机。保留足够多的原始信息,出问题时才能快速定位是哪个包导致的重启循环。
4.5 回包与签名:最后一步决定成不成
定制完成后的回包操作,在菜单里对应“Build ROM from working folder”选项。Kitchen 会把整个 working 目录按其识别到的原始镜像格式重新封装成新的 system.img 和 boot.img,然后再打包成一个可被 Recovery 刷入的 zip 文件。打包完成后输出目录里会出现custom_rom.zip或者类似命名的文件。接下来是最关键的一步:签名。
cd ~/kitchen/output java -jar ../tools/signapk.jar \ ../tools/testkey.x509.pem \ ../tools/testkey.pk8 \ custom_rom.zip \ custom_rom_signed.zip参数说明:signapk.jar是 Android 源码里自带的签名工具,接收三个参数,依次为公钥证书、私钥文件和待签名 zip,输出是第四个参数指定的文件名。Kitchen 里内置了测试密钥,这张密钥可以用于个人刷机用途,因为 Recovery 在刷入 zip 时会校验签名,而默认的测试密钥可以被第三方 Recovery 直接接受。如果需要做公开发布的 ROM,得替换成你自己的正式密钥,否则别人刷入时如果校验严格会直接失败。
5. Android Kitchen 避坑指南:环境、权限、版本选择上的 4 个高发问题
5.1 Cygwin 下挂载 system.img 失败,进度条卡在 98%
现象:在 Windows 的 Cygwin 环境里解包 system.img,日志滚动到将近完成时卡住,或者提示mount error,但同样的镜像放到 Linux 虚拟机里可以正常解包。
原因:Cygwin 的 mount 实现是模拟的,它对 ext4 文件系统的支持不完整,尤其是在处理稀疏镜像和 64 位 ext4 特性时会出现兼容性问题。Kitchen 挂载 system.img 需要真正调用 mount 系统调用,而这恰好是 Cygwin 的弱项。
解决:不要在 Cygwin 里跑解包 system.img 这一步。把原始 ROM 的 system.img 先拷贝到 WSL 或 Linux 虚拟机中完成解包和编辑,再把整个 working 目录传回 Windows。如果实在要在 Windows 里工作,可以把simg2img转换和debugfs提取作为替代方案,但这操作门槛比直接用 Linux 高得多。我的经验是:环境不对就换环境,别在 Cygwin 上死磕。
5.2 回包后刷入手机,开机卡在厂商 Logo
现象:定制好的 ROM 刷入后,设备停留在品牌 Logo 界面,无法进入系统,adb logcat 都没有输出。
原因:这种情况 90% 是改动的问题,不是打包的问题。常见诱发因素有三个:一是把app/里的某个核心系统应用删了,比如Phonesky以外的系统组件;二是修改了build.prop里跟硬件解码器相关的属性,导致服务启动死循环;三是精简时误删了framework/下的资源包,系统 UI 无法加载。
解决:先用上一步备份的原始 working 目录恢复,重新打包一次确认不是你的环境问题。如果恢复原厂就能开机,那就是某个改动点的问题,采用二分排查法:先只改 build.prop,回包测试;通过后再只精简应用,再测试。分成两步而不是一次性改完,能快速定位问题所在。另外,刷机前尽量保留一个完整的官方 ROM 包在电脑里,一旦新包有问题,随时可以 fastboot 刷回原厂。
5.3 .rar 格式解压脚本报bad magic number
现象:解压 Kitchen 包时,执行.sh文件报错说文件头不对,或者 bash 提示cannot execute binary file。
原因:可能是压缩包解压不完整,也可能是文件在传输过程中发生了格式转换。最常见的场景是你在 Windows 下用记事本打开过脚本,然后保存过,导致文件编码变成 CRLF 换行,bash 在执行时读到了\r字符,把它当成文件名的一部分。
解决:用dos2unix把所有脚本和配置文件转换一次,或者用编辑器把换行符改回 LF。
sudo apt install -y dos2unix dos2unix ~/kitchen/*.sh ~/kitchen/tools/*.jar bash menu.sh这个问题的典型特征是同样的脚本在别人的电脑上能运行,到了你这里就报错。如果你有在 Windows 和 Linux 之间来回拷贝文件的习惯,这个坑迟早会遇到。写脚本用的换行标准在 Linux 下是 LF,不要随便用 Windows 的记事本改动任何.sh文件。
5.4 新版 Android ROM 使用 system.new.dat,Kitchen 无法识别
现象:把新版系统包放进去,菜单里选择解包 ROM 后提示找不到 system.img,但压缩包里明明有 system 相关的文件。
原因:Android 5.0 之后的官方刷机包开始广泛使用system.transfer.list和system.new.dat格式,它们不再是一个直接的 ext4 镜像,而是数据块差分文件。V0.223 年代的 Kitchen 不认识这种格式,菜单当然找不到它想要的文件名。
解决:先用sdat2img工具把system.new.dat转换为system.img,然后把转换出来的镜像放回 original 目录,再走 Kitchen 的解包流程。这个工具是一个单文件的 Python 脚本,在 GitHub 上可以找到,运行命令如下:
python sdat2img.py system.transfer.list system.new.dat system.img参数说明:三个参数依次是 transer.list、new.dat 和输出文件名。运行完成后会得到一个 ext4 的完整镜像,这时再打开 Kitchen 菜单解包即可。这条路径是我做新机 ROM 定制时最常用的办法,它不改变 Kitchen 的内部逻辑,只是在输入端多做一步转换,变相延长了这套老工具的使用寿命。
6. 进阶验证:刷入前自查、设备端确认和避免重复踩坑的习惯
6.1 回包后用脚本检查 zip 结构与签名完整性
不要急着把包刷进手机。我一般会先做两个快速验证:第一,检查 zip 内部的文件层级是否和官方包一致;第二,确认签名是否生效。层级不对的话,刷进去 Recovery 可能提示安装失败;签名不正确,部分 Recovery 会直接拒绝。
cd ~/kitchen/output unzip -l custom_rom_signed.zip | head -30预期列表里应该能看到boot.img、system.img、META-INF/com/google/android/这几个必备项。路径里缺少META-INF的话,刷机包大概率无法被 Recovery 识别。再运行一次签名检查,用 Android SDK 里的apksigner验证也可以,但更直接的方法是看 zip 里是否已经有签名用的原目录被加入。对于 V0.223 生成的刷机包,只要不是在签名前误删了META-INF,一般都没有问题。
6.2 刷入后的设备端验证:不只开机,还要看 logcat
设备可以开机,并不代表定制成功了。系统应用的精简隐藏问题,往往会在使用一段时间后才暴露。我的习惯是刷完机后的前十分钟内,用 adb 抓取一段 logcat 检查报错信息,特别是PackageManager和ActivityManager的输出。刷入后 adb 通常默认可用,执行以下命令:
adb logcat -d -s PackageManager:E ActivityManager:E如果日志里频繁出现Package [com.example.xxx] ... failed或者Unable to start service,说明有应用在启动时被其他依赖拖住了。这不一定是坏事,只要不影响正常使用,那就不用管;但如果反复弹“XX 已停止运行”,就要考虑把对应应用恢复回去。每次定制完我都习惯把这次的改动记录到一个文本文件里,包括删了哪些包、改了哪些属性。下次出了问题,翻一下记录,比盲猜快得多。
6.3 这套工具值不值得继续投入时间
用了这么多年,我的结论是 Android Kitchen 的思路值得学,但直接拿来做现代设备的主力工具,已经有点吃力了。它更准确的角色是一个教学工具和通用工作台:通过它,你能彻底搞懂 boot.img、system.img、ramdisk、签名这些概念之间的关系,这份认知迁移到任何现代的 ROM 构建工具上都是有效的。对于追求新设备的用户,AOSP 源码编译和super.img分区才是归宿,但如果你只是为了把手头的老设备整理得顺手一点,V0.223 依然是效率最高的一条路。
我自己现在仍然在用它做一件事:把老旧设备的系统精简到最低限度,去掉所有用不上的服务,让只做备用机的手机跑得更轻快。每次在working目录里删掉一个几十兆的预装应用、回包刷进去,那种掌控感是图形工具给不了的。所有技艺型的工具都会有类似的宿命——界面会老、格式会变,但方法论不会。把 Kitchen 这套思路吃透,下次遇到再新的打包格式,你也知道该怎么拆开它、改哪里、再装回去。希望帮到你。
本文还有配套的精品资源,点击获取