内容发布更新时间 : 2024/12/24 4:02:27星期一 下面是文章的全部内容请认真阅读。
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.
一个模块可以通过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描述的文件。