在上一篇再谈谈Android上获得系统root权限的方法文章发出之后,不少朋友留言或者发mail询问更详细的东西,也有朋友因为过程失误而出问题的。更多的朋友可能是按照步骤成功,但是不明白这些文件和img的关系。所以这里我就大概讲一下。


把你的Android设备和host连上,用adb shell 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”

这些东西是存在你手机中的不同的devices,整个文件系统分成了多个部分,分别放在了这些devices上面。system,也就是mtd3,存放了所有你开机后能在/system 目录下看到的文件,这是自动mount的,同样,userdata,也就是mtd5,存放所有你开机后能在/data 目录下看到的东西,包括你所安装的所有的app,你的配置文件,等等。

对于普通爱好者来说,主要关注的就是mtd1和mtd2,也就是recovery image和boot image。其中boot image包含的文件会在你每次启动设备时自动加载到root根文件系统。这两个镜像设备可谓非常重要,所以基本上如果你是一个刷机爱好者,都建议你将他们备份出来以备不时之需。备份可以这样来做

# cat /dev/mtd/mtd1 > /sdcard/mtd1.img
# cat /dev/mtd/mtd2 > /sdcard/mtd2.img

这样,两个img都存在你的SD卡上了。然后你要做的事情,就是将 再谈谈Android上获得系统root权限的方法 这篇文章中提到过的update.zip文件也放到SD卡上,是根目录,不是任何子目录。这样,一旦你搞砸了任何东西,包括你的boot镜像,都可以去fastboot模式下重新进行update,比如刷recovery镜像。

换句话说,你在所有网络上看到的什么刷机,刷xx版本镜像,刷工厂镜像,刷xxx自定义镜像,刷root镜像,统统都是这个原理:放出修改过或者从原厂设备中提取出来的img,同时可能也会放出相应的更新脚本,然后让你下载,放到SD卡里面,刷到设备中,完。所以,实际上,如果你学会了镜像的识别,提取,修改以及重新打包,就能做自己想做的任何种类的镜像,什么加busybox或者某某工具之类的,统统不是问题。看到后面你就明白了。

这里再次强调一下,update.zip包含的就是你希望添加到文件系统的工具,比如sudo这种,使用之前,你需要做的,首先确保找一个适合你的设备,Magic或者Dream或者Hero的recovery image,然后找对应的update.zip文件,如果有的话。如果没有,请参考标准流程,我在上篇文章中也给出了。

我们继续探讨这些image。实际上,由于像recovery.img这样的镜像是在你每次关机的手就会自动烧到mtd1的,也就是说,你在运行机器的时候对mtd1中任何文件所做的任何修改,都不会做数,一旦重启,一切恢复。

那么,在mtd1和mtd2这样的镜像中究竟包括哪些文件呢?应该如何对这些文件进行修改呢?实际上,boot和recovery镜像都不是普通意义上的文件系统,而是一种特殊的Android定制格式,由boot header,压缩的内核,ramdisk以及second stage loader(可选)组成,可以从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. 所有entities在机载Flash中都是页对齐的
1. kernel和ramdisk必须存在
2. second不一定都有。

注:如果有不明白second stage的同学,请参考我以前关于grub引导传统Linux的文章。理解个大概就行了。

在这里,boot header和kernel我们一般都不会去碰它,但ramdisk就是可能经常会碰的东西了,特别是考虑到要为以后进一步的系统hacking做准备:)

Ramdisk,基本上就是一个包含了所有核心文件的小型文件系统,这些核心文件都是系统初始化必须的,例如关键的init进程,以及init.rc。任何Linux用户都不会对这些东西陌生,而任何感觉陌生的Windows用户,请自行Google相关概念:)简单说,init.rc就是一个你可以设置整个系统范围的属性的文件。下面是boot镜像中Ramdisk所包含的文件列表;

./init.trout.rc
./default.prop
./proc
./dev
./init.rc
./init
./sys
./init.goldfish.rc
./sbin
./sbin/adbd
./system
./data

那么recovery镜像呢?基本上文件列表是和boot差不多的,只不过会有一些额外的文件来支持recover机器的过程,比如有一些就是你按住home和电源键后,让你进入fastboot模式的文件。多出来的文件列表如下

./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

对于用户来讲,经常修改的应该是init.rc已经其他一些init文件,或者放一些自己想要的,在Android上能用的应用程序进去。那么,怎么样去永久性修改Ramdisk中的内容,从而达到做自己的recovery镜像的目的呢?下一篇文章中,我们就会谈这个方法。

reference