安卓内核定制开发笔记(一)内核源码编译
注意:本文默认读者知晓刷机风险,并且熟练进行刷机操作
测试设备:一加3T 安卓P
测试系统:Ubuntu 20.04
先放上前后对比图,如下图内核版本名称从3.18.120-perf+变为了3.18.120-perf+cube
刷内核前:
刷内核后:
一、环境准备
1.安装依赖
apt install git gnupg flex bison gperf build-essential zip curl zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev libgl1-mesa-dev libxml2-utils xsltproc unzip bc gcc-aarch64-linux-gnu
2.安装交叉编译工具链
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9
根据需要迁出分支
git checkout -B android9_local -t origin/pie-release
3.拉取AnyKernel3
git clone https://github.com/osm0sis/AnyKernel3
二、内核源码拉取
以一加3T为例,[官方内核源码仓库地址](GitHub - OnePlusOSS/android_kernel_oneplus_msm8996 at oneplus/QC8996_P_9.0)
如果是为了构建KernelSU,可以参考[这里](非官方支持设备 | KernelSU)查找源码仓库
三、编译内核
1.查找用于编译的配置文件
在源码中查找合适的配置文件,一般在/arch/arm64/configs目录(arm64架构下),以一加3T为例,官方使用的配置文件为msm-perf_defconfig
2.执行编译
#配置环境变量
export ANDROID_AARCH64=/这里使用工具链路径/aarch64-linux-android-4.9/bin/
export ARCH=arm64
export SUBARCH=arm64
export PATH=$ANDROID_AARCH64:$PATH
export CROSS_COMPILE=aarch64-linux-android-
# 清理
make distclean
# 指定输出目录和编译配置文件
make O=output/ msm-perf_defconfig
# 开始编译 -j后的数字表示线程数
make O=output/ -j4
编译成功输出如下:
output/arch/arm64/boot/Image.gz-dtb就是编译完成的内核二进制文件
四、刷入内核
使用AnyKernel来打包内核
1.修改AnyKernel配置文件
按照需要来修改AnyKernel的配置文件,例如:
相比于默认配置文件修改如下:
do.devicecheck=0 //禁用了设备校验
block=auto //自动选择分区
2.加入内核编译产物
本次的编译产物包含内核二进制文件和内核模块
内核文件即上面的Image.gz-dtb
内核模块分散在输出目录,在编译输出目录执行以下命令(确保modules 目录存在)
find -name *ko -exec cp "{}" ./modules \;
即可将所有内核模块复制到modules目录
3.制作内核刷机包
将上一步的Image.gz-dtb和modules文件夹复制到AnyKernel根目录,并在根目录执行
# custom_kernel.zip是期望生成的刷机包名称
zip -r9 custom_kernel.zip *
4.刷入手机
使用recovery将custom_kernel.zip刷入手机,开机并检查各项功能是否正常
五、问题和解决(针对一加3T)
1.Wifi无法使用
原因是原系统的wifi驱动的vermagic和新刷入的内核不匹配,导致内核无法加载wifi驱动,解决方案有两种
方案一
修改内核编译配置文件,使CONFIG_LOCALVERSION字段的值与原系统完全一致,以一加3T为例,官方放出的刷机包中的CONFIG_LOCALVERSION值为"-perf+“,而在代码仓库中,配置文件msm-perf_defconfig的CONFIG_LOCALVERSION为”-perf",少了一个加号,改成一致即可。
方案二
修改内核源代码,使得内核在加载驱动时不再进行校验,校验的代码位于/kernel/module.c,修改思路可以参考文章([原创] 绕过Android内核模块加载验证-Android安全-看雪-安全社区|安全招聘|kanxue.com),修改check_version和module_sig_check两个函数强制返回校验通过即可
关于版本号字符串控制,可以参考文章([Kernel]内核版本添加字符和内核版本'+'解决 - aaronGao - 博客园 (cnblogs.com))