KernelSU 与 Magisk 模块的差异详解:兼容开发与实现机制深度对比
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
KernelSU 与 Magisk 都是基于模块化机制实现 systemless 系统改动的 root 方案,但由于两者在内核态与用户态的完全不同的实现架构,模块在安装、挂载、脚本执行时机等方面存在诸多差异。本文以官方文档 difference-with-magisk.md 为主体,结合 KernelSU 仓库中ksud用户态守护进程的源码实现,系统梳理两者的相同点与差异点,并给出让同一模块同时兼容 KernelSU 与 Magisk 的实战建议。读完本文,你将掌握通过KSU环境变量区分运行环境、使用REMOVE/REPLACE替代.replace机制、以及理解 KernelSU 独有的post-mount与boot-completed脚本阶段等关键能力。
一、KernelSU 与 Magisk 模块的相同点
尽管两者实现机制截然不同,但为了降低模块开发者的迁移成本,KernelSU 在模块格式与约定上高度对齐 Magisk。官方文档明确列出以下相同点:
- 模块文件格式:两者均使用 ZIP 压缩包组织模块,模块内部的文件结构几乎一致。
- 模块安装目录:两者都安装到
/data/adb/modules目录下。 - Systemless 机制:两者都支持以无系统修改(systemless)的方式通过模块改动
/system分区。 post-fs-data.sh:执行时机与语义完全一致。service.sh:执行时机与语义完全一致。system.prop:行为完全一致,用于在开机阶段注入系统属性。sepolicy.rule:行为完全一致,用于追加 SELinux 策略规则。- BusyBox:两种环境下,模块脚本都在开启了 standalone mode 的 BusyBox 中运行。
从源码层面看,KernelSU 的ksud在脚本执行环境中显式设置了ASH_STANDALONE=1(见 module.rs 中的get_common_script_envs),这正是文档所述 "standalone mode" 的落实:sh脚本通过 BusyBox 的独立模式运行,保证各模块脚本行为可预期。
二、如何区分模块运行在 KernelSU 还是 Magisk
在模块脚本可执行的所有位置(customize.sh、post-fs-data.sh、service.sh,以及 KernelSU 新增的阶段脚本),都可以通过环境变量KSU判断当前运行环境:在 KernelSU 中该变量会被设置为true。
对应源码实现在ksud的get_common_script_envs中:
let mut envs = vec![ ("ASH_STANDALONE", "1".to_string()), ("KSU", "true".to_string()), ("KSU_KERNEL_VER_CODE", ksucalls::get_version().to_string()), ("KSU_VER_CODE", defs::VERSION_CODE.to_string()), ("KSU_VER", defs::VERSION_NAME.to_string()), ("KSU_UAPI_VER", ksucalls::uapi_version().to_string()), ("KSU_RUNTIME_MODE", ksucalls::runtime_mode().to_string()), ... ];参考 module.rs,除KSU=true外,KernelSU 还会注入KSU_VER、KSU_VER_CODE、KSU_UAPI_VER、KSU_RUNTIME_MODE等版本与运行模式信息;当模块通过ksud安装时还会注入KSU_MODULE(模块 ID),在 late load 场景下额外注入KSU_LATE_LOAD=1。因此模块脚本中可以这样分支处理:
if [ "$KSU" = "true" ]; then ui_print "- Running in KernelSU" else ui_print "- Running in Magisk" fi需要说明的是,以上KSU_*系列变量的完整集合属于 KernelSU 内部实现细节,官方文档仅保证KSU变量在 KernelSU 环境中为true;Magisk 环境不会设置该变量,这是最稳妥的判别依据。
三、核心差异总览
官方文档列出的主要差异如下表所示:
| 维度 | KernelSU | Magisk |
|---|---|---|
| Recovery 模式安装 | 不支持 | 支持 |
| Zygisk 内置支持 | 无(需通过 ZygiskNext 等方案加载) | 内置 |
| 文件替换/删除方式 | 不支持.replace,使用mknod filename c 0 0或REMOVE/REPLACE变量 | 支持.replace |
| BusyBox 路径 | /data/adb/ksu/bin/busybox | /data/adb/magisk/busybox |
| 脚本阶段 | 在post-fs-data、service基础上新增post-mount与boot-completed | 传统两个阶段 |
以下对各差异逐项展开说明。
3.1 Recovery 模式安装
KernelSU 模块不能在 Recovery 模式下安装。KernelSU 的模块安装完全依赖ksud守护进程在 Android 系统启动完成后执行,这与 Magisk 通过 Recovery 侧脚本安装的能力不同。从源码看,ksud在模块安装前会显式校验系统是否已完成启动(ensure_boot_completed检查sys.boot_completed属性,未完成则直接bail!("Android is Booting!"),见 module.rs),这也印证了安装流程强依赖运行中的 Android 环境。
3.2 Zygisk 支持
KernelSU 模块没有内置Zygisk 支持,但可以通过 ZygiskNext 等第三方实现加载 Zygisk 模块,从而在 KernelSU 上使用 Zygisk 生态的模块。官方文档明确说明此差异,属于 KernelSU 设计上的取舍:核心保持精简,能力通过生态扩展。
3.3 文件替换与删除机制:.replacevsmknod/REMOVE/REPLACE
这是两者差异最大、也最影响模块兼容性的部分:
- Magisk 支持在模块目录内放置
.replace文件(或目录)来替换系统对应路径。 - KernelSU 不支持
.replace方法。要删除(屏蔽)系统对应文件,需要创建一个同名文件,类型为字符设备节点:
mknod filename c 0 0- 同时,KernelSU 提供了
REMOVE与REPLACE两个变量,用于在customize.sh中声明需要删除或替换的文件与目录。
REMOVE/REPLACE的实现位于内置安装脚本 installer.sh:
# Handle replace folders for TARGET in $REPLACE; do ui_print "- Replace target: $TARGET" mark_replace $MODPATH$TARGET done # Handle remove files for TARGET in $REMOVE; do ui_print "- Remove target: $TARGET" mark_remove $MODPATH$TARGET doneksud在运行阶段会读取模块目录下的标记文件(remove等,见 defs.rs 的REMOVE_FILE_NAME)来决定是否跳过/卸载对应模块。实战中,兼容两种环境的模块通常这样写:
# customize.sh 片段 if [ "$KSU" = "true" ]; then REMOVE=" /system/app/SomeApp " REPLACE=" /system/priv-app/AnotherApp " else # Magisk 使用 .replace touch $MODPATH/system/app/SomeApp/.replace fi注意REPLACE主要用于目录级替换(系统会保留模块内的同名目录),REMOVE用于移除路径;两者语义不同,使用时需按需选择。
3.4 BusyBox 路径差异
两个环境的 BusyBox 位置不同:
- KernelSU:
/data/adb/ksu/bin/busybox - Magisk:
/data/adb/magisk/busybox
在 KernelSU 源码中,BINARY_DIR定义为${WORKING_DIR}bin/(见 defs.rs),BUSYBOX_PATH即${BINARY_DIR}busybox(见 assets.rs),ksud执行模块安装与阶段脚本时统一使用该 BusyBox(见 module.rs)。
⚠️ 官方文档特别提醒:这是 KernelSU 的内部行为,未来可能发生变化。因此模块脚本不应硬编码依赖该路径,而应优先通过PATH环境中的busybox命令,或仅将路径用于显式调用场景。
3.5 KernelSU 新增的脚本阶段:post-mount与boot-completed
在 Magisk 传统的post-fs-data、service两阶段之外,KernelSU 额外引入了两个阶段:
post-mount:在模块挂载完成后运行。从 init_event.rs 可以看到,post-fs-data阶段依次执行 metamodule 与普通模块的post-fs-data.sh、加载system.prop、执行 metamodule 挂载脚本(metamount.sh)之后,紧跟着run_stage("post-mount", true)。该阶段为阻塞执行(block=true),适合在挂载完成后对文件系统做进一步处理。boot-completed:在系统启动完成后运行。ksud会等待sys.boot_completed属性变为有效值(见 init_event.rs 中reset_boot_completed/wait_for_boot_completed),随后触发on_boot_completed并执行run_stage("boot-completed", false)(非阻塞)。
阶段脚本的执行顺序由 init_event.rs 的run_stage统一调度:先执行公共目录(如post-mount.d、boot-completed.d)中的通用脚本,再执行 metamodule 的阶段脚本,最后执行普通模块的阶段脚本;且检测到 Magisk 存在或处于安全模式时会跳过阶段脚本,避免冲突。
四、架构差异的延伸:模块挂载与 Metamodule
虽然越南语文档主体未展开,但当前仓库中英文版 difference-with-magisk.md 与 metamodule.md 补充了最重要的架构级差异,在此一并说明:
- Magisk 将模块挂载逻辑内建于核心中;
- KernelSU 采用metamodule(元模块)机制,把挂载能力从核心剥离到可插拔的 metamodule(例如官方的
meta-overlayfs)中。未安装任何 metamodule 时,模块不会被挂载,因此全新安装 KernelSU 后需要先安装一个 metamodule(如meta-overlayfs)模块挂载才能生效。
对应实现位于 metamodule.rs:metamodule 通过module.prop中的metamodule=1标记身份,并可通过metamount.sh、metainstall.sh、metauninstall.sh三个钩子接管挂载、安装与卸载逻辑。这意味着 KernelSU 的模块系统更具可扩展性,但模块开发者需要理解"挂载依赖 metamodule"这一前提。
五、兼容开发实战建议
结合官方文档与源码,为让模块同时兼容 KernelSU 与 Magisk,建议遵循以下实践:
- 统一用
KSU环境变量分支:所有脚本(customize.sh、post-fs-data.sh、service.sh、新增阶段脚本)中都可通过[ "$KSU" = "true" ]判断环境。 - 弃用
.replace,改用REMOVE/REPLACE:这是 KernelSU 不支持的机制,迁移时必须处理。 - 不硬编码 BusyBox 路径:KernelSU 的
/data/adb/ksu/bin/busybox是内部实现,未来可能变动;优先依赖脚本环境的PATH。 - 利用新增阶段:
post-mount阶段适合依赖挂载结果的操作;boot-completed阶段适合需要在系统完全启动后执行的任务(如等待属性、与用户态服务交互)。 - 理解挂载前提:KernelSU 环境需要安装 metamodule 模块挂载才生效;若模块只运行脚本、不改动系统文件,则无需 metamodule。
六、总结
KernelSU 与 Magisk 在模块格式和基础约定上刻意保持一致,降低了模块生态的迁移成本;但在 Recovery 安装、Zygisk、文件替换机制、BusyBox 路径以及脚本阶段上存在明确差异。其中最关键的三点是:用KSU变量做环境判别、用REMOVE/REPLACE或mknod替代.replace、以及理解 KernelSU 的 metamodule 挂载架构与post-mount/boot-completed新增阶段。模块开发者只要围绕这些差异做兼容处理,即可让同一模块稳定运行在两种 root 方案之上。
相关文档与源码索引:
- 官方对比文档(英文版):website/docs/guide/difference-with-magisk.md
- 元模块机制详解:website/docs/guide/metamodule.md
- 脚本环境变量注入与模块安装:userspace/ksud/src/module.rs
- 阶段脚本调度与 boot-completed 实现:userspace/ksud/src/init_event.rs
REMOVE/REPLACE处理逻辑:userspace/ksud/src/installer.sh- BusyBox 路径定义:userspace/ksud/src/assets.rs
【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考