boot和recovery映像并不是一个完整的文件系统,它们是一种android
自定义的文件格式,该格式包括了2K的文件头,后面紧跟着是用 gzip
压缩过的内核,再后面是一个ramdisk内存盘,然后紧跟着第二阶段的
载入器程序(这个载入器程序是可选的,在某些映像中或许没有这部分)。
boot是正常引导手机系统的,recovery 是在boot的基础上增加了一些
功能。他们的img 结构如下:
** +—————–+
** | boot header | 1 page
** +—————–+
** | kernel | n pages
** +—————–+
** | ramdisk | m pages
** +—————–+
** | second stage | o pages
** +—————–+
**
其中ramdisk映像是一个最基础的小型文件系统,它包括了初始化系统
所需要的全部核心文件,例如:初始化init 进程以及init.rc(可以用于设
置很多系统的参数)等文件。
如果你您很擅长使用16进制编辑器的话,你您可以打开boot.img或者
recovery.img,然后跳过开始的2K的头数据,然后寻找一大堆0的数 据,
在这一堆0的数据后面,紧跟着1F 8B这两个数字(1F 8B是gzip格式
的文件的结束标记)。从此文件开始的地方(跳过2K的头),一大堆0
后面紧跟着到1F 8B这两个数字为止的全部数据,就是gzip压缩过的
linux 内核。从1F 8B后面紧跟着的数据一直到文件的结尾包含的全部数
据,就是ramdisk 内存盘的数据。你可以把把内核和ramdisk 两个文件
分别保存下来,在进行 分别的修改和处理。
###自制recovery的方法####
对应的windows下的程序大家可以自己找,由于
windows的文件名不区分大小写,不支持软连接,所
以我建议大家最好还是在linux 环境下改写
recovery.img.
下载split_bootimg.zip 文件,在此zip 文件中包含一个perl 文 件,
split_bootimg.pl 脚本,该脚本可以读取recovery.img 头将kernel 和
ramdisk读取出来,此脚本也会输出内核命令行和板子名字。
下面是一个仅是一个解包recovery.img的例子:
% ./split_bootimg.pl recovery.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 recovery.img-kernel … complete.
Writing recovery.img-ramdisk.gz … complete.
解包ramdisk的命令如下:
% mkdir ramdisk
% cd ramdisk
% gzip -dc ../recovery.img-ramdisk.gz | cpio -i
% cd ..
解码完毕后,就可以修改了,主要的工作在这里,这里是自制的地方。(例如,在default.prop
设置ro.secure=0等等)
使用mkbootfs工具来重新创建ramdisk,可以使用如下命令来操作:
% mkbootfs ./ramdisk | gzip > ramdisk-new.gz
使用mkbootimg来重新创建recovery-new.img:
% mkbootimg –cmdline ‘no_console_suspend=1 console=null’ –kernel recovery.img-kernel
–ramdisk ramdisk-new.gz -o recovery-new.img
到此我们就得到了一个新的recovery-new.img,然后我
们按照上面讲的刷入第三方recovery的方法刷入就可
以验证刚做的recovery了。
###自制recovery####
接着开始自制recovery吧,下面步骤:
1。从官方包,解压出原生的recovery.img。
2。按照上面解img 的方法,解出原生recovery包的内
核recovery.img-kernel 和ramdisk 内存镜像,再把
ramdisk内存镜像解包,我们要在这个基础上作修改。
3。找到合适的功能比较好的第三方recovery包,比如
以G6的recovery-clockwork-5.0.2.0.img为例,同样解
出其内核kernel 和ramdisk 内存镜像,再把ramdisk
内存镜像解包,我们需要这个包内的有用文件。
4。准备新recovery 的内核,我们使用官方原生包的
recovery.img-kernel,只有原生的内核才能跟手机的硬
件匹配。
5。修改ramdisk内存盘,其内文件列表大致如下:
./init.trout.rc
./default.prop
./proc
./dev
./init.rc
./init
./sys
./etc
./init.goldfish.rc
./sbin
./system
./data
1)default.prop,是一定要改的,可以参照第三方的改,
最关键的:
ro.secure=0 关闭保护
ro.allow.mock.location=1
ro.debuggable=1 调试模式开
persist.service.adb.enable=1 adb远程开
2)/sbin 里面所有的文件都替换成第三方包里面的,
特别是其中有个recovery文件,所有的第三方功能都
在这个recovery中实现。
3)/etc 里的recovery.fstab,是挂载表,可以提供sd
卡ext分区支持。
4)/init可以用原生的,第三方的也行。
6。按照上面打包ramdisk 的方法打包新改的ramdisk
内存盘。
7。按照上面打包img 的方法打包生成新的
recovery-new.img。
正常情况下,到这一步我们自制的recovery.img 就做
好了,可是按上面刷recovery的方法刷入手机了,可
是手机依然是S-ON。这就意味着Hboot会对recovery
进行校验,如果校验不对,那么对不起,你别想启动
手机。最终我发现了HTC S-ON验证的秘密:
还记得上面说img 的2K的文件头么?秘密就在这里,
可惜不能直接贴图,具体操作如下:
[——现在看来这段话以及下面的8、9、10三步的分
析是有问题的,但是操作虽然怪异结果却是正确的,
正确的分析以及正常的操作,请看下面我11.27日的
补充。小秋 2011.11.29 注]
8。用UltraEdit-32(或者其他16进制编辑器)打开刚
改好生成的recovery-new.img,记住第二行的前三个字
节(10h的0、1、2三个),一会儿有用。
9。再打开手机原生的recovery.img。对比来两个文件
的文件头,把原生的前16行(000h-100h)复制到新
的recovery上覆盖。这个就是S-on校验的内容,直接
生成的img 启动不了就是因为这里通不过校验。
10。最后把新的recovery-new.img,第二行的前三个字
节改回到刚才记下的三个值,保存就OK了。这一步
很关键,我一直是在此处徘徊的,最初我只保留前两
个字节,造成只要对原生img 一改动得稍大一点就启
动不了。总之这里的三个值很关键,好像跟img 的大
小有关系,如果不对的话新的recovery绝对启动不了。
###刷入自制的recovery####
1。关于怎么刷入新的recovery,往上面看,按照[刷
第三方recovery]的方法刷。
2。关于怎么进recovery模式,也往上看,按照官方原
生的[进入recoery的方法]进。
#####其他####
再说一点,关于解S-ON的问题:
1。这可是HTC的最后一道关,加密得很严的,哪有
那么容易的。
2。除非是硬解,拆开机子,到也不是很难。
3。我个人觉得,既然recovery搞定了,要备份能备份,
要刷机能刷机,所有想干的都能干了,还在乎s-on,
干什么阿。
4。s-on还是有好处的,再怎么折腾,也能保修,呵呵
##### 小秋 2011.11.27
最新补充 ####
关于基址 base的计算方法
boot.img recovery.img 还有一个重要的参数,基址
base,用于告诉手机从哪个地址开始,是准备给内存盘
的入口,哪个地址是给kernel的入口。如果你对不上
号,对不起,不能不能启动手机。
在android系统ROM的boardconfig.h中存在地址偏移
的define:
#define PHYSICAL_DRAM_BASE 0x00200000 //这就是定义基址,各手机是
不一样的
#define KERNEL_ADDR (PHYSICAL_DRAM_BASE + 0x00008000) //内核地址
#define RAMDISK_ADDR (PHYSICAL_DRAM_BASE + 0x01000000) //散存盘
地址
#define TAGS_ADDR (PHYSICAL_DRAM_BASE + 0x00000100)
#define NEWTAGS_ADDR (PHYSICAL_DRAM_BASE + 0x00004000)
boot.img是怎么打包在一起的呢?找到bootimg.c文件,
看吧。 header + padding + kernel + padding + ramdisk +
padding + …
所以一个boot.img或者recovery.img开头的结构具体
如下:
4 * 2, magic,固定为”ANDROID!”
4 * 1, kernel长度,小端unsigned类型
4 * 1, kernel地址,应为base + 0x00008000
4 * 1, ramdisk长度,小端unsigned
4 * 1, ramdisk地址,应为base + 0x01000000
4 * 1, second stage长度,小端unsigned,为0
4 * 1, second stage地址,应为base + 0x00f00000
4 * 1, tags地址,应为base + 0x00000100
4 * 1, page大小,小端unsigned, 为2048或者4096
4 * 2, 未使用,固定为0x00
4 * 4, 板子名字,一般为空
4 * 128, 内核命令参数,一大串
4 * 8, id,不知道啥玩意,0x00
以我们官方原生的recovery为例,如下图:
从图中我们可以知道: 41 4E 44 52 4F 49 44 21 就是
Magic Number ,内容是固定的ANDROID!。一一对应
kernel_size就是D4 C9 31 00 –>0x0031C9D4。注意,小
端读法。是Byte内,顺读,整个类型中,逆读。
kernel_addr 即00 80 40 80 –>0x 80408000。根据
KERNEL_ADDR (PHYSICAL_DRAM_BASE + 0x00008000),
所以PHYSICAL_DRAM_BASE=0x80400000.
ramdisk_size是:D3 25 10 00 –>0x001025D3。
ramdisk_addr 即00 00 40 81 –>0x81400000。根据
RAMDISK_ADDR (PHYSICAL_DRAM_BASE + 0x01000000),
所以PHYSICAL_DRAM_BASE=0x80400000.
second_stage size:00000000
second_stage addr:00 00 30 81 –>0x81300000.根据
RAMDISK_ADDR (PHYSICAL_DRAM_BASE + 0x00f00000),
所以PHYSICAL_DRAM_BASE=0x80400000.
tags_addr:00 01 40 80 –>0x80400100.根据TAGS_ADDR
(PHYSICAL_DRAM_BASE + 0x00000100), 所以
PHYSICAL_DRAM_BASE=0x80400000.
page_size:00 80 –>0x0800.这是页长。页长一般都为
1K(1024)的整数倍吧,此处页长是0x0800,转为十进制,
则是2048
根 据 上 面 的 计 算 咱 们A6390/A6388 的 基 址
为:PHYSICAL_DRAM_BASE=0x80400000
同时我们在图上还能看到,传入内核的参数为:
‘rootwait console=ttyS2,115200n8
videoout=omap24xxvout omapfb.vram=0:2M
omap_vout.vid1_static_vrfb_alloc=y
omap_vout.video1_numbuffers=6
omap_vout.vid2_static_vrfb_alloc=y
omap_vout.video2_numbuffers=6’
综上, 我们在打包A6390/A6388 的boot.img 或
recovery.img时,使用mkbootimg的具体参数为:
./mkbootimg –cmdline ‘rootwait
console=ttyS2,115200n8 videoout=omap24xxvout
omapfb.vram=0:2M omap_vout.vid1_static_vrfb_alloc=y
omap_vout.video1_numbuffers=6
omap_vout.vid2_static_vrfb_alloc=y
omap_vout.video2_numbuffers=6’ –kernel
recovery.img-kernel –ramdisk ramdisk-new.gz –base
0x80400000 -o boot-new.img
其中recovery.img-kernel为新内核;ramdisk-new.gz为新
的内存盘;boot-new.img为生成的新img.
按照此方法打包的boot.img或recovery.img因为基址
和内核参数都正确可以直接在A6390/A6388上使用,
不用做任何修改.
即不用做上面”自制A6390的recovery”的第8、9、10
步。这三步在当时做的时候虽然可用了,但是不知为
啥可用,现在总算解释清楚了
评论前必须登录!
注册