1. 下载内核
1
2
| repo init -u https://mirrors.ustc.edu.cn/aosp/kernel/manifest.git/ -b android-msm-redbull-4.19-android11-qpr3
repo sync
|
2. 编译内核
./build/build.sh
3. 引子
魔幻的地方来了,网上千篇一律都是推荐这么编译,偏偏我这里报错不断。花了一点时间,跟踪了build的脚本执行流程。
4. 分析
build.sh 其实就是准备Linux 内核编译所需的各种编译参数,如交叉编译工具链,编译环境变量等。
还有android特有的一些配置,如特殊的内核源码位置,输出文件的位置等。
以下按照调用流程分析:
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
| # build/build.sh
# 配置环境变量
source "${ROOT_DIR}/build/_setup_env.sh"
# build/_setup_env.sh
# 定义配置参数
export BUILD_CONFIG=${BUILD_CONFIG:-build.config}
# build/build.config
# 配置编译器 环境变量等
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.redbull.common.clang
# 给 POST_DEFCONFIG_CMDS 赋值,之后在build.sh会调用到
POST_DEFCONFIG_CMDS="check_defconfig && update_nocfi_config"
# private/msm-google/build.config.redbull.common.clang
. ${ROOT_DIR}/${KERNEL_DIR}/build.config.redbull.common
CC=clang # 设置编译器
LD=ld.lld
CLANG_TRIPLE=aarch64-linux-gnu-
# private/msm-google/build.config.redbull.common
# 编译器选项
CROSS_COMPILE=aarch64-linux-gnu-
CROSS_COMPILE_ARM32=arm-linux-gnueabi-
CROSS_COMPILE_COMPAT=$CROSS_COMPILE_ARM32
# 编译器模式,编译器所在的目录
LLVM=1
DEPMOD=depmod
CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r383902/bin
BUILDTOOLS_PREBUILT_BIN=build/build-tools/path/linux-x86
# 回到_setup_env.sh
# 设置环境变量PATH
PREBUILTS_PATHS=(
LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN
LINUX_GCC_CROSS_COMPILE_ARM32_PREBUILTS_BIN
LINUX_GCC_CROSS_COMPILE_COMPAT_PREBUILTS_BIN
CLANG_PREBUILT_BIN
LZ4_PREBUILTS_BIN
DTC_PREBUILTS_BIN
LIBUFDT_PREBUILTS_BIN
BUILDTOOLS_PREBUILT_BIN
)
for PREBUILT_BIN in "${PREBUILTS_PATHS[@]}"; do
PREBUILT_BIN=\${${PREBUILT_BIN}}
eval PREBUILT_BIN="${PREBUILT_BIN}"
if [ -n "${PREBUILT_BIN}" ]; then
# Mitigate dup paths
PATH=${PATH//"${ROOT_DIR}\/${PREBUILT_BIN}:"}
PATH=${ROOT_DIR}/${PREBUILT_BIN}:${PATH}
fi
done
export PATH
# 回到 build.sh
# 导出环境变量
export CLANG_TRIPLE CROSS_COMPILE CROSS_COMPILE_COMPAT CROSS_COMPILE_ARM32 ARCH SUBARCH MAKE_GOALS
# 设置编译器
HOSTCC=clang
HOSTCXX=clang++
CC=clang
LD=ld.lld
AR=llvm-ar
NM=llvm-nm
OBJCOPY=llvm-objcopy
OBJDUMP=llvm-objdump
READELF=llvm-readelf
OBJSIZE=llvm-size
STRIP=llvm-strip
# 编译前的准备工作,主要是生成内核编译所需的 .config 文件
if [ -n "${POST_DEFCONFIG_CMDS}" ]; then
echo "========================================================"
echo " Running pre-make command(s):"
set -x
eval ${POST_DEFCONFIG_CMDS} # 就是 check_defconfig && update_nocfi_config
set +x
fi
# 生成 .config build/build.config
function update_nocfi_config() {
# Disable clang-specific options
${KERNEL_DIR}/scripts/config --file ${OUT_DIR}/.config \
-e THINLTO \
-d CFI \
-d CFI_PERMISSIVE \
-d CFI_CLANG
(cd ${OUT_DIR} && \
make O=${OUT_DIR} CLANG_TRIPLE=${CLANG_TRIPLE} CROSS_COMPILE=${CROSS_COMPILE} "${TOOL_ARGS[@]}" ${MAKE_ARGS} olddefconfig)
# 展开为:
+ make O=/kernel_android-msm-redbull-4.19-android11-qpr3/out/android-msm-pixel-4.19/private/msm-google CLANG_TRIPLE=aarch64-linux-gnu- CROSS_COMPILE=aarch64-linux-gnu- LLVM=1 DEPMOD=depmod olddefconfig
+ GEN ./Makefile
+ scripts/kconfig/conf --olddefconfig Kconfig
+ # configuration written to .config
}
# 接下来的主要工作就是编译内核了
# build/build.sh
echo " Building kernel"
set -x
(cd ${OUT_DIR} && make O=${OUT_DIR} "${TOOL_ARGS[@]}" ${MAKE_ARGS} ${MAKE_GOALS})
set +x
# 展开为:
+ cd /kernel_android-msm-redbull-4.19-android11-qpr3/out/android-msm-pixel-4.19/private/msm-google
+ make O=/kernel_android-msm-redbull-4.19-android11-qpr3/out/android-msm-pixel-4.19/private/msm-google LLVM=1 DEPMOD=depmod
|
5. 问题解决
报错1:
编译内核时报错: /usr/bin/as: unrecognized option '-EL'
:
排查为在编译时,之前设置的环境变量没有被获取到。
临时解决方式:
打印出环境变量,手动export,并执行make:
env
保存到 env.sh
source env.sh
手动执行 echo " Building kernel"
步骤。
或者:
1
2
3
4
5
6
7
| echo " Building kernel"
set -x
echo "----------env:"
env > /tmp/env
echo "----------done"
(cd ${OUT_DIR} && source /tmp/env && make O=${OUT_DIR} "${TOOL_ARGS[@]}" ${MAKE_ARGS} ${MAKE_GOALS})
|
报错2:
1
2
3
4
5
6
7
8
9
10
11
12
| In file included from /kernel_android-msm-redbull-4.19-android11-qpr3/private/msm-google/init/version.c:9:
./include/generated/compile.h:7:24: error: missing terminating '"' character [-Werror,-Winvalid-pp-token]
#define LINUX_COMPILER "Android (6443078 based on r383902) clang version 11.0.1 (https://android.googlesource.com/toolchain/llvm-project b397f81060ce6d701042b782172ed13bee898b79)
^
./include/generated/compile.h:8:1: error: unknown type name 'Found'
Found CUDA installation: /usr/local/cuda, version 7.0, LLD 11.0.1 (/buildbot/tmp/tmp6_m7QH b397f81060ce6d701042b782172ed13bee898b79)"
^
./include/generated/compile.h:8:11: error: expected ';' after top level declarator
Found CUDA installation: /usr/local/cuda, version 7.0, LLD 11.0.1 (/buildbot/tmp/tmp6_m7QH b397f81060ce6d701042b782172ed13bee898b79)"
^
;
./include/generated/compile.h:8:133: error: missing terminating '"' character [-Werror,-Winvalid-pp-token]
|
查看 compile.h内容:
cat out/android-msm-pixel-4.19/private/msm-google/include/generated/compile.h
1
2
3
4
5
6
7
8
| /* This file is auto generated, version 1 */
/* SMP PREEMPT */
#define UTS_MACHINE "aarch64"
#define UTS_VERSION "#1 SMP PREEMPT Tue Jul 30 23:49:29 CST 2024"
#define LINUX_COMPILE_BY "xxx"
#define LINUX_COMPILE_HOST "xxxx"
#define LINUX_COMPILER "Android (6443078 based on r383902) clang version 11.0.1 (https://android.googlesource.com/toolchain/llvm-project b397f81060ce6d701042b782172ed13bee898b79)
Found CUDA installation: /usr/local/cuda, version 7.0, LLD 11.0.1 (/buildbot/tmp/tmp6_m7QH b397f81060ce6d701042b782172ed13bee898b79)"
|
多了最后一行。
grep了整个项目,发现,最后一行在clang中有关键字:
1
2
3
4
5
6
7
8
9
| grep -nr 'Found CUDA installation' ./
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782c/bin/clang-10: binary file matches
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782c/bin/clang-check: binary file matches
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782c/bin/clang-tidy.real: binary file matches
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782c/lib64/libclang_cxx.so.10git: binary file matches
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782c/lib64/liblldb.so.10.0.5git: binary file matches
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782c/lib64/libclang.so.10git: binary file matches
grep: ./prebuilts-master/clang/host/linux-x86/clang-r377782b/bin/clang-10: binary file matches
...
|
最终在 kernel: Force disable LLVM CUDA 找到答案:
1
2
3
4
5
6
7
8
9
10
11
| index 2409894..40285e5 100644
--- a/build/tasks/kernel.mk
+++ b/build/tasks/kernel.mk
@@ -239,7 +239,7 @@
endif
PATH_OVERRIDE += PATH=$(TARGET_KERNEL_CLANG_PATH)/bin:$$PATH
ifeq ($(KERNEL_CC),)
- KERNEL_CC := CC="$(CCACHE_BIN) clang"
+ KERNEL_CC := CC="$(CCACHE_BIN) clang --cuda-path=/dev/null"
endif
endif
|
编辑:private/msm-google/Makefile
1
2
| - CLANG_FLAGS :=
+ CLANG_FLAGS := --cuda-path=/dev/null
|
终极解决方案, 换版本。其他版本的内核 执行 bash build/build.sh 可以直接编译成功(makefile 中 cuda 的修改仍是必须的)。
6. 不能启动问题修复
找到aosp编译中的原版 boot.img:
out/target/product/bramble/boot.img
解压工具:(Android_boot_image_editor)[https://github.com/cfig/Android_boot_image_editor.git]
1
2
3
4
5
6
7
8
9
| cd Android_boot_image_editor
./gradlew unpack
cp /aosp/out/target/product/bramble/boot.img ./
cd build/unzip_boot
cp /android-msm-redbull-4.19-android13/out/android-msm-pixel-4.19/dist/Image.lz4-dtb ./kernel
./gradlew pack
adb reboot bootloader
fastboot boot boot.img.signed
|
此时启动会卡住,然后重启。
1
2
3
4
| cd private/msm-google/arch/arm64/configs
mv redbull_defconfig redbull_defconfig_bak
拷贝上面 build/unzip_boot 的 kernel_configs.txt
cp /Android_boot_image_editor/build/unzip_boot/kernel_configs.txt out/android-msm-pixel-4.19/private/msm-google/.config
|
7. 启动kasan
编辑aosp 中 device/google/redbull/BoardConfig-common.mk
1
2
3
4
5
| # Kernel modules
# 最有一个else
KERNEL_MODULE_DIR := $(TARGET_KERNEL_DIR)
# 改为
KERNEL_MODULE_DIR := $(TARGET_KERNEL_DIR)/kasan
|
重新 编译工程,生成新的 boot.img
拷贝新 boot.img 的 config 作为编译 config
内核编译中的环境变量
- 默认配置 自定义config 的时候 置为1
export SKIP_DEFCONFIG=1
- 清理编译临时文件 一般增量编译的时候,置为1
export SKIP_MRPROPER=1
./build/build.sh