如何解压缩和编辑boot.img进行ROM移植?


14

我最近为Allview P5 下载了此ROM(Allview P5相当于Gionee GN700W / FLY IQ441 / QMobile Noir A8)。它称为Primonex ROM,是为手机的Gionee版本制成的。

  • 首先,我尝试按原样安装它,但是它卡在了启动屏幕上。
  • 经过研究后,我发现该boot.img文件可能有问题,我不知道如何提取或编辑该文件。

有人可以告诉我该怎么做吗?

Answers:


12

工具选择

我在这里介绍的方法依赖于CyanogenMod的Android源代码。

而谷歌的AOSP只提供工具建立boot.img文件,的CyanogenMod也增加了unpackbootimg工具,允许你解开它。该工具似乎没有以任何方式专门为CyanogenMod设计,因此大多数机会也可以用于其他ROM。

但是,有很多替代方法可以解压缩boot.img文件,它们的工作原理几乎相同。

基本上,这种解压缩工具将提取boot.img文件的内容并显示一组参数,您必须将这些参数传递给Google的mkbootimg工具才能构建其配置(主要是内核参数和内存地址)与原始配置相匹配的文件。

以下是一些示例,我没有亲自测试过,因此无法推荐它们,我仅供参考。

  • 一些是基于开源或脚本的:

    • Android Kitchen显然是Android开发人员的某种瑞士军刀。最初的作者正式停止维护该项目,其他一些用户则像javilonascmotc一样对其进行了分叉
    • szym通过将shell脚本包装器添加到其工具集中来简化操作,从而使完整的拆包和重新包装过程更加直接。
    • osm0sis根据项目自己的描述提出了“派生和更新”的CyanogenMod工具的分支。这个项目的确似乎仍在维护,这在该领域不是很普遍,但是相对于CyanogenMod原始工具的实际优势仍然不清楚。
  • 一些是免费的封闭源专有二进制文件:

    • Kuisma的unmkbootimg出现经常出现在帮助论坛中,并且似乎在帮助处理奇怪的情况方面做得很好,当在mkbootimg源代码中需要进行某些修改时,会输出“人类可读”的英语推荐,并显示用于重建图像的确切命令行。
    • 小鹿的名字mkbootimg_tools似乎也经常提到,并允许解压缩和重新打包boot.img设备树文件dt.img。不要被它托管在GitHub上的事实所迷惑:它一个封闭的源代码专有二进制文件,并且在其存储库中仅提供已编译的二进制文件(实际上,我什至想知道使用源代码存储库进行存储的确切兴趣)二进制斑点,但不同的人,不同的想法...)。
    • XDA论坛上的CNexus提供了包含各种工具的存档。
    • 在Unix.SE中,此答案推荐从似乎已失效的Android串行端口项目中使用的一些工具。但是,文件名使我认为它们应该是CyanogenMod工具的旧预构建版本(该项目已关闭,既没有文档也没有支持)。

所有这些工具(以及在任何搜索引擎中可能找到的其他工具)都应以相同的方式工作,但是在处理您自己的设备可能遇到的某些特殊情况时,某些工具可能比其他工具更好。但是,大多数工具(至少在开源领域中)似乎没有定期维护,因此,我认为拥有有效的,维护的和记录在案的工具,最好的选择是与CyanogenMod的工具搭配使用。

一些制造商生产的ROM或多或少与AOSP标准(异常地址,标头,文件格式等)相距甚远。如果下面的标准步骤不起作用,则可能这些替代软件之一可以解决问题。否则,您将必须检查特定于设备的问题:某些问题似乎需要特定的过程甚至特定的工具(例如,将此问题与联发科技设备相关)。

工具安装

编译CyanogenMod工具集以进行boot.img打包和拆包非常简单。

  • 如果您已经安装了完整的Android源代码树(可以查看我的其他答案以获取有关此信息的更多信息),请进入system/core/mkbootimg/目录(提醒一下,Google的AOSP源代码仅提供构建boot.img文件的工具,而没有提供此工具)提供任何拆箱工具),
  • 如果您没有,也不需要其他目的,那么一个简单快捷的解决方案是仅克隆CyanogenMod的android_system_core存储库:

    git clone https://github.com/CyanogenMod/android_system_core.git
    cd android_system_core/mkbootimg/
    

进入正确的目录后,编译并安装:

gcc -o ./mkbootimg -I ../include ../libmincrypt/*.c ./mkbootimg.c
gcc -o ./unpackbootimg -I ../include ../libmincrypt/*.c ./unpackbootimg.c
sudo cp ./mkbootimg ./unpackbootimg /usr/bin/

需要注意的是谷歌正在替换C mkbootimg一个Python版本,所以在未来的版本中可能不再需要该命令没有编译。

您还需要在计算机上安装Android工具,以使其与手机通信。您将需要adb(Android调试桥,一个可与Android的调试子系统进行通信的shell实用程序),adbd(相关守护程序)和fastboot(一个可与您的手机的Bootloader系统进行通信的shell实用程序)。

您最喜欢的Linux发行版可能以单个或单独的程序包形式提供它们,但是通常它们始终被称为“ android-tools”:

  • Debian / Ubuntu: sudo apt-get install android-tools-{adb,adbd,fastboot}
  • Fedora / CentOS: sudo yum install android-tools
  • openSUSE: sudo zypper install android-tools

提取boot.img文件

从ROM .zip文件或直接从设备提取boot.img:

  • 从ROM的.zip文件中提取:某些应用程序(例如SuperSU)可能会直接在设备上修改boot.img,将其替换为库存文件会破坏此类应用程序。
  • 直接从设备上:有人报告读取问题导致损坏boot.img。IMO,这些问题很可能与使用不良的USB电缆或USB集线器有关,可以通过使用质量好的电缆直接将电话直接连接到计算机来避免。您还需要能够在root模式下运行ADB(取决于所使用的ROM,这可能微不足道)。

第一种方法非常明显:使用任何ZIP软件提取.zip文件,该boot.img文件应位于存档根目录中。

对于第二种方法,您首先必须确定boot.img可以检索到其内容的存储设备的路径(特定于设备)。我知道两种方法:

  • ls /dev/block/platform/*/by-name/(其中*包含另一个设备特定的文件夹名称,可能是下面的唯一目录platform/),要搜索的确切名称也取决于平台,但具有通常的意义(一些示例:bootLNX(“ Linux”的缩写))。该目录中的文件实际上是符号链接,有些人不愿手动转到目标,但我建议坚持使用基于较高名称的路径,该路径虽然较长,但仍不易出错。因此,您最终会遇到类似的路径/dev/block/platform/sdhci-tegra.3/by-name/LNX
  • 在某些(较旧的)设备上,可以通过调查的输出找到合适的设备cat /proc/mtd。如果看到与标签mtd2关联的设备"boot",则将使用path /dev/mtd2

现在:

  • 在手机的开发者菜单中:
    • 在手机上启用调试,
    • 允许对ADB的根访问(此步骤适用于运行CynogenMod的电话,其他设备可能需要一些可能更复杂的过程),
  • 将其连接到计算机(如果从虚拟机中运行Android工具,则从那里连接到VM ​​guest虚拟机)。

如果尚未完成,建议您在计算机侧手动启动ADB服务器,这将使您可以直接在设备侧验证RSA密钥,而不会影响以下ADB命令的行为:

adb start-server

然后以root模式切换ADB:

adb root

最后,您应该能够boot.img使用以下命令直接从设备中提取文件(源和目标路径以及名称作为示例给出,使它们适应您的需求和偏好):

adb pull /dev/block/platform/sdhci-tegra.3/by-name/LNX ./boot.img

该命令将复制整个分区(包括已用空间和可用空间),因此生成的boot.img文件将比原始boot.imgROM .zip文件随附的原始文件大,因此不要感到惊讶,其内容本身仍然相似。

传输完成后,请断开手机的连接,不要忘记从开发人员菜单中禁用调试和root用户访问权限。

解压原始boot.img文件

boot.img使用先前编译的命令解压缩文件本身:

unpackbootimg -i ./boot.img

这将输出一些必不可少的信息,使您可以boot.img使用正确的库存结构重建新库存boot.img。但是,请不要着急于记事本,因为CyanogenMod upackbootimg还将相同的信息保存在以后将要使用的几个文件中。

此命令将生成几个带有特定后缀的文件,这些后缀添加到输入文件的名称中:

  • *-second:这是第二阶段引导程序,是可选的,很少在最终用户电话上使用。如果此文件为空(最常见的情况),那么电话的引导程序将直接调用Linux内核。
  • *-zImage:这是Linux内核。
  • *-ramdisk.gz*-ramdisk.lz4:用于填充设备根目录的RAM磁盘。扩展名因使用的压缩算法而异。
  • *-dt:设备树,正在填充/dev
  • 其余的都是小文件,每个文件都存储unpackbootimg输出中显示的值之一。这些值定义了传递给Linux内核的命令行参数以及引导加载程序在引导时必须加载每个对象的地址。

最常见的是,将其解压缩后便boot.img可以编辑手机根目录的内容。如上所示,此内容存储在*-ramdisk.gz*-ramdisk.lz4文件中,可以使用以下命令将其提取:

mkdir ./ramdisk
cd ./ramdisk/
gzip -dc ../boot.img-ramdisk.gz | cpio -imd

对于LZ4压缩RAM磁盘,请用代替最后一步lz4 -d ../boot.img-ramdisk.lz4 | cpio -imd

现在,您可以继续进行所需的修改。但是,值得进行一次完整的拆包-重新包装-引导过程,而无需进行任何更改以确保您的工具能够按预期工作。否则,在出现问题的情况下,您将无法确定原因是否是您的修改或某些不兼容(请参阅开始时有关某些制造商要求非标准程序或工具的评论)。

重建以获取新new-boot.img文件

CyanogenMod ROM的构建过程依赖于内部工具mkbootfs来生成boot.img文件(这在build / tools / releasetools / common.py中发生)。但是,对我来说,构建此工具的步骤似乎毫无用处,而使用系统提供的功能cpio似乎同样有效。根据我对(非常)快速检入mkbootfs源代码后的理解,两者之间的主要区别似乎是,后者采用了一些合理的措施,即/root在生成的归档文件中不包括点缀文件和目录,而cpio下面的基于-过程只会盲目地将整个选定的目录树放入存档中。

结论:编译时不必要的复杂,只有很少的优势,所以让我们继续使用系统提供的工具吧!

从创建新的RAM磁盘开始,从ramdisk上面创建的目录中键入:

find . ! -name . | LC_ALL=C sort | cpio -o -H newc -R root:root | gzip > ../new-boot.img-ramdisk.gz

或者,如果您需要生成LZ4归档文件:

find . ! -name . | LC_ALL=C sort | cpio -o -H newc -R root:root | lz4 > ../new-boot.img-ramdisk.lz4

这里的目标是创建一个新的RAM磁盘文件,其属性应与原始文件尽可能接近(例如,在论坛和博客共享的过程中似乎常常缺少设置所有者的权限,但是这在我的设备上是必需的)。

现在转到父目录以生成new-boot.img文件本身。

cd ..

如上所示,CyanogenMod的unpackbootimg命令生成一个文件,该文件与所需的每个参数匹配mkbootimg。因此,您要做的就是发出a mkbootimg -h以获得所有参数的列表,然后使用匹配文件将每个参数设置为适当的值。请注意,某些参数需要文件路径,而其他参数则希望接收文件内容作为值。请参见下面的结果命令示例:

mkbootimg --kernel ./boot.img-zImage \
--ramdisk ./new-boot.img-ramdisk.gz \
--second ./boot.img-second \
--cmdline "$(cat ./boot.img-cmdline)" \
--base "$(cat ./boot.img-base)" \
--pagesize "$(cat ./boot.img-pagesize)" \
--dt ./boot.img-dt \
--ramdisk_offset "$(cat ./boot.img-ramdisk_offset)"
--second_offset "$(cat ./boot.img-second_offset)" \
--tags_offset "$(cat ./boot.img-tags_offset)" \
--output ./new-boot.img

此处未设置两个参数:

  • --board:根据我的理解,这只是一个信息字段,允许在结果图像中插入模型名称。
  • --id:此值不希望有任何值,它只是在构建图像后打印出唯一的标识符(结合时间戳和校验和)。

new-boot.img文件刷新到设备上

  • 以快速启动模式(也称为引导加载程序模式,通常通过按住电源和增大音量按钮)启动设备。
  • 连接USB电缆。
  • 检查是否正确检测到设备:

    sudo fastboot devices
    
  • 尝试使用新的ROM引导(尚未闪烁),因此,在出现问题的情况下,您只需重新启动手机即可使其恢复正常运行,请./new-boot.img用您自己的文件名替换文件名):

    sudo fastboot boot ./new-boot.img
    
  • 如果电话成功使用新的启动映像工作,请返回快速启动模式并永久闪烁:

    sudo fastboot flash boot ./new-boot.img
    sudo fastboot reboot
    

结论

这个过程乍看之下似乎很艰巨,但是一旦您掌握了它,您就会发现实际上并非如此。

“令人生畏”的方面来自没有一个“ Android系统”的事实:许多制造商和ROM供应商进行的更改范围从细微的路径差异到完全非标准的环境。

您需要做的是确定特定设备的姿势,然后确定适合您情况的几条命令?一旦获得它们,就可以坚持使用它们,如果经常需要它们,甚至可以轻松编写脚本。

有时,我会自愿介绍一些相对较低的详细信息,因为这会使您更轻松地解决问题。您是否会使用一些“更轻松”的不透明实用程序来生成并刷新新boot.img文件,并发现设备无法启动该文件,这将使您更难确定哪个步骤出错了。在这里,您可以在每个步骤中将要处理的数据与原始boot.img文件中的数据或电话中显示的数据进行比较,或者尝试boot.img使用原始文件或新生成的文件重建文件检查RAM磁盘文件是否有任何区别(这使您可以查明问题是来自boot.img还是RAM磁盘文件生成过程)。


2

使用Android Kitchen。在下有一个解压缩boot.img的选项Advanced options


遗憾的是,原始作者已正式停止维护Android Kitchen:“ 该项目已于2013年退休,因为我对支持的设备数量,需求,不良的健康状况和不断寻求帮助的需求不知所措 ”。尽管已经做了一些分叉(我在回答中提供了一些链接),但是我不知道它们得到了多少支持(例如,我没有发现任何明显的公开方式来提出问题或要求进行改进)。
WhiteWinterWolf,2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.