8.4 KiB
Developer Guides
Please read through Magisk Details before reading the following guides. If you are developing a module, pay extra attention to the Magic Mount section.
Magisk Modules
A Magisk module is a folder placed in /data/adb/modules
with a structure below:
/data/adb/modules
├── .
├── .
|
├── $MODID <--- The folder is named with the ID of the module
│ │
│ │ *** Module Identity ***
│ │
│ ├── module.prop <--- This files stores the metadata of the module
│ │
│ │ *** Status files ***
│ │
│ ├── skip_mount <--- If exists, Magisk will NOT mount your files
│ ├── disable <--- If exists, the module will be disabled
│ ├── remove <--- If exists, the module will be removed next reboot
│ │
│ │ *** Scripts ***
│ │
│ ├── post-fs-data.sh <--- This script will be executed in post-fs-data
│ ├── service.sh <--- This script will be executed in late_start service
| ├── uninstall.sh <--- This script will be executed when Magisk removes your module
│ │
│ │ *** Resetprop Files ***
│ │
│ ├── system.prop <--- This file will be loaded as system properties by resetprop
│ │
│ │ *** Module contents ***
│ │
│ ├── system <--- This folder will be Magic Mounted if skip_mount does not exists
│ │ ├── .
│ │ ├── .
│ │ └── .
│ │
│ │ *** Auto Generated by Magisk ***
│ │
│ ├── vendor <--- A symlink to $MODID/system/vendor
│ ├── product <--- A symlink to $MODID/system/product
│ │
│ │ *** Others ***
│ │
│ ├── . <--- Any additional files / folders are allowed
│ └── .
|
├── another_module
│ ├── .
│ └── .
├── .
├── .
As long as a folder follows the structure above, it will be recognized as a module.
Here is the strict format of module.prop
:
id=<string>
name=<string>
version=<string>
versionCode=<int>
author=<string>
description=<string>
id
has to match this regular expression:^[a-zA-Z][a-zA-Z0-9._-]+$
ex: ✓a_module
, ✓a.module
, ✓module-101
, ✗a module
, ✗1_module
, ✗-a-module
This is the unique identifier of your module. You should not change it once published.versionCode
has to be an integer. This is used to compare versions- Others that isn't mentioned above can be any single line string.
Magisk Module Installer
The official Magisk Module installer is hosted here.
That repo is a starting point for creating a Magisk module installer zip. Here are some details:
- You will found out that
META-INF/com/google/android/update-binary
is a dummy file. If you are creating a module locally for personal usage or testing, download the latest installermodule_installer.sh
and replaceupdate-binary
with the script - The next thing to do is to modify
module.prop
to provide information about your module - Finally, modify
install.sh
to fit your need. The script is heavily documented so you should know what to do. - (Optional) If you want to run custom uninstallation logic when your module is removed, add a new file
uninstall.sh
to the root of the installer - Windows users aware!! The line endings of all text files should be in the Unix format. Please use advanced text editors like Sublime, Atom, Notepad++ etc. to edit ALL text files, NEVER use Windows Notepad.
Submit Modules
You can submit a module to Magisk-Module-Repo so users can download your module directly in Magisk Manager. Before submitting, follow the instructions in the previous section to create a valid installer for your module. You can then create a request for submission via this link: submission.
- When your module is downloaded with Magisk Manager,
META-INF/com/google/android/update-binary
will be forcefully replaced with the latestmodule_installer.sh
to make sure all installation uses the latest scripts. - Since
update-binary
will be replaced, this means that all modules in the repo are expected to follow how the installation framework works: the installation framework will load yourinstall.sh
script and run the corresponding callbacks. - This also means that you should NOT add custom logic in
update-binary
as they will simply be ignored.
Boot Scripts
In Magisk, you can run boot scripts in 2 different modes: post-fs-data and late_start service mode.
- post-fs-data mode
- This stage is BLOCKING. Boot process is paused before execution is done, or 10 seconds has passed.
- Scripts run before any modules are mounted. This allows a module developer to dynamically adjust their modules before it gets mounted.
- This stage happens before Zygote is started, which pretty much means everything in Android
- Run scripts in this mode only if necessary!
- late_start service mode
- This stage is NON-BLOCKING. Your script runs in parallel along with the booting process.
- This is the recommended stage to run most scripts!
In Magisk, there are also 2 kinds of scripts: general scripts and module scripts.
- General Scripts
- Placed in
/data/adb/post-fs-data.d
or/data/adb/service.d
- Only executed if the script is executable (execution permissions,
chmod +x script.sh
) - Scripts in
post-fs-data.d
runs in post-fs-data mode, and scripts inservice.d
runs in late_start service mode. - Will still be executed when Core-Only mode is enabled.
- Modules should NOT add general scripts since it violates encapsulation
- Placed in
- Module Scripts
- Placed in the folder of the module
- Only executed if the module is enabled
post-fs-data.sh
runs in post-fs-data mode, andservice.sh
runs in late_start service mode.- Will NOT be executed when Core-Only mode is enabled (all modules are disabled)
- Modules require boot scripts should ONLY use module scripts instead of general scripts
Magisk's internal busybox's path $BBPATH
is always prepended in PATH
. This means all commands you call in scripts are always using busybox unless the applet is not included. This makes sure that your script always run in a predictable environment and always have the full suite of commands regardless of which Android version it is running on.
Root Directory Overlay System
Since /
is read-only in system-as-root devices, Magisk provides an overlay system, allowing developers to patch files / add new rc scripts. Additional files shall be placed in the overlay.d
folder in the ramdisk, and they will have the following restrictions:
- All
*.rc
files inoverlay.d
will be read and concatenated AFTERinit.rc
- Replacing existing files are allowed.
e.g. you can replace/res/random.png
by adding the fileoverlay.d/res/random.png
- Non-existing files will be ignored (with exceptions detailed in the next point).
e.g.overlay.d/new_file
will be ignored if/new_file
does not exist - Additional files in
overlay.d/sbin
is allowed as they will be copied into Magisk's sbin overlay.
e.g.overlay.d/sbin/libfoo.ko
will be copied to/sbin/libfoo.ko
.
Remove Files
How to remove a file systemless-ly? To actually make the file disappear is complicated (possible, not worth the effort). Replacing it with a dummy file should be good enough! Create an empty file with the same name and place it in the same path within a module, it shall replace your target file with a dummy file.
Remove Folders
Same as mentioned above, actually making the folder disappear is not worth the effort. Replacing it with an empty folder should be good enough! A handy trick for module developers is to add the folder you want to remove into the REPLACE
list within install.sh
. If your module doesn't provide a corresponding folder, it will create an empty folder, and automatically add .replace
into the empty folder so the dummy folder will properly replace the one in /system
.