
KernelSU 模块开发完全指南从 module.prop 到 Late-load 模式的系统级原理与实践【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU本文以 KernelSU 官方模块指南日语版原文与英文版 module.md 同源为骨架结合仓库内 ksud 用户态源码与内核 hook 实现系统讲解 KernelSU 模块的目录结构、配置文件、OverlayFS 系统挂载、initrc 注入、模块安装器、启动脚本与 Late-load 模式。读完本文你将能够从零编写一个可发布、可更新、可兼容多运行模式的 KernelSU 模块并理解其底层执行链路。什么是 KernelSU 模块systemless 机制概览KernelSU 提供了一种模块机制在保持系统分区完整性的前提下实现修改系统目录的效果。这种机制通常被称为systemless系统无修改。与直接刷写或改写/system分区不同模块机制通过 OverlayFS 等挂载技术在运行时叠加改动/system物理分区保持不变从而提升安全性与可维护性。KernelSU 的模块机制与 Magisk 几乎相同。如果你熟悉 Magisk 模块开发那么开发 KernelSU 模块几乎没有学习成本可以直接跳过基础介绍重点阅读 与 Magisk 的差异。::: warning METAMODULE 仅在需要修改系统文件时才必须安装 KernelSU 使用 metamodule 架构来挂载system目录。只有当你需要通过system目录修改/system文件时才需要安装一个 metamodule例如官方参考实现meta-overlayfs。脚本、sepolicy 规则、system.prop 等其他模块功能无需 metamodule 即可工作。这一设计对应源码中的模块检查逻辑在 module.rs 中当存在带有自定义安装器的 metamodule 时普通模块的安装会被阻止而system目录的实际挂载动作由 metamodule 的metamount.sh负责见 init_event.rs。 :::KernelSU 模块还支持两大附加能力分别有独立文档WebUI模块可以展示界面并与用户交互详见 WebUI 文档。模块配置系统KernelSU 内置配置系统允许模块保存持久化或临时性的键值配置详见 模块配置文档。BusyBox 与 ASH Standalone 模式KernelSU 内置一个功能完整的 BusyBox 二进制包含完整的 SELinux 支持位于/data/adb/ksu/bin/busybox对应源码常量 BINARY_DIR。KernelSU 的 BusyBox 支持运行时切换的ASH Standalone Shell 模式。所谓 Standalone 模式是指当在 BusyBox 的ashshell 中执行时无论PATH如何设置所有命令都直接使用 BusyBox 内部的 applet。例如ls、rm、chmod不会使用PATH中的版本Android 默认是/system/bin/ls、/system/bin/rm、/system/bin/chmod而是直接调用 BusyBox 内部的 applet。这保证了脚本始终运行在可预测的环境中无论设备运行哪个 Android 版本命令集始终完整可用。若要强制某个命令不使用 BusyBox必须以完整路径调用该可执行文件。在 KernelSU 上下文中运行的所有 shell 脚本都会在启用了 Standalone 模式的 BusyBoxashshell 中执行对第三方开发者而言这包括所有启动脚本和模块安装脚本。如果你想在 KernelSU 之外使用这一 Standalone 模式有两种启用方式设置环境变量ASH_STANDALONE1示例ASH_STANDALONE1 /data/adb/ksu/bin/busybox sh script使用命令行选项/data/adb/ksu/bin/busybox sh -o standalone script由于环境变量会继承给子进程方式 1 是更推荐的做法——它能确保之后执行的所有shshell 也运行在 Standalone 模式KernelSU 与 KernelSU Manager 内部正是这样使用的。源码层面可以验证这一点module.rs 的 get_common_script_envs 在每次执行脚本时都会注入ASH_STANDALONE1、KSUtrue、KSU_VER、KSU_VER_CODE、KSU_KERNEL_VER_CODE、KSU_UAPI_VER、KSU_RUNTIME_MODE等环境变量而 exec_script 统一通过assets::BUSYBOX_PATH sh script来运行所有脚本。::: tip 与 Magisk 的差异 KernelSU 的 BusyBox 现在直接使用从 Magisk 项目编译的二进制文件。因此 Magisk 与 KernelSU 的 BusyBox 脚本完全相同无需担心兼容性问题 :::KernelSU 模块的目录结构一个 KernelSU 模块是放在/data/adb/modules下的文件夹对应源码常量 MODULE_DIR结构如下/data/adb/modules ├── . ├── . │ ├── $MODID --- 文件夹以模块的 ID 命名 │ │ │ │ *** 模块标识 *** │ │ │ ├── module.prop --- 此文件保存模块的元数据 │ │ │ │ *** 主要内容 *** │ │ │ ├── system --- 如果不存在 skip_mount此文件夹会被挂载 │ │ ├── ... │ │ ├── ... │ │ └── ... │ │ │ │ *** 状态标志 *** │ │ │ ├── skip_mount --- 存在时KernelSU 不会挂载你的 system 文件夹 │ ├── disable --- 存在时模块会被禁用 │ ├── remove --- 存在时模块会在下次重启时被删除 │ │ │ │ *** 可选文件 *** │ │ │ ├── post-fs-data.sh --- 此脚本在 post-fs-data 阶段执行 │ ├── service.sh --- 此脚本在 late_start service 阶段执行 │ ├── uninstall.sh --- 此脚本在 KernelSU 删除模块时执行 │ ├── system.prop --- 此文件中的属性会由 resetprop 作为系统属性加载 │ ├── sepolicy.rule --- 添加自定义 sepolicy 规则 │ ├── initrc/ --- 此目录中的 .rc 文件会在启动时注入 init.rc │ │ ├── myservice.rc │ │ └── ... │ │ │ │ *** 自动生成请勿手动创建或修改 *** │ │ │ ├── vendor --- 指向 $MODID/system/vendor 的符号链接 │ ├── product --- 指向 $MODID/system/product 的符号链接 │ ├── system_ext --- 指向 $MODID/system/system_ext 的符号链接 │ │ │ │ *** 允许添加任何其他文件/文件夹 *** │ │ │ ├── ... │ └── ... │ ├── another_module │ ├── . │ └── . ├── . ├── .几点补充说明结合英文原版与源码disable/remove标志的判定在源码中有明确实现foreach_module会跳过带disable或remove文件的模块module.rsuninstall_module只是创建remove标记文件真正的清理执行uninstall.sh、清除模块配置、删除目录发生在下次启动的prune_modules阶段module.rs 与 module.rs。英文原版还提到模块可选的post-mount.shOverlayFS 挂载完成后执行、boot-completed.sh开机完成时执行与action.sh用户在 Manager 中点击 Action 按钮时执行。其中action.sh由 run_action 直接同步执行常用于模块的交互式操作入口。模块更新时新文件会先解压到/data/adb/modules_update源码常量 MODULE_UPDATE_DIR下次启动由handle_updated_modules合并进正式目录module.rs。::: tip 与 Magisk 的差异 KernelSU没有内置 Zygisk 支持因此模块中不存在与 Zygisk 相关的内容。但可以安装 ZygiskNext 来支持 Zygisk 模块此时 Zygisk 模块的内容与 Magisk 支持的完全相同。 :::module.propmodule.prop是模块的配置文件。在 KernelSU 中不包含此文件的模块不会被识别为模块。其格式如下idstring namestring versionstring versionCodeint authorstring descriptionstring updateJsonurl (可选) actionIconpath (可选) webuiIconpath (可选)各字段规则id必须匹配正则表达式^[a-zA-Z][a-zA-Z0-9._-]$示例✓a_module、✓a.module、✓module-101、✗a module、✗1_module、✗-a-module这是模块的唯一标识符发布后不应更改。versionCode必须是整数用于版本比较。其余字段可以是任意单行字符串。换行符必须使用UNIX (LF)不能使用Windows (CRLF)或Macintosh (CR)。actionIcon与webuiIcon是可选图标路径分别用作 Manager 中模块动作快捷方式与WebUI 快捷方式的默认图标。路径必须相对于模块根目录例如actionIconicon/icon.png会被解析为MODDIR/icon/icon.png。源码验证id的校验在 validate_module_id 中与文档完全一致安装模块时若 ZIP 内缺少module.prop或id非法会直接中止安装install_module_to_system。此外resolve_module_icon_path 会拒绝绝对路径和**含父目录穿越..**的图标路径仅接受模块目录内的相对路径这是安装模块时需要注意的安全边界。::: tip 动态描述description字段可以通过模块配置系统在运行时动态覆盖详见覆盖模块描述。源码中override.description配置项正是用于此目的module.rs。 :::模块脚本post-fs-data.sh与service.sh的区别请参考后文启动脚本章节。对大多数模块开发者而言如果只是想运行一个启动脚本service.sh通常就足够了若需要在开机完成后运行可选用boot-completed.sh若需要在 OverlayFS 挂载后做事可选用post-mount.sh。在模块的所有脚本中请使用MODDIR${0%/*}获取模块的基目录路径不要在脚本中硬编码模块路径。::: tip 与 Magisk 的差异 可以使用环境变量KSU判断脚本运行在 KernelSU 还是 Magisk 中。运行在 KernelSU 时该值为true。对应源码get_common_script_envs始终注入KSUtruemodule.rs。 :::system目录与 OverlayFS 挂载system目录的内容会在系统启动后被 OverlayFS 叠加到系统的/system分区之上与系统中对应目录里同名文件会被此目录中的文件覆盖与系统中对应目录里同名文件夹会被此目录中的文件夹合并。::: tip metamodule 依赖system目录只有在安装了提供挂载功能的 metamodule如meta-overlayfs时才会被挂载。metamodule 负责决定模块如何被挂载详见 Metamodule 指南。 :::删除系统文件mknod 白名单whiteout如果想删除原系统目录中的文件或文件夹需要在模块目录中用mknod filename c 0 0创建与目标同名的文件。这样 OverlayFS 系统会自动将此文件白名单化whiteout效果等同于已删除/system分区实际上未被修改。也可以在customize.sh中声明名为REMOVE的变量列出需要执行删除操作的目录列表KernelSU 会自动在模块对应目录执行mknod TARGET c 0 0。例如REMOVE /system/app/YouTube /system/app/Bloatware 上述列表会执行mknod $MODPATH/system/app/YouTube c 0 0与mknod $MODPATH/system/app/Bloatware c 0 0模块生效后/system/app/YouTube与/system/app/Bloatware即被删除。源码验证安装器 installer.sh 会遍历$REMOVE并调用mark_removemknod $1 c 0 0; chmod 644 $1见 installer.sh。替换系统目录opaque 不透明属性如果想替换系统中的目录需要在模块目录中创建相同路径的目录并为其设置属性setfattr -n trusted.overlay.opaque -v y TARGET。这样 OverlayFS 系统会自动替换系统中对应的目录不修改/system分区。同样可以在customize.sh中声明REPLACE变量列出要替换的目录列表KernelSU 会自动执行相应操作。例如REPLACE /system/app/YouTube /system/app/Bloatware 该列表会自动创建$MODPATH/system/app/YouTube与$MODPATH/system/app/Bloatware目录并执行setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/YouTube与setfattr -n trusted.overlay.opaque -v y $MODPATH/system/app/Bloatware。模块生效后这两个目录会被替换为空目录。::: tip 与 Magisk 的差异 KernelSU 采用 metamodule 架构挂载逻辑被委托给可插拔的 metamodule。官方meta-overlayfs使用内核 OverlayFS 实现 systemless 修改而 Magisk 使用内建于核心的 magic mountbind mount。两种实现方式差异很大但最终目标相同在不物理修改/system分区的前提下更改/system文件。 :::对 OverlayFS 感兴趣的话推荐阅读 Linux 内核的 OverlayFS 文档。system.prop此文件与build.prop格式相同每行由[key][value]组成。KernelSU 在启动时通过resetprop -n语义加载其中的属性源码见 load_system_prop它遍历所有启用模块的system.prop并交给resetprop::load_system_prop_file处理。sepolicy.rule如果你的模块需要额外的 sepolicy 补丁请将这些规则添加到该文件中文件中的每一行会被视为一条策略语句。源码 load_sepolicy_rule 会在 post-fs-data 阶段遍历启用模块并逐一应用sepolicy.rule单条失败只会告警而不会中断启动。initrc 注入 {#initrc-injection}KernelSU 提供将自定义 Android Init RC 指令注入系统init.rc的机制。这使得模块无需修改系统分区即可注册自定义 Android 服务、设置属性触发器或执行其他 Init 语言动作。工作原理启动过程中KernelSU 内核模块会拦截read()与fstat()系统调用。当 Android init 进程读取/system/etc/init/hw/init.rc时KernelSU 会把自定义 RC 内容透明地追加到文件末尾init 进程会像解析原始 init.rc 内容一样解析这些注入的指令。内核侧实现位于 kernel/runtime/ksud_integration.cksu_handle_sys_read仅对文件名为init.rc且路径为/system/etc/init/hw/init.rc的读取生效L405-L416随后通过read_proxy/read_iter_proxy在原始内容末尾追加modules.rcL285-L339。用户态侧ksud 将所有启用模块的.rc文件拼接为一个modules.rc文件存储在/metadata分区/metadata/ksu/modules.rc见 ksud_integration.c 与源码常量 PREINIT_DIR_DEFAULT。每当模块状态变化安装、启用、禁用、卸载等时该文件会自动重新生成对应 regenerate_preinit_rc。模块级 initrc 文件在模块目录中创建initrc/子目录并放入.rc文件/data/adb/modules/MODID/ ├── initrc/ │ ├── myservice.rc │ └── another.rc └── ...::: tip文件扩展名必须是.rc。只要模块处于启用状态initrc/目录中的全部.rc文件都会被包含不需要可执行权限。文件按目录内的文件名字母顺序处理模块按模块 ID 字母顺序处理。 :::这一排序行为与源码一致collect_rc_files 使用sort_by_key按文件名排序regenerate_preinit_rc使用BTreeMap按模块 ID 排序且modules_update/中的模块优先同 ID 冲突时新安装的模块胜出module.rs。通用 initrc 文件除模块级 RC 文件外还可以把.rc文件放在全局目录/data/adb/initrc.d/ ├── myservice.rc └── another.rc::: warning 通用 initrc 文件需要可执行权限 与模块的initrc/目录不同/data/adb/initrc.d/中的文件必须具有可执行权限才会被包含不可执行的.rc文件会被静默跳过。 :::通用initrc.d/文件会先于所有模块 RC 文件处理源码 regenerate_preinit_rc 首先收集initrc.d/且 collect_rc_files 对通用目录执行了is_executable检查。示例下面是一个注册自定义 Android 服务的.rc文件示例service myservice /data/adb/modules/mymodule/bin/myservice user root group root disabled seclabel u:r:ksu:s0 on property:sys.boot_completed1 start myservice将该文件放在/data/adb/modules/mymodule/initrc/myservice.rc后它会在启动时注册名为myservice的服务并在sys.boot_completed1时启动该服务。手动刷新可以使用以下命令手动触发modules.rc的重新生成更改将在下次启动时生效ksud initrc refresh::: tipinitrc 注入发生在启动流程的极早期init 读取 init.rc 时早于 post-fs-data 与任何模块脚本的执行。注入的 RC 内容会被 init 视为原始 init.rc 的一部分支持全部 Android Init 语言语法服务定义、触发器、属性设置等。initrc 注入在late-load 模式下不可用因为该模式未安装系统调用 hook。使用 ksud 给镜像打补丁时可通过传递--no-custom-rc参数禁用模块 RC 注入。 :::模块安装器Module InstallerKernelSU 模块安装器是一个打包为 ZIP 文件、可在 KernelSU Manager 中安装的 KernelSU 模块。最简单的模块安装器就是直接把模块打包成 ZIPmodule.zip │ ├── customize.sh ---可选详见下文 │ 此脚本会被 update-binary source加载执行 ├── ... ├── ... /* 模块的其余文件 */ │::: warning 警告 KernelSU 模块不支持在自定义 Recovery 中安装安装入口是 KernelSU Manager 应用对应 ksud 的 install_module 流程其会先校验sys.boot_completed1见 ensure_boot_completed。 :::自定义安装流程customize.sh如果需要自定义模块安装流程可以在安装器中创建名为customize.sh的脚本。该脚本会在所有文件解压完成、默认权限与 secontext 应用之后被模块安装器脚本source加载而非执行。当模块需要基于设备 ABI 进行额外配置或需要为部分模块文件设置特殊权限/secontext 时这非常有用。如果想要完全掌控并自定义安装流程可以在customize.sh中声明SKIPUNZIP1来跳过所有默认安装步骤。此时customize.sh需要负责安装所有内容。customize.sh运行在启用了 Standalone 模式的 KernelSU BusyBoxashshell 中见 exec_install_script通过busybox sh -c执行并注入公共环境变量。以下变量与函数可用变量KSU(bool)标记脚本运行在 KernelSU 环境中的变量值恒为true可用于区分 KernelSU 与 Magisk。KSU_VER(string)当前安装的 KernelSU 版本字符串如v0.4.0。KSU_VER_CODE(int)当前安装在用户空间的 KernelSU 版本代码如10672。KSU_KERNEL_VER_CODE(int)当前安装在内核空间的 KernelSU 版本代码如10672。BOOTMODE(bool)在 KernelSU 中恒为true。MODPATH(path)模块文件应安装到的路径。TMPDIR(path)可临时存放文件的位置。ZIPFILE(path)模块的安装 ZIP 文件。ARCH(string)设备的 CPU 架构取值arm、arm64、x86、x64之一。IS64BIT(bool)ARCH为arm64或x64时为true。API(int)设备的 API 级别Android 版本如 Android 6.0 为23。KSU_UAPI_VER(int)KernelSU 用户空间ksud的 UAPI 版本如2。当内核驱动有破坏性变更时该版本会递增模块可用它检查兼容性。KSU_RUNTIME_MODE(string)KernelSU 当前的运行模式取值built-in即 GKI 模式编译进内核、lkm启动时作为内核模块加载或late-load启动后作为内核模块加载。KSU_LATE_LOAD(int?)如果 KernelSU 在启动后被延迟加载此变量值为1否则不设置。以上变量的注入逻辑集中在 get_common_script_envs其中KSU_RUNTIME_MODE与KSU_LATE_LOAD来自内核侧ksucalls的实时查询KSU_UAPI_VER对应 ksu_uapi.rs 中的 UAPI 版本常量。::: warning 警告 在 KernelSU 中MAGISK_VER_CODE恒为25200MAGISK_VER恒为v25.2。请不要用这两个变量判断是否运行在 KernelSU 上。安装器源码 installer.sh 中确实会export MAGISK_VER25.2与MAGISK_VER_CODE25200仅为兼容依赖这些变量的旧脚本。 :::函数ui_print msg 向控制台打印 msg 避免使用 echo因为它不会显示在自定义 Recovery 的控制台中 abort msg 向控制台打印错误信息 msg 并终止安装 避免使用 exit因为它会跳过终止时的清理步骤 set_perm target owner group permission [context] 若 [context] 未设置默认值为 u:object_r:system_file:s0 该函数是以下命令的简写 chown owner.group target chmod permission target chcon context target set_perm_recursive directory owner group dirpermission filepermission [context] 若 [context] 未设置默认值为 u:object_r:system_file:s0 对 directory 中的所有文件执行 set_perm file owner group filepermission context 对 directory 中的所有目录包括自身执行 set_perm dir owner group dirpermission context这些函数的实际定义见 installer.shui_print、abort与 installer.shset_perm、set_perm_recursive。另外安装器默认会为$MODPATH设置0 0 0755 0644的权限并对system/bin、system/xbin、system/system_ext/bin、system/vendor设置0 2000 0755 0755及对应的 SELinux 上下文installer.sh并在安装完成后处理vendor、system_ext、product、odm分区的符号链接handle_partition。启动脚本 {#boot-scripts}在 KernelSU 中脚本按运行模式分为两类post-fs-data 模式与late_start service 模式。post-fs-data 模式阻塞式。执行完成或 10 秒超时之前启动过程会暂停。脚本在任何模块挂载之前运行模块开发者可以在模块被挂载前动态调整模块。此阶段发生在 Zygote 启动之前基本可抢在 Android 几乎所有流程之前执行。警告使用setprop会导致启动进程死锁请改用resetprop -n prop_name prop_value。仅在确实必要时才在该模式下运行命令。late_start service 模式非阻塞式。脚本与启动过程的其余部分并行运行。推荐大多数脚本在此模式运行。此外启动脚本按存放位置又分为通用脚本与模块脚本通用脚本存放在/data/adb/post-fs-data.d、/data/adb/service.d、/data/adb/post-mount.d或/data/adb/boot-completed.d。只有被设置为可执行chmod x script.sh时才会被执行。post-fs-data.d中的脚本以 post-fs-data 模式运行service.d中的脚本以 late_start service 模式运行。模块不应在安装时添加通用脚本。模块脚本存放在模块自己的文件夹中。仅当模块启用时才会执行。post-fs-data.sh以 post-fs-data 模式运行service.sh以 late_start service 模式运行boot-completed.sh在开机完成后运行post-mount.sh在 OverlayFS 挂载后运行。所有启动脚本都会在启用 Standalone 模式的 KernelSU BusyBoxashshell 中运行。源码中的执行顺序用户态的执行链在 init_event.rs 中非常清晰on_post_data_fs依次执行post-fs-data.d/通用脚本 → 处理模块更新与删除 →regenerate_preinit_rc→ 加载sepolicy.rule→metamodule 的post-fs-data.sh优先执行→ 普通模块的post-fs-data.sh→ 加载system.prop→ 执行 metamodule 挂载脚本OverlayFS→ 进入post-mount阶段。run_stage每个阶段都遵循通用.d脚本 → metamodule 阶段脚本 → 普通模块阶段脚本的固定顺序且可指定阻塞或非阻塞。on_services 与 on_boot_completed 分别触发service与boot-completed阶段。同时exec_common_scripts 对通用脚本目录中的每个文件执行is_executable检查不可执行的脚本会被跳过——这与文档中通用脚本需要chmod x的要求一一对应。Late-load 模式 {#late-load-mode}除了上述标准启动流程KernelSU 还针对 LKM可加载内核模块场景支持late-load 模式。在此模式下KernelSU 内核模块不是在 init 过程中加载而是在系统完全启动后加载。late-load 何时发生通过运行ksud late-load命令触发。该命令会检测当前 KMI 版本并从内置资源中加载对应的kernelsu.ko执行通常会在启动时进行的模块初始化SELinux 规则、允许列表、特性等。由于系统已完全运行部分启动时机制不可用或不必要。源码流程见 late_load.rs检测 KMI → 从内存加载kernelsu.ko→handle_updated_modules/prune_modules/restorecon→ 加载 sepolicy → 初始化特性 → 依次运行各阶段脚本。与标准启动的差异行为标准启动Late-load 模式内核模块由 initPID 1加载是否启动后加载initrc 注入将模块.rc文件插入 init.rc是不可用ksud 的 kprobe hookexecve/read/fstat/input是跳过安全模式检测音量键是始终禁用启动日志捕获logcat/dmesg是跳过Magisk 共存检查是跳过向内核上报post-fs-data事件是跳过向内核上报boot-completed事件是初始化时直接设置post-fs-data.sh/post-fs-data.d/脚本是由late-load阶段替代system.prop加载是是OverlayFS 挂载metamodule是是post-mount.sh/post-mount.d/脚本是是service.sh/service.d/脚本是是boot-completed.sh/boot-completed.d/脚本是是环境变量KSU_LATE_LOAD未设置设为1内核 info 标志0x4未设置已设置脚本执行顺序late-load 模式下的脚本执行顺序如下ksud late-load: 1. 加载 kernelsu.ko若尚未加载 2. 展开二进制、处理模块更新、加载 SELinux 规则、初始化特性 3. 执行 late-load.d/ 通用脚本与模块 late-load 脚本阻塞 4. 加载 system.propresetprop -n 5. 执行 metamodule 挂载脚本OverlayFS 6. 执行 post-mount.d/ 通用脚本与模块 post-mount.sh阻塞 7. 执行 service.d/ 通用脚本与模块 service.sh非阻塞 8. 执行 boot-completed.d/ 通用脚本与模块 boot-completed.sh非阻塞这与 late_load.rs 中的实现完全一致init_event::run_stage(late-load, true)→load_system_prop()→metamodule::exec_mount_script(...)→run_stage(post-mount, true)→run_stage(service, false)→run_stage(boot-completed, false)。Late-load 专用脚本模块可以提供late-load.sh脚本它仅在 late-load 模式下运行作为post-fs-data.sh的替代品。该脚本在 OverlayFS 挂载前执行时机与标准流程中的post-fs-data.sh类似。此外可以将通用脚本放在/data/adb/late-load.d/中以便在此阶段运行。在脚本中检测 late-load 模式模块可以通过检查环境变量KSU_LATE_LOAD来检测是否处于 late-load 模式if [ $KSU_LATE_LOAD 1 ]; then # 正在 late-load 模式下运行 echo Late-load mode detected fi这使模块可以相应地调整自身行为例如跳过仅在早期启动时才需要的操作。该变量由 get_common_script_envs 在检测到内核为 late-load 状态时注入。从文档到源码模块开发者的完整认知闭环至此KernelSU 模块机制的核心脉络已经清晰身份与元数据module.propid/versionCode/actionIcon/webuiIcon等决定模块能否被识别、如何展示校验逻辑在 module.rs内容与挂载system目录通过 metamoduleOverlayFS叠加REMOVE/REPLACE控制 whiteout 与 opaque处理逻辑在 installer.sh运行时行为post-fs-data.sh/service.sh/post-mount.sh/boot-completed.sh/late-load.sh按阶段由 init_event.rs 与 late_load.rs 编排执行系统级注入sepolicy.rule、system.prop、initrc/分别通过 sepolicy 加载、resetprop 与内核 read/fstat hookksud_integration.c生效。如需继续深入可进一步阅读本仓库与模块机制配套的文档模块配置系统、WebUI 开发、Metamodule 架构 与 与 Magisk 的差异以及用户态核心实现 module.rs 与安装器脚本 installer.sh。【免费下载链接】KernelSUA Kernel based root solution for Android项目地址: https://gitcode.com/GitHub_Trending/ke/KernelSU创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考