您的位置:首页 > 其它

system.img,userdata.img,ramdisk.img,recovery.img,cache.img,boot.img关系解析

2017-08-30 23:50 417 查看
1、系统镜像(system.img)

系统镜像是地址ROM最常使用的一个镜像,用于存储Android系统的核心文件,System.img就是设备中system目录的镜像,里面包含了Android系统主要的目录和文件。一般这些文件是不允许修改的。系统镜像对应的文件名一般叫system.img,当然,系统镜像的文件可以人以命名,之所以叫system.img,是为了与生成镜像文件之前的system目录保持一致,这样比较容易与其他类型的镜像文件区分。

system.img可以添加

1、Android系统应用,

2、更多的library

那么如何查看在system.img镜像中都有哪些内容呢,那么就需要我们解压

尽管ROM中的5个镜像文件的扩展名都是img,但其格式却不同,也就是说不能使用同一种方法对其解压。

对于system.img文件来说,可以使用unyafss命令对其解压。Android源代码中并未提供该命令,所以读者可以到

http://code.google.com/p/unyaffs/downloads/list下载unyaffs的二进制程序和源代码,要注意,unyafss的二进制程序是Linux版本,如果要得到其他系统(windows和mac)的版本,需要在相应的系统上重新编译源代码。

编译命令

gcc -o unyaffs unyaffs.c

unyaffs system.img

如果对编译Android源代码生成的system.img文件执行上面的命令,可以完美的将system.img文件还原成system目录,会从system目录中看到相应的子目录,例如,/system/app、/system/lib等,实际上,system.img文件就是Android远吗/out/target/product/generic/system中的文件压缩生成的。不过很遗憾,对官方提供的system.img文件执行上面的命令并不能将system.img解压,所以可以初步判断官方提供的system.img的格式与有Android源代码生成的system.img文件格式不同。

为了进一步验证system.img文件的格式,可以分别对官方提供的和由Android源代码生成的system.img文件执行如下的命令,并进行对比。

file system.img

我们发现不同,既然官方提供的system.img文件不能用unyaffs命令解压,那就使用另外一种方法。这种方法并不需要讲system.img解压,而是将系统镜像挂载(mount)到Linux的某个目录,实际上,这种方式比直接解压system.img文件更方便操作。

注意:

实际上,高版本Android的system.img通常是ext4格式的文件系统,而不是yaffs格式的文件系统,所以不能使用mkyaffs2image命令制作system.img,也不能使用unyaffs命令将其解压。如果想生成system.img文件,需要使用make_ext4命令,解压system.img需要使用mount命令将其挂载到某个目录.

由于system.img是压缩格式,所以并不能直接使用mount命令挂载。在编译Android 源代码后会在Android源代码目录/out/host/linux-x86/bin目录生成一个simg2img命令行工具,建议将该目录加到PATH环境变量中,因为在本书中会大量使用bin目录中的各种命令行工具。

simg2img可以通过如下的命令将system.img转化为普通的Linux镜像文件(system.img.raw)。

simg2img system.img system.img.raw

然后在/mnt目录中建立一个system子目录,并执行下面的 命令挂载系统镜像。

mount system.img.raw /mnt/system

执行文上面的命令后,进到/mnt/system目录,就会看到官方提供的系统镜像中所有文件,

所有的目录都是可读写的。

文件列表如下

===========================================================

app目录:存放一般的apk文件。

bin目录:存放一些Linux的工具,但是大部分都是toolbox的链接.

etc目录:存放系统的配置文件。

fonts目录:存放系统的字体文件。

framework目录:存放系统平台所有jar包和资源文件包。

lib目录:存放系统的共享库。

media目录:存放系统的多媒体资源,主要是铃声。

priv-app目录:android4.4开始新增加的目录,存放系统核心的apk文件。

tts目录:存放系统的语言合成文件。

usr目录:存放各种键盘布局,时间区域文件。

vendor目录:存放一些第三方厂商的配置文件、firmware以及动态库。

xbin目录:存放系统管理工具,这个文件夹的作用相当于标准Linux文件系统中的sbin.

build.prop文件:系统属性的定义文件。

============================================================

将system.img.raw挂载到/mnt/system 目录后,该目录中的内容实际上与system.img中的内容完全一样,现在可以任意修改/mnt/system目录中的内容,例如,添加或替换/mnt/system/app 目录中的apk文件,或更换开机动画。在修改完系统镜像后,还需要使用make_extfs命令将/mnt/system目录重新生成system.img文件(EXT4文件系统)。

