编译设备厂商原始内核 - JackA1ltman/NonGKI_Kernel_Build_2nd GitHub Wiki
相对于常规的第三方内核,设备厂商提供的原始内核反而更难成功编译。但如果你从未刷入过第三方 ROM,厂商原始内核则是最稳妥的选择。
本章按厂商分节,各节相互独立,按需阅读即可。
注意:厂商原始内核在未经适配修改前,无法直接通过本项目进行编译。内核源码与项目源码至少需要修改其中之一。
欧加集团旗下三个品牌的内核源码由各自独立的账号维护:
| 品牌 | GitHub 账号 |
|---|---|
| OnePlus | oneplusoss |
| OPPO | oppo-source |
| Realme | realme-kernel-opensource |
编译器:ZyC Clang 10 + Google AOSP GCC 4.9
以 ColorOS 15 为例。源码分支命名规则:oppo/<CPU代号>_<Android版本字母>_<ColorOS版本号>_<设备型号>
内核源码
git clone -b oppo/sm7325_v_15.0.0_reno10 \
https://github.com/oppo-source/android_kernel_oppo_sm7325 \
/home/username/kernel/msm-5.4 --depth 1驱动源码
git clone -b oppo/sm7325_v_15.0.0_reno10 \
https://github.com/oppo-source/android_kernel_modules_and_devicetree_oppo_sm7325 \
/home/username/kernel_modules --depth 1从已获取 Root 权限的手机中提取 /proc/config.gz,解压后将 config 文件重命名为 reno10_defconfig,放置至:
/home/username/kernel/msm-5.4/arch/arm64/configs/reno10_defconfig
mv /home/username/kernel_modules/vendor /home/username/
mv /home/username/kernel_modules/kernel/msm-5.4/techpack/* \
/home/username/kernel/msm-5.4/techpack/export PATH=/home/username/Clang/bin:$PATH
# 生成 .config
make -j$(nproc --all) CC="ccache clang" O=out ARCH=arm64 \
LD=ld.lld LLVM=1 LLVM_IAS=1 \
CLANG_TRIPLE=aarch64-linux-gnu- \
CROSS_COMPILE=/home/username/Gcc/google_gcc_arm64/bin/aarch64-linux-android- \
CROSS_COMPILE_ARM32=/home/username/Gcc/google_gcc_arm/bin/arm-linux-androideabi- \
reno10_defconfig
# 正式编译
make -j$(nproc --all) CC="ccache clang" O=out ARCH=arm64 \
LD=ld.lld LLVM=1 LLVM_IAS=1 \
CLANG_TRIPLE=aarch64-linux-gnu- \
CROSS_COMPILE=/home/username/Gcc/google_gcc_arm64/bin/aarch64-linux-android- \
CROSS_COMPILE_ARM32=/home/username/Gcc/google_gcc_arm/bin/arm-linux-androideabi-出现 OBJCOPY Image 即代表编译成功。
小米集团旗下各品牌的内核源码统一托管在同一仓库:
编译器:Clang r377782b + Google AOSP GCC 4.9
以 MIUI 11 为例。源码分支命名规则:<设备代号>-<Android版本代号>-oss
内核源码
git clone -b cannon-r-oss \
https://github.com/MiCode/Xiaomi_Kernel_OpenSource \
/home/username/cannon-kernel --depth 1驱动源码
git clone -b cannon-r-oss \
https://github.com/MiCode/MTK_kernel_modules \
/home/username/vendor/mediatek/kernel_modules --depth 1小米设备的内核源码通常已包含完整的 defconfig 文件,本例使用 cannon_user_defconfig,无需额外提取。
编译前需解决以下三个已知问题:
问题 1:找不到 fw_sample.i
从社区维护仓库获取该文件(感谢 @xiaomi-mt6853-devs):
https://github.com/xiaomi-mt6853-devs/android_kernel_xiaomi_cannon/blob/lineage-20/drivers/input/touchscreen/fts8719/include/firmware/fw_sample.i
下载后放置至正确路径:
mkdir -p /home/username/cannon-kernel/drivers/input/touchscreen/fts8719/include/firmware/
cp fw_sample.i /home/username/cannon-kernel/drivers/input/touchscreen/fts8719/include/firmware/问题 2:蓝牙与 Wi-Fi 驱动嵌入失败
编辑 drivers/misc/mediatek/connectivity/Makefile:
将以下内容:
ABS_PATH_TO_WMT_DRV = $(srctree)/../$(PATH_TO_WMT_DRV)
ABS_PATH_TO_WLAN_CHR_DRV = $(srctree)/../$(PATH_TO_WLAN_CHR_DRV)
ABS_PATH_TO_WLAN_DRV = $(srctree)/../$(PATH_TO_WLAN_DRV)
...
$(shell ln -s $(ABS_PATH_TO_WMT_DRV) $(srctree)/$(src)/wmt_drv)
$(shell ln -s $(ABS_PATH_TO_WLAN_CHR_DRV) $(srctree)/$(src)/wmt_chrdev_wifi)
$(shell ln -s $(ABS_PATH_TO_WLAN_DRV) $(srctree)/$(src)/wlan_drv_gen4m)
...
# For BT built-in mode start @{
# ifneq (,$(filter $(CONFIG_MTK_COMBO_CHIP), "CONSYS_6885"))
# PATH_TO_BT_DRV = vendor/mediatek/kernel_modules/connectivity/bt/mt66xx/connac2
# ...
# endif
# ABS_PATH_TO_BT_DRV = $(srctree)/../$(PATH_TO_BT_DRV)
# $(shell unlink $(srctree)/$(src)/bt)
# $(shell ln -s $(ABS_PATH_TO_BT_DRV) $(srctree)/$(src)/bt)
# obj-y += bt/
# @} For BT built-in mode end替换为:
ABS_PATH_TO_WMT_DRV = $(abspath $(srctree)/../$(PATH_TO_WMT_DRV))
ABS_PATH_TO_WLAN_CHR_DRV = $(abspath $(srctree)/../$(PATH_TO_WLAN_CHR_DRV))
ABS_PATH_TO_WLAN_DRV = $(abspath $(srctree)/../$(PATH_TO_WLAN_DRV))
...
$(shell ln -snf $(ABS_PATH_TO_WMT_DRV) $(srctree)/$(src)/wmt_drv)
$(shell ln -snf $(ABS_PATH_TO_WLAN_CHR_DRV) $(srctree)/$(src)/wmt_chrdev_wifi)
$(shell ln -snf $(ABS_PATH_TO_WLAN_DRV) $(srctree)/$(src)/wlan_drv_gen4m)
...
PATH_TO_BT_DRV = vendor/mediatek/kernel_modules/connectivity/bt/mt66xx/legacy
ABS_PATH_TO_BT_DRV = $(abspath $(srctree)/../$(PATH_TO_BT_DRV))
$(shell unlink $(srctree)/$(src)/bt)
$(shell ln -snf $(ABS_PATH_TO_BT_DRV) $(srctree)/$(src)/bt)
obj-y += bt/主要变更:
$(srctree)外层改用$(abspath ...)确保路径解析正确;软链接命令由ln -s改为ln -snf避免重复创建时报错;蓝牙驱动部分取消注释并启用。
问题 3:fw_entry 函数重复定义
编辑以下文件:
drivers/misc/mediatek/connectivity/wlan_drv_gen4m/os/linux/gl_kal.c
将文件中所有 fw_entry 全局替换为 fw_entry_wlan(使用编辑器的全文替换功能即可)。
export PATH=/home/username/Clang/bin:$PATH
# 生成 .config
make -j$(nproc --all) CC="ccache clang" O=out ARCH=arm64 \
LD=ld.lld \
CLANG_TRIPLE=aarch64-linux-gnu- \
CROSS_COMPILE=/home/username/Gcc/google_gcc_arm64/bin/aarch64-linux-android- \
CROSS_COMPILE_ARM32=/home/username/Gcc/google_gcc_arm/bin/arm-linux-androideabi- \
cannon_user_defconfig
# 正式编译
make -j$(nproc --all) CC="ccache clang" O=out ARCH=arm64 \
LD=ld.lld \
CLANG_TRIPLE=aarch64-linux-gnu- \
CROSS_COMPILE=/home/username/Gcc/google_gcc_arm64/bin/aarch64-linux-android- \
CROSS_COMPILE_ARM32=/home/username/Gcc/google_gcc_arm/bin/arm-linux-androideabi-出现 CAT Image.gz-dtb 即代表编译成功。
编译器:Clang r377782b + Google AOSP GCC 4.9
内核源码
git clone -b cas-q-oss \
https://github.com/MiCode/Xiaomi_Kernel_OpenSource \
kernel/msm-4.19 --depth 1驱动源码(三个仓库可并行克隆)
git clone -b cas-q-oss --depth 1 https://github.com/MiCode/vendor_qcom_opensource_audio-kernel.git
git clone -b cas-q-oss --depth 1 https://github.com/MiCode/vendor_qcom_opensource_data-kernel.git
git clone -b cas-q-oss --depth 1 https://github.com/MiCode/vendor_qcom_opensource_wlan.gitmv vendor_qcom_opensource_audio-kernel kernel/msm-4.19/techpack/audio
mv vendor_qcom_opensource_wlan/* kernel/msm-4.19/drivers/staging/
mv vendor_qcom_opensource_data-kernel kernel/msm-4.19/techpack/datadata 驱动的额外修补
data 驱动缺少 Kconfig/Makefile 集成文件,需应用以下补丁:
diff --git a/techpack/Kconfig b/techpack/Kconfig
new file mode 100644
index 00000000..c3197b62
--- /dev/null
+++ b/techpack/Kconfig
@@ -0,0 +1,5 @@
+menu "Tech packages"
+
+source "techpack/data/Kconfig"
+
+endmenu
\ No newline at end of file
diff --git a/techpack/data/Kconfig b/techpack/data/Kconfig
new file mode 100644
index 000000000000..696071f9cd05
--- /dev/null
+++ b/techpack/data/Kconfig
@@ -0,0 +1 @@
+source "techpack/data/drivers/Kconfig"
diff --git a/techpack/data/Makefile b/techpack/data/Makefile
new file mode 100644
index 000000000000..1ff634d5a361
--- /dev/null
+++ b/techpack/data/Makefile
@@ -0,0 +1 @@
+obj-y += drivers/
diff --git a/techpack/data/drivers/Kconfig b/techpack/data/drivers/Kconfig
new file mode 100644
index 000000000000..a45052c6bdc0
--- /dev/null
+++ b/techpack/data/drivers/Kconfig
@@ -0,0 +1,5 @@
+menu "RmNet extensions"
+
+source "techpack/data/drivers/rmnet/Kconfig"
+
+endmenu
diff --git a/techpack/data/drivers/Makefile b/techpack/data/drivers/Makefile
new file mode 100644
index 000000000000..7a2c7ff726fd
--- /dev/null
+++ b/techpack/data/drivers/Makefile
@@ -0,0 +1 @@
+obj-y += rmnet/
diff --git a/techpack/data/drivers/rmnet/Kconfig b/techpack/data/drivers/rmnet/Kconfig
new file mode 100644
index 000000000000..82b861ac06bd
--- /dev/null
+++ b/techpack/data/drivers/rmnet/Kconfig
@@ -0,0 +1,2 @@
+source "techpack/data/drivers/rmnet/perf/Kconfig"
+source "techpack/data/drivers/rmnet/shs/Kconfig"
diff --git a/techpack/data/drivers/rmnet/Makefile b/techpack/data/drivers/rmnet/Makefile
new file mode 100644
index 000000000000..82e56d0ab7c5
--- /dev/null
+++ b/techpack/data/drivers/rmnet/Makefile
@@ -0,0 +1,2 @@
+obj-y += perf/
+obj-y += shs/
diff --git a/techpack/data/drivers/rmnet/perf/Kbuild b/techpack/data/drivers/rmnet/perf/Kbuild
index e3537c75ed67..71bae10b8c1c 100644
--- a/techpack/data/drivers/rmnet/perf/Kbuild
+++ b/techpack/data/drivers/rmnet/perf/Kbuild
@@ -1,3 +1,3 @@
-obj-m += rmnet_perf.o
+obj-$(CONFIG_RMNET_PERF) += rmnet_perf.o
rmnet_perf-y := rmnet_perf_config.o rmnet_perf_core.o rmnet_perf_opt.o \
rmnet_perf_tcp_opt.o rmnet_perf_udp_opt.o
diff --git a/techpack/data/drivers/rmnet/perf/Kconfig b/techpack/data/drivers/rmnet/perf/Kconfig
index e55d24e59668..f2af253aa93d 100644
--- a/techpack/data/drivers/rmnet/perf/Kconfig
+++ b/techpack/data/drivers/rmnet/perf/Kconfig
@@ -2,9 +2,9 @@
# RMNET_PERF driver
#
-menuconfig RMNET_PERF
- tristate "Rmnet Perf driver"
- default m
-# depends on RMNET
- ---help---
- performance mode of rmnet driver
\ No newline at end of file
+config RMNET_PERF
+ tristate "Rmnet Perf driver"
+ default m
+ depends on RMNET
+ ---help---
+ performance mode of rmnet driver
diff --git a/techpack/data/drivers/rmnet/shs/Kbuild b/techpack/data/drivers/rmnet/shs/Kbuild
index 055d8561a80b..31ae0ce036c7 100644
--- a/techpack/data/drivers/rmnet/shs/Kbuild
+++ b/techpack/data/drivers/rmnet/shs/Kbuild
@@ -1,2 +1,2 @@
-obj-m += rmnet_shs.o
+obj-$(CONFIG_RMNET_SHS) += rmnet_shs.o
rmnet_shs-y := rmnet_shs_config.o rmnet_shs_main.o rmnet_shs_wq.o
diff --git a/techpack/data/drivers/rmnet/shs/Kconfig b/techpack/data/drivers/rmnet/shs/Kconfig
index 52c401995bb3..b5c9199a4011 100644
--- a/techpack/data/drivers/rmnet/shs/Kconfig
+++ b/techpack/data/drivers/rmnet/shs/Kconfig
@@ -2,9 +2,9 @@
# RMNET_SHS driver
#
-menuconfig RMNET_SHS
- tristate "Rmnet SHS driver"
- default m
-# depends on RMNET
- ---help---
- performance mode of rmnet driver
+config RMNET_SHS
+ tristate "Rmnet SHS driver"
+ default m
+ depends on RMNET
+ ---help---
+ performance mode of rmnet driver并在 defconfig 文件末尾添加:
CONFIG_RMNET_PERF=y
CONFIG_RMNET_SHS=y
使用 cas_user_defconfig:
export PATH=/home/username/Clang/bin:$PATH
# 生成 .config
make -j$(nproc --all) CC="ccache clang" O=out ARCH=arm64 \
LLVM=1 LLVM_IAS=1 \
CLANG_TRIPLE=aarch64-linux-gnu- \
CROSS_COMPILE=/home/username/Gcc/google_gcc_arm64/bin/aarch64-linux-android- \
CROSS_COMPILE_ARM32=/home/username/Gcc/google_gcc_arm/bin/arm-linux-androideabi- \
cas_user_defconfig
# 正式编译
make -j$(nproc --all) CC="ccache clang" O=out ARCH=arm64 \
LLVM=1 LLVM_IAS=1 \
CLANG_TRIPLE=aarch64-linux-gnu- \
CROSS_COMPILE=/home/username/Gcc/google_gcc_arm64/bin/aarch64-linux-android- \
CROSS_COMPILE_ARM32=/home/username/Gcc/google_gcc_arm/bin/arm-linux-androideabi-出现 OBJCOPY arch/arm64/boot/Image 即代表编译成功。
问题 1:multiple definition of 'yylloc'
编辑 scripts/dtc/dtc-lexer.l,将:
YYLTYPE yylloc;改为:
extern YYLTYPE yylloc;问题 2:gcc-wrapper.py 执行报错
在内核源码根目录的 Makefile 中,找到:
REAL_CC = $(CROSS_COMPILE)gcc将 REAL_CC 改为 CC:
CC = $(CROSS_COMPILE)gcc同时移除以下 gcc-wrapper 调用代码:
# Use the wrapper for the compiler. This wrapper scans for new
# warnings and causes the build to stop upon encountering them
CC = $(PYTHON) $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)问题 3:built-in.a: member techpack/audio/dsp/elliptic in archive is not an object
编辑 techpack/audio/Makefile,移除以下内容:
obj-y += dsp/elliptic
#for mius start
ifeq ($(CONFIG_US_PROXIMITY), y)
obj-y += dsp/mius
endif
#for mius end问题 4:error: relocation R_AARCH64_ABS32 cannot be used against symbol __crc_gsi_write_channel_scratch; recompile with -fPIC
需对两个文件应用补丁,核心改动是移除所有 __packed 限定符(该限定符与 AArch64 的重定位规则不兼容)。
drivers/platform/msm/gsi/gsi.c:
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c
index 7c09cd45..f9b7d46a 100644
--- a/drivers/platform/msm/gsi/gsi.c
+++ b/drivers/platform/msm/gsi/gsi.c
@@ -1724,7 +1724,7 @@ int gsi_alloc_evt_ring(struct gsi_evt_ring_props *props, unsigned long dev_hdl,
EXPORT_SYMBOL(gsi_alloc_evt_ring);
static void __gsi_write_evt_ring_scratch(unsigned long evt_ring_hdl,
- union __packed gsi_evt_scratch val)
+ union gsi_evt_scratch val)
...
int gsi_write_channel_scratch(unsigned long chan_hdl,
- union __packed gsi_channel_scratch val)
+ union gsi_channel_scratch val)
...
-static union __packed gsi_channel_scratch __gsi_update_mhi_channel_scratch(
- unsigned long chan_hdl, struct __packed gsi_mhi_channel_scratch mscr)
+static union gsi_channel_scratch __gsi_update_mhi_channel_scratch(
+ unsigned long chan_hdl, struct gsi_mhi_channel_scratch mscr)
...(完整补丁覆盖该文件中所有含 __packed 的函数签名,逐一将 union __packed / struct __packed 改为 union / struct。)
include/linux/msm_gsi.h:
diff --git a/include/linux/msm_gsi.h b/include/linux/msm_gsi.h
index 177e1abd..8aed281b 100644
--- a/include/linux/msm_gsi.h
+++ b/include/linux/msm_gsi.h
int gsi_write_evt_ring_scratch(unsigned long evt_ring_hdl,
- union __packed gsi_evt_scratch val);
+ union gsi_evt_scratch val);
...
int gsi_write_channel_scratch(unsigned long chan_hdl,
- union __packed gsi_channel_scratch val);
+ union gsi_channel_scratch val);
...(完整补丁同样覆盖头文件中所有含 __packed 的函数声明与内联函数,处理方式相同。)