Android启动过程



Android在启动的时候,会由UBOOT传入一个init参数,这个init参数指定了开机的时候第一个运行的程序,默认就是init程序,这个程序在ramdisk.img中。可以分析一下它的代码,看看在其中到底做了一些什么样的初始化任务,它的源文件在system/core/init/init.c中。
它会调用到init.rc初始化文件,这个文件在out/target/product/generic/root下,我们在启动以后,会发现根目录是只读属性的,而且sdcard的owner是system,就是在这个文件中做了些手脚,可以将它改过来,实现根目录的可读写。
通过分析这几个文件,还可以发现,android启动时首先加载ramdisk.img镜像,并挂载到/目录下,并进行了一系列的初始化动作,包括创建各种需要的目录,初始化console,开启服务等。System.img是在init.rc中指定一些脚本命令,通过init.c进行解析并挂载到根目录下的/system目录下的。

ramdisk.img、system.img、userdata.img镜像产生过程:

首先在linux终端下使用命令file ramdisk.img,打印出如下字符ramdisk.img: gzip compressed data, from Unix,可以看出,它是一个gzip压缩的格式,下面对其进行解压,使用fedora自带的工具进行解压,或者使用gunzip进行解压(可能需要将扩展名改为.gz),可以看到解压出一个新的ramdisk.img,这个ramdisk.img是使用cpio压缩的,可以使用cpio命令对其进行解压,cpio –i –F ramdisk.img,解压后可以看到生成了一些文件夹和文件。看到这些文件就会明白,它和root目录下的内容完全一样。说明了ramdisk.img其实是对root目录的打包和压缩。

下面分析system.img的来源。在build/core/Makefile里的629行,可以看到这么一段文字
# The installed image, which may be optimized or unoptimized.
#

INSTALLED_SYSTEMIMAGE := $(PRODUCT_OUT)/system.img
从这里可以看出,系统应该会在$(PRODUCT_OUT)目录下生成system.img
再继续往下看,在662行有一个copy-file-to-target,这实现了将system.img从一个中间目录复制到/generic目录。
BUILD_SYSTEM的定义在636行。
这里的system.img不是/generic目录下面我们看到的那个system.img,而是另一个中间目录下的,但是是同一个文件。一开始看到的复制就是把out /target/product/generic/obj/PACKAGING/systemimage_unopt_intermediates目录下面的system.img复制到/generic目录下。

