$(BUILT_TARGET_FILES_PACKAGE): $(INSTALLED_BOOTIMAGE_TARGET) $(INSTALLED_RADIOIMAGE_TARGET) $(INSTALLED_RECOVERYIMAGE_TARGET) $(INSTALLED_SYSTEMIMAGE) $(INSTALLED_USERDATAIMAGE_TARGET) $(INSTALLED_ANDROID_INFO_TXT_TARGET) $(built_ota_tools) $(APKCERTS_FILE) $(HOST_OUT_EXECUTABLES)/fs_config | $(ACP)
在上一篇博文中,我们有发现$(BUILT_TARGET_FILES_PACKAGE)依赖于冒号(":")后面的对象,诸如$(INSTALLED_BOOTIMAGE_TARGET)等等。也就是说$(INSTALLED_BOOTIMAGE_TARGET)必须存在,那么$(BUILT_TARGET_FILES_PACKAGE)才能够生成。此篇文章旨在分析$(INSTALLED_BOOTIMAGE_TARGET)是如何生成的。也就是boot.img是怎样生成的。
ifneq ($(strip $(TARGET_NO_KERNEL)),true) # ----------------------------------------------------------------- # the boot image, which is a collection of other images. INTERNAL_BOOTIMAGE_ARGS := $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) --kernel $(INSTALLED_KERNEL_TARGET) --ramdisk $(INSTALLED_RAMDISK_TARGET) INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS)) BOARD_KERNEL_CMDLINE := $(strip $(BOARD_KERNEL_CMDLINE)) ifdef BOARD_KERNEL_CMDLINE INTERNAL_BOOTIMAGE_ARGS += --cmdline "$(BOARD_KERNEL_CMDLINE)" endif BOARD_KERNEL_BASE := $(strip $(BOARD_KERNEL_BASE)) ifdef BOARD_KERNEL_BASE INTERNAL_BOOTIMAGE_ARGS += --base $(BOARD_KERNEL_BASE) endif BOARD_KERNEL_PAGESIZE := $(strip $(BOARD_KERNEL_PAGESIZE)) ifdef BOARD_KERNEL_PAGESIZE INTERNAL_BOOTIMAGE_ARGS += --pagesize $(BOARD_KERNEL_PAGESIZE) endif INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img ifeq ($(TARGET_BOOTIMAGE_USE_EXT2),true) tmp_dir_for_image := $(call intermediates-dir-for,EXECUTABLES,boot_img)/bootimg INTERNAL_BOOTIMAGE_ARGS += --tmpdir $(tmp_dir_for_image) INTERNAL_BOOTIMAGE_ARGS += --genext2fs $(MKEXT2IMG) $(INSTALLED_BOOTIMAGE_TARGET): $(MKEXT2IMG) $(INTERNAL_BOOTIMAGE_FILES) $(call pretty,"Target boot image: [email protected]") $(hide) $(MKEXT2BOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output [email protected] else # TARGET_BOOTIMAGE_USE_EXT2 != true $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_FILES) $(call pretty,"Target boot image: [email protected]") $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) --output [email protected] $(hide) $(call assert-max-image-size,[email protected],$(BOARD_BOOTIMAGE_PARTITION_SIZE),raw) endif # TARGET_BOOTIMAGE_USE_EXT2 else # TARGET_NO_KERNEL # HACK: The top-level targets depend on the bootimage. Not all targets # can produce a bootimage, though, and emulator targets need the ramdisk # instead. Fake it out by calling the ramdisk the bootimage. # TODO: make the emulator use bootimages, and make mkbootimg accept # kernel-less inputs. INSTALLED_BOOTIMAGE_TARGET := $(INSTALLED_RAMDISK_TARGET) endif
1行:$(TARGET_NO_KERNEL)没有定义,所以这个判断条件为真。执行ifneq <--> else内的代码.
27行:INSTALLED_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
这就是我们要生成的目标
39行:生成boot.img依赖的对象以及生成boot.img的命令脚本。其中$(INTERNAL_BOOTIMAGE_FILES)是我们需要关注的对象。也是最为重要的依赖对象。它的定义在第10行。
10行:$(INTERNAL_BOOTIMAGE_FILES)也就是$(INTERNAL_BOOTIMAGE_ARGS)中由符号"--"所标识的对象。
--kernel $(INSTALLED_KERNEL_TARGET) --ramdisk $(INSTALLED_RAMDISK_TARGET)
两个对象:$(INSTALLED_KERNEL_TARGET)和$(INSTALLED_RAMDISK_TARGET)
$(INSTALLED_KERNEL_TARGET)也就是zImage
$(INSTALLED_RAMDISK_TARGET)就是ramdisk.img
那么$(INSTALLED_KERNEL_TARGET)是在哪里定义的?build/target/board/Android.mk
ifneq ($(strip $(TARGET_NO_KERNEL)),true) INSTALLED_KERNEL_TARGET := $(PRODUCT_OUT)/kernel else INSTALLED_KERNEL_TARGET := endif -include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
这里我们要注意的不仅仅是第2行,还需要注意第6行。后面在讲到如何将Linux Kernel加入到AOSP的编译系统中会讲解到。这里可以先跳过。
我们继续分析ramdisk.img是如何生成的。
# ################################################################# # Targets for boot/OS images # ################################################################# # ----------------------------------------------------------------- # the ramdisk INTERNAL_RAMDISK_FILES := $(filter $(TARGET_ROOT_OUT)/%, $(ALL_PREBUILT) $(ALL_COPIED_HEADERS) $(ALL_GENERATED_SOURCES) $(ALL_DEFAULT_INSTALLED_MODULES)) BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img # We just build this directly to the install location. INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET) $(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) | $(MINIGZIP) $(call pretty,"Target ram disk: [email protected]") $(hide) $(MKBOOTFS) $(TARGET_ROOT_OUT) | $(MINIGZIP) > [email protected]
到这里整个boot.img的生成从大轮廓上就已经结束了。那么小轮廓是什么?这里小轮廓我是指一些细节,诸如$(ALL_PREBUILT),$(ALL_COPIED_HEADERS)...是什么?怎么生成的?这些会在其它章节展开详细讨论。