news 2026/9/10 9:31:54

KernelSU 旧内核适配实战:4.14 到 5.3 设备手动集成到拿到 root 的完整路径

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
KernelSU 旧内核适配实战:4.14 到 5.3 设备手动集成到拿到 root 的完整路径

KernelSU 旧内核适配实战:4.14 到 5.3 设备手动集成到拿到 root 的完整路径

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

KernelSU 是一个基于 Linux 内核的 Android root 方案:权限判定、模块加载、SU 提权全部发生在内核里,而不依赖系统分区的可写性。它的非 GKI 分支已经 backport 到 4.14,所以 4.14–5.3 的老设备仍然可以集成,只是官方不再提供现成 boot 镜像。这篇文章解决的就是这一类问题:管理器提示"不支持"之后,从源码集成、改补丁、编译到刷写验证的完整走法。成本先说清楚:你需要有能力从自己设备的内核源码编译出一个能正常开机的内核,全程至少留 3 小时,并接受一次 fastboot 刷机风险。

🧭 KernelSU 支持到哪个内核:4.14 是分水岭

先给结论:5.10+ 走 GKI/LKM 路线直接刷镜像即可;4.14–5.3 的非 GKI 内核需要把 KernelSU 源码集成进自己的内核树重新编译;低于 4.14 只能参考社区移植补丁做深度 backport,难度陡增。

内核区间能不能用集成方式你需要做什么
5.10+(GKI)官方支持LKM 可加载模块下载官方 boot 刷入
4.14–5.3(非 GKI)已 backport源码集成进内核改 defconfig + 打补丁 + 编译打包
4.14 以下实验性手动 backport 核心模块逐处移植 API,自担风险

一个绕不开的版本红线:KernelSU v1.0 起已放弃非 GKI 支持,最后支持旧内核的版本是v0.9.5。主线分支的源码对 4.19 这类设备已经不能直接用,下文所有集成步骤都锁定在这个 tag 上。

⏱️ 动手编译前必须确认的三件事

不满足任何一条就不要点"编译",省下的都是反复救砖的时间。

  1. 内核版本。连接设备执行:
    adb shell uname -r

    输出例如4.19.191-android11-8-gb2f41e6,只看主版本号:落在 4.14–5.3 区间就属于本文的适配对象。

  2. 管理器侧确认。安装 KernelSU 管理器后如果状态直接显示"不支持",说明它检测不到 GKI 内核,这正是要走手动集成的信号。
  3. 内核源码可编译。你的设备内核必须开源、且你(或社区)已经能从源码编出可开机的 boot。这条不满足时,先解决"把原版内核编译通过"的问题,再谈加 KernelSU——官方集成文档 how-to-integrate-for-non-gki.md 也把它列为前提,该文档现已转为存档参考,仅供旧设备查档。

🔧 把 v0.9.5 源码挂进内核树

这一步对设备无侵入,做坏了可以用脚本自带的--cleanup回滚。

  1. 获取 KernelSU 源码并锁定到最后一个支持非 GKI 的版本:
    git clone https://gitcode.com/GitHub_Trending/ke/KernelSU cd KernelSU git checkout v0.9.5
  2. 进入你的内核源码根目录,执行仓库内的集成脚本(kernel/setup.sh),把kernel/以软链接挂到drivers/kernelsu,并自动追加MakefileKconfig条目:
    sh /path/to/KernelSU/kernel/setup.sh v0.9.5
  3. 打开设备的 defconfig——多数放在arch/arm64/configs/设备代号_defconfig,部分厂商放在arch/arm64/configs/vendor/设备代号_defconfig——加入:
    # KernelSU CONFIG_KSU=y

    适配期间建议同时打开调试开关,方便出问题时看日志:

    CONFIG_KSU_DEBUG=y

    对应开关在 kernel/Kconfig 中定义,y编进内核、M编成kernelsu.ko模块,n关闭。

挂好之后有两条路,按顺序尝试:先试 kprobe 路径,不通再改手动路径

路径一:kprobe 集成(优先)

KernelSU 默认用 kprobe 机制挂内核 hook,只要你的内核里 kprobe 工作正常,就什么都不用改,直接编译。确认以下配置已打开:

CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_KPROBE_EVENTS=y

如果 KPROBES 编译后仍未生效,十有八九是它的依赖CONFIG_MODULES没开;还不行就进make menuconfig搜索 KPROBES,把其余未满足的依赖逐项启用。