make_ext4fs命令在如下的目录中,所以建议读者将该目录加到PATH环境变量中,这样的任意目录下都可以使用make_ext4fs命令。

我们可以在Linux终端执行如下的命令生成system.img文件。

make_ext4fs -s -l 1024M -a system system.img /mnt/system

在执行make_ext4fs 命令使用了3个命令行参数,这些参数的含义如下:

-s:生成Spare格式的镜像。这种格式的镜像文件的尺寸会更小,但无法直接使用mount命令挂载。要想挂载Spare格式的镜像文件,需要首先使用simg2img命令按着前面描述的方式进行转换。如果不加-s参数,生成的system.img文件是可以直接通过mount挂载。不过不管是不是Spare格式的系统镜像文件,Nexus 7都可以使用(其他的Android设备应该也可以),但建议生成Spare格式的镜像文件,因为这样的镜像文件尺寸更小。

-l :  镜像的尺寸。该参数指定的值并不是生成镜像文件(r如system.img)的实际尺寸,而是文件系统的尺寸。这有些类似在Windows中建立的心得逻辑分区,而该参数指定的值就是逻辑分区的尺寸,生成的镜像文件的尺寸不能大于文件系统的尺寸。例如官方提供的用于Nexus 7的system.img文件(Spare格式的镜像文件)的尺寸大小越是480M,

-a: 指定挂载点,这里是system.

重新生成经过修改的system.img文件后,首先让Nexus 7 进入Bootloader模式,然后执行下面的命令即可刷机

fastboot flash system system.img 

 

用户镜像用来存储与用户相关的数据,一般对应的文件名是userdata.img(也可以是任何文件名,为了方便,我们将userdata称为用户镜像文件)。

这些数据大多都是有用户在使用Android设备的过程中产生的,例如,通过Google play安装的第三方APK程序,用户的配置文件等。当然,在制作ROM时,也可以将部分数据放到userdata.img中。例如,如果允许用户使用普通的方法卸载ROM内置的应用,就可以将APK文件放到userdata.img文件中 (这里是普通的应用程序,而system.img放入的是系统应用程序)

在学习userdata.img之前,首先应该了解userdata.img在整个Android系统中起到了什么作用。从前面的描述可以断定,userdata.img的作用之一就是将某些与
11ba3
用户相关的文件打包到ROM中,如果是APK程序,还允许卸载这些程序,除此之外,userdata.img还有另外一个作用,就是确定Android设备内存的大小。在Android


设备中可供用户操作的存储区域通常有如下三部分。

RAM   

内存

外出存储器(SD卡)

RAM就是传统意义上的内存,与PC的内存是一个概念,只有在通电时吗才能存储数据,断点后所有数据将自动消失,所有要运行的程序都需要调用RAM。不过Android设备的内存就与RAM不一样了,这里的内存是指内部存储器。这一部分是大多数PC所有没有。因为现在所有的Android设备都有都带有一定大小的内部存储器(嵌入到芯片上,类似于内部嵌入一个SD卡),用于存储一些随机器发布的系统和应用程序。而PC除了RAM,就是硬盘了。一般PC在出厂时并不会将硬盘嵌入的芯片上,所以PC比Android设备少了一个内部存储器。

最后一部分就是外部存储器,通常是SD卡。有的Android系统加入了OTG(On-The-Go)支持,所以通过OTG连接的U盘、移动硬盘也应属于外部存储器,有一些Android设备(如Nexus 7) 不支持插入SD卡。所以Android系统通过Linux 文件系统将内存划分成不同区域,例如,本节要讲的userdata.img就属于userdata分区,该分区就是前面所说

的内存。而剩余的内存空间就会将其作为外部存储器。通常在Android设备的shell中可以通过/sdcard目录访问,从这些描述可以得出结论。userdata.mg的另一个作用就是确定Android设备内存的大小。如果Android设备支持外部存储器,内存的设置可以占用所有剩余的内部存储器(系统镜像、缓存区等部分也需要一定的存储空间)。如果Android设备不支持外部存储器,userdata.img就不能太大我,否则系统将无法利用剩余的空间映射SD卡(/sdcard,目录)

userdata.img有如下两个功能:

 

封装与用户相关的文件,并连同ROM一起发布,或单独刷userdata.img文件。

确定Android设备内存的大小。

 

2、用户数据镜像(userdata.img)

 

学习userdata.img的第一步就是解剖他。方法与解剖system类似.

