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避免重复创建时报错;蓝牙驱动部分取消注释并启用。
问题 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 即代表编译成功。
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 即代表编译成功。
已知编译问题
问题 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 的函数声明与内联函数,处理方式相同。)
🌐 Language / 语言
📖 English
Local Build
- Setting Up the Environment
- Choosing a Toolchain
- Compiling the Kernel
- Compiling on a Mobile Device
- Compiling the Stock Vendor Kernel
- Embedding KernelSU & Patching SuSFS
- Packaging and Flashing
- Kernel Build FAQ
Build with Actions
- Fork the Repository
- Configuring the YML File
- Variable Reference
- Running and Downloading Artifacts
- Automated Release
Hide Root Trace
📖 中文
基础编译
利用 Action 构建内核
隐藏Root痕迹