现在,知道了system.img的来历,然后要分析它是一个什么东西,里面包含什么??
Makefile line624
$(BUILT_SYSTEMIMAGE_UNOPT): $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_MKUSERFS)
$(call build-systemimage-target,[email protected])
这里调用了build-systemimg-target Makefile line605
ifeq ($(TARGET_USERIMAGES_USE_EXT2),true)
## generate an ext2 image
# $(1): output file
define build-systemimage-target
@echo "Target system fs image: $(1)"
$(call build-userimage-ext2-target,$(TARGET_OUT),$(1),system,)
endef
else # TARGET_USERIMAGES_USE_EXT2 != true
## generate a yaffs2 image
# $(1): output file
define build-systemimage-target
@echo "Target system fs image: $(1)"
@mkdir -p $(dir $(1))
*$(hide) $(MKYAFFS2) -f $(TARGET_OUT) $(1)*
endef
endif # TARGET_USERIMAGES_USE_EXT2
找不到TARGET_USERIMAGES_USE_EXT2的定义!!!不过从上面的分析可以推断出应该是yaffs2文件系统。
其中MKYAFFS2:(core/config.mk line161)
MKYAFFS2 := $(HOST_OUT_EXECUTABLES)/mkyaffs2image$(HOST_EXECUTABLE_SUFFIX)
定义MKYAFFS2是目录/media/disk/mydroid /out/host/linux-x86/bin下的一个可执行文件mkyaffs2image,运行这个程序可得到如下信息:
#./mkyaffs2image
mkyaffs2image: image building tool for YAFFS2 built Nov 13 2009
usage: mkyaffs2image [-f] dir image_file [convert]
-f fix file stat (mods, user, group) for device
dir the directory tree to be converted
image_file the output file to hold the image
'convert' produce a big-endian image from a little-endian machine
得知这个程序可以生成yaffs2的文件系统映像。并且也清楚了上面*$(hide) $(MKYAFFS2) -f $(TARGET_OUT) $(1)*的功能,把TARGET_OUT目录转变成yaffs2格式并输出成/media/disk/mydroid/out/target /product/generic/obj/PACKAGING/systemimage_unopt_intermediates /system.img(也就是我们最终在/generic目录下看到的那个system.img)。
到现在已经差不多知道system.img的产生过程,要弄清楚system.img里面的内容,就要分析TARGET_OUT目录的内容了。 (想用mount把system.img挂载到linux下面看看里面什么东西,却不支持yaffs和yaffs2文件系统!!!)
下一步:分析TARGET_OUT 在build/core/envsetup.sh文件(line205)中找到了TARGET_OUT的定义:
TARGET_OUT := $(PRODUCT_OUT)/system
也就是/media/disk/mydroid/out/target /product/generic目录下的system目录。
#tree -L 1
.
|-- app
|-- bin
|-- build.prop
|-- etc
|-- fonts
|-- framework
|-- lib
|-- usr
`-- xbin
现在一切都明白了,我们最终看到的system.img文件是该目录下的system目录的一个映像,类似于linux的根文件系统的映像,放着android的应用程序,配置文件,字体等。
Userdata.img来来自于data目录,默认里面是没有文件的。


ramdisk.img、system.img、userdata.img镜像拆解过程:

1、ramdisk.img:

RAMDISK(initrd)是一个小的分区镜像,在引导时内核以只读方式挂载它。它只保护/init和一些配置文件。它用于初始化和挂载其它的文件系统镜像。RAMDISK是一个标准的Linux特性。

ramdisk.img被包含Google android SDK中($SDK_ROOT/tools/lib/images/ramdisk.img),也可以编译生成($SDK_ROOT/out/target/product/$PRODUT_NAME/ramdisk.img)。这是一个gzip压缩的CPIO文件。

修改Android的RAMDISK镜像

要修改它,首先复制它到你的Linux机器上,并用如下命令解开:

<span style="margin: 0px; font-size: 16px;">[email protected]:$ mv ramdisk.img ramdisk.cpio.gzgzip -d ramdisk.cpio.gzmkdir ramdiskcd ramdisk  cpio -i -F ../ramdisk.cpio</span>

解开后,做一些你的修改和删除无用的文件后,通过如下命令重新创建ramdisk.cpio:

<span style="margin: 0px; font-size: 16px;">[email protected]:$ cpio -i -t -F ../ramdisk.cpio | cpio -o -H newc -O ../ramdisk_new.cpio</span>

然后可以重新改名并压缩:

[email protected]:$ cd ..
gzip ramdisk_new.cpio
mv ramdisk_new.cpio.gz ramdisk.img

2、SYSTEM和DATA镜像

system.img是挂载到 / 下的镜像,它包含了全部的系统可执行文件。

userdata.img挂载到 /data 下的镜像,它包含了应用及用户相关的数据。

在实际的物理设备中,他们通过ramdisk中的init.rc脚本挂载为文件系统。它们可以有各种不同的格式,如 YAFFS2、EXT4或 UBI-FS。

它们通过Android构建系统生成并刷入到物理设备中。模拟器对它们的使用有所不同(见下文):

3、Android模拟器镜像

system.img被复制到一个临时文件中,用于模拟器工作。所以你对模拟器中的根目录做的任何改变都会在模拟器退出后丢失。

userdata.img只用于使用了 -wipe-data参数时。通常将~/.android/userdata-qemu.img(linux下)作为 /data 分区镜像挂载,而使用 -wipe-data 时会复制userdata.img中的内容到userdata-qemu.img。

sdcard.img 用于使用了-sdcard参数时,挂载到/sdcard

cache.img用于使用了-cache参数来指定/cache内容。如果未指定该参数,模拟器启动时会创建一个空的临时文件挂载到/cache上。这个临时文件会在退出时自动清除。

模拟器不会修改system.img和userdata.img。 4、拆解Android’s YAFFS2 镜像

一个YAFFS2文件在Linux被识别为“VMS Alpha executable”文件。

[email protected]:$ file ${SDK_ROOT}}/out/target/product/imx51_ccwmx51js/system.img
./out/target/product/imx51_ccwmx51js/system.img: VMS Alpha executable

从Google代码站中下载unyaffs

如果上面的可执行文件在你的系统不工作的话,你也可以下载源代码并重新编译它。

[email protected]:$gcc -o unyaffs unyaffs.c
sudo chmod +x /complete/directory/path/to/unyaffs

然后使用这个命令来拆解 YAFF2 镜像文件:

[email protected]:$ mkdir image
cd image
unyaffs ../system.img

5、拆解EXT4镜像

如果镜像是EXT4,那么很简单,直接挂载就可以读取其中的内容了:

[email protected]:$ mount -o loop -t ext4 system.img /media

6、拆解JFFS2镜像

作为补充,这里说一下如何拆解JFFS2镜像:

[email protected]: modprobe mtdblock
modprobe jffs2
modprobe mtdram total_size=65536 erase_size=256
mknod /tmp/mtdblock0 b 31 0
dd if=/pathtoimage/rootfs.jffs2 of=/tmp/mtdblock0
mount -t jffs2 /tmp/mtdblock0 /mnt


更多相关文章

  1. Ubuntu中useradd和adduser的区别
  2. Android(安卓)NDK开发技巧二
  3. Android(安卓)APK加固后如何签名
  4. OpenCV4Android(安卓)环境配置(最新详细教程)
  5. Android(安卓)Q之提前适配攻略(五)(存储权限变更)
  6. Android.jar文件浅析
  7. 用smali实现Android(安卓)apk的简单汉化
  8. Ubuntu下安装VirtualBox和Android(安卓)安装到虚拟机中
  9. Android(安卓)Studio打包与依赖(jar、aar)

随机推荐

  1. CSS Feature Query
  2. 定制替换Android桌面
  3. JDK10都发布了,nio你了解多少?
  4. 你不知道的,Java代码性能优化的 40+ 细节,
  5. [置顶] android利用zbar二维码扫描-(解决
  6. 还是初识
  7. X-Ray检测Android设备Root漏洞过程分析
  8. 源码实战 | 本地可跑,上线就崩?慌了!
  9. SQLite
  10. 图解源码 | MyBatis的Mapper原理