一加7 Pro非GKI内核集成KernelSu:老设备Root方案实战
一加七Pro这机器放到今天依然是折腾党眼里的好玩具骁龙855、2K 90Hz曲面屏、真全面屏设计刷上LineageOS 17.1之后当主力机或者备机都挺舒服。不过ROM刷完之后root方案选什么就成了一道坎。Magisk当然是最常见的路子但如果你想要更底层的权限控制、想避开Magisk那一套zygisk注入的牵连KernelSu这个基于内核的root方案就很有吸引力了。问题在于一加七Pro属于非GKI设备默认跑的是4.14老内核。KernelSu的新版本v1.x以后官方已经放弃了对这类设备的直接支持你打开KernelSu Manager或者看GitHub Release说明会直接看到“你的设备是非GKI内核当前版本KernelSu不再提供官方支持”这类提示。听到这个提示不少人的第一反应是放弃其实完全没必要——KernelSu本来就是以内核补丁方式存在的官方不给现成包我们就自己拿源码编译一个内置KernelSu的4.14内核把这条路自己走通。这篇文章是我给一加七ProLineageOS 17.1 / Android 10 / 内核4.14集成KernelSu的完整记录包含方案选型、编译环境搭建、内核打补丁、打包刷入、验证Zygisk和bug排查。适合两类人看一是已经刷了LineageOS想换root方案的二是手里有其他非GKI设备、想搞懂KernelSu编译集成原理的。我会把每一步的“为什么这么做”也说清楚按步骤抄作业基本不会翻车。1. 项目整体思路与方案选型1.1 为什么一加七Pro集成KernelSu必须先走编译路线先说结论非GKI设备没有捷径必须自己编译内核。GKIGeneric Kernel Image是Google从Android 12开始推的通用内核方案它把内核和厂商驱动模块拆开设备厂商只提供vendor modules系统用的是Google统一构建的GKI内核。KernelSu对GKI设备的支持就是直接给你一个编好的boot.img或者kernel镜像刷进去就行全程不用碰编译器。这也是为什么你在KernelSu官网下载页面能看到一堆针对Pixel、小米等GKI设备的现成镜像。但一加七Pro发布的时候还在Android 9/10时代没有GKI的概念内核是OnePlus基于高通sm8150平台源码维护的4.14内核。LineageOS 17.1用的也是这份内核源码改动不大。这类设备的内核里没有KernelSu需要的预置支持KernelSu官方在v1.x之后直接把非GKI设备从release通道里摘掉了不再提供预编译镜像。剩下的路只有一条把KernelSu的源码作为补丁打进内核源码树然后重新编译内核再把带KernelSu的内核刷进设备。听起来是不是有点当年刷第三方内核的感觉对本质上就是这么回事。KernelSu在非GKI设备上的集成就是以“内核内建模块”的方式存在的编译的时候直接编进kernel image。只要内核能编出来KernelSu的补丁就会跟着进去刷完开机就是root状态。1.2 KernelSu版本选择不要盲目追新KernelSu的版本线大概可以分成两代v0.x时代和v1.x时代。v0.x时期v0.5到v0.9.x对老内核的支持非常积极4.4、4.9、4.14、5.10、6.1这些都能跑。v1.0之后项目重心转移到GKI设备上官方对非GKI老内核的支持慢慢被砍掉了到v1.x中后期基本就是只维护GKI分支。我给一加七Pro选的版本是KernelSu v0.9.0。理由有三点。第一兼容性。v0.9.0是v0.x系列的后期版本fix了很多老内核上kprobe相关的问题4.14内核正好在它的活跃支持范围内。新版KernelSu Manager拿到v0.9.0的内核也能正常识别和管理。第二稳定性。4.14内核本身已经很成熟KernelSu v0.9.0在其上跑了很长时间社区反馈的bug基本都修得差不多了。后面v1.x虽然功能更多、支持了更多GKI特性但对4.14的支持反而开始出现回归没必要拿稳定换一个用不到的新功能。第三Zygisk支持。这点很多人有误解。KernelSu本身并不等同于Zygisk它只负责在内核层提供root能力。真正要跑Zygisk模块比如LSPosed、隐藏root的模块需要额外装Zygisk Next之类的独立实现。KernelSu v0.9.0配合Zygisk Next在Android 10上是经过大量验证的方案不算激进。下表是v0.9.x和v1.x/2.x/3.x的核心差异方便你判断自己的设备该选哪条路对比项KernelSu v0.9.xKernelSu v1.x及以上GKI设备支持部分支持方案不统一官方直接支持提供通用镜像非GKI设备支持官方支持需编译内核集成停止支持需自行使用旧版或分支补丁内核版本要求4.x~5.x均可主要用于5.10GKI要求严格Zygisk机制配合Zygisk Next使用原生开放一部分API仍建议配合Zygisk Next管理器兼容旧版管理器可正常用新版管理器对老内核会提示“不支持”稳定性老内核上经过大量验证GKI设备上先进老内核未覆盖一句话总结如果你的设备是LineageOS 17.1这种Android 10配4.14内核的机器v0.9.0就是最稳的选择。不要拿一加七Pro去追KernelSu 3.x的新特性那是给新手机准备的。2. 编译环境搭建与源码准备2.1 宿主机配置与依赖安装内核编译对机器要求不算低但也不算苛刻。我用的编译机是Ubuntu 22.04 LTS内存32GBCPU是8核16线程。如果你内存只有16GB也能编但建议至少留100GB磁盘空间因为LineageOS源码树加上编译中间产物很占地方只拉内核源码则50GB足够。如果需要拉完整LineageOS源码树磁盘建议直接给300GB。我犯过的错就是第一天只给虚拟机分了120GB结果repo sync到一半磁盘满了还得迁移目录。依赖包建议这样装sudo apt update sudo apt install -y bc bison build-essential ccache curl flex g-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev openjdk-8-jdk这里有几个容易踩坑的点提前说清楚。OpenJDK版本要控制在1.8因为LineageOS 17.1构建系统依赖的是Java 8装新版本JDK会在编译框架层的时候报类型错误。内核本身不依赖Java但如果你后面要跑完整的make bootimage流程就会用到。ccache强烈建议开后续每次调整内核配置重新编译ccache能把时间从十几分钟砍到几分钟。配置方式export USE_CCACHE1然后执行ccache -M 50G设置缓存上限内存充足的开到100G也行。2.2 同步LineageOS源码与内核仓库这一步取决于你是打算编译完整的LineageOS ROM加内核还是只编内核。两种路线我都试过先讲省事的。只编内核的路线你只需要内核源码和一套交叉编译工具链不需要等LineageOS全量同步。内核源码直接拉LineageOS的维护仓库git clone https://github.com/LineageOS/android_kernel_oneplus_sm8150.git -b lineage-17.1工具链方面OnePlus 7 Pro在LineageOS 17.1下编译内核官方用Cooler也就是clang。你需要准备aarch64的gcc工具链作为辅助。我用的是LineageOS源码树里的预编译工具链但如果只拉内核仓库是没有的。最省心的方案是直接从AOSP源码目录下载git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 git clone https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86注意prebuilts/clang仓库很大可以只拉clang-r353983这个版本目录。Android 10时代对应的clang版本大概在9.0.x左右版本不匹配的话内核编译会在链接阶段报奇怪的符号错误。完整路线想彻底重编LineageOS 17.1则要这样mkdir -p ~/los17 cd ~/los17 repo init -u https://github.com/LineageOS/android.git -b lineage-17.1 repo sync -c -j16 source build/envsetup.sh breakfast guacamole同步完成后内核源码在kernel/oneplus/sm8150vendor驱动在vendor/oneplus/sm8150。编译完整的boot镜像直接make bootimage即可会在out/target/product/guacamole/下生成boot.img。我自己的经验如果只是折腾KernelSu走完整同步会等得非常痛苦一加7 Pro全量源码加git历史少说三五十GB只拉内核仓库加工具链就够了。但如果你后续还想改系统层的东西、做Magisk模块兼容测试那完整同步就值了。2.3 提权前先确认设备配置这里顺手提一句编译LineageOS时容易忽略的东西breakfast guacamole之后构建脚本会尝试从设备读取vendor blob。如果你手头有设备且已经刷好LineageOS可以用./extract_files.sh从设备上提取私有驱动。没有设备的话网上也有现成vendor仓库可以拉。KernelSu编译本身不依赖vendor但如果你要编完整boot.imgvendor配置缺失会导致编译中断。3. KernelSu源码集成与内核补丁3.1 KernelSu在非GKI设备上的工作原理搞清楚原理后面改代码才不会懵。KernelSu的root能力本质上是在内核态实现的。它利用了内核的kprobe机制在运行时动态修改内核函数入口从而劫持关键系统调用比如sys_call_table里的execve、kill等当进程请求su时KernelSu通过判断uid、sepolicy等规则决定是否授予root权限。这意味着你的内核必须开启kprobe相关配置否则KernelSu就算编进去了也没法正常工作。这也是评论区里有人问“为什么我编了KernelSu进去管理器却说不支持”的原因——八成是缺了CONFIG_KPROBES。具体需要的内核配置项至少包括CONFIG_KPROBESy CONFIG_HAVE_KPROBESy CONFIG_KPROBE_EVENTSy CONFIG_MODULESy CONFIG_MODULE_UNLOADyCONFIG_MODULES是给KernelSu的运行时模块加载用的虽然我们把KernelSu直接编进内核但模块子系统仍然是基础依赖。CONFIG_KALLSYMS建议也开着KernelSu内部符号解析需要它有些精简defconfig会关掉这个选项不开的话编译不报错但运行时静默失败。3.2 把KernelSu源码合入内核树首先下载KernelSu v0.9.0源码git clone https://github.com/tiann/kernelsu.git cd kernelsu git checkout v0.9.0然后进入你的内核源码目录拷贝KernelSu的内核模块部分cd ~/android_kernel_oneplus_sm8150 mkdir -p drivers/kernelsu cp -r ../kernelsu/kernel/* drivers/kernelsu/加进Kconfig和Makefile# 编辑 drivers/Kconfig在合适位置加入 source drivers/kernelsu/Kconfig # 编辑 drivers/Makefile在合适位置加入 obj-y kernelsu/这里提一个细节drivers/Makefile里obj-$(CONFIG_XXX)的用法很多但KernelSu这个模块我们直接obj-y编进去不做条件编译。因为KernelSu没有提供独立的Kconfig开关你就算写obj-$(CONFIG_KSU)也找不到这个配置项反而会在menuconfig里卡壳。验证KernelSu源码是否完整拷贝成功主要看drivers/kernelsu/下有没有ksu.c和Kconfig这两个文件。漏掉Kconfig的话后面编内核时会直接报drivers/Kconfig:XXX: cant open file drivers/kernelsu/Kconfig。3.3 修改defconfig开启必要内核选项找到一加七Pro的defconfig。在LineageOS的内核仓库里它通常在arch/arm64/configs/目录下命名可能是lineageos_guacamole_defconfig或者vendor/guacamole_defconfig一加官方源码里常见的是vendor/guacamole_defconfig。保险起见用find命令搜find arch/arm64/configs -name *guacamole*打开defconfig确认以下配置CONFIG_KPROBESy CONFIG_HAVE_KPROBESy CONFIG_KPROBE_EVENTSy CONFIG_MODULESy CONFIG_MODULE_UNLOADy CONFIG_KALLSYMSy CONFIG_KALLSYMS_ALLy如果有些项目在defconfig里没出现说明走的是默认值那就直接追加。特别注意CONFIG_KALLSYMS_ALLy一加默认defconfig可能只开了CONFIG_KALLSYMS没开ALL这个会影响KernelSu的符号解析成功率。追加方式就是在文件末尾加几行编译时defconfig会被完整解析。3.4 一加内核特有的编译方式一加sm8150内核编译时对工具链很敏感。我在第一次编译时就卡在工具链上折腾了两个小时才发现是历史遗留的坑高通时代的4.14内核编译的时候既需要clang又需要aarch64的gcc配合做链接、备份等混合编译。推荐的编译环境变量设置export ARCHarm64 export SUBARCHarm64 export CLANG_TRIPLEaarch64-linux-gnu- export CROSS_COMPILE/path/to/aarch64-linux-android-4.9/bin/aarch64-linux-android-然后生成配置并编译make Oout vendor/guacamole_defconfig make Oout -j16注意vendor/guacamole_defconfig前面的vendor/前缀要和你实际find到的defconfig路径保持一致。如果你的文件就叫lineageos_guacamole_defconfig那就写make Oout lineageos_guacamole_defconfig。编译产物在out/arch/arm64/boot/Image.gz-dtb这就是我们要的内核镜像。4. 内核编译与刷机验证4.1 完整的独立编译内核流程我在实际编译时遇到一个细节直接make -j16如果并发太高link阶段内存会飙到接近30GB16GB内存的机器可能直接OOM。建议8核以下用-j8内存紧张就-j4。编译前先检查磁盘空间df -h确保out/所在分区至少有20GB空闲。下面是完整命令序列从配置到生成内核镜像cd ~/android_kernel_oneplus_sm8150 export ARCHarm64 export SUBARCHarm64 export CLANG_TRIPLEaarch64-linux-gnu- # 替换成你的gcc工具链实际路径 export CROSS_COMPILE~/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android- make Oout vendor/guacamole_defconfig make Oout -j8编译界面滚动结束、最后出现Image.gz-dtb的字样时说明内核编出来了。验证产物ls -lh out/arch/arm64/boot/Image.gz-dtb test -f out/arch/arm64/boot/Image.gz-dtb echo OK如果这一步没有生成Image.gz-dtb先检查是不是编译中断了再看out/arch/arm64/boot/下有没有只生成Image或Image.gz的情况。部分老内核配置只生成Image不生成Image.gz-dtb需要检查defconfig里的CONFIG_ARM64相关标志。4.2 打包与刷入推荐的AnyKernel3方案拿到Image.gz-dtb之后不要直接拿它刷机Linux内核通常不能单独刷进boot分区还需要和dtb、ramdisk组合成boot.img。最简单的方案是用AnyKernel3这个模板它会在刷入时自动把新内核合进当前boot分区保留你现有的LineageOS ramdisk和dtb。AnyKernel3地址https://github.com/osm0sis/AnyKernel3使用方法git clone https://github.com/osm0sis/AnyKernel3.git cd AnyKernel3 # 把编译产物替换模板里的Image.gz-dtb cp ~/android_kernel_oneplus_sm8150/out/arch/arm64/boot/Image.gz-dtb . # 编辑 anykernel.sh确认设备代号包含guacamole # 默认模板的device.name有guacamole一般不用改 zip -r9 kernelsu-4.14-anykernel3.zip . -x .git/* -x README.md打包好后把zip传到手机进TWRP刷入。刷入前强烈建议先备份当前boot分区方法是在TWRP里选择Backup勾选Boot即可恢复的时候方便回滚。如果你用的是fastboot模式也可以直接这样fastboot flash boot boot.img fastboot reboot不过boot.img需要你自己用mkbootimg工具把ramdisk和内核打包麻烦而且容易出问题我首推AnyKernel3方案。第一次刷完重启时我建议先不加-w参数保留系统数据正常开机后再看KernelSu管理器是否能识别内核。4.3 KernelSu Manager与Zygisk启用刷入带KernelSu的新内核后正常开机安装KernelSu Manager。老版本管理器就直接在GitHub Release页面找v0.9.0对应的管理器APK即可。打开管理器如果能看到类似KernelSu version: v0.9.0和Kernel mode: /dev/ksu字样恭喜核心功能已经跑通了。这时候终端执行su应该能直接获得root权限。Zygisk层面KernelSu本身不提供Zygisk实现需要额外安装Zygisk Next。推荐在KernelSu Manager里直接给root授权后用Magisk模块刷入Zygisk Next或者用官方推荐的方式下载Zygisk Next的release zip在KernelSu Manager里打开“模块”页面选择本地安装选择Zygisk Next的zip刷入并重启重启后在KernelSu Manager里确认模块状态是启用且没有报错再装LSPosed测试是否正常。如果Zygisk Next和KernelSu版本合不来最常见的现象是开机后系统服务闪烁、部分应用加载异常这时候换一个Zygisk Next版本或者退回KernelSu v0.8.x试试。4.4 内核编译期间的日志排查编译过程中如果遇到配置错误或编译错误日志会直接打印在终端上。我建议养成把日志落盘的习惯免得报错信息滚屏刷掉make Oout -j8 21 | tee build.log错误排查时先看build.log末尾几百行绝大多数问题都能定位到具体的.c或.h文件比盲改defconfig高效很多。5. 常见问题与避坑实录5.1 编译阶段高频问题我在编译过程里遇到的问题按频率排序如下。问题1KernelSu源码放进去后编译报找不到ksu.h或kernelsu目录。这个八成是拷贝路径不对。检查drivers/kernelsu/目录是否存在另外确认一下是不是把整个kernel/目录拷贝过去了。正确做法是把kernelsu/kernel/下的内容拷进drivers/kernelsu/不是把kernel目录本身拷过去。问题2提示gcc: error: unrecognized command-line option ‘-mstack-protector-strong’或者类似选项错误。这个是工具链版本太老导致的。4.14内核编译时默认使用clang但gcc作为辅助工具链不能太旧。我换成aarch64-linux-android-4.9之后解决了。如果你还在用aarch64-linux-gnu-gcc 7.x以下版本大概率会碰到这个错。问题3KernelSu Manager开起来显示“当前版本KernelSu不再提供官方支持”。这个提示不必紧张。新版管理器对旧内核会有这个提示但只要你的内核里集成了KernelSu管理器能正常读取版本信息功能就不受影响。你也可以换用和v0.9.0配套的旧版管理器显示更干净。问题4编译过程中secure_img相关错误。一加sm8150的defconfig里有CONFIG_SECURE_IMAGE相关的选项配置部分分支编译时会调用签章工具普通环境里缺少对应工具就会报错。如果只是自用、不涉及自定义recovery签名校验直接在defconfig里把这个配置关了就行# CONFIG_SECURE_IMAGE is not set5.2 刷入后的运行问题刷完带KernelSu的内核后最常见的问题是开机卡第一屏或无限重启。这时候不要慌先fastboot刷回原bootfastboot flash boot 备份的boot.img如果没备份直接刷回LineageOS官方包里的boot.img也行或者重刷一遍你之前的boot分区备份。如果正常开机但KernelSu Manager里显示root不可用优先排查这几个点症状可能原因处理方式KSU版本显示“未知”内核未成功集成KernelSu检查drivers/kernelsu目录是否进编译确认Makefile加入obj-ysu命令提示permission deniedselinux策略或sepolicy未适配检查内核日志看KernelSu模块是否加载成功必要时关掉selinux验证管理器显示root但应用无法使用管理器版本过旧升级Manager并打开“超级用户”页面查看授权列表Zygisk模块不生效Zygisk Next和KernelSu版本不匹配更换Zygisk Next版本优先选兼容4.14内核的版本还有一个经常被忽略的坑如果之前在Magisk环境下刷过很多模块切到KernelSu后模块目录不通用Magisk的模块不会自动迁移需要到KernelSu Manager里重新刷入需要的模块。我在迁移时就忘了这茬LSPosed一直不生效排查了半天才发现是模块没重装。5.3 避坑总结几条实操心得写几条只有真刷过才会注意到的经验。第一编译内核前先备份原有boot。别偷懒我已经数不清有多少次是靠着原boot救回设备的。一加七Pro刷LineageOS之后TWRP还在刷挂了大不了fastboot刷boot分区但备份能省去很多麻烦。第二KernelSu v0.9.0配合LineageOS 17.1时尽量保持内核defconfig和系统一致性。如果你不懂ffmperf、gpu驱动配置就不要乱动defconfig里其他选项。我试过为了精简内核关掉一些驱动结果Wi-Fi模块加载失败手机能开机但没网折腾半天。KernelSu只负责root不负责优化内核别越界。第三如果决定长期用KernelSuMagisk可以保留但别同时启用MagiskHide之类的功能。两者共存会互相干扰尤其都尝试hook同一批系统调用的时候轻则root失效重则系统重启。第四多准备几个版本的内核包。不同LineageOS OTA版本升级后内核不一定兼容。我刷机后的习惯是每编好一个KernelSu内核就顺手在电脑上归档一个zip标注好日期和LineageOS版本号。后续OTA升级时如果系统内核替换掉了我可以快速刷回带KernelSu的版本。6. 写在最后这次给一加七Pro集成KernelSu前后花了两个晚上。第一晚卡在工具链和defconfig上第二晚刷进去之后管理器一直不识别KernelSu版本最后发现是KernelSu源码拷贝时把目录结构弄错了drivers/kernelsu下空有一个kernel子目录真正的代码没进来。改过来之后重新编译一次通过。经验就是这些。KernelSu在非GKI设备上的编译集成难点不在KernelSu本身而在你对内核源码树、defconfig、工具链这些基础知识的熟悉程度。把这几个点吃透你手里的任何4.14老设备都能用上KernelSu不只是这一台一加七Pro。我接下来还想试试在KernelSu基础上再接一套自定义内核patch比如调度器优化或者内核级防追踪模块等有结果了再来分享。