编译设备厂商原始内核 - JackA1ltman/NonGKI_Kernel_Build_2nd GitHub Wiki

编译设备厂商原始内核

相对于常规的第三方内核,设备厂商提供的原始内核反而更难成功编译。但如果你从未刷入过第三方 ROM,厂商原始内核则是最稳妥的选择。

本章按厂商分节,各节相互独立,按需阅读即可。

注意:厂商原始内核在未经适配修改前,无法直接通过本项目进行编译。内核源码与项目源码至少需要修改其中之一。


OPPO / OnePlus / Realme

欧加集团旗下三个品牌的内核源码由各自独立的账号维护:

品牌 GitHub 账号
OnePlus oneplusoss
OPPO oppo-source
Realme realme-kernel-opensource

OPPO Reno 10

编译器:ZyC Clang 10 + Google AOSP GCC 4.9

步骤 1:获取源码

以 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

步骤 2:提取 defconfig

从已获取 Root 权限的手机中提取 /proc/config.gz,解压后将 config 文件重命名为 reno10_defconfig,放置至:

/home/username/kernel/msm-5.4/arch/arm64/configs/reno10_defconfig

步骤 3:放置驱动文件

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/

步骤 4:编译

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 即代表编译成功。


小米 / 红米 / POCO

小米集团旗下各品牌的内核源码统一托管在同一仓库:

Redmi Note 9 5G

编译器:Clang r377782b + Google AOSP GCC 4.9

步骤 1:获取源码

以 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

步骤 2:确认 defconfig

小米设备的内核源码通常已包含完整的 defconfig 文件,本例使用 cannon_user_defconfig,无需额外提取。

步骤 3:修补驱动

编译前需解决以下三个已知问题:


问题 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(使用编辑器的全文替换功能即可)。


步骤 4:编译

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 即代表编译成功。


Xiaomi 10 Ultra

编译器:Clang r377782b + Google AOSP GCC 4.9

步骤 1:获取源码

内核源码

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.git

步骤 2:嵌入驱动

mv 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/data

data 驱动的额外修补

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

步骤 3:编译

使用 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 的函数声明与内联函数,处理方式相同。)

⚠️ **GitHub.com Fallback** ⚠️