路径二:手动改内核源码

kprobe 不工作(常见原因是厂商内核的上游 bug 或版本过低)时,改用显式调用点。必须修改四个系统调用处理函数,各自的位置和补丁如下:

1.fs/exec.cdo_execveat_common

#ifdef CONFIG_KSU extern bool ksu_execveat_hook __read_mostly; extern int ksu_handle_execveat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); extern int ksu_handle_execveat_sucompat(int *fd, struct filename **filename_ptr, void *argv, void *envp, int *flags); #endif static int do_execveat_common(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags) { #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); }

2.fs/open.cdo_faccessat

#ifdef CONFIG_KSU extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, int *flags); #endif long do_faccessat(int dfd, const char __user *filename, int mode) { /* ...原有局部变量... */ #ifdef CONFIG_KSU ksu_handle_faccessat(&dfd, &filename, &mode, NULL); #endif /* ...原有权限检查逻辑... */

内核早于 4.17、没有do_faccessat时,改为直接在SYSCALL_DEFINE3(faccessat, ...)定义内部插入同样的调用。

3.fs/read_write.cvfs_read

#ifdef CONFIG_KSU extern bool ksu_vfs_read_hook __read_mostly; extern int ksu_handle_vfs_read(struct file **file_ptr, char __user **buf_ptr, size_t *count_ptr, loff_t **pos); #endif ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { #ifdef CONFIG_KSU if (unlikely(ksu_vfs_read_hook)) ksu_handle_vfs_read(&file, &buf, &count, &pos); #endif /* ...原有读取逻辑... */

4.fs/stat.cvfs_statx

#ifdef CONFIG_KSU extern int ksu_handle_stat(int *dfd, const char __user **filename_user, int *flags); #endif int vfs_statx(int dfd, const char __user *filename, int flags, struct kstat *stat, unsigned int query_flags) { #ifdef CONFIG_KSU ksu_handle_stat(&dfd, &filename, &flags); #endif /* ...原有属性查询逻辑... */

若你的内核还没有vfs_statx(4.16 及更早),把同样的调用挂进vfs_fstatat代替。

两个强烈建议追加的补丁

安全模式(救砖入口):修改drivers/input/input.cinput_handle_event,开机按住音量下可进入安全模式,对旧设备用户是保命功能:

#ifdef CONFIG_KSU extern bool ksu_input_hook __read_mostly; extern int ksu_handle_input_handle_event(unsigned int *type, unsigned int *code, int *value); #endif static void input_handle_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { #ifdef CONFIG_KSU if (unlikely(ksu_input_hook)) ksu_handle_input_handle_event(&type, &code, &value); #endif /* ...原有输入处理逻辑... */ }

注意一个反直觉的坑:如果走手动集成路径却没关闭CONFIG_KPROBES,开机后按音量下反而可能误触发安全模式。手动路径下建议把 KPROBES 关掉,只用显式调用点。

pm 命令修复su -c pm ...执行失败时,给fs/devpts/inode.cdevpts_get_priv加一行调用:

extern int ksu_handle_devpts(struct inode*); void *devpts_get_priv(struct dentry *dentry) { ksu_handle_devpts(dentry->d_inode); /* ...原有逻辑... */ }

⚙️ 编译、打包 boot 镜像与临时验证

编译前先确认 overlayfs 相关配置齐了,模块挂载系统依赖它:

CONFIG_OVERLAY_FS=y CONFIG_OVERLAY_FS_INDEX=y CONFIG_OVERLAY_FS_REDIRECT_DIR=y

然后照你的设备既有流程配置、编译、打包(arm64 示例,工具链前缀按你自己的环境替换):

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- menuconfig make ARCH=arm64 CROSS_COMPILE=aarch64-linux-android- -j$(nproc) mkbootimg --kernel arch/arm64/boot/Image.gz \ --ramdisk ramdisk.img \ --output boot-ksu.img

永远先临时启动,不直接刷写:

adb reboot bootloader fastboot boot boot-ksu.img

设备正常进入系统、管理器状态变为已支持后,再刷永久分区。root 成功的验证命令:

adb shell su -v # 输出 KernelSU 版本信息 adb shell su -c id # 输出 uid=0(root) gid=0(root)

🚨 刷进去起不来?按这个顺序排查