首先需要使用simg2img命令将userdata.img文件还原成非压缩格式的镜像文件,这样可以直接使用mount命令将userdata.img文件挂载到某个目录,进而查看userdata.img中的内容。可以使用前面章节编译官方Android源代码或CM Android源代码生成userdata.img文件做这个实验,也可以使用官方发布的Nexus系列ROM中的userdata.img文件做这个实验。还原userdata.img的命令如下:

simg2img userdata.img userdata.img.raw

执行上面的命令后,会生成还原后的userdata.img.raw文件。然后使用下面的命令挂载userdata.img.raw文件。

mkdir -p /mnt/rom/userdata

mount  userdata.img.raw /mnt/rom/userdata

如果挂载成功,会在/mnt/rom/userdata 目录看到userdata.img 中的内容。通常该目录除了“lost+found”(该目录一般为空,在系统非法关机时会存放一些文件) 系统目录外,什么都没有。读者可以执行下面的命令查看当前挂载的用户镜像尺寸。,

df -h

现在可以在/mnt/rom/userdata目录放一些目录或文件,例如,将Test.apk作为普通的Android应用放入userdata.img,如要在/mnt/rom/userdata目录建立一个app子目录,然后将Test.apk文件放入app目录即可。

在修改完/mnt/roim/userdata目录后,需要使用下面的命令重新打包/mnt/rom/userdata 目录。为了与userdata.img区别即可。

在修改完/mnt/rom/userdata目录后,需要使用下面的命令重新打包/mnt/rom/userdata目录,为了与userdata.img区别,在这里将该目录打包成了userdata.img.new。 要注意,在打包的过程中会确定用户镜像对应的空间大小,例如,下面的命令生成了最大为128M的用户镜像文件(userdata.img.new,ext4格式的镜像文件)。

make_ext4fs -s -l 128M -a data userdata.img.new /mnt/rom/userdata

要注意的是,加上"-s"命令行,参数就表示生成的userdata.img.new 文件是压缩格式,不能直接使用mount命令挂载,需要按着签名的而方法通过simg2img命令来还原才能挂载到某一目录。“-a”命令行参数后面的是文件系统,这里需要制定data。

接下来可以使用下面的命令将userdata.img.new 文件刷到Android设备上(加上目录Android设备正处于正常的启动状态,并通过USB线PC相连)。注意:在刷userdata.img.new文件之前,一定 要备份Android设备上已安装的应用程序、配置和其他数据,否则这些数据将全部丢失(SD卡中的数据不会丢失)。

adb reboot bootloader

fastboot flash userdata userdata.img.new

fastboot reboot

上面的命令在刷完userdata.img.new 后,会重启Android设备。在进行一些设置后(因为以前的配置都丢失了),会重新进入Home界面。然后通过“设置”》"存储"可以查看使用情况,

make_ext4fs -s -l 1G -a data userdata.img.new /mnt/rom/userdata

注意:

用户镜像占用的存储空间不能超过Android设备的内部存储器的总尺寸,否则即使成功刷机,Android设备也可能会启不来,即使启来也由于SD卡无法挂载而出现如图4-10所示的界面,要求输入密码(实际上就是映射失败)。

 

 

3、内存磁盘镜像(ramdisk.img)

内存磁盘镜像存储了Linux内核启动时要装载的核心文件,通常的镜像文件名为ramdisk.img.尽管ramdisk.img需要放在Linux内核镜像(boot.img)中,但却属于Android源代码的一部分。也就是说,在编译Android 源代码后,会生成一个ramdisk.img文件,其实该文件就是root目录压缩后生成的文件。ramdisk.img文件中封装的内容是Linux内核与Android系统杰出的第一批文件,其中有一个非常重要的init命令(在root目录中可以找到该命名文件),该命令用于读取init.rc以及相关配置文件中的初始化命令。之所以称ramdisk.img为内存磁盘镜像,是因为ramdisk.img中的文件映射的实际上都是内存中的文件,也就是说,即使有权修改init.rc等文件,也只是修改原始文件在内存中的镜像,重新启动Android设备后,有会恢复到最初的状态。而修改这些文件的唯一方法就是重新制作ramdisk.img文件,并连同Linux内核二进制文件(ZImage)生成boot.img文件,并且在Bootloader模式刷机才可以。而ramdisk.img是boot.img中重要的组成部分之一,

ramdisk.img文件与前面介绍的system.img、userdata.img不一样,不能使用simg2img还原,并使用mount挂载。其实ramdisk.img文件只是一个普通的zip压缩文件,可以直接使用gunzip命令解压,不过解压后并不是原声文件和目录,而是有cpio命令备份的文件,所以还需要使用cpio继续还原。

