关于 kernel 的构建
include kernel
增量编译,这个 device/qcom/kernelscripts/buildkernel.sh 好像每次都会执行,如果去掉这个编译会节省不少时间。大概节省30分钟。
在 device/zzzz/sa8295_xxxx/AndroidBoard.mk 中 include 这个 msmnile_gvmq 下面的 AndroidBoard.mk
在 device/qcom/msmnile_gvmq/AndroidBoard.mk 中 include 这个 kernel_definitions.mk 文件
调用 build-kernel
在 device/qcom/kernelscripts/kernel_definitions.mk 中有调用 build-kernel
1 2 3
| $(TARGET_PREBUILT_KERNEL): $(KERNEL_OUT) $(DTC) $(KERNEL_USR) echo "Building the requested kernel.."; \ $(call build-kernel,$(KERNEL_DEFCONFIG),$(KERNEL_OUT),$(KERNEL_MODULES_OUT),$(KERNEL_HEADERS_INSTALL),0,$(TARGET_PREBUILT_INT_KERNEL))
|
TARGET_PREBUILT_KERNEL 目标 就是编译 内核的。里面调用了那个 buildkernel.sh
定义 build-kernel
脚本在 build-kernel 中 调用 这个 device/qcom/kernelscripts/buildkernel.sh 脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| # Build the kernel # $(1): KERNEL_DEFCONFIG to build for # $(2): KERNEL_OUT directory # $(3): KERNEL_MODULES_OUT directory # $(4): KERNEL_HEADERS_INSTALL directory # $(5): HEADERS_INSTALL; If 1, the call would just generate the headers and quit # $(6): TARGET_PREBUILT_INT_KERNEL: The location to the kernel's binary format (Image, zImage, and so on) define build-kernel KERNEL_DIR=$(TARGET_KERNEL_SOURCE) \ DEFCONFIG=$(1) \ OUT_DIR=$(2) \ MAKE_PATH=$(MAKE_PATH)\ ARCH=$(KERNEL_ARCH) \ CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) \ KERNEL_MODULES_OUT=$(3) \ KERNEL_HEADERS_INSTALL=$(4) \ HEADERS_INSTALL=$(5) \ TARGET_PREBUILT_INT_KERNEL=$(6) \ TARGET_INCLUDES=$(TARGET_KERNEL_MAKE_CFLAGS) \ TARGET_LINCLUDES=$(TARGET_KERNEL_MAKE_LDFLAGS) \ VENDOR_KERNEL_MODULES_ARCHIVE=$(VENDOR_KERNEL_MODULES_ARCHIVE) \ VENDOR_RAMDISK_KERNEL_MODULES_ARCHIVE=$(VENDOR_RAMDISK_KERNEL_MODULES_ARCHIVE) \ VENDOR_RAMDISK_KERNEL_MODULES="$(VENDOR_RAMDISK_KERNEL_MODULES)" \ TARGET_PRODUCT=$(TARGET_BOARD_PLATFORM) \ device/qcom/kernelscripts/buildkernel.sh \ $(real_cc) \ $(TARGET_KERNEL_MAKE_ENV) endef ```
## 调用日志 相关的编译进程信息如下
```bash bash,2256375 -c echo "Building the requested kernel.."; \011\011 # 这2个字符不知道哪里打印出来的????? 这2个字符是 tab 键, 一个在 define build-kernel 中引入的,一个在 $(call build-kernel) 引入的。 KERNEL_DIR=kernel/msm-5.4 DEFCONFIG=vendor/autogvm-qgki-debug_defconfig OUT_DIR=out/target/product/sa8295_xxxx/obj/kernel/msm-5.4 MAKE_PATH=./prebuilts/build-tools/linux-x86/bin/ ARCH=arm64 CROSS_COMPILE=./prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- KERNEL_MODULES_OUT=out/target/product/msmnile_gvmq/dlkm/lib/modules KERNEL_HEADERS_INSTALL=out/target/product/sa8295_xxxx/obj/kernel/msm-5.4/usr HEADERS_INSTALL=0 TARGET_PREBUILT_INT_KERNEL=out/target/product/sa8295_xxxx/obj/kernel/msm-5.4/arch/arm64/boot/Image TARGET_INCLUDES="-I.kernel/msm-5.4/include/uapi -I/usr/include -I/usr/include/x86_64-linux-gnu -I.kernel/msm-5.4/include -L/usr/lib -L/usr/lib/x86_64-linux-gnu -fuse-ld=lld" TARGET_LINCLUDES="-L/usr/lib -L/usr/lib/x86_64-linux-gnu -fuse-ld=lld" VENDOR_KERNEL_MODULES_ARCHIVE=vendor_modules.zip VENDOR_RAMDISK_KERNEL_MODULES_ARCHIVE= VENDOR_RAMDISK_KERNEL_MODULES="" TARGET_PRODUCT=msmnile device/qcom/kernelscripts/buildkernel.sh # 执行这个脚本,前面的是定义的变量 REAL_CC=./prebuilts/clang/host/linux-x86/clang-r416183b/bin/clang CLANG_TRIPLE=aarch64-linux-gnu- AR=./prebuilts/clang/host/linux-x86/clang-r416183b/bin/llvm-ar LLVM_NM=./prebuilts/clang/host/linux-x86/clang-r416183b/bin/llvm-nm LD=./prebuilts/clang/host/linux-x86/clang-r416183b/bin/ld.lld NM=./prebuilts/clang/host/linux-x86/clang-r416183b/bin/llvm-nm DTC_EXT=./out/host/linux-x86/bin/dtc DTC_OVERLAY_TEST_EXT=./out/host/linux-x86/bin/ufdt_apply_overlay CONFIG_BUILD_ARM64_DT_OVERLAY=y HOSTCC=./prebuilts/clang/host/linux-x86/clang-r416183b1/bin/clang HOSTAR=./prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ar HOSTLD=./prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.17-4.8/bin/x86_64-linux-ld M4=./prebuilts/build-tools/linux-x86/bin/m4 LEX=./prebuilts/build-tools/linux-x86/bin/flex YACC=./prebuilts/build-tools/linux-x86/bin/bison
|
关于 \011\011 这2个诡异的符号
1 2 3
| $(TARGET_PREBUILT_KERNEL): $(KERNEL_OUT) $(DTC) $(KERNEL_USR)↵ → echo "Building the requested kernel.."; \↵ → $(call build-kernel,$(KERNEL_DEFCONFIG),$(KERNEL_OUT),$(KERNEL_MODULES_OUT),$(KERNEL_HEADERS_INSTALL),0,$(TARGET_PREBUILT_INT_KERNEL))↵
|
把 echo 那一行的 结尾的 \ 去掉就能 消除 \011 这个符号的引入。
1 2 3
| $(TARGET_PREBUILT_KERNEL): $(KERNEL_OUT) $(DTC) $(KERNEL_USR)↵ → echo "Building the requested kernel.."↵ → $(call build-kernel,$(KERNEL_DEFCONFIG),$(KERNEL_OUT),$(KERNEL_MODULES_OUT),$(KERNEL_HEADERS_INSTALL),0,$(TARGET_PREBUILT_INT_KERNEL))↵
|
去掉后会变成如下的 调用方式:
1 2 3 4 5 6
| bash,809616 -c (echo "Building the requested kernel.." ) && (KERNEL_DIR=kernel/msm-5.4
....省略后续的
|
去掉前是如下的 调用方式:
1 2 3 4 5 6 7
| bash,2256375 -c echo "Building the requested kernel.."; \011\011 KERNEL_DIR=kernel/msm-5.4
....省略后续的
|
问题1,到底哪个依赖让TARGET_PREBUILT_KERNEL这个目标执行了呢?
思路 1
到底 哪个 依赖 让 TARGET_PREBUILT_KERNEL 这个目标执行了呢???
我们最开始执行的是make命令,默认目标是 droid ???
先分析 device/qcom/kernelscripts/kernel_definitions.mk 文件里面 对 TARGET_PREBUILT_KERNEL 的依赖目标
1 2 3 4 5 6 7 8 9 10 11
| ifeq ($(TARGET_PREBUILT_KERNEL),) 这里说明没定义这个,才会进入到这个文件里面,这里就会重新定义。
TARGET_PREBUILT_KERNEL := $(TARGET_PREBUILT_INT_KERNEL) 这里是给这边目标变量赋值,是一个路径 out/target/product/sa8295_xxxx/obj/kernel/msm-5.4/arch/arm64/boot/Image $(BOARD_VENDOR_KERNEL_MODULES_ARCHIVE): $(TARGET_PREBUILT_KERNEL) 定义依赖编译内核目标的, 这个目标没找到被其他所依赖!!! $(BOARD_VENDOR_RAMDISK_KERNEL_MODULES_ARCHIVE): $(TARGET_PREBUILT_KERNEL) 定义依赖编译内核目标的, 这个目标没找到被其他所依赖!!! $(BOARD_VENDOR_RAMDISK_KERNEL_MODULES_ARCHIVE): $(TARGET_PREBUILT_KERNEL) 定义依赖编译内核目标的, 这个目标没找到被其他所依赖!!! $(BOARD_VENDOR_RAMDISK_KERNEL_MODULES): $(TARGET_PREBUILT_KERNEL) 定义依赖编译内核目标的 $(INSTALLED_KERNEL_TARGET): $(TARGET_PREBUILT_KERNEL) $(GKI_TARGET_PREBUILT_KERNEL) 定义依赖编译内核目标的, 最终发现 还是 从这里进入的!!!!!!!!!!!
$(TARGET_PREBUILT_KERNEL): $(KERNEL_OUT) $(DTC) $(KERNEL_USR) 定义这个目标依赖
|
后来偶然发现:
怎么发现的,也是偶然发现的, TARGET_PREBUILT_KERNEL 这一个文件,是一个变量,值是 out/target/product/sa8295_xxxx/obj/kernel/msm-5.4/arch/arm64/boot/Image,然后就随便改名了一下。
改名后就报错了,然后尝试解决报错。需要把 myimage 文件从原来的位置复制一个,不能随便新建个空文件,不然后续的 check_vintf、build/make/tools/extract_kernel.py 什么的检查会报错的。
发现里面的 cp 动作 和 $(INSTALLED_KERNEL_TARGET) 下面定义的 一致!!!
尝试改名的一个报错信息如下:
1 2 3 4 5 6 7 8 9 10 11 12
| [sa8295_xxxx-userdebug][ 86% 447/518]FAILED: out/target/product/sa8295_xxxx/kernel [sa8295_xxxx-userdebug][ 86% 447/518]/bin/bash -c "( cp out/target/product/sa8295_xxxx/obj/kernel/msm-5.4/arch/arm64/boot/myimage out/target/product/sa8295_xxxx/kernel ) && ( if [ ! -z \"\" ]; then cp out/target/product/sa8295_xxxx/kernel-gki; fi ) && ( touch out/target/product/sa8295_xxxx/obj/KERNEL_OBJ/usr -r out/target/product/sa8295_xxxx/obj/kernelusr.time )" [sa8295_xxxx-userdebug][ 86% 447/518]cp: bad 'out/target/product/sa8295_xxxx/obj/kernel/msm-5.4/arch/arm64/boot/myimage': No such file or directory [sa8295_xxxx-userdebug][ 86% 447/518]
|
$(INSTALLED_KERNEL_TARGET) 依赖这个 TARGET_PREBUILT_KERNEL 在 kernel_definitions.mk 文件中
1 2 3 4 5 6
| $(INSTALLED_KERNEL_TARGET): $(TARGET_PREBUILT_KERNEL) $(GKI_TARGET_PREBUILT_KERNEL) cp $(TARGET_PREBUILT_KERNEL) $(PRODUCT_OUT)/kernel if [ ! -z "$(GKI_TARGET_PREBUILT_KERNEL)" ]; then \ cp $(GKI_TARGET_PREBUILT_KERNEL) $(PRODUCT_OUT)/kernel-gki; \ fi touch $(KERNEL_USR) -r $(KERNEL_USR_TS)
|
INSTALLED_KERNEL_TARGET 这个也是个变量,一个文件路径 值是 out/target/product/sa8295_xxxx/kernel 。
$(INSTALLED_KERNEL_TARGET) 依赖这个 TARGET_PREBUILT_KERNEL 在 msmnile_gvmq/AndroidBoard.mk 文件中 。
1 2
| $(INSTALLED_KERNEL_TARGET): $(TARGET_PREBUILT_KERNEL) | $(ACP) $(transform-prebuilt-to-target)
|
重要重要: makefile中同名目标会被后面的覆盖,只是下面的命令部分被覆盖掉,目标后面的依赖会合并到一起。
尝试 把 INSTALLED_KERNEL_TARGET 目标名称改掉,发现 也会调用编译内核的脚本。。。
到底 哪个 依赖 让 TARGET_PREBUILT_KERNEL 这个目标执行了呢??? 我们最开始执行的是make命令,默认目标是 droid ???
还需要继续查找 谁 依赖 TARGET_PREBUILT_KERNEL 这个,让这个目标进行编译构建了!!!!!!!!!!!
重要重要: TARGET_PREBUILT_KERNEL 目标的更新 会导致 INSTALLED_KERNEL_TARGET 目标执行。
思路 2
现在切换思路,不去看冒号前面的,要看 冒号好后面的 依赖部分了,依赖部分更新的话也会导致 内核被编译。
1 2 3
| $(TARGET_PREBUILT_KERNEL): $(KERNEL_OUT) $(DTC) $(KERNEL_USR) echo "Building the requested kernel.."; \ $(call build-kernel,$(KERNEL_DEFCONFIG),$(KERNEL_OUT),$(KERNEL_MODULES_OUT),$(KERNEL_HEADERS_INSTALL),0,$(TARGET_PREBUILT_INT_KERNEL))
|
1 2 3 4 5
| 1️⃣KERNEL_OUT=out/target/product/sa8295_xxxx/obj/kernel/msm-5.4 这是一个目录
2️⃣DTC=out/host/linux-x86/bin/dtc 这是一个 可执行命令
3️⃣KERNEL_USR=out/target/product/sa8295_xxxx/obj/KERNEL_OBJ/usr=" 这是一个目录
|
去掉后面 这几个 $(KERNEL_OUT) $(DTC) $(KERNEL_USR) 依赖 发现 内核不会被编译了!!!!
https://groups.google.com/g/android-building/c/7xTXJ480MO8