http://www.uml.org.cn/mobiledev/201705272.asp

https://blog.csdn.net/qq_26787115/article/details/79745022

https://www.jianshu.com/p/5ad125c62af3

https://blog.csdn.net/gzzaigcnforever/article/details/20146483

https://blog.csdn.net/z1106609486/article/details/51406744/ (巨详细!)

https://blog.csdn.net/cx_chess/article/details/101938206

https://blog.csdn.net/u014674293/article/details/105158562/

https://www.cnblogs.com/aspirs/p/7822474.html

https://www.cnblogs.com/wi100sh/p/4338539.html (对一些变量作了详细的说明)

https://blog.csdn.net/lizhaohui815/article/details/44676113 (make dist 执行 Build,并将 MAKECMDGOALS 变量定义的输出文件拷贝到 /out/dist 目录。)

https://source.android.google.cn/docs/setup/about?hl=da (google官网)

https://www.jianshu.com/p/fd86aef44365?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes (**)

https://blog.csdn.net/z1106609486/article/details/51406744

https://blog.csdn.net/xiehaihit/article/details/92642127

https://www.jianshu.com/p/b088befb8c61 (**)

一、镜像制作相关的脚本分析(以android10源码为例)

build_image.py (制作镜像)

https://blog.csdn.net/lewif/article/details/56837191
文件位置:build/make/tools/releasetools/build_image.py

  • LoadGlobalDict与ImagePropFromGlobalDict
    LoadGlobalDict读取system_image_info.txt到数组,ImagePropFromGlobalDict则根据不同的镜像添加不同的参数。

  • BuildImage

BuildImage->
------------1)SetUpInDirAndFsConfig
------------2)BuildImageMkfs

1) in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)

理解这个方法需要了解Android的分区机制system-as-roothttps://blog.csdn.net/u012932409/article/details/105075851

非常重要!!!!!!!!!!
编译始终将 $TARGET_SYSTEM_OUT 和 $TARGET_ROOT_OUT 合并到 system.img 中;此配置是搭载 Android 10 的所有设备的默认行为。boot.img在第一阶段依然做为根文件系统加载,之后执行/init将system.img加载到/system上。然后执行切换根操作将装载从 /system 移动到 /,装载完成后ramdisk 的内容将会释放。

对于system镜像,in_dir则为build_image.py制作镜像时传入的第一个参数:out/target/product/${project}/system
$(systemimage_intermediates)/system_image_info.txt中定义的root_dir=out/target/product/qssi/root,此方法会创建临时文件夹in_dir(out/soong/.temp/随机生成的文件夹名,也可能是别的目录,具体是什么机制没有太了解)并将根文件系统拷贝过去,并且将system复制到根文件系统下。

165   # Construct a staging directory of the root file system.
166   in_dir = common.MakeTempDir()
167   root_dir = prop_dict.get("root_dir")
168   if root_dir:
169     shutil.rmtree(in_dir)
170     shutil.copytree(root_dir, in_dir, symlinks=True)
171   in_dir_system = os.path.join(in_dir, "system")
172   shutil.rmtree(in_dir_system, ignore_errors=True)
173   shutil.copytree(origin_in, in_dir_system, symlinks=True)

2) BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
作用:Builds a pure image for the files under in_dir and writes it to out_file

mkfs_output = common.RunAndCheckOutput(build_command)
common模块即build/make/tools/releasetools/common.py
执行命令会打印日志:common.py - INFO : Running:

最终会调用到mkuserimg_mke2fs工具(源码位于system/extras/ext4_utils)生成镜像xx.img

mkuserimg_mke2fs.py(制作镜像文件系统)

源码位置:system/extras/ext4_utils,会被打包到out/soong/host/linux-x86/bin/目录下。
mkuserimg_mke2fs又会调用到mke2fs与e2fsdroid,它们属于第三方库,源码位于external/e2fsprogs,打包位于out/soong/Android-xx.mk(xx为产品名)中.

add_img_to_target_files.py (将镜像写入target_files.zip包)

文件位置:build/make/tools/releasetools/add_img_to_target_files.py

  • AddImagesToTargetFiles
    作用:Creates and adds images (boot/recovery/system/...) to a target_files.zip
    依次调用AddXX->CreateImage,CreateImage会调用build_image.py的BuildImage方法。

  • 相关日志

++++ xx ++++

2024-02-05 13:39:09 - add_img_to_target_files - INFO    : creating xx.img...

二、Android系统镜像文件打包的过程

https://blog.csdn.net/luoshengyang/article/details/20501657
https://blog.csdn.net/xiaodongzitt/article/details/49952169
https://blog.csdn.net/yiranfeng/article/details/109084552

以android10源码为例
make执行默认目标

  39 # This is the default target.  It must be the first declared target.
  40 .PHONY: droid
  41 DEFAULT_GOAL := droid
  42 $(DEFAULT_GOAL): droid_targets
  43 
  44 .PHONY: droid_targets
  45 droid_targets:

droid_targets在某些条件下可能会被重写,默认如下:

1811 # Building a full system-- the default is to build droidcore
1812 droid_targets: droidcore dist_files


1)目标droidcore
作用:Build files and then package it into the rom formats