假设ramdisk.img文件在当前目录下,则还原ramdisk.img文件的命令如下:

mkdir ramdisk

cp ramdisk 

gunzip -c ../ramdisk.img > ../ramdisk.cpio

cpio -i < ../ramdisk.cpio

也可以将最后两行命令合成如下的一行。

gunzip -c ../ramdisk.img | cpio -i

执行上面的命令后,就会在ramdisk目录中看到内存磁盘镜像还原后的目录结构,

如果现在要修改init.rc等配置文件,可以自己在ramdisk目录中找到相应的文件并修改。例如,有Linux的瑞士军刀之称busybox,可以放到ramdisk中的sbin目录下。这样在Recovery模式下就可以使用busybox命令完成很多操作了。

修改完ramdisk目录的内容后,就需要使用下面的命令将ramdisk目录重新生成ramdisk.img文件。为了与原来的ramdisk.img文件有所区别,这里生成了ramdisk.img.new文件,在执行下面的命令之前,要保证Linux终端的当前目录是ramdisk。

mkbootfs . | minigzip > ../ramdisk.img.new

 

4、Linux内核镜像(boot.img)

Linux内核镜像包含了内核二进制(zImage)和内存磁盘镜像(ramdisk.img),一般对应的镜像文件是boot.img(也可以是任何其他的名字)。由于ramdisk.img中包含的init命令是与Linux内核第一个交互的程序,所以在boot.img中需要同时包含Linux内核(zImage)和ramdisk.img。当Linux内核调用init后,系统就会根据init.rc及其相关文件的代码对整个Android系统进行初始化。其中主要的初始化工作就是建立如/system、/data、等系统目录,然后使用mount命令将相应的镜像挂载到这些目录上。

Android源代码经过编译后,也可以在其中找到对boot.img解压和生成boot.img文件的命令。

其中unpackbooting 为解压命令,mkbooting命令可以将zImage和ramdisk.img文件合并成boot.img。下面先来用unpackbooting命令将boot.img解压,再看看boot.img是不是有zImage和ramdisk.img文件组成的。

假设boot.img文件(我们可以使用从其他Rom压缩包中获得的boot.img,也可以使用通过Android源代码生成的boot.img)在当前目录中,使用下面的命令可以将boot.img文件解压到boot目录中。

mkdir boot

cd boot 

unpackbootimg -i  ../boot.img

 

执行完上面的命令后,会发现boot目录中多了几个文件,其中有两个主要的文件:

boot.img-zImage 和boot.img-ramdisk.gz。前者是Linux 内核文件(与zImage文件完全一样),后者是内存磁盘镜像(与ramdisk.img完全一样)。为了证明boot.img-ramdisk.gz 与ramdisk.img文件完全相等,可以使用下面的命令将boot.img-ramdisk.gz 解压到ramdisk目录。

mkdir ramdisk

cd ramdisk

gunzip -c ../boot.img-ramdisk.gz | cpio  -i

目录结构与ramdisk.img 一样

、如果想向init.rc或娶她文件中添加新的内容,或在内存磁盘镜像中添加新的命令,可以修改刚才由boot.img-ramdisk.gz 文件解压生成的ramdisk目录中的相应文件和目录的内容,然后使用下面的命令重新将ramdisk目录中的相应文件和目录的内容,然后使用下面的命令重新将ramdisk打包成boot.img-ramdisk.gz.new(当前目录是ramdisk)。

mkbootfs . " minigzip > ../boot.img-ramdisk.gz.new

接下来推到上一层目录,然后使用下面的命令将boot.img-zImage 和boot.img-ramdisk.gz.new

文件合并成boot.img.new 文件(为了区分boot.img,这里生成了boot.img.new 文件)。

mkbootimg --kernel boot.img-zImage --ramdisk boot.img-ramdisk.gz.new -o boot.img.new

如果想修改Linux内核,需要下载Linux内核源代码(官方和CM都提供了相应Android设备的Linux内核源代码)

接下来退到上一层目录,然后使用下面的命令将boot.img-zImage  和boot.img-ramdisk.gz.new

现在可以使用下面的命令重新刷Linux内核(加上Android系统处于正常启动状态,并通过USB线和PC相连)。不过要注意的是Linux内核必须与当前Android设备匹配,否则刷完后Android设备有可能起不来。刷Linux内核不会对系统(system.img)和用户数据(userdata.img)造成任何影响。

adb reboot bootloader

fastboot flash boot boot.img,new 

fastboot reboot

重启Android设备后,如果我们修改了Linux内核和内存磁盘镜像,就会立刻生效

注意:

