Linux的recovery分区编译,如何编译和修改第三方recovery

大家都知道电脑用winCE做系统的ghost备份吧?启动

另外一个小的系统,然后把电脑上的系统备份下来,当

出了问题的时候再ghost回去。我们手机上的recovery

其实就相当于这个小系统。

先说官方原生的recovery:

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

官方原生的recovery 功能太少。

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

1。[进入recoery的方法]:

a.手机完全关机(即关机后拔电池3秒,然后再装上),

或者先把设置-应用程序-快速启动的钩去掉然后关机。

b.按住音量下键,再按电源键。这时手机会进入Hboot

模式。音量上下是选择,电源键是确定。

c.选择进入recovery。这时你会看到一个三角叹号。有

人会被这个图形吓住,不敢动。我告诉你就算你等一

天还是这个图形,因为还要按键。

d.按住音量上键,然后再按电源键。现在进入recovery

见面了,界面标题是:Android  system  recovery  <3e>,

有四个选项依次是:重起,从SD卡更新,擦除DATA

区和擦除cache区。

2。原生recovery的功能及局限:

可以看到原生的recovery,唯一可能有用的是“从SD

卡更新”。这里我试过,局限很大:

a.文件名必须是updata.zip,并且放在SD根目录。

b.这个updata.zip必须是官方发布的,也就是要进行官

方签名认证。有心的人肯定试过,哪怕是官方发布的

包,只要对里面内容做一点修改,签名就破坏掉了,

也就不能用了。

c.只能升级,不能降级。这就是为什么有的人升成2.0

的了,想用官方1.8的包救命救不了的原因。

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

第三方recovery 没有能用的

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

既然原生的recovery 不好用,那我们装第三方的

recovery 把,网上到处都是,最著名例如:

recovery-clockwork和4EXTRecovery等等,这些可不可

以直接拿来用呢?有心的人又会发现,这些recovery

不是通用的,不同的机型对应着不同的recovery,可

是网上任何地方都找不到可用的啊!

怎么[刷第三方recovery]:

1。因为依然是s-on,所以不能通过fastboot 直接刷

recovery。

2。因为我们原生的recovery只认官方签名的升级包,

所以我们不能通过recovery来升级到第三方recovery。

3。所以我们剩下一个办法了,用root权限刷recovery。

a.首先是取得root权限。

b.下载解压刷写程序:flash_image,并放到adb所在目

录中,以我的一键root包为例,既放到adbtools中。

c.下载第三方recovery 放在相同目录下,假设文件名

为:recovery.img。

d.连接手机到电脑,并打开调试模式,在电脑上运行

cmd命令,cd到相关目录下,然后运行:

E:\adbtools>adb push .\flash_image /sdcard/

E:\adbtools>adb push .\recovery.img /sdcard/

E:\adbtools>adb shell

$su (有的可能此处需要到手机确认赋予root权限)

#mount -o remount rw /system

#cat /sdcard/flash_image>/system/bin/flash_image

#rm /sdcard/flash_image

#chmod 755 /system/bin/flash_image

#chown root.shell /system/bin/flash_image

#cd /sdcard

#flash_image recovery recovery.img

然后回现实刷写进程,几秒之后回到# 。

我按照上述方法刷过2、3十个不同的第三方recovery,

都可以正常刷入,重起进入recovery 时停在G3第一

屏。如果要恢复官方的recovery可以按照上诉方法把

官方的recovery.img 刷入即可,可以正常的恢复到三

角叹号。最后的结论是:在root权限下,recovery可

以刷入,问题是刷入的第三方recovery都不适合所以

我们只能自制recovery了。

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

##### 自制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 的 基 址

63054079_1.gifHYSICAL_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

步。这三步在当时做的时候虽然可用了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值