用户镜像用来存储与用户相关的数据,一般对应的文件名是userdata.img(也可以是任何文件名,为了方便,我们将userdata称为用户镜像文件)。
这些数据大多都是有用户在使用Android设备的过程中产生的,例如,通过Google play安装的第三方APK程序,用户的配置文件等。当然,在制作ROM时,也可以将部分数据放到userdata.img中。例如,如果允许用户使用普通的方法卸载ROM内置的应用,就可以将APK文件放到userdata.img文件中 (这里是普通的应用程序,而system.img放入的是系统应用程序)
在学习userdata.img之前,首先应该了解userdata.img在整个Android系统中起到了什么作用。从前面的描述可以断定,userdata.img的作用之一就是将某些与用户相关的文件打包到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.img的另一个作用就是确定Android设备内存的大小。如果Android设备支持外部存储器,内存的设置可以占用所有剩余的内部存储器(系统镜像、缓存区等部分也需要一定的存储空间)。如果Android设备不支持外部存储器,userdata.img就不能太大我,否则系统将无法利用剩余的空间映射SD卡(/sdcard,目录)
userdata.img有如下两个功能:
封装与用户相关的文件,并连同ROM一起发布,或单独刷userdata.img文件。
确定Android设备内存的大小。
学习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所示的界面,要求输入密码(实际上就是映射失败)。