(boot.img解压后,除了生成boot.img-zImage和boot.img-ramdisk.gz文件外,还会生成一些其他的文件,如boot.img-base、boot.img-cmdline、boot.img-pagesize等,这些文件都是一些配置文件。例如,boot.img-cmdline文件中包含了Linux内核启动时传入的参数。通常并不需要管这些文件,只需要保持默认值即可)。

 

 

 

5、5、Recovery镜像(recovery.img)



Recovery镜像只用于刷机,通常的镜像文件名为:receovery.img,其实制作ROM并不一定要制作Recovery镜像。因为有很多现成好用的Recovery,例如,Clockworkmod Recovery就是其咋红的佼佼者。尽管有很多Recovery可以同不过有时由于特殊的需要或显示自己更加geek。想定制自己的Recovery。本节将详细介绍如何定制recovery.img,不过事先说明一点,定制recovery.img的方法只是在已经有recovery镜像文件的前提下完成的。关于如何更深入定制recovery和修改recovery的源代码。


在学习定制Recovery.img之前,先清除recovery.img到底是个什么东西。从本质上说,recovery.img和boot.img高达90%是一样的。这就意味着,recovery.img也是Linux内核(zImage)和内存磁盘镜像(ramdisk.img)组成的。这两个镜像中的Linux内核是完全一样的,区别只是ramdisk.img中的少部分文件存在差异。其中最主要的差异是recovery.img和ramdisk.img中的sbin目录中多了一个recovery命令进入Recovery主界面,而不会正常启动Android系统。实现的原理是Recovery.img和boot.img在自己的分区各自有一个Linux内核(zImage),尽管Linux内核都一样,但Linux内核调用的init命令解析的init.rc及其相关文件的内容有一定的差异。而Bootloader根据用户的选择决定使用boot.img中Linux内核,还是使用Recovery.img中的Linux内核启动系统。如果使用前者,Android系统就会正常启动,如果使用后者,就会进入Recovery选择菜单,所以recovery.img和boot.img的第二个差异就是其中的init.rc及其相关配置文件的内容略有不同。

从前面的描述还可以看出,recovery.img和boot.img其实都是一个最小的运行系统,也就是说他们都各自带一个满足最低要求的运行环境(ramdisk.img)。boot.img利用这个运行环境监理更大的运行环境(system.img) ,而recovery.img就直接使用了这个运行环境进行基本的操作(复制文件、删除文件、加压文件、mount等),这些操作也就是Recovery模式下刷机要进行的一些操作。

既然了解了recovery.img是什么东西,那么就可以解压recovery.img,并且重写生成recovery.img文件。

假设recovery.img文件在当前目录下,具体的解压和打包命令如下。

解压recovery.img

mkdir recovery

cd recovery

uppackbootimg -i ../recovery.img

执行下面的命令会在recovery目录下生成如下5个文件。

recovery.img-zImage

recovery.img-ramdisk.gz

recovery.img-cmdline

recovery.img-pagesize

recovery.img-base

其中前两个分别为recovery.img中的Linux内核和内存磁盘镜像。可以使用下面的命令解压recovery.img-ramdisk.gz文件。

解压recovery.img-ramdisk.gz文件

mkdir ramdisk

cd ramdisk

gunzip -c ../recovery.img-ramdisk.gz | cpio -i

现在回到上一层目录,最后按着4.2.4小节的方法重新生成内存镜像文件(这里为Recovery.img-randisk.gz.new),并使用下面的命令重新生成Recovery镜像(这里为recovery.img.new )。

重新生成Recovery镜像文件

mkbootimg --kernel recovery.img-zImage --ramdisk recovery.img-ramdisk.gz.new -o recovery.img.new

现在可以使用下面的命令重新刷Recovery(加上Android 处在正常启动状态),并进入Recovery模式。

刷Recovery镜像

adb reboot bootloader

fastboot flash recovery recovery.img.new

fastboot reboot

adb reboot recovery

6、缓存镜像(cache.img)

缓存镜像用于存储系统或用户应用产生的临时数据,通常的镜像文件名为chche.img。一般ROM并不需要包含缓存镜像,不过在这里还是介绍一下如何制作和刷缓存镜像。

缓存镜像实际上就是一个空的ext4格式的文件系统镜像,可以使用下面的命令生成缓存镜像。

mkdir -p /mnt/rom/cache

make_ext4fs -s -l 256M -a cache cache.img /mnt/rom/cache

可以使用下面的命令刷缓存镜像。

adb reboot bootloader

fastboot flash cache cache.img

fastboot reboot

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