Android系统镜像文件的打包过程分析资料 下载本文

Android系统镜像文件的打包过程分析

在前面一篇文章中,我们分析了Android模块的编译过程。当Android系统的所有模块都编译好之后,我们就可以对编译出来的模块文件进行打包了。打包结果是获得一系列的镜像文件,例如system.img、boot.img、ramdisk.img、userdata.img和recovery.img等。这些镜像文件最终可以烧录到手机上运行。在本文中,我们就详细分析Android系统的镜像文件的打包过程。

Android系统镜像文件的打包工作同样是由Android编译系统来完成的,如图1所示:

从前面和这两篇文章可以知道,Android编译系统在初始化的过程中,会通过根目录下的Makefile脚本加载build/core/main.mk脚本,接着build/core/main.mk脚本又会加载build/core/Makefile脚本,而Android系统镜像文件就是由build/core/Makefile脚本负责打包生成的。

在build/core/main.mk文件中,与Android系统镜像文件打包过程相关的内容如下所示:

[plain] view plain copy ......

ifdef FULL_BUILD

# The base list of modules to build for this product is specified # by the appropriate product definition file, which was included # by product_config.make.

product_MODULES := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES) # Filter out the overridden packages before doing expansion

product_MODULES := $(filter-out $(foreach p, $(product_MODULES), \\ $(PACKAGES.$(p).OVERRIDES)), $(product_MODULES))

$(call expand-required-modules,product_MODULES,$(product_MODULES)) product_FILES := $(call module-installed-files, $(product_MODULES))

...... else

# We're not doing a full build, and are probably only including

# a subset of the module makefiles. Don't try to build any modules # requested by the product, because we probably won't have rules # to build them. product_FILES := endif ......

modules_to_install := $(sort \\

$(ALL_DEFAULT_INSTALLED_MODULES) \\ $(product_FILES) \\

$(foreach tag,$(tags_to_install),$($(tag)_MODULES)) \\ $(call get-tagged-modules, shell_$(TARGET_SHELL)) \\ $(CUSTOM_MODULES) \\ )

# Some packages may override others using LOCAL_OVERRIDES_PACKAGES. # Filter out (do not install) any overridden packages.

overridden_packages := $(call get-package-overrides,$(modules_to_install)) ifdef overridden_packages

# old_modules_to_install := $(modules_to_install) modules_to_install := \\

$(filter-out $(foreach p,$(overridden_packages),$(p) %/$(p).apk), \\ $(modules_to_install)) endif ......

# Install all of the host modules

modules_to_install += $(sort $(modules_to_install) $(ALL_HOST_INSTALLED_FILES))

# build/core/Makefile contains extra stuff that we don't want to pollute this

# top-level makefile with. It expects that ALL_DEFAULT_INSTALLED_MODULES # contains everything that's built during the current make, but it also further # extends ALL_DEFAULT_INSTALLED_MODULES.

ALL_DEFAULT_INSTALLED_MODULES := $(modules_to_install) include $(BUILD_SYSTEM)/Makefile

modules_to_install := $(sort $(ALL_DEFAULT_INSTALLED_MODULES)) ALL_DEFAULT_INSTALLED_MODULES := ......

.PHONY: ramdisk

ramdisk: $(INSTALLED_RAMDISK_TARGET)

......

.PHONY: userdataimage

userdataimage: $(INSTALLED_USERDATAIMAGE_TARGET) ......

.PHONY: bootimage

bootimage: $(INSTALLED_BOOTIMAGE_TARGET) ......

如果定义在FULL_BUILD这个变量,就意味着我们是要对整个系统进行编译,并且编译完成之后 ,需要将编译得到的文件进行打包,以便可以得到相应的镜像文件,否则的话,就仅仅是对某些模块进行编译。

在前面一篇文章中,我们提到,变量INTERNAL_PRODUCT描述的是执行lunch命令时所选择的产品所对应的产品Makefile文件,而变量PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_PACKAGES描述的是在该产品Makefile文件中通过变量PRODUCT_PACKAGES所定义的模块名称列表。因此,我们得到的变量product_MODULES描述的就是要安装的模块名称列表。

我们知道,Android源码中自带了很多默认的APK模块。如果我们想用自己编写的一个APK来代替某一个系统自带的APK,那么就可以通过变量PACKAGES..OVERRIDES := 来说明。其中,表示用来替换的APK,而表示被替换的APK。在这种情况下,被替换的APK是不应该被打包到系统镜像中去的。因此,我们需要从上一步得到的模块名称列表中剔除那些被替换的APK,这是通过Makefile脚本提供的filter-out函数来完成的。

一个模块可以通过LOCAL_REQUIRED_MODULES变量来指定它所依赖的其它模块,因此,当一个模块被安装的时候,它所依赖的其它模块也会一起被安装。调用函数expand-required-modules获得的就是所有要安装的模块所依赖的其它模块,并且将这些被依赖的模块也一起保存在变量product_MODULES中。

注意,这时候我们得到的product_MODULES描述的仅仅是要安装的模块的名称,但是我们实际需要的这些模块对应的具体文件,因此,需要进一步调用函数module-installed-files来获得要安装的模块所对应的文件,也就是要安装的模块经过编译之后生成的文件,这些文件就保存在变量product_FILES中。

最终需要安装的文件除了变量product_FILES所描述的文件之后, 还包含以下四类模块文件:

1. 变量ALL_DEFAULT_INSTALLED_MODULES描述的文件。

2. 变量CUSTOM_MODULES描述的文件。