### Example metamount.sh Script Source: https://kernelsu.org/guide/metamodule.html This example `metamount.sh` script demonstrates a simple bind mount implementation, iterating through modules and mounting their system directories if not disabled or skipped. It correctly sets the source to KSU. ```shell #!/system/bin/sh MODDIR="${0%/*}" # Example: Simple bind mount implementation for module in /data/adb/modules/*; do if [ -f "$module/disable" ] || [ -f "$module/skip_mount" ]; then continue fi if [ -d "$module/system" ]; then # Mount with source=KSU (REQUIRED!) mount -o bind,dev=KSU "$module/system" /system fi done ``` -------------------------------- ### Kernel Version Format Example Source: https://kernelsu.org/guide/installation.html Illustrates the expected format for kernel release versions, highlighting the components that constitute the Kernel Module Interface (KMI) version. ```txt KernelRelease := Version.PatchLevel.SubLevel-AndroidRelease-KmiGeneration-suffix w .x .y -zzz -k -something ``` -------------------------------- ### Terminate Installation with Error Message Source: https://kernelsu.org/guide/module.html Use `abort` to display an error message and terminate the installation gracefully, ensuring cleanup steps are performed. Avoid using `exit`. ```shell abort ``` -------------------------------- ### Define Custom SELinux Domain and Rules Source: https://kernelsu.org/guide/app-profile.html This example demonstrates how to define a custom SELinux domain 'app1' and set basic 'allow' rules. Note that the broad 'allow app1 * * *' rule is for demonstration and not recommended for production. ```sh type app1 enforce app1 typeattribute app1 mlstrustedsubject allow app1 * * * ``` -------------------------------- ### KernelSU Module Installer Structure Source: https://kernelsu.org/guide/module.html A basic KernelSU module installer is a ZIP file containing module files and an optional customize.sh script. ```txt module.zip │ ├── customize.sh <--- (Optional, more details later) │ This script will be sourced by update-binary ├── ... ├── ... /* The rest of module's files */ │ ``` -------------------------------- ### Add KernelSU Support (Main Branch) Source: https://kernelsu.org/guide/how-to-build.html Integrate the development version (main branch) of KernelSU into your kernel source by downloading and running the setup script with the 'main' argument. ```bash curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s main ``` -------------------------------- ### Install AnyKernel3 ZIP via ADB Sideload Source: https://kernelsu.org/guide/installation.html Install the AnyKernel3 ZIP package on a device with a custom recovery (like TWRP) using ADB sideload. This method is suitable for initial installations and upgrades. ```bash adb sideload AnyKernel-*.zip ``` -------------------------------- ### Add KernelSU Support (Latest Tag) Source: https://kernelsu.org/guide/how-to-build.html Integrate the latest stable version of KernelSU into your kernel source by downloading and running the setup script. ```bash curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash - ``` -------------------------------- ### Add KernelSU Support (Specific Tag) Source: https://kernelsu.org/guide/how-to-build.html Integrate a specific version (e.g., v0.5.2) of KernelSU into your kernel source by downloading and running the setup script with the desired tag. ```bash curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.5.2 ``` -------------------------------- ### Example metauninstall.sh Script Source: https://kernelsu.org/guide/metamodule.html This `metauninstall.sh` script serves as a cleanup hook for when regular modules are uninstalled. It receives the `MODULE_ID` of the uninstalled module and can perform custom cleanup tasks. ```shell #!/system/bin/sh # Called when uninstalling regular modules MODULE_ID="$1" IMG_MNT="/data/adb/metamodule/mnt" ``` -------------------------------- ### Example ADB Shell ID Command Output Source: https://kernelsu.org/guide/app-profile.html This output from the 'id' command in ADB shell illustrates user and group IDs, along with supplementary groups that define specific permissions like network access or SD card read/write. ```shell oriole:/ $ id uid=2000(shell) gid=2000(shell) groups=2000(shell),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),1078(ext_data_rw),1079(ext_obb_rw),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid),3012(readtracefs) context=u:r:shell:s0 ``` -------------------------------- ### Standard Android Boot Process with KernelSU Source: https://kernelsu.org/guide/module.html Illustrates the sequence of operations during an Android boot, highlighting KernelSU's integration points and script execution stages like post-fs-data, service, and boot-completed. ```text 0. Bootloader (nothing on screen) load patched boot.img load kernel: - GKI mode: GKI kernel with KernelSU integrated - LKM mode: stock kernel ... 1. kernel exec init (OEM logo on screen): - GKI mode: stock init - LKM mode: exec ksuinit, insmod kernelsu.ko, exec stock init mount /dev, /dev/pts, /proc, /sys, etc. property-init -> read default props read init.rc ... early-init -> init -> late_init early-fs start vold fs mount /vendor, /system, /persist, etc. post-fs-data *safe mode check *execute general scripts in post-fs-data.d/ *load sepolicy.rule *execute metamodule's post-fs-data.sh (if exists) *execute module scripts post-fs-data.sh **(Zygisk)./bin/zygisk-ptrace64 monitor *(pre)load system.prop (same as resetprop -n) *execute metamodule's metamount.sh (mounts all modules) *execute general scripts in post-mount.d/ *execute metamodule's post-mount.sh (if exists) *execute module scripts post-mount.sh zygote-start load_all_props_action *execute resetprop (actual set props for resetprop with -n option) ... -> boot class_start core start-service logd, console, vold, etc. class_start main start-service adb, netd (iptables), zygote, etc. 2. kernel2user init (ROM animation on screen, start by service bootanim) *execute general scripts in service.d/ *execute metamodule's service.sh (if exists) *execute module scripts service.sh *set props for resetprop without -p option **(Zygisk) hook zygote (start zygiskd) **(Zygisk) mount zygisksu/module.prop start system apps (autostart) ... boot complete (broadcast ACTION_BOOT_COMPLETED event) *execute general scripts in boot-completed.d/ *execute metamodule's boot-completed.sh (if exists) *execute module scripts boot-completed.sh 3. User operable (lock screen) input password to decrypt /data/data *actual set props for resetprop with -p option start user apps (autostart) ``` -------------------------------- ### Sync Kernel Source Code Source: https://kernelsu.org/guide/how-to-build.html Initialize the kernel manifest, set the manifest file, and sync the repository. Ensure you use the correct manifest.xml for reproducible builds. ```bash repo init -u https://android.googlesource.com/kernel/manifest mv .repo/manifests repo init -m manifest.xml repo sync ``` -------------------------------- ### Display ksud boot-patch help Source: https://kernelsu.org/guide/installation.html Use this command to view all available options and their descriptions for patching boot images with ksud. ```sh ksud boot-patch -h ``` -------------------------------- ### Metamodule File Structure Source: https://kernelsu.org/guide/metamodule.html A typical metamodule includes `module.prop` and optional hook scripts like `metamount.sh`, `metainstall.sh`, and `metauninstall.sh`, alongside standard module files. ```plaintext meta-example/ ├── module.prop (must include metamodule=1) │ │ *** Metamodule-specific hooks *** ├── metamount.sh (optional: custom mount handler) ├── metainstall.sh (optional: installation hook for regular modules) ├── metauninstall.sh (optional: cleanup hook for regular modules) │ │ *** Standard module files (all optional) *** ├── customize.sh (installation customization) ├── post-fs-data.sh (post-fs-data stage script) ├── service.sh (late_start service script) ├── boot-completed.sh (boot completed script) ├── uninstall.sh (metamodule's own uninstallation script) └── [any additional files] ``` -------------------------------- ### Meta-overlayfs metamount.sh Implementation Source: https://kernelsu.org/guide/metamodule.html This script handles mounting the ext4 image for the meta-overlayfs metamodule. It ensures the image is mounted read-write and sets environment variables for dual-directory support before executing the main binary. ```shell #!/system/bin/sh MODDIR="${0%/*}" IMG_FILE="$MODDIR/modules.img" MNT_DIR="$MODDIR/mnt" # Mount ext4 image if not already mounted if ! mountpoint -q "$MNT_DIR"; then mkdir -p "$MNT_DIR" mount -t ext4 -o loop,rw,noatime "$IMG_FILE" "$MNT_DIR" fi # Set environment variables for dual-directory support export MODULE_METADATA_DIR="/data/adb/modules" export MODULE_CONTENT_DIR="$MNT_DIR" # Execute the mount binary # (The actual mounting logic is in a Rust binary) "$MODDIR/meta-overlayfs" ``` -------------------------------- ### Manage Module Configuration - KernelSU Source: https://kernelsu.org/guide/module-config.html Use the `ksud module config` commands to manage your module's configuration. Temporary values take priority over persistent values for the same key. Configurations are stored in `/data/adb/ksu/module_configs//`. ```bash # Get a configuration value value=$(ksud module config get my_setting) ``` ```bash # Set a persistent configuration value ksud module config set my_setting "some value" ``` ```bash # Set a temporary configuration value (cleared on reboot) ksud module config set --temp runtime_state "active" ``` ```bash # Set value from stdin (useful for multiline or complex data) ksud module config set my_key < ``` -------------------------------- ### Set File Permissions and Context Source: https://kernelsu.org/guide/module.html A shorthand function to set file ownership, permissions, and SELinux context. If context is omitted, it defaults to `u:object_r:system_file:s0`. ```shell set_perm [context] ``` -------------------------------- ### Build aarch64 Kernel Image Source: https://kernelsu.org/guide/how-to-build.html Build an aarch64 kernel image using the provided script. The LTO=thin flag is recommended, especially if your system has limited memory (less than 24 GB). ```bash LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh ``` -------------------------------- ### KernelSU Module Structure Source: https://kernelsu.org/guide/module.html Defines the standard directory structure for a KernelSU module. Includes essential files like module.prop and optional scripts for various boot stages. ```txt /data/adb/modules ├── $MODID <--- The folder is named with the ID of the module │ │ │ │ *** Module Identity *** │ │ │ ├── module.prop <--- This file stores the metadata of the module │ │ │ │ *** Main Contents *** │ │ │ ├── system <--- This folder will be mounted if skip_mount does not exist │ │ ├── ... │ │ ├── ... │ │ └── ... │ │ │ │ *** Status Flags *** │ │ │ ├── skip_mount <--- If exists, KernelSU will NOT mount your system folder │ ├── disable <--- If exists, the module will be disabled │ ├── remove <--- If exists, the module will be removed next reboot │ │ │ │ *** Optional Files *** │ │ │ ├── post-fs-data.sh <--- This script will be executed in post-fs-data │ ├── post-mount.sh <--- This script will be executed in post-mount │ ├── service.sh <--- This script will be executed in late_start service │ ├── boot-completed.sh <--- This script will be executed on boot completed | ├── uninstall.sh <--- This script will be executed when KernelSU removes your module | ├── action.sh <--- This script will be executed when user click the Action button in KernelSU app │ ├── system.prop <--- Properties in this file will be loaded as system properties by resetprop │ ├── sepolicy.rule <--- Additional custom sepolicy rules │ │ │ │ *** Auto Generated, DO NOT MANUALLY CREATE OR MODIFY *** │ │ │ ├── vendor <--- A symlink to $MODID/system/vendor │ ├── product <--- A symlink to $MODID/system/product │ ├── system_ext <--- A symlink to $MODID/system/system_ext │ │ │ │ *** Any additional files / folders are allowed *** │ │ │ ├── ... │ └── ... │ ├── another_module │ ├── . │ └── . ├── . ├── . ``` -------------------------------- ### Integrate KernelSU into fs/devpts/inode.c Source: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Add KernelSU integration to the `devpts_get_priv` function in `fs/devpts/inode.c`. This is necessary if you encounter issues executing `pm` in the terminal. ```diff diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 32f6f1c68..d69d8eca2 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -602,6 +602,8 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) return dentry; } +#ifdef CONFIG_KSU +extern int ksu_handle_devpts(struct inode*); +#endif + /** * devpts_get_priv -- get private data for a slave * @pts_inode: inode of the slave @@ -610,6 +612,7 @@ struct dentry *devpts_pty_new(struct pts_fs_info *fsi, int index, void *priv) */ void *devpts_get_priv(struct dentry *dentry) { + #ifdef CONFIG_KSU + ksu_handle_devpts(dentry->d_inode); + #endif if (dentry->d_sb->s_magic != DEVPTS_SUPER_MAGIC) return NULL; return dentry->d_fsdata; ``` -------------------------------- ### Module Structure with Web Interface Source: https://kernelsu.org/guide/module-webui.html This is the basic directory structure for a KernelSU module that includes a web interface. Ensure the `webroot` directory contains an `index.html` file. ```plaintext . |-- module.prop `-- webroot `-- index.html ``` -------------------------------- ### module.prop Configuration Source: https://kernelsu.org/guide/module.html Specifies the required metadata format for the module.prop file. Ensures correct syntax for module identification and properties. ```properties id= name= version= versionCode= author= description= updateJson= (optional) actionIcon= (optional) webuiIcon= (optional) ``` -------------------------------- ### Add KernelSU Hooks to open.c Source: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Integrates KernelSU hooks into the faccessat system call handler in fs/open.c. This allows KernelSU to manage file access permissions. ```c #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) { const struct cred *old_cred; struct cred *override_cred; struct path path; struct inode *inode; struct vfsmount *mnt; int res; unsigned int lookup_flags = LOOKUP_FOLLOW; #ifdef CONFIG_KSU ksu_handle_faccessat(&dfd, &filename, &mode, NULL); #endif if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; ``` -------------------------------- ### Repack boot.img with magiskboot on Android Source: https://kernelsu.org/guide/installation.html After replacing the kernel file, use this command to repack the boot.img on an Android device. The output is a new bootable image. ```bash ./magiskboot repack boot.img ``` -------------------------------- ### Reboot device after flashing Source: https://kernelsu.org/guide/installation.html Execute this command after successfully flashing the boot.img to reboot the device and apply the changes. ```sh fastboot reboot ``` -------------------------------- ### Build Kernel with Bazel (Android 13+) Source: https://kernelsu.org/guide/how-to-build.html Build the kernel using Bazel for Android 13 and later versions. This command builds the aarch64 distribution. ```bash tools/bazel build --config=fast //common:kernel_aarch64_dist ``` -------------------------------- ### Set Source String for Modern Mount APIs Source: https://kernelsu.org/guide/metamodule.html For modern mount APIs, use `fsconfig_set_string` to set the source string to "KSU". This ensures KernelSU can correctly identify and manage the mount. ```rust fsconfig_set_string(fs, "source", "KSU")?; ``` -------------------------------- ### Add KernelSU faccessat Handler Source: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html This code snippet adds the necessary KSU handler for the `faccessat` syscall in older kernels. Ensure `CONFIG_KSU` is enabled. ```c #ifdef CONFIG_KSU extern int ksu_handle_faccessat(int *dfd, const char __user **filename_user, int *mode, int *flags); #endif ``` ```c #ifdef CONFIG_KSU ksu_handle_faccessat(&dfd, &filename, &mode, NULL); #endif ``` -------------------------------- ### Enable KernelSU Safe Mode in input.c Source: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Modify the `input_handle_event` function to include KernelSU's safe mode hook. This is recommended for preventing bootloops. ```diff diff --git a/drivers/input/input.c b/drivers/input/input.c index 45306f9ef247..815091ebfca4 100755 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -367,10 +367,13 @@ static int input_get_disposition(struct input_dev *dev, return disposition; } +#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) { int disposition = input_get_disposition(dev, type, code, &value); + #ifdef CONFIG_KSU + if (unlikely(ksu_input_hook)) + ksu_handle_input_handle_event(&type, &code, &value); + #endif if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN) add_input_randomness(type, code, value); ``` -------------------------------- ### Unpack boot.img with magiskboot on Android Source: https://kernelsu.org/guide/installation.html Use this command to unpack the boot.img file on an Android device using magiskboot. This extracts the kernel file, which can then be replaced. ```bash adb push Magisk-*/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot cd /data/local/tmp/ chmod +x magiskboot ./magiskboot unpack boot.img ``` -------------------------------- ### Add KernelSU to Kernel Source Tree (v0.9.5) Source: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Use this command to add KernelSU to your kernel source tree. Ensure you specify version v0.9.5 for non-GKI compatibility, as later versions do not support non-GKI kernels. ```sh curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5 ``` -------------------------------- ### Patch boot image with KernelSU Source: https://kernelsu.org/guide/installation.html This is the most common usage for patching a boot image. Specify the boot image path and the KMI version. ```sh ksud boot-patch -b --kmi android13-5.10 ``` -------------------------------- ### Correct Mount Operation with KSU Source Source: https://kernelsu.org/guide/metamodule.html When performing mount operations within `metamount.sh`, ensure the source/device name is set to "KSU" to identify KernelSU mounts. This is a critical requirement for proper management. ```shell mount -t overlay -o lowerdir=/lower,upperdir=/upper,workdir=/work KSU /target ``` -------------------------------- ### KernelSU Late-load Mode Script Execution Order Source: https://kernelsu.org/guide/module.html Details the sequence of operations when KernelSU is loaded in late-load mode, after the system has fully booted. This includes loading the kernel module, initializing features, and executing specific scripts. ```text ksud late-load: 1. Load kernelsu.ko (if not already loaded) 2. Extract binaries, handle module updates, load SELinux rules, init features 3. Execute late-load.d/ and module late-load scripts (blocking) 4. Load system.prop (resetprop -n) 5. Execute metamodule mount script (OverlayFS) 6. Execute post-mount.d/ and module post-mount.sh (blocking) 7. Execute service.d/ and module service.sh (non-blocking) 8. Execute boot-completed.d/ and module boot-completed.sh (non-blocking) ``` -------------------------------- ### Add KernelSU Hooks to read_write.c Source: https://kernelsu.org/guide/how-to-integrate-for-non-gki.html Integrates KernelSU hooks into the vfs_read system call handler in fs/read_write.c. This allows KernelSU to intercept and manage read operations. ```c #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) { ssize_t ret; #ifdef CONFIG_KSU if (unlikely(ksu_vfs_read_hook)) ksu_handle_vfs_read(&file, &buf, &count, &pos); #endif if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) ``` -------------------------------- ### Enable ASH Standalone Mode with Command-line Option Source: https://kernelsu.org/guide/module.html Alternatively, ASH Standalone Mode can be toggled using the '-o standalone' command-line option when executing BusyBox. ```bash /data/adb/ksu/bin/busybox sh -o standalone