1631 # Build files and then package it into the rom formats
1632 .PHONY: droidcore
1633 droidcore: $(filter $(HOST_OUT_ROOT)/%,$(modules_to_install)) \
1634     $(INSTALLED_SYSTEMIMAGE_TARGET) \
1635     $(INSTALLED_RAMDISK_TARGET) \
1636     $(INSTALLED_BOOTIMAGE_TARGET) \
1637     $(INSTALLED_DEBUG_RAMDISK_TARGET) \
1638     $(INSTALLED_DEBUG_BOOTIMAGE_TARGET) \
1639     $(INSTALLED_RECOVERYIMAGE_TARGET) \
1640     $(INSTALLED_VBMETAIMAGE_TARGET) \
1641     $(INSTALLED_USERDATAIMAGE_TARGET) \
1642     $(INSTALLED_CACHEIMAGE_TARGET) \
1643     $(INSTALLED_BPTIMAGE_TARGET) \
1644     $(INSTALLED_VENDORIMAGE_TARGET) \
1645     $(INSTALLED_ODMIMAGE_TARGET) \
1646     $(INSTALLED_SUPERIMAGE_EMPTY_TARGET) \
1647     $(INSTALLED_PRODUCTIMAGE_TARGET) \
1648     $(INSTALLED_SYSTEMOTHERIMAGE_TARGET) \
1649     $(INSTALLED_FILES_FILE) \
1650     $(INSTALLED_FILES_JSON) \
1651     $(INSTALLED_FILES_FILE_VENDOR) \
1652     $(INSTALLED_FILES_JSON_VENDOR) \
1653     $(INSTALLED_FILES_FILE_ODM) \
1654     $(INSTALLED_FILES_JSON_ODM) \
1655     $(INSTALLED_FILES_FILE_PRODUCT) \
1656     $(INSTALLED_FILES_JSON_PRODUCT) \
1657     $(INSTALLED_FILES_FILE_PRODUCT_SERVICES) \
1658     $(INSTALLED_FILES_JSON_PRODUCT_SERVICES) \
1659     $(INSTALLED_FILES_FILE_SYSTEMOTHER) \
1660     $(INSTALLED_FILES_JSON_SYSTEMOTHER) \
1661     $(INSTALLED_FILES_FILE_RAMDISK) \
1662     $(INSTALLED_FILES_JSON_RAMDISK) \
1663     $(INSTALLED_FILES_FILE_DEBUG_RAMDISK) \
1664     $(INSTALLED_FILES_JSON_DEBUG_RAMDISK) \
1665     $(INSTALLED_FILES_FILE_ROOT) \
1666     $(INSTALLED_FILES_JSON_ROOT) \
1667     $(INSTALLED_FILES_FILE_RECOVERY) \
1668     $(INSTALLED_FILES_JSON_RECOVERY) \
1669     $(INSTALLED_ANDROID_INFO_TXT_TARGET) \
1670     auxiliary \
1671     soong_docs

2)目标dist_files

重要规律:
1.很多目标都是用变量表示的
2.某些日志没有打印,可能的原因是这些日志相关的目标没有变化,就不会重新生成。

一、各个.img镜像的构建过程及说明

1.根文件系统的制作

system/core/rootdir下的Android.mk,主要是将rootdir下的文件复制到out/target/product/产品名/root下,最后制作system镜像时被一起打包到system.img中。
https://blog.csdn.net/ldswfun/article/details/120933632

2.system.img

https://blog.csdn.net/Thanksgining/article/details/83374493
https://blog.csdn.net/Thanksgining/article/details/83417531
https://blog.csdn.net/mingmigndfds/article/details/135084594

具体构建过程

system.img对应INSTALLED_SYSTEMIMAGE_TARGET目标,搜索发现目标INSTALLED_SYSTEMIMAGE_TARGET位于make/core/Makefile

2289 $(INSTALLED_SYSTEMIMAGE_TARGET): $(BUILT_SYSTEMIMAGE) $(RECOVERY_FROM_BOOT_PATCH)
2290         @echo "Install system fs image: $@"
2291         $(copy-file-to-target)
2292         $(hide) $(call assert-max-image-size,$@ $(RECOVERY_FROM_BOOT_PATCH),$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))
2293 
2294 systemimage: $(INSTALLED_SYSTEMIMAGE_TARGET)

目标INSTALLED_SYSTEMIMAGE_TARGET对应同名变量:
定义于make/core/Makefile:2253:INSTALLED_SYSTEMIMAGE_TARGET := $(PRODUCT_OUT)/system.img

也就是说$(PRODUCT_OUT)/system.img依赖于$(BUILT_SYSTEMIMAGE)$(RECOVERY_FROM_BOOT_PATCH)
1)目标 $(BUILT_SYSTEMIMAGE)
BUILT_SYSTEMIMAGE := $(systemimage_intermediates)/system.img

2250 $(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE) $(BUILD_IMAGE_SRCS)
2251         $(call build-systemimage-target,$@)

依赖的目标:

  • 1-1)FULL_SYSTEMIMAGE_DEPS

FULL_SYSTEMIMAGE_DEPS := $(INTERNAL_SYSTEMIMAGE_FILES) $(INTERNAL_USERIMAGES_DEPS)
$(INTERNAL_USERIMAGES_DEPS)目标
主要是一些与system镜像相关的工具的依赖,如simg2img。

$(INTERNAL_SYSTEMIMAGE_FILES)目标

2142 INTERNAL_SYSTEMIMAGE_FILES := $(sort $(filter $(TARGET_OUT)/%, \
2143     $(ALL_GENERATED_SOURCES) \
2144     $(ALL_DEFAULT_INSTALLED_MODULES) \
2145     $(PDK_FUSION_SYSIMG_FILES) \
2146     $(RECOVERY_RESOURCE_ZIP)) \
2147     $(PDK_FUSION_SYMLINK_STAMP))

TARGET_OUT:即为out/target/product/产品名/system

ALL_GENERATED_SOURCES:描述的是要拷贝到目标设备上去的由工具自动生成的源代码文件。

ALL_DEFAULT_INSTALLED_MODULES:描述的是所有需要安装的module

PDK_FUSION_SYSIMG_FILES:是从PDK(Platform Development Kit)提取出来的相关文件

RECOVERY_RESOURCE_ZIP:描述的是Android的recovery系统要使用的资源文件,对应于/system/etc目录下的recovery-resource.dat文件。

PDK_FUSION_SYMLINK_STAMP:PDK的符号链接文件

  • 1-2)INSTALLED_FILES_FILE
    2169 INSTALLED_FILES_FILE := $(PRODUCT_OUT)/installed-files.txt
    2170 INSTALLED_FILES_JSON := $(INSTALLED_FILES_FILE:.txt=.json)
    2171 $(INSTALLED_FILES_FILE): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON)
    2172 $(INSTALLED_FILES_FILE): $(FULL_SYSTEMIMAGE_DEPS) $(FILESLIST)
    2173         @echo Installed file list: $@
    2174         @mkdir -p $(dir $@)
    2175         @rm -f $@
    2176         $(hide) $(FILESLIST) $(TARGET_OUT) > $(@:.txt=.json)
    2177         $(hide) build/make/tools/fileslist_util.py -c $(@:.txt=.json) > $@

$(FILESLIST)目标
build/make/core/config.mk:519:FILESLIST := $(SOONG_HOST_OUT_EXECUTABLES)/fileslist,fileslist为二进制工具。
TARGET_OUT即为out/target/product/产品名/system

$(hide) $(FILESLIST) $(TARGET_OUT) > $(@:.txt=.json)即是将TARGET_OUT下的全部文件的sha值、路径(由system开始)、size写入到installed-files.json文件中。
$(hide) build/make/tools/fileslist_util.py -c $(@:.txt=.json) > $@即是将installed-files.json里的格式转换成installed-files.txt

