旧内核装不上 KernelSU?4.14+ 设备四步完成 KernelSU旧内核适配 移植指南
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
KernelSU 是 Android 上的内核级 root 方案,但跑 4.14 系内核的老手机上,官方路线走不通,管理器直接判定不支持。本文面向做过 root、没碰过内核编译的开发者,按"进源码树 → 选钩子路线 → 加安全模式 → 试机刷机"四步,把 KernelSU旧内核适配 完整走一遍。
🔍 动手前:三步确认你的设备值得折腾
第一步,看内核版本定档位。
adb shell uname -r adb shell "su -c 'dd if=/dev/block/by-name/boot of=/data/local/tmp/boot_bak.img'" adb pull /data/local/tmp/boot_bak.img回显第一段的"主.次"就是档位依据,对照下表:
| 内核版本 | 结论 |
|---|---|
| 5.10+(GKI 设备) | 官方支持,刷镜像即可,不用看本文 |
| 4.14 ~ 5.4(非 GKI) | 本文主线,需手动移植后自己编译 |
| 4.14 以下 | 无现成回移成果,需自行回移 kprobe 路径,不建议 |
版本号里的 android11 这类后缀只反映出厂 Android 版本,判断兼容性一律认"主.次"。第二条命令顺手把原始 boot 备份到电脑——后面任何一步搞挂,它都是唯一的回头票。
第二步,用管理器交叉验证。安装 KernelSU 管理器,状态页显示Not installed说明设备官方支持,本文可以关掉;显示Unsupported则确认要走自编译路线。
第三步,确认原内核能编。拿到你机型的官方内核源码,先原样编译出一遍可启动的 boot 镜像。原内核都编不过,移植没有意义,先解决编译环境。
🛠️ 适配主线:从进源码到第一次开机
第一步:把 KernelSU 挂进内核源码树
目的:让构建系统在drivers/kernelsu这个固定位置找到内核侧代码。
cd /path/to/kernel-source # 你的内核源码根目录 git clone https://gitcode.com/GitHub_Trending/ke/KernelSU git -C KernelSU checkout v0.9.5 # v1.0 起放弃非 GKI,必须锁旧版本 ln -s KernelSU/kernel drivers/kernelsu再给drivers/Makefile追加obj-$(CONFIG_KSU) += kernelsu/,给drivers/Kconfig插入source "drivers/kernelsu/Kconfig",各一行。
判断标准:make menuconfig出现 "KernelSU function support" 菜单,help 里写明依赖 KPROBES 与 EXT4_FS。
常见小坑:软链名写错或漏改 Makefile 时,编译会静默跳过整个模块,产物里没有内核侧代码也报不出错。
第二步:选钩子路线,先易后难
目的:把 root 拦截点挂上,老内核有两条路,先走省事的。
路线 A(kprobe 自动挂钩)为什么优先:KernelSU 默认靠 kprobe 在系统调用入口挂钩子,旧内核上 kprobe 健康就完全不用改源码。在 defconfig 补齐:
CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_KPROBE_EVENTS=y CONFIG_KSU=y判断标准:刷机后dmesg | grep -i ksu能看到初始化输出。
常见小坑:部分 4.14 厂商内核 kprobe 入口本身带 bug,路线 A 直接开机会卡 logo,先用fastboot boot试,不行转路线 B。
路线 B(手动打系统调用补丁)为什么存在:kprobe 坏掉时只能手工在四个函数里插钩子调用——fs/open.c的do_faccessat、fs/exec.c的do_execveat_common、fs/read_write.c的vfs_read、fs/stat.c的vfs_statx。以 exec.c 为例:
static int do_execveat_common(int fd, struct filename *filename, ...) { if (unlikely(ksu_execveat_hook)) // 钩子开关打开才接管 ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); return __do_execve_file(fd, filename, argv, envp, flags, NULL); }ksu_execveat_hook、ksu_handle_execveat的 extern 声明包在#ifdef CONFIG_KSU里,其余三处照此写法。
判断标准:su -c id返回uid=0(root)。
常见小坑:4.14 上找不到vfs_statx就改用vfs_fstatat;找不到do_faccessat就改到faccessat系统调用函数体内。
第三步:补安全模式这条退路
目的:给启动循环留一个逃生口。安全模式靠钩住输入子系统实现——开机时连按三下音量下键,即可禁用全部模块。在drivers/input/input.c的input_handle_event里插一段:
static void input_handle_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { if (unlikely(ksu_input_hook)) ksu_handle_input_handle_event(&type, &code, &value); /* 原有处理逻辑不动 */ }判断标准:开机后在首屏出现时快速按三下音量下(按了松开再按,别长按),管理器模块页应全部显示已禁用。
常见小坑:走路线 B 时务必把CONFIG_KPROBES关掉,否则日常误触音量键也会触发安全模式。
第四步:先 fastboot 试机,再正式刷机
目的:不动分区验证新镜像,稳了才落盘。
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- -j$(nproc) fastboot boot boot.img # 临时加载测试,失败拔线即恢复判断标准:设备正常进系统且adb shell su -c id输出 uid=0,再执行fastboot flash boot boot.img永久写入。
常见小坑:boot 镜像压缩格式必须与设备一致(gz 与 lz4 混刷直接不开机);fastboot boot失败不写盘,不用紧张。
🚑 翻车急救:高频故障的三个根因方向
卡开机 logo 进不了系统 根因:该内核 kprobe 入口损坏(4.14 上最常见),或四个钩子点漏改一处。 修复:fastboot boot确认问题出在新镜像后,转手动路线逐点核对四个补丁;仍失败就回刷备份的原始 boot。
管理器提示 Unsupported 或始终不给 root 根因:管理器 1.0 及以上版本不再包含非 GKI 路线,和 v0.9.5 内核不配套。 修复:安装与内核 v0.9.5 配套的旧版管理器再测,两侧版本必须配对。
模块能装但卸载不生效 根因:内核侧path_umount接口 5.9 才引入,老内核没有。 修复:把 5.9 的can_umount/path_umount回移到fs/namespace.c;嫌麻烦可临时跳过,仅影响卸载功能。
📦 收尾:验证与低配机瘦身
重启稳定后跑一遍验证:
su -c id su -c "/data/adb/ksud module list"应分别看到uid=0(root)和模块列表输出,两者都成立才算移植完成。
低配机瘦身:老手机内存紧张,defconfig 里可打开CONFIG_KSU_DISABLE_MANAGER(关管理器集成)与CONFIG_KSU_DISABLE_POLICY(关 App Profile)缩小模块体积;运行期不用的功能逐项关掉:
su -c "ksud feature set adb_root 0" su -c "ksud feature set selinux_hide 0"要点:
- 永久刷写前永远先
fastboot boot试机,原始 boot 备份留到移植全部结束。 - 内核侧锁定 v0.9.5,管理器版本必须与之配对。
- kprobe 不稳定就果断走手动打补丁路线,更稳。
完整补丁参照与回移细节,见官方文档 website/docs/guide/how-to-integrate-for-non-gki.md。
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考