☰
老设备刷KernelSU实战:Linux 4.14+旧内核的完整适配避坑指南
2026/10/14 7:27:51 网站建设 项目流程

老设备刷KernelSU实战:Linux 4.14+旧内核的完整适配避坑指南

【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU

管理器装完提示"当前内核不受支持",老设备root无门。这篇写给手里有台跑4.14~5.3旧内核的Android机器、会刷机和adb但没改过内核源码的你:把KernelSU手动集成进自家内核,从自检、集成、改码到编译打包,一次跑通。

先别急着动手:设备自检

按顺序过一遍,四步都点头再往下走:

  1. 查内核版本
    adb shell uname -r

    预期输出形如4.19.191-android11-8-gb2f41e6。判断标准:主版本号落在 4.14~5.3(4.19、5.4 都算)——这是 KernelSU 非GKI路线的舒适区;4.14 以下属于实验性,除非你就是想折腾,否则劝退。

  2. 确认内核源码是开源的,且你能编出能开机的内核。这是硬前提:老设备内核不开源,后面一切免谈。先拿设备原厂 defconfig 裸编一遍,能开机才谈改造。
  3. 确认确实走不了官方镜像:管理器显示"不支持"、设备又是非GKI,意味着官方不再给你现成的 boot 镜像,boot 得自己打。
  4. 试一下 kprobe 能不能用:在make menuconfig里搜 KPROBES,能勾上且编译通过,你就有一条省事路线;勾不上或开机就重启,只能手动改源码。

选一条改造路线

  • kprobe 自动集成:内核 kprobe 正常工作时的首选,基本只加配置不改代码,适合"就想快点用上"的人。
  • 手动改源码:kprobe 有 bug 或内核太老时的兜底,要在内核里预埋四个系统调用钩子加一个输入事件钩子,改动多但最稳。下面以手动路线为主线展开。

先泼一盆冷水:官方对非GKI内核的支持停在v0.9.5,v1.0 起已经放弃,集成时务必指定这个 tag,别直接拉最新 main。

动手区

1)把KernelSU塞进内核源码树

在仓库里的 kernel/setup.sh 可以看到官方脚本的做法:克隆KernelSU仓库、把kernel/目录软链到drivers/kernelsu、再往构建文件里各加一行。手动照做即可:

git clone https://gitcode.com/GitHub_Trending/ke/KernelSU /tmp/KernelSU ln -s /tmp/KernelSU/kernel <内核树>/drivers/kernelsu echo 'obj-$(CONFIG_KSU) += kernelsu/' >> <内核树>/drivers/Makefile

再在drivers/Kconfig的endmenu之前加一行source "drivers/kernelsu/Kconfig"。做完这两件事,menuconfig 里应该能看到新的 "KernelSU" 菜单——看到它就算集成成功。

2)defconfig 里把开关打开

找到你设备的 defconfig(老机器常见藏在arch/arm64/configs/vendor/设备代号_defconfig,别只找第一层目录),追加:

# KernelSU CONFIG_KSU=y CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_KPROBE_EVENTS=y

为什么是这几项:CONFIG_KSU把内核侧代码编进内核,三个 KPROBE 项是它的 hook 机制。保存后重新make,再 grep 一遍.config确认全是y,KPROBES 若报依赖缺失,把CONFIG_MODULES=y打开即可。

3)预埋四个系统调用钩子(手动路线核心)

原因:kprobe 路线能自动注册 hook,手动路线得提前在四个 syscall 路径上"埋坑"。KernelSU 内核侧(kernel/feature/sucompat.c等)已提供现成的处理函数,你只负责调用,每处都是 diff 级改动:

fs/exec.c—— 改do_execveat_common,拦截进程启动,这是 root 授权的主入口:

static int do_execveat_common(int fd, struct filename *filename, ...) { +#ifdef CONFIG_KSU + if (unlikely(ksu_execveat_hook)) + ksu_handle_execveat(&fd, &filename, &argv, &envp, &flags); + else + ksu_handle_execveat_sucompat(&fd, &filename, &argv, &envp, &flags); +#endif return __do_execve_file(fd, filename, argv, envp, flags, NULL); }

其余三处同一套路(文件头补extern声明,函数体最前面加#ifdef CONFIG_KSU块):

  • fs/open.c——do_faccessat;4.17 以下内核没有它,就改SYSCALL_DEFINE3(faccessat, ...)宏定义,调用ksu_handle_faccessat(&dfd, &filename, &mode, NULL)。
  • fs/read_write.c——vfs_read,用unlikely(ksu_vfs_read_hook)判断后调ksu_handle_vfs_read(&file, &buf, &count, &pos),这个钩子让管理器能读设备信息。
  • fs/stat.c——vfs_statx;你的内核若没有vfs_statx,改vfs_fstatat并传&flag。

改完的预期:编译时无未定义符号,ksu_handle_*全部来自 KernelSU 自己的编译单元。

4)顺手把安全模式和 devpts 补上

drivers/input/input.c的input_handle_event开头加(强烈建议:安全模式是改翻车时唯一的救命通道,开机狂按音量下就能进):

static void input_handle_event(struct input_dev *dev, ...) { +#ifdef CONFIG_KSU + if (unlikely(ksu_input_hook)) + ksu_handle_input_handle_event(&type, &code, &value); +#endif

注意一个坑:手动集成且没关CONFIG_KPROBES时,这个输入钩子和 kprobe 路线会打架,开机按音量下可能误入安全模式——纯手动改代码的话,把 KPROBES 关掉。

fs/devpts/inode.c的devpts_get_priv里加一句ksu_handle_devpts(dentry->d_inode);,否则后面模块里的pm命令会执行失败,建议一开始就带上。想要"卸载模块"能力,再从 5.9 把path_umount回移到 fs/namespace.c,补丁参考仓库里的 非GKI集成文档。

5)编译打包出 boot

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- menuconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- -j$(nproc)

预期:drivers/kernelsu/全部编译通过,arch/arm64/boot/Image更新。打包:

mkbootimg --kernel arch/arm64/boot/Image.gz --ramdisk ramdisk.img --output boot-ksu.img

先fastboot boot boot-ksu.img临时试启动,能正常进系统、管理器识别成功,再真正写入 boot 分区。

翻车现场

按真实排查顺序串起来,每个坑我都踩过:

编译期 undefined reference to ksu_handle_xxx。九成是CONFIG_KSU没真正生效:先查你是不是改错了 defconfig(老设备八成在vendor/子目录里),再查 menuconfig 改动有没有保存后重新 make。还有一种隐蔽的:集成时没锁 v0.9.5,新版本的接口签名变了,符号对不上。

开机卡在 logo。老内核上 kprobe 不正常是最常见原因。定位思路是"先排除":把 v0.9.5 入口里ksu_sucompat_init()和ksu_ksud_init()注释掉重编,能开机了就坐实是 kprobe 的锅,转手动改码路线。所以前面才反复强调安全模式要先开好——卡 logo 时狂按音量下,还有救砖机会。

su 能用,pm 命令不动。缺 devpts 补丁,回到动手区第 4 节改fs/devpts/inode.c重编即可。

模块装上了,/system 的修改却不生效。检查.config里CONFIG_OVERLAY_FS、CONFIG_OVERLAY_FS_INDEX、CONFIG_OVERLAY_FS_REDIRECT_DIR三项是否都是 y,老内核经常一项都没开;装得上去卸不下来,则是没回移path_umount,补上再编。

跑通之后

验证三连:adb shell su -c id应返回uid=0(root),adb shell su -v显示 KernelSU 版本信息;然后连续重启三五次确认不翻车,装一个测试模块看挂载是否生效。

日常调优:适配期在 defconfig 里打开CONFIG_KSU_DEBUG多打点日志,dmesg 里能看清 hook 触发情况,稳定后关掉;内存小的老机器,可在 Kconfig 里用KSU_DISABLE_POLICY、KSU_DISABLE_MANAGER裁掉用不上的功能。

如果你的机型适配成功,把补丁和步骤沉淀回项目的讨论区,能帮到下一个拿同型号设备的人。老内核的路不好走,但走通之后,KernelSU 会在那台老机器上一直干活。

【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询