$(FULL_SYSTEMIMAGE_DEPS)目标,上面有作说明。

  • 1-3)BUILD_IMAGE_SRCS
    build/make/core/config.mk:600:BUILD_IMAGE_SRCS := $(wildcard build/make/tools/releasetools/*.py)

开始打包镜像:
$(systemimage_intermediates)/system.img即是通过build-systemimage-target函数(定义在make/core/Makefile中)生成的,会打印日志:Target system fs image

build-systemimage-target函数定义:

2233 # $(1): output file
2234 define build-systemimage-target
2235   @echo "Target system fs image: $(1)"
2236   $(call create-system-vendor-symlink)
2237   $(call create-system-product-symlink)
2238   $(call create-system-product_services-symlink)
2239   $(call check-apex-libs-absence-on-disk)
2240   @mkdir -p $(dir $(1)) $(systemimage_intermediates) && rm -rf $(systemimage_intermediates)/system_image_info.txt
2241   $(call generate-image-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt,system, \
2242       skip_fsck=true)
2243   $(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH \
2244       build/make/tools/releasetools/build_image.py \
2245       $(TARGET_OUT) $(systemimage_intermediates)/system_image_info.txt $(1) $(TARGET_OUT) \
2246       || ( mkdir -p $${DIST_DIR}; cp $(INSTALLED_FILES_FILE) $${DIST_DIR}/installed-files-rescued.txt; \
2247            exit 1 )
2248 endef

build-systemimage-target函数会调用build_image.py来编译镜像,日志有时没有调用build_image.py是什么情况?(TODO)

参数$(1):out/target/product/${project}/system
参数$(2):$(systemimage_intermediates)/system_image_info.txt   //记录了镜像文件系统格式、ext文件系统制作工具等内容
参数$(3):$(systemimage_intermediates)/system.img
参数$(4):out/target/product/${project}/system

2)目标 $(RECOVERY_FROM_BOOT_PATCH)
在设备上,可以通过boot.img和recovery_from_boot.p文件生成一个recovery.img文件,使得设备可以进入recovery模式。

3)动作 copy-file-to-target
会创建/out/target/product/xxx/目录,其中xxx是产品名,然后把(BUILT_SYSTEMIMAGE)变量所代表的文件直接拷贝过来。经比较,两者md5确实一致。

构建日志

以上构建过程会对应两条非常重要的日志:

[ 99% 30426/30429] Target system fs image: out/target/product/qssi/obj/PACKAGING/systemimage_intermediates/system.img
[ 99% 30427/30429] Install system fs image: out/target/product/qssi/system.img

3.ramdisk.img(最小根文件系统)

https://blog.csdn.net/yangjizhen1533/article/details/113573468

 892 BUILT_RAMDISK_TARGET := $(PRODUCT_OUT)/ramdisk.img
 893 
 894 # We just build this directly to the install location.
 895 INSTALLED_RAMDISK_TARGET := $(BUILT_RAMDISK_TARGET)
 896 $(INSTALLED_RAMDISK_TARGET): $(MKBOOTFS) $(INTERNAL_RAMDISK_FILES) $(INSTALLED_FILES_FILE_RAMDISK) | $(MINIGZIP)
 897         $(call pretty,"Target ram disk: $@")
 898         $(hide) $(MKBOOTFS) -d $(TARGET_OUT) $(TARGET_RAMDISK_OUT) | $(MINIGZIP) > $@

1)目标 $(MKBOOTFS)
build/make/core/config.mk:554:MKBOOTFS := $(HOST_OUT_EXECUTABLES)/mkbootfs$(HOST_EXECUTABLE_SUFFIX)
build/make/core/envsetup.mk:325:HOST_OUT_EXECUTABLES := $(HOST_OUT)/bin
$(MKBOOTFS)即out/host/linux-x86/bin/mkbootfs,源码位于system/core/cpio/mkbootfs.c

2)目标 $(INTERNAL_RAMDISK_FILES)

 876 INTERNAL_RAMDISK_FILES := $(filter $(TARGET_RAMDISK_OUT)/%, \
 877         $(ALL_GENERATED_SOURCES) \
 878         $(ALL_DEFAULT_INSTALLED_MODULES))

build/make/core/envsetup.mk:843:TARGET_RAMDISK_OUT := $(PRODUCT_OUT)/$(TARGET_COPY_OUT_RAMDISK),即out/target/product/qssi/ramdisk目录。
其它的两个依赖暂时就不去研究了
3)目标 $(INSTALLED_FILES_FILE_RAMDISK)
INSTALLED_FILES_FILE_RAMDISK := $(PRODUCT_OUT)/installed-files-ramdisk.txt

 882 $(INSTALLED_FILES_FILE_RAMDISK): .KATI_IMPLICIT_OUTPUTS := $(INSTALLED_FILES_JSON_RAMDISK)
 883 $(INSTALLED_FILES_FILE_RAMDISK) : $(INTERNAL_RAMDISK_FILES) $(FILESLIST)
 884         @echo Installed file list: $@
 885         @mkdir -p $(TARGET_RAMDISK_OUT)
 886         @mkdir -p $(dir $@)
 887         @rm -f $@
 888         $(hide) $(FILESLIST) $(TARGET_RAMDISK_OUT) > $(@:.txt=.json)
 889         $(hide) build/make/tools/fileslist_util.py -c $(@:.txt=.json) > $@

这个可以借鉴syste.img的生成,类似。
3)目标 $(MINIGZIP)
build/make/core/config.mk:555:MINIGZIP := $(HOST_OUT_EXECUTABLES)/minigzip$(HOST_EXECUTABLE_SUFFIX)
out/host/linux-x86/bin/minigzip,源码位于/external/zlib
minigzip介绍:
https://www.cnblogs.com/pengdonglin137/p/10468556.html

4.boot.img

https://blog.csdn.net/weixin_42135087/article/details/103384825

912 BUILT_BOOTIMAGE_TARGET := $(PRODUCT_OUT)/boot.img
955 INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)
INSTALLED_BOOTIMAGE_TARGET := $(BUILT_BOOTIMAGE_TARGET)

 $(INSTALLED_BOOTIMAGE_TARGET): $(MKBOOTIMG) $(AVBTOOL) $(INTERNAL_BOOTIMAGE_FILES) $(BOARD_AVB_BOOT_KEY_PATH)
 963         $(call pretty,"Target boot image: $@")
 964         $(hide) $(MKBOOTIMG) $(INTERNAL_BOOTIMAGE_ARGS) $(INTERNAL_MKBOOTIMG_VERSION_ARGS) $(BOARD_MKBOOTIMG_ARGS) --output $@
 965         $(hide) $(call assert-max-image-size,$@,$(call get-hash-image-max-size,$(BOARD_BOOTIMAGE_PARTITION_SIZE)))
 966         $(hide) $(AVBTOOL) add_hash_footer \
 967           --image $@ \
 968           --partition_size $(BOARD_BOOTIMAGE_PARTITION_SIZE) \
 969           --partition_name boot $(INTERNAL_AVB_BOOT_SIGNING_ARGS) \
 970           $(BOARD_AVB_BOOT_ADD_HASH_FOOTER_ARGS)

1)目标$(MKBOOTIMG)
build/make/core/config.mk:558:MKBOOTIMG := $(HOST_OUT_EXECUTABLES)/mkbootimg$(HOST_EXECUTABLE_SUFFIX)
out/host/linux-x86/bin/mkbootimg,boot镜像的制作工具。
2)目标$(AVBTOOL)
build/make/core/config.mk:568:AVBTOOL := $(HOST_OUT_EXECUTABLES)/avbtool$(HOST_EXECUTABLE_SUFFIX)
out/host/linux-x86/bin/avbtool

avbtool介绍:https://blog.csdn.net/u010164190/article/details/136532158?spm=1001.2014.3001.5501
AVB校验:https://blog.csdn.net/weixin_45264425/article/details/128039053
3)目标$(INTERNAL_BOOTIMAGE_FILES)
927 INTERNAL_BOOTIMAGE_FILES := $(filter-out --%,$(INTERNAL_BOOTIMAGE_ARGS))
上面这个函数非常巧妙,从参数中去除--%,剩下的就是相关的文件了。后面会继续给INTERNAL_BOOTIMAGE_ARGS变量追加参数
3-1)目标INTERNAL_BOOTIMAGE_ARGS
是制作boot.img所需的参数

 914 ifneq ($(strip $(TARGET_NO_KERNEL)),true)
 915 INTERNAL_BOOTIMAGE_ARGS := \
 916         $(addprefix --second ,$(INSTALLED_2NDBOOTLOADER_TARGET)) \
 917         --kernel $(INSTALLED_KERNEL_TARGET)
 918 
 919 ifdef BOARD_INCLUDE_DTB_IN_BOOTIMG
 920   INTERNAL_BOOTIMAGE_ARGS += --dtb $(INSTALLED_DTBIMAGE_TARGET)
 921 endif
 922 
 923 ifneq ($(BOARD_BUILD_SYSTEM_ROOT_IMAGE),true)
 924 INTERNAL_BOOTIMAGE_ARGS += --ramdisk $(INSTALLED_RAMDISK_TARGET)
 925 endif

4)目标$(BOARD_AVB_BOOT_KEY_PATH)
TODO

5)执行打包命令
boot.img制作日志(add image to target的日志,不是首编生成boot.img的日志。):

++++ boot ++++

2024-02-05 11:10:41 - common.py - INFO    : building image from target_files BOOT...
2024-02-05 11:10:41 - common.py - INFO    :   Running: "mkbootfs -f /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/PACKAGING/target_files_intermediates/qssi-target_files-eng.root/META/boot_filesystem_config.txt /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/PACKAGING/target_files_intermediates/qssi-target_files-eng.root/BOOT/RAMDISK"
2024-02-05 11:10:41 - common.py - INFO    :   Running: "minigzip"
2024-02-05 11:10:41 - common.py - INFO    :   Running: "out/host/linux-x86/bin/mkbootimg --kernel /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/PACKAGING/target_files_intermediates/qssi-target_files-eng.root/BOOT/kernel --dtb /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/PACKAGING/target_files_intermediates/qssi-target_files-eng.root/BOOT/dtb --cmdline console=ttyMSM0,115200n8 earlycon=msm_geni_serial,0xa90000 androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 service_locator.enable=1 swiotlb=2048 loop.max_part=7 androidboot.usbcontroller=a600000.dwc3 buildvariant=userdebug --base 0x00000000 --pagesize 4096 --header_version 2 --os_version 10 --os_patch_level 2020-08-05 --ramdisk /home/xinyi/code/sg865/sg865w_android10/out/soong/.temp/tmpRfujAB --output /home/xinyi/code/sg865/sg865w_android10/out/soong/.temp/tmpz1mcIo"
2024-02-05 11:10:42 - common.py - INFO    : 
2024-02-05 11:10:42 - common.py - INFO    :   Running: "avbtool add_hash_footer --image /home/xinyi/code/sg865/sg865w_android10/out/soong/.temp/tmpz1mcIo --partition_size 100663296 --partition_name boot --prop com.android.build.boot.os_version:10 --prop com.android.build.boot.security_patch:2020-08-05 --prop com.android.build.boot.security_patch:2020-08-05"
2024-02-05 11:10:42 - common.py - INFO    : 
2024-02-05 11:10:43 - add_img_to_target_files - INFO    : 

4-1)kernel的生成过程

以qssi产品为例

内核构建脚本

device/qcom/kernelscripts/buildkernel.sh

脚本相关变量:

根据device/qcom/kernelscripts/kernel_definitions.mkbuild out/target/product/qssi/obj/kernel/msm-4.19/usr会走上面的if流程,没有调用build_kernel方法(通过搜索关键符号======================可以区分)。

1.make_defconfig方法(根据内核配置文件生成.config文件)
 53 make_defconfig()
 54 {
 55         if [ -z "${SKIP_DEFCONFIG}" ] ; then
 56                 echo "======================"
 57                 echo "Building defconfig"
 58                 set -x
 59                 (cd ${KERNEL_DIR} && \
 60                 make O=${OUT_DIR} ${MAKE_ARGS} HOSTCFLAGS="${TARGET_INCLUDES}" HOSTLDFLAGS="${TARGET_LINCLUDES}" ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} ${DEFCONFIG})
 61                 set +x
 62         fi
 63 }

cd kernel/msm-4.19
#make命令参数格式化
make 
##指定make的输出目录
O=/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19 
REAL_CC=/home/xinyi/code/sg865/sg865w_android10/vendor/qcom/proprietary/llvm-arm-toolchain-ship/8.0/bin/clang 
CLANG_TRIPLE=aarch64-linux-gnu- 
DTC_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/dtc 
DTC_OVERLAY_TEST_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/ufdt_apply_overlay 
CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-gcc
 HOSTAR=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar 
 HOSTLD=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld 'HOSTCFLAGS=-I/home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19/include/uapi -I/usr/include -I/usr/include/x86_64-linux-gnu -L/usr/lib -L/usr/lib/x86_64-linux-gnu' 'HOSTLDFLAGS=-L/usr/lib -L/usr/lib/x86_64-linux-gnu' 
 ARCH=arm64 
 CROSS_COMPILE=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-androidkernel- 
##make的目标
 vendor/kona_defconfig

分析一下各个变量是在哪里定义的(大多数都是在device/qcom/kernelscripts/kernel_definitions.mk中定义的):

  • DEFCONFIG
    在kernel_definitions.mk中定义,为KERNEL_DEFCONFIG。KERNEL_DEFCONFIG在device/qcom/qssi/BoardConfig.mk中定义赋值

    device/qcom/qssi/BoardConfig.mk:93:KERNEL_DEFCONFIG := kona_defconfig
    device/qcom/qssi/BoardConfig.mk:95:KERNEL_DEFCONFIG := vendor/$(KERNEL_DEFCONFIG)
2.headers_install(复制内核源码下的头文件到内核编译输出目录下的/usr/include目录)
 66 headers_install()
 67 {
 68         echo "======================"
 69         echo "Installing kernel headers"
 70         set -x
 71         (cd ${OUT_DIR} && \
 72         make HOSTCFLAGS="${TARGET_INCLUDES}" HOSTLDFLAGS="${TARGET_LINCLUDES}" ARCH=${ARCH} C    ROSS_COMPILE=${CROSS_COMPILE} O=${OUT_DIR} ${CC_ARG} ${MAKE_ARGS} headers_install)
 73         set +x
 74 }

cd /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19
#make命令格式化
make 
'HOSTCFLAGS=-I/home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19/include/uapi -I/usr/include -I/usr/include/x86_64-linux-gnu -L/usr/lib -L/usr/lib/x86_64-linux-gnu' 
'HOSTLDFLAGS=-L/usr/lib -L/usr/lib/x86_64-linux-gnu' 
ARCH=arm64 
CROSS_COMPILE=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-androidkernel- 
O=/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19 
REAL_CC=/home/xinyi/code/sg865/sg865w_android10/vendor/qcom/proprietary/llvm-arm-toolchain-ship/8.0/bin/clang 
CLANG_TRIPLE=aarch64-linux-gnu- DTC_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/dtc 
DTC_OVERLAY_TEST_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/ufdt_apply_overlay 
CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-gcc 
HOSTAR=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar 
HOSTLD=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld 
headers_install
3.build_kernel(构建内核)
 77 build_kernel()
 78 {
 79         echo "======================"
 80         echo "Building kernel"
 81         set -x
 82         (cd ${OUT_DIR} && \
 83         make ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} HOSTCFLAGS="${TARGET_INCLUDES}" HOSTLDFLAGS="${TARGET_LINCLUDES}" O=${OUT_DIR} ${CC_    ARG} ${MAKE_ARGS} -j$(nproc))
 84         set +x
 85 }

#上面的make没有带任何目标 
4.modules_install(模块安装)
 88 modules_install()
 89 {
 90         echo "======================"
 91         echo "Installing kernel modules"
 92         rm -rf ${MODULES_STAGING_DIR}
 93         mkdir -p ${MODULES_STAGING_DIR}
 94         set -x
 95         (cd ${OUT_DIR} && \
 96         make O=${OUT_DIR} ${CC_ARG} INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=${MODULES_STAGING_DIR} ${MAKE_AR    GS} modules_install)
 97         set +x
 98 }

cd /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19 
#make命令格式化 
make
O=/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19 
INSTALL_MOD_STRIP=1 
INSTALL_MOD_PATH=/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19/staging 
REAL_CC=/home/xinyi/code/sg865/sg865w_android10/vendor/qcom/proprietary/llvm-arm-toolchain-ship/8.0/bin/clang 
CLANG_TRIPLE=aarch64-linux-gnu- DTC_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/dtc
DTC_OVERLAY_TEST_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/ufdt_apply_overlay 
CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-gcc 
HOSTAR=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar 
HOSTLD=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld
modules_install

MODULES_STAGING_DIR为模块安装目录out/target/product/qssi/obj/kernel/msm-4.19/staging

5.copy_all_to_prebuilt()

copy_all_to_prebuilt ${KERNEL_BINS}带的参数${KERNEL_BINS}为目录/home/xinyi/code/sg865/sg865w_android10/kernel/ship_prebuilt/primary_kernel,会赋值给PREBUILT_OUT变量。

1)拷贝模块到PREBUILT_OUT目录
会调用copy_modules_to_prebuilt方法,该方法会遍历所有安装的模块.ko文件,然后拷贝到${PREBUILT_OUT}/${KERNEL_MODULES_OUT}目录。
device/qcom/qssi/qssi.mk:228:KERNEL_MODULES_OUT := out/target/product/$(PRODUCT_NAME)/$(KERNEL_MODULES_INSTALL)/lib/modules
device/qcom/qssi/qssi.mk:227:KERNEL_MODULES_INSTALL := dlkm

${KERNEL_MODULES_OUT}即为 out/target/product/qssi/dlkm/lib/modules
2)拷贝内核镜像等文件到PREBUILT_OUT目录

内核构建日志

根据日志,可知内核会构建两个目标。

build out/target/product/qssi/obj/kernel/msm-4.19/usr
+++ dirname device/qcom/kernelscripts/buildkernel.sh

build out/target/product/qssi/obj/kernel/msm-4.19/arch/arm64/boot/Image
+++ dirname device/qcom/kernelscripts/buildkernel.sh

grep -nr "buildkernel.sh" build kernel system device,可以搜索到buildkernel.sh的调用位置:
device/qcom/kernelscripts/kernel_definitions.mk:158: device/qcom/kernelscripts/buildkernel.sh \
device/qcom/kernelscripts/kernel_definitions.mk:180: device/qcom/kernelscripts/buildkernel.sh \

device/qcom/kernelscripts/kernel_definitions.mk正好定义了上面两个目标,注意在执行buildkernel.sh之前定义了很多变量:

TODO:上面的两个目标,在构建boot.img的时候又是如何关联起来的?

5.super_empty.img

droidcore:INSTALLED_SUPERIMAGE_EMPTY_TARGET

4602 INSTALLED_SUPERIMAGE_EMPTY_TARGET := $(PRODUCT_OUT)/super_empty.img
4603 $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): intermediates := $(call intermediates-dir-for,PACKAGING,super_empty)
4604 $(INSTALLED_SUPERIMAGE_EMPTY_TARGET): $(LPMAKE) $(BUILD_SUPER_IMAGE)
4605         $(call pretty,"Target empty super fs image: $@")
4606         mkdir -p $(intermediates)
4607         rm -rf $(intermediates)/misc_info.txt
4608         $(call dump-super-image-info,$(intermediates)/misc_info.txt)
4609         PATH=$(dir $(LPMAKE)):$$PATH \
4610             $(BUILD_SUPER_IMAGE) -v $(intermediates)/misc_info.txt $@

1)目标$(LPMAKE)
build/make/core/config.mk:592:LPMAKE := $(HOST_OUT_EXECUTABLES)/lpmake$(HOST_EXECUTABLE_SUFFIX)
out/host/linux-x86/bin/lpmake,源码位于system/extras/partition_tools/lpmake.cc
2)目标$(BUILD_SUPER_IMAGE)
build/make/core/config.mk:593:BUILD_SUPER_IMAGE := build/make/tools/releasetools/build_super_image.py
3)命令
$(BUILD_SUPER_IMAGE) -v $(intermediates)/misc_info.txt $@

177 def BuildSuperImage(inp, out):
178 
179   if isinstance(inp, dict):
180     logger.info("Building super image from info dict...")
181     return BuildSuperImageFromDict(inp, out)
182 
183   if isinstance(inp, str):
184     if os.path.isdir(inp):
185       logger.info("Building super image from extracted target files...")
186       return BuildSuperImageFromExtractedTargetFiles(inp, out)
187 
188     if zipfile.is_zipfile(inp):
189       logger.info("Building super image from target files...")
190       return BuildSuperImageFromTargetFiles(inp, out)
191 
192     if os.path.isfile(inp):
193       with open(inp) as f:
194         lines = f.read()
195       logger.info("Building super image from info dict...")
196       return BuildSuperImageFromDict(common.LoadDictionaryFromLines(lines.split("\n")), out)
197 
198   raise ValueError("{} is not a dictionary or a valid path".format(inp))

可知super_empty.img构建时,会走到Building super image from info dict...,读取misc_info.txt到字典,然后再调用BuildSuperImageFromDict方法。

super_empty.img无法解包?TODO

6.super.img (比较特殊,是在target包制作完成之后才会生成。)

https://blog.csdn.net/guyongqiangx/article/details/124052932 (*)
https://huaweicloud.csdn.net/64f986f2993dd34278ee1df2.html
https://blog.51cto.com/u_16099314/7779971
虽然说super.img相关的目标在build/make/core/Makefile里存在,但是在droidcore里却没有它的依赖。找了半天,才知道它位于高通自己写的脚本 vendor/qcom/opensource/core-utils/build/build.sh中的generate_dynamic_partition_images方法。

二、各个.img镜像构建完成之后干了什么

制作升级包

观察日志:
[ 99% 1075/1080] Package target files: out/target/product/qssi/obj/PACKAGING/target_files_intermediates/qssi-target_files-eng.root.zip
https://cloud.tencent.com/developer/article/1578427?from=15425
https://blog.csdn.net/liyuchong2537631/article/details/97517850
https://blog.csdn.net/thinkinwm/article/details/8985530

执行$(BUILT_TARGET_FILES_PACKAGE)目标(位于build/make/core/Makefile)则开始制作target包

注意zip_root,即out/target/product/xx/obj/PACKAGING/target_files_intermediates/xx-target_files-eng.root目录

3732 # -----------------------------------------------------------------
3733 # A zip of the directories that map to the target filesystem.
3734 # This zip can be used to create an OTA package or filesystem image
3735 # as a post-build step.
3736 #
3737 name := $(TARGET_PRODUCT)
3738 ifeq ($(TARGET_BUILD_TYPE),debug)
3739   name := $(name)_debug
3740 endif
3741 name := $(name)-target_files-$(FILE_NAME_TAG)
3742 
3743 intermediates := $(call intermediates-dir-for,PACKAGING,target_files)
3744 BUILT_TARGET_FILES_PACKAGE := $(intermediates)/$(name).zip
3745 $(BUILT_TARGET_FILES_PACKAGE): intermediates := $(intermediates)
3746 $(BUILT_TARGET_FILES_PACKAGE): \
3747             zip_root := $(intermediates)/$(name)

将各种文件拷贝到zip_root目录下,并向一些文件写入数据。
将zip_root包含的文件路径写入到xx-target_files-eng.root.zip.list文件中
调用add_img_to_target_files工具,将各个image写到target包IMAGES目录下
$(hide) PATH=$(foreach p,$(INTERNAL_USERIMAGES_BINARY_PATHS),$(p):)$$PATH MKBOOTIMG=$(MKBOOTIMG) \ 4257 build/make/tools/releasetools/add_img_to_target_files -a -r -v -p $(HOST_OUT) $(zip_root)
最后调用out/soong/host/linux-x86/bin/soong_zip压缩工具(源码位于build/soong/zip/cmd/main.go)将zip_root目录打包名为xx-target_files-eng.root.zip.

三、qssi与kona的target包对比

共有目录:BOOT、IMAGES、META、OTA、ROOT
qssi独有:PRODUCT、SYSTEM
kona独有:DATA、ODM、PREBUILT_IMAGES(dtbo.img)、RADIO、RECOVERY、VENDOR

qssi与kona的mk文件

1.device/qcom/qssi/qssi.mk

1)注释说明了只打system镜像
2)不支持动态分区

2.device/qcom/kona/kona.mk

1)支持动态分区

qssi与kona的target包如何merged

各自特有的目录独自拷贝,共有的目录。

BOOT

直接使用kona的BOOT目录,通过diff -r kona/BOOT merge/BOOT无输出即可验证。

IMAGES

qssi与kona的IMAGES目录对比

  • 只在qssi/IMAGES中存在
    product.img、product.map、system.img、system.map
  • 只在kona/IMAGES中存在
    dtbo.img、odm.img、odm.map、recovery.img、recovery-two-step.img、userdata.img、vendor.img、vendor.map
  • qssi/IMAGE与kona/IMAGES中都存在但是md5不一
    super_empty.img、vbmeta.img、vbmeta_system.img、boot.img
    merge/IMAGES目录使用了谁的镜像
    发现merge/IAMGES下的镜像文件和qssi与kona的都不一样!!

META

部分取自qssi,部分取自kona.

OTA

直接使用kona.

四、高通build.sh脚本分析

1.lunch重要日志分析

1-1)lunch qssi-userdebug

glob xx.prof
out/soong/.bootstrap/bin/soong_build out/soong/build.ninja

initializing build system ...
#include各个模块的Android.mk文件
including xx/Android.mk
[ 55% 778/1399] including build/make/target/board/Android.mk ...
Using DTB Image
Using uncompressed kernel
device/qcom/common/generate_extra_images.mk:567: warning: ==== device/qcom/qssi/qssi.mk ====
[ 99% 1398/1399] finishing build rules ...
#注意这里是不同的文件(TODO:没有搜索到vendor/qcom/build/tasks/generate_extra_images.mk引用的位置?)
vendor/qcom/build/tasks/generate_extra_images.mk:567: warning: ==== device/qcom/qssi/qssi.mk ====
[100% 1399/1399] writing build rules ...

Starting ninja...

#内核构建
#目标1
[ 74% 1406/1894] build out/target/product/qssi/obj/kernel/msm-4.19/usr
+++ dirname device/qcom/kernelscripts/buildkernel.sh (**执行此脚本,开始构建内核。**)
#1.构建vendor/kona_defconfig目标
Building defconfig
+ set -x
+ cd kernel/msm-4.19
+ make O=/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19 REAL_CC=/home/xinyi/code/sg865/sg865w_android10/vendor/qcom/proprietary/llvm-arm-toolchain-ship/8.0/bin/clang CLANG_TRIPLE=aarch64-linux-gnu- DTC_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/dtc DTC_OVERLAY_TEST_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/ufdt_apply_overlay CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-gcc HOSTAR=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar HOSTLD=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld 'HOSTCFLAGS=-I/home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19/include/uapi -I/usr/include -I/usr/include/x86_64-linux-gnu -L/usr/lib -L/usr/lib/x86_64-linux-gnu' 'HOSTLDFLAGS=-L/usr/lib -L/usr/lib/x86_64-linux-gnu' ARCH=arm64 CROSS_COMPILE=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-androidkernel- vendor/kona_defconfig
make[1]: 进入目录“/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19”
  GEN     ./Makefile
arch/arm64/configs/vendor/kona_defconfig:351:warning: override: reassigning to symbol PPP_DEFLATE
#
# configuration written to .config
#
make[1]: 离开目录“/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19”
#2.构建headers_install目标
Installing kernel headers
+ cd /home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19
+ make 'HOSTCFLAGS=-I/home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19/include/uapi -I/usr/include -I/usr/include/x86_64-linux-gnu -L/usr/lib -L/usr/lib/x86_64-linux-gnu' 'HOSTLDFLAGS=-L/usr/lib -L/usr/lib/x86_64-linux-gnu' ARCH=arm64 CROSS_COMPILE=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-androidkernel- O=/home/xinyi/code/sg865/sg865w_android10/out/target/product/qssi/obj/kernel/msm-4.19 REAL_CC=/home/xinyi/code/sg865/sg865w_android10/vendor/qcom/proprietary/llvm-arm-toolchain-ship/8.0/bin/clang CLANG_TRIPLE=aarch64-linux-gnu- DTC_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/dtc DTC_OVERLAY_TEST_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/ufdt_apply_overlay CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-gcc HOSTAR=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar HOSTLD=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld headers_install
make[6]: 对“__headers”无需做任何事。
+ set +x
[ 74% 1407/1894] build out/target/product/qssi/obj/KERNEL_OBJ/usr
...构建了一些其它的东西

#目标2
[ 98% 1818/1842] build out/target/product/qssi/obj/kernel/msm-4.19/arch/arm64/boot/Image
+++ dirname device/qcom/kernelscripts/buildkernel.sh
...之前的和目标1一样(Building defconfig、Installing kernel headers),额外执行了一些操作
Building kernel
Installing kernel modules
Copying modules files

+ cd /home/xinyi/code/sg865/sg865w_android10/out/target/product/kona/obj/kernel/msm-4.19
#make默认目标
+ make ARCH=arm64 CROSS_COMPILE=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- 'HOSTCFLAGS=-I/home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19/include/uapi -I/usr/include -I/usr/include/x86_64-linux-gnu -L/usr/lib -L/usr/lib/x86_64-linux-gnu' 'HOSTLDFLAGS=-L/usr/lib -L/usr/lib/x86_64-linux-gnu' O=/home/xinyi/code/sg865/sg865w_android10/out/target/product/kona/obj/kernel/msm-4.19 REAL_CC=/home/xinyi/code/sg865/sg865w_android10/vendor/qcom/proprietary/llvm-arm-toolchain-ship/8.0/bin/clang CLANG_TRIPLE=aarch64-linux-gnu- DTC_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/dtc DTC_OVERLAY_TEST_EXT=/home/xinyi/code/sg865/sg865w_android10/out/host/linux-x86/bin/ufdt_apply_overlay CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-gcc HOSTAR=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar HOSTLD=/home/xinyi/code/sg865/sg865w_android10/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld -j8
  GEN     ./Makefile
scripts/kconfig/conf  --syncconfig Kconfig
  GEN     ./Makefile
  Using /home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19 as source for kernel
  CALL    /home/xinyi/code/sg865/sg865w_android10/kernel/msm-4.19/scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  GZIP    kernel/config_data.gz
  DTC     arch/arm64/boot/dts/vendor/qcom/kona.dtb
  DTC     arch/arm64/boot/dts/vendor/qcom/kona-v2.dtb

2.generate_ota_zip(制作OTA升级包)

313 function generate_ota_zip () {
314     log "Processing dist/ota commands:"
315 
316     SYSTEM_TARGET_FILES="$(find $DIST_DIR -name "qssi*-target_files-*.zip" -print)"
317     log "SYSTEM_TARGET_FILES=$SYSTEM_TARGET_FILES"
318     check_if_file_exists "$SYSTEM_TARGET_FILES"
319 
320     OTHER_TARGET_FILES="$(find $DIST_DIR -name "${TARGET_PRODUCT}*-target_files-*.zip" -print)"
321     log "OTHER_TARGET_FILES=$OTHER_TARGET_FILES"
322     check_if_file_exists "$OTHER_TARGET_FILES"
323 
324     log "MERGED_TARGET_FILES=$MERGED_TARGET_FILES"
325 
326     check_if_file_exists "$DIST_DIR/merge_config_system_misc_info_keys"
327     check_if_file_exists "$DIST_DIR/merge_config_system_item_list"
328     check_if_file_exists "$DIST_DIR/merge_config_other_item_list"
329 
330     MERGE_TARGET_FILES_COMMAND="./build/tools/releasetools/merge_target_files.py \
331         --system-target-files $SYSTEM_TARGET_FILES \
332         --other-target-files $OTHER_TARGET_FILES \
333         --output-target-files $MERGED_TARGET_FILES \
334         --system-misc-info-keys $DIST_DIR/merge_config_system_misc_info_keys \
335         --system-item-list $DIST_DIR/merge_config_system_item_list \
336         --other-item-list $DIST_DIR/merge_config_other_item_list \
337         --output-ota  $MERGED_OTA_ZIP"
338 
339     if [ "$ENABLE_AB" = false ]; then
340         MERGE_TARGET_FILES_COMMAND="$MERGE_TARGET_FILES_COMMAND --rebuild_recovery"
341     fi
342 
343     command "$MERGE_TARGET_FILES_COMMAND"
344 }

1.merge日志

[build.sh]: Processing dist/ota commands:
============================================
============================================
[build.sh]: SYSTEM_TARGET_FILES=out/dist/qssi-target_files-eng.root.zip
============================================
============================================
[build.sh]: OTHER_TARGET_FILES=out/dist/kona-target_files-eng.root.zip
============================================
============================================
[build.sh]: MERGED_TARGET_FILES=out/dist/merged-qssi_kona-target_files.zip
============================================
============================================
[build.sh]: Command: "./build/tools/releasetools/merge_target_files.py         --system-target-files out/dist/qssi-target_files-eng.root.zip         --other-target-files out/dist/kona-target_files-eng.root.zip         --output-target-files out/dist/merged-qssi_kona-target_files.zip         --system-misc-info-keys out/dist/merge_config_system_misc_info_keys         --system-item-list out/dist/merge_config_system_item_list         --other-item-list out/dist/merge_config_other_item_list         --output-ota  out/dist/merged-qssi_kona-ota.zip"
============================================
2024-02-05 19:53:44 - merge_target_files.py - INFO    : starting: merge system out/dist/qssi-target_files-eng.root.zip and other out/dist/kona-target_files-eng.root.zip into output out/dist/merged-qssi_kona-target_files.zip
2024-02-05 19:53:44 - merge_target_files.py - INFO    : extracting from out/dist/qssi-target_files-eng.root.zip
2024-02-05 19:53:45 - common.py - INFO    :   Running: "unzip -o -q out/dist/qssi-target_files-eng.root.zip -d /tmp/merge_target_files_ubTwC5/output META/apexkeys.txt META/apkcerts.txt META/filesystem_config.txt META/root_filesystem_config.txt META/system_manifest.xml META/system_matrix.xml META/update_engine_config.txt PRODUCT/* ROOT/* SYSTEM/*"
2024-02-05 19:54:03 - common.py - INFO    : 
2024-02-05 19:54:03 - merge_target_files.py - INFO    : extracting from out/dist/kona-target_files-eng.root.zip
2024-02-05 19:54:03 - common.py - INFO    :   Running: "unzip -o -q out/dist/kona-target_files-eng.root.zip -d /tmp/merge_target_files_ubTwC5/output META/boot_filesystem_config.txt META/file_contexts.bin META/otakeys.txt META/releasetools.py META/vendor_filesystem_config.txt META/vendor_manifest.xml META/vendor_matrix.xml BOOT/* DATA/* ODM/* OTA/android-info.txt PREBUILT_IMAGES/* RADIO/* RECOVERY/* VENDOR/*"
2024-02-05 19:54:59 - common.py - INFO    : 
2024-02-05 19:54:59 - merge_target_files.py - INFO    : extracting from out/dist/qssi-target_files-eng.root.zip
2024-02-05 19:54:59 - common.py - INFO    :   Running: "unzip -o -q out/dist/qssi-target_files-eng.root.zip -d /tmp/merge_target_files_ubTwC5/system META/*"
2024-02-05 19:54:59 - common.py - INFO    : 
2024-02-05 19:54:59 - merge_target_files.py - INFO    : extracting from out/dist/kona-target_files-eng.root.zip
2024-02-05 19:54:59 - common.py - INFO    :   Running: "unzip -o -q out/dist/kona-target_files-eng.root.zip -d /tmp/merge_target_files_ubTwC5/other META/*"

1-1) merge_target_files.py的参数说明
--system-target-files:qssi产品的target包。
--other-target-files:kona产品的target包。
--output-target-files:qssi与kona产品merge后的target包。
--system-item-list:qssi的target包需要merge的文件。
--other-item-list:kona的target包需要merge的文件。
...见源码说明,非常详细!!!!

1-2) merge主要流程
调用call_func_with_temp_dir方法创建临时目录/tmp/merge_target_files_xx,然后调用merge_target_files方法开始merge.
merge_target_files
1-2-1)extract_items:将qssi与kona的target包的主要文件合并到merge临时目录
1-2-2)add_img_to_target_files.main(add_img_args):add_img_args参数就包括merge临时目录。
@@》add_img_to_target_files

def AddImagesToTargetFiles(filename):
696   """Creates and adds images (boot/recovery/system/...) to a target_files.zip.
697 
698   It works with either a zip file (zip mode), or a directory that contains the
699   files to be packed into a target_files.zip (dir mode). The latter is used when
700   being called from build/make/core/Makefile.
701 
702   The images will be created under IMAGES/ in the input target_files.zip.
703 
704   Args:
705     filename: the target_files.zip, or the zip root directory.
706   """

@@@@》GetBootableImage
在临时merge目录中/IAMGES目录下查找相关的镜像文件,如果不存在就调用_BuildBootableImage方法生成镜像,会输出日志:
building image from target_files
只有++++ boot ++++、++++ recovery ++++、++++ recovery (two-step image) ++++重新生成了,why??? //TODO

3.generate_dynamic_partition_images(制作super.img动态分区)

285 function generate_dynamic_partition_images () {
286     log "Generate Dynamic Partition Images for ${TARGET_PRODUCT}"
287     # Handling for Dist Enabled targets
288     # super.img/super_empty generation
289     if [ "$DIST_ENABLED" = true ]; then
290        if [ "$DP_IMAGES_OVERRIDE" = true ]; then
291            command "mkdir -p $DYNAMIC_PARTITIONS_IMAGES_PATH"
292        fi
293        command "cp $QSSI_OUT/vbmeta_system.img $OUT/"
294        command "unzip -jo $MERGED_TARGET_FILES IMAGES/*.img -x IMAGES/userdata.img -d $DYNAMIC_PARTITI    ONS_IMAGES_PATH"
295        command "./build/tools/releasetools/build_super_image.py $MERGED_TARGET_FILES $DYNAMIC_PARTITIO    NS_IMAGES_PATH/super.img"
296     else
            ...
310     fi
311 }

五、高通pkg_tools/common/build/build.py 脚本分析

主要是生成烧录相关的一些文件


0 条评论

发表回复

您的电子邮箱地址不会被公开。