3 编译设备厂商原始内核
JackA1ltman edited this page 2026-05-12 14:34:23 +08:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

编译设备厂商原始内核

相对于常规的第三方内核,设备厂商提供的原始内核反而更难成功编译。但如果你从未刷入过第三方 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 避免重复创建时报错;蓝牙驱动部分取消注释并启用。


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


Redmi Note 7

编译器:具有完整编译能力的 Google AOSP GCC 4.9(纯 GCC 编译,无需 Clang

步骤 1获取源码

git clone -b lavender-q-oss \
  https://github.com/MiCode/Xiaomi_Kernel_OpenSource \
  lavender_kernel --depth 1

步骤 2确认 defconfig

本设备使用 lavender-perf_defconfig,源码中已包含,无需额外提取。

步骤 3编译

# 生成 .config
make -j$(nproc --all) O=out ARCH=arm64 SUBARCH=arm64 DTC_EXT=dtc \
  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- \
  lavender-perf_defconfig
 
# 正式编译
make -j$(nproc --all) O=out ARCH=arm64 SUBARCH=arm64 DTC_EXT=dtc \
  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 arch/arm64/boot/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 即代表编译成功。

已知编译问题


问题 1multiple definition of 'yylloc'

编辑 scripts/dtc/dtc-lexer.l,将:

YYLTYPE yylloc;

改为:

extern YYLTYPE yylloc;

问题 2gcc-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)

问题 3built-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

问题 4error: 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 的函数声明与内联函数,处理方式相同。)