分类: LINUX
2010-12-25 00:33:56
英文的原版资料在如下地址:
一些用户已经凭借他们自身了解了这些知识,但是我仍然有一些可以进一步描述的东西,包括启动和恢复镜像是如何构建的,以及如何进行修改。
内容:
1. 背景;
2. 启动和恢复images 的结构;
3. 解压,编辑和重新压缩镜像
4. 将你的新镜像重新下载到手机
1. 背景
你的手机包含下面的部分:
#cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00020000 "misc"
mtd1: 00500000 00020000 "recovery"
mtd2: 00280000 00020000 "boot"
mtd3: 04380000 00020000 "system"
mtd4: 04380000 00020000 "cache"
mtd5: 04ac0000 00020000 "userdata"
注意,不同的手机可能有不同的文件顺序。在这个教程中,我们会和恢复、启动打交道。系统会读取所有/目录下的内容,userdata/有显示为data/,用于安装全部的应用。
启动和回复分区位于/dev/mtd/mtd1和/dev/mtd/mtd2下。当你在进行任何操作前,请备份这两个分区。
# cat /dev/mtd/mtd1 > /sdcard/mtd1.img
# cat /dev/mtd/mtd2 > /sdcard/mtd2.img
另一个你需要做的事情就是将你最常用的升级zip文件放在sd卡的根目录,这样如果你挂了,可以进入恢复模式,重新升级系统。
这里有另外一个你必须知道的东西:/system/recovery.img,这是所有东西的镜像。这个文件会在关机时自动加载到mtd1.这说明两个事情:1.任何你直接对/dev/mtd/mtd1所做的操作都会在重启后失效;2.如果你想更改/dev/mtd/mtd1你需要修改/system/recovery.img并且重启。当创建了你自己的升级压缩文件后,即使你没有修改/system/recovery.img /dev/mtd/mtd1下面的文件也会被覆盖。
2. 启动和恢复镜像的结构
启动和恢复镜像并不是文件系统。它是典型的android格式,包含2k的一个头,跟随了一个压缩的内核,一个ramdisk。这个结果在mkbootimg.h中。
+-----------------+
| boot header | 1 page
+-----------------+
| kernel | n pages
+-----------------+
| ramdisk | m pages
+-----------------+
| second stage | o pages
+-----------------+
n = (kernel_size + page_size - 1) / page_size
m = (ramdisk_size + page_size - 1) / page_size
o = (second_size + page_size - 1) / page_size
0. all entities are page_size aligned in flash
1. kernel and ramdisk are required (size != 0)
2. second is optional (second_size == 0 -> no second)
Ramdisk是一个基本的小文件系统,包涵了系统用于初始化的核心文件。包涵了一个init.rc文件,该文件包含了系统启动的一些信息,如果你想了解更多,这里有一个文档here is the documentation.这里是一个典型ramdisk的文件列表:
./init.trout.rc
./default.prop
./proc
./dev
./init.rc
./init
./sys
./init.goldfish.rc
./sbin
./sbin/adbd
./system
./data
恢复镜像包含一些额外的文件,包涵了恢复用的二进制文件,包含:
./res
./res/images
./res/images/progress_bar_empty_left_round.bmp
./res/images/icon_firmware_install.bmp
./res/images/indeterminate3.bmp
./res/images/progress_bar_fill.bmp
./res/images/progress_bar_left_round.bmp
./res/images/icon_error.bmp
./res/images/indeterminate1.bmp
./res/images/progress_bar_empty_right_round.bmp
./res/images/icon_firmware_error.bmp
./res/images/progress_bar_right_round.bmp
./res/images/indeterminate4.bmp
./res/images/indeterminate5.bmp
./res/images/indeterminate6.bmp
./res/images/progress_bar_empty.bmp
./res/images/indeterminate2.bmp
./res/images/icon_unpacking.bmp
./res/images/icon_installing.bmp
./sbin/recovery
3. 解压,编辑和重新压缩镜像
注意:我在下面解释了解压和重新压缩镜像的具体方法,但是我创建了两个perl脚本做了大部分的工作。如果你对于16进制编辑很在行,你可以打开这些镜像文件并查看开始的2k数据。然后查看一串0其后跟随了十六进制的1F 8B(表示了gzip文件的开始)。拷贝文件第一行的所有东西知道遇到1F 8B。这就是内核。从1F 8B到最后都是ramdisk。你可以保存其中每个文件。为了看到ramdisk内容,你需要un-gzip,并却un-cpio。你需要使用下面的命令
gunzip -c ../your-ramdisk-file | cpio -i
这将把所有文件从ramdisk中释放出来。你可以编辑他们。为了从新创建ramdisk你可以re-cpio并re-gzip这些文件,可以使用下面的命令:
find . | cpio -o -H newc | gzip > ../newramdisk.cpio.gz
最终的步骤是合并内核和你的新ramdisk到一个完整的镜像,可以使用mkbootimg程序,
mkbootimg --cmdline 'no_console_suspend=1 console=null' --kernel your-kernel-file --ramdisk newramdisk
因为命令比较多,所以我编写了unpack和repack的perl脚本。
其他的方法:
你也可以下载,该文件包涵了一个perl文件,split_bootimg.pl,用于读取boot.img的头部分(可以参考bootim.h和android的源码)和解压内核和ramdisk。
注意不要直接从/dev/mtd/mtd2中解压获得boot.img,这个镜像可能不能直接读取。给出一个例子如下:
% ./split_bootimg.pl boot.img
Page size: 2048 (0x00000800)
Kernel size: 1388548 (0x00153004)
Ramdisk size: 141518 (0x000228ce)
Second size: 0 (0x00000000)
Board name:
Command line: no_console_suspend=1
Writing boot.img-kernel ... complete.
Writing boot.img-ramdisk.gz ... complete.
解压ramdisk
% mkdir ramdisk
% cd ramdisk
% gzip -dc ../boot.img-ramdisk.gz | cpio -i
% cd ..
做一些需要的修改,然后重新创建cpio结构文件
% mkbootfs ./ramdisk | gzip > ramdisk-new.gz
重新创建image文件:
% mkbootimg --cmdline 'no_console_suspend=1 console=null' --kernel boot.img-kernel --ramdisk ramdisk-new.gz -o boot-new.img
4. 将你的新image写回电话:
你可以直接将镜像写回/system/recover.img自动会写进系统。如果你创建了一个新的恢复镜像,就直接放入/system/recovery.img并重启。如果你需要手动进行请参考下面的命令:
adb push ./mynewimage.img /sdcard
接着开一个shell:
# cat /dev/zero > /dev/mtd/mtd2
write: No space left on device [this is ok, you can ignore]
# flash_image boot /sdcard/mynewimage.img