三类故障占了绝大多数翻车现场,现象和解法对照着看:

现象一:卡在开机 logo 直接重启——kprobe 异常。验证方法很干脆:注释掉 kernel/core/init.c 里的ksu_sucompat_init()ksu_ksud_init()重新编译,如果就能正常开机,说明内核的 kprobe 本身有病。要么修厂商内核里这个 bug,要么切回手动改源码的路径二。

现象二:卡 logo,日志里有 SELinux 拒绝。adb logcat里出现avc: denied { module_load }一类记录,是策略与模块加载冲突,需要按 kernel/selinux/ 下的策略逻辑调整对应规则后重编。

现象三:能开机、root 正常,但模块挂载无效。OverlayFS 没启用或选项不全,系统分区的叠加修改写不进去。回到编译前检查里那三项CONFIG_OVERLAY_FS*配置,补齐重编。

稳定性别只测一次:连续重启 5 次都正常,再跑一段时间压力测试,最后过一遍常用的 root 应用兼容性,才算真正落地。

🧾 适配检查清单与下一步

刷之前逐条对照,全部打勾再动 fastboot:

  • adb shell uname -r落在 4.14–5.3,且管理器显示不支持
  • 原版内核源码已能独立编译并开机
  • KernelSU 锁在v0.9.5,集成脚本执行成功、软链接已挂到drivers/kernelsu
  • defconfig 中CONFIG_KSU=y(调试期加CONFIG_KSU_DEBUG=y
  • kprobe 路径:KPROBES/HAVE_KPROBES/KPROBE_EVENTS三项已开,且CONFIG_MODULES未漏
  • 手动路径:exec/open/read_write/stat 四处调用点全部打上,vfs_statx缺失时改用vfs_fstatat
  • 安全模式补丁已加;手动路径下CONFIG_KPROBES已关闭
  • CONFIG_OVERLAY_FS三项配置完整
  • fastboot boot临时验证通过,su -c id返回 root

下一步你可以做的事:把CONFIG_KSU_DEBUG关掉出正式版镜像;若旧内核上需要"卸载模块"能力,可以从 Linux 5.9 向fs/namespace.c移植path_umount(官方存档文档里有完整参考补丁);遇到 pm 失效再补fs/devpts/inode.c那一行。完整背景资料见仓库内的 非 GKI 集成文档 与 设备支持 FAQ。

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 9:31:16

半不变量概率潮流:IEEE34节点配电网电压风险评估与Matlab实现

搞配电网规划或者分布式电源接入评估的朋友,大概率都遇到过同一个尴尬:你手里有一套确定的负荷数据,算完潮流,报告里写着“XX节点电压为0.98 p.u.”,但实际上现场负荷一直在波动,光伏风电更是看天吃饭&…

作者头像 李华
网站建设 2026/9/10 9:31:02

MATLAB多目标跟踪从零实现:卡尔曼滤波、匈牙利匹配与HOTA评估

简介:多目标跟踪是计算机视觉与信号处理领域的重要课题,旨在识别并连续追踪图像序列中的多个动态目标。该MATLAB项目完整实现了从前景检测、卡尔曼滤波预测、匈牙利匹配到轨迹创建与删除的闭环流程,适合正在学习目标跟踪算法或需要MATLAB参考…

作者头像 李华
网站建设 2026/9/10 9:30:10

瓶子目标检测数据集:VOC与YOLO双格式校验与转换实战

简介:本资源是一套面向计算机视觉初学者与算法工程师的瓶子目标检测专用数据集,适用于YOLO、Faster R-CNN等主流检测模型的训练与验证。数据集共4500张高质量JPEG图像,全部标注为单一类别“bottle”,含12790个精确矩形框&#xff…

作者头像 李华
网站建设 2026/9/10 9:29:59

Phase 2: [Name]

Phase 2: [Name] 【免费下载链接】get-shit-done A light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TCHES. 项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done Goal: [What…

作者头像 李华
网站建设 2026/9/10 9:29:42

deer-flow:沙箱化多智能体协作架构原理与实践

1. “deer-flow”不是框架,是沙箱环境下的多智能体协作范式“deer-flow”这个词最近在技术社区里频繁出现,但翻遍 PyPI、npm、GitHub Trending 和主流技术文档,你找不到一个叫deer-flow的官方开源库、CLI 工具或 npm 包。它不提供pip install…

作者头像 李华