自制recovery【转】

原作者不知道是谁了,我是在这里看到的http://bbs.anzhi.com/thread-5136410-1-1.html

###################################### 

##### 自制recovery ######## 
###################################### 

###背景知识#### 
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
步。这三步在当时做的时候虽然可用了,但是不知为
啥可用,现在总算解释清楚了
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值