Answers:
我在这里介绍的方法依赖于CyanogenMod的Android源代码。
而谷歌的AOSP只提供工具建立的boot.img
文件,的CyanogenMod也增加了unpackbootimg
工具,允许你解开它。该工具似乎没有以任何方式专门为CyanogenMod设计,因此大多数机会也可以用于其他ROM。
但是,有很多替代方法可以解压缩boot.img
文件,它们的工作原理几乎相同。
基本上,这种解压缩工具将提取boot.img
文件的内容并显示一组参数,您必须将这些参数传递给Google的mkbootimg
工具才能构建其配置(主要是内核参数和内存地址)与原始配置相匹配的文件。
以下是一些示例,我没有亲自测试过,因此无法推荐它们,我仅供参考。
一些是基于开源或脚本的:
一些是免费的封闭源专有二进制文件:
unmkbootimg
出现经常出现在帮助论坛中,并且似乎在帮助处理奇怪的情况方面做得很好,当在mkbootimg
源代码中需要进行某些修改时,会输出“人类可读”的英语推荐,并显示用于重建图像的确切命令行。mkbootimg_tools
似乎也经常提到,并允许解压缩和重新打包boot.img
设备树文件dt.img
。不要被它托管在GitHub上的事实所迷惑:它是一个封闭的源代码专有二进制文件,并且在其存储库中仅提供已编译的二进制文件(实际上,我什至想知道使用源代码存储库进行存储的确切兴趣)二进制斑点,但不同的人,不同的想法...)。所有这些工具(以及在任何搜索引擎中可能找到的其他工具)都应以相同的方式工作,但是在处理您自己的设备可能遇到的某些特殊情况时,某些工具可能比其他工具更好。但是,大多数工具(至少在开源领域中)似乎没有定期维护,因此,我认为拥有有效的,维护的和记录在案的工具,最好的选择是与CyanogenMod的工具搭配使用。
一些制造商生产的ROM或多或少与AOSP标准(异常地址,标头,文件格式等)相距甚远。如果下面的标准步骤不起作用,则可能这些替代软件之一可以解决问题。否则,您将必须检查特定于设备的问题:某些问题似乎需要特定的过程甚至特定的工具(例如,将此问题与联发科技设备相关)。
编译CyanogenMod工具集以进行boot.img
打包和拆包非常简单。
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”:
sudo apt-get install android-tools-{adb,adbd,fastboot}
sudo yum install android-tools
sudo zypper install android-tools
boot.img
文件从ROM .zip文件或直接从设备提取boot.img:
boot.img
。IMO,这些问题很可能与使用不良的USB电缆或USB集线器有关,可以通过使用质量好的电缆直接将电话直接连接到计算机来避免。您还需要能够在root模式下运行ADB(取决于所使用的ROM,这可能微不足道)。第一种方法非常明显:使用任何ZIP软件提取.zip文件,该boot.img
文件应位于存档根目录中。
对于第二种方法,您首先必须确定boot.img
可以检索到其内容的存储设备的路径(特定于设备)。我知道两种方法:
ls /dev/block/platform/*/by-name/
(其中*
包含另一个设备特定的文件夹名称,可能是下面的唯一目录platform/
),要搜索的确切名称也取决于平台,但具有通常的意义(一些示例:boot
,LNX
(“ Linux”的缩写))。该目录中的文件实际上是符号链接,有些人不愿手动转到目标,但我建议坚持使用基于较高名称的路径,该路径虽然较长,但仍不易出错。因此,您最终会遇到类似的路径/dev/block/platform/sdhci-tegra.3/by-name/LNX
。cat /proc/mtd
。如果看到与标签mtd2
关联的设备"boot"
,则将使用path /dev/mtd2
。现在:
如果尚未完成,建议您在计算机侧手动启动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.img
ROM .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
文件刷新到设备上检查是否正确检测到设备:
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磁盘文件生成过程)。
使用Android Kitchen。在下有一个解压缩boot.img的选项Advanced options
。