Commit fbb4f85e authored by topjohnwu's avatar topjohnwu

Update documentation

parent 716f0684
......@@ -24,7 +24,7 @@ Here are some feature highlights:
## Useful Links
- [Installation Instruction](https://topjohnwu.github.io/Magisk/install.html)
- [OTA Upgrade Guide](https://topjohnwu.github.io/Magisk/ota.html)
- [Frequently Asked Questions](https://topjohnwu.github.io/Magisk/faq.html)
- [Full Official Docs](https://topjohnwu.github.io/Magisk/)
- [Magisk Troubleshoot Wiki](https://www.didgeridoohan.com/magisk/HomePage) (by [@Didgeridoohan](https://github.com/Didgeridoohan))
......
# Magisk Documentation
(Updated on 2020.3.23)
(Updated on 2020.10.2)
- [Installation Instructions](install.md)
- [OTA Upgrade Guides](ota.md)
- [Frequently Asked Questions](faq.md)
The following sections are for developers
......
......@@ -30,12 +30,12 @@ Method | Initial rootdir | Final rootdir
- Devices that does not fall in any of Method B and C's criteria
- **Method B - Legacy SAR**: This method was first seen on Pixel 1. The kernel directly mounts the `system` partition as rootdir and exec `/init` to boot.
- Devices with `(LV = 28)`
- Google: Pixel 1 and 2. Pixel 3 and 3a with `(RV = 28)` only.
- OnePlus: 5T - 7
- Google: Pixel 1 and 2. Pixel 3 and 3a when `(RV = 28)`.
- OnePlus: 6 - 7
- Maybe some `(LV < 29)` Android Go devices?
- **Method C - 2SI ramdisk SAR**: This method was first seen on Pixel 3 Android 10 developer preview. The kernel uses `initramfs` as rootdir and exec `/init` in `rootfs`. This `init` is responsible to mount the `system` partition and use it as the new rootdir, then finally exec `/system/bin/init` to boot.
- Devices with `(LV >= 29)`
- Devices with `(LV < 28, RV >= 29)`, excluding exceptions that were using Method B
- Devices with `(LV < 28, RV >= 29)`, excluding those that were already using Method B
- Google: Pixel 3 and 3a with `(RV >= 29)`
### Discussion
......@@ -47,7 +47,7 @@ However for Magisk, the real difference lies in what the device ends up using wh
The criteria for Method C is a little complicated, in layman's words: either your device is modern enough to launch with Android 10+, or you are running an Android 10+ custom ROM on a device that was using Method A.
- Any Method A device running Android 10+ will automatically be using Method C
- **Method B devices are stuck with Method B**, maybe only with the exception of Pixel 3 and 3a, which Google retrofitted the device to adapt the new method.
- **Method B devices are stuck with Method B**, with the only exception being Pixel 3 and 3a, which Google retrofitted the device to adapt the new method.
SAR is a very important part of [Project Treble](https://source.android.com/devices/architecture#hidl) as rootdir should be tied to the platform. This is also the reason why Method B and C comes with `(LV >= ver)` criterion as Google has enforced all OEMs to comply with updated requirements every year.
......@@ -57,7 +57,9 @@ When Google released the first generation Pixel, it also introduced [A/B (Seamle
Let's go back in time when Google is first designing A/B. If using SAR (only Boot Method B exists at that time), the kernel doesn't need `initramfs` to boot Android (because rootdir is in `system`). This mean we can be smart and just stuff the recovery ramdisk (containing the minimalist Linux environment) into `boot`, remove `recovery`, and let the kernel pick whichever rootdir to use (ramdisk or `system`) based on information from the bootloader.
As time passed from Android 7.1 to Android 10, Google introduced [Dynamic Partitions](https://source.android.com/devices/tech/ota/dynamic_partitions/implement). This is bad news for SAR, because the Linux kernel cannot understand this new partition format, thus unable to directly use `system` as rootdir. This is when they came up with Boot Method C: always boot into `initramfs`, and let userspace handle the rest of booting.
As time passed from Android 7.1 to Android 10, Google introduced [Dynamic Partitions](https://source.android.com/devices/tech/ota/dynamic_partitions/implement). This is bad news for SAR, because the Linux kernel cannot directly understand this new partition format, thus unable to directly mount `system` as rootdir. This is when they came up with Boot Method C: always boot into `initramfs`, and let userspace handle the rest of booting. This includes deciding whether to boot into Android or recovery, or as they officially call: `USES_RECOVERY_AS_BOOT`.
Some modern devices using A/B with 2SI also comes with `recovery_a/_b` partitions. This is officially supported with Google's standard. These devices will then only use the boot ramdisk to boot into Android as recovery is stored on a separate partition.
## Piecing Things Together
......@@ -66,10 +68,9 @@ With all the knowledge above, now we can categorize all Android devices into the
Type | Boot Method | Partition | 2SI | Ramdisk in `boot`
:---: | :---: | :---: | :---: | :---:
**I** | A | A-only | No | `boot` ramdisk
**II** | B | A/B | No | `recovery` ramdisk
**III** | B | A-only | No | ***N/A***
**II** | B | A/B | Any | `recovery` ramdisk
**III** | B | A-only | Any | ***N/A***
**IV** | C | Any | Yes | Hybrid ramdisk
**II\* / III\*** | B | II / III | Yes | II / III
These types are ordered chronologically by the time they were first available.
......@@ -77,8 +78,7 @@ These types are ordered chronologically by the time they were first available.
- **Type II**: Legacy A/B devices. Pixel 1 is the first device of this type, being both the first A/B and SAR device
- **Type III**: Late 2018 - 2019 devices that are A-only. **The worst type of device to ever exist as far as Magisk is concerned.**
- **Type IV**: All devices using Boot Method C are Type IV. A/B Type IV ramdisk can boot into either Android or recovery based on info from bootloader; A-only Type IV ramdisk can only boot into Android.
- **Type \***: Type II* and III* are Boot Method B devices running on Android 10+ (2SI). **They are NOT new device types**. In Magisk the code treat them drastically different due to complicated reasons, hence mentioning them here.
Further details on Type III devices: Magisk is always installed in the ramdisk of a boot image. For all other device types, because their `boot` partition have ramdisk included, Magisk can be easily installed by patching boot image through Magisk Manager or flash zip in custom recovery. However for Type III devices, they are **limited to install Magisk into the `recovery` partition**. Magisk will not function when booted normally; instead Type III device owners have to always reboot to recovery to maintain Magisk access.
Some Type III devices' bootloader will still accept and provide `initramfs` manually added to `boot` image to the kernel (e.g. some Xiaomi phones), but many device don't (e.g. Samsung S10, Note 10). It solely depends on how the OEM implements its bootloader.
Some Type III devices' bootloader will still accept and provide `initramfs` that was manually added to the `boot` image to the kernel (e.g. some Xiaomi phones), but many device don't (e.g. Samsung S10, Note 10). It solely depends on how the OEM implements its bootloader.
# Deployment
(Note: This is not a user tutorial for installing Magisk, this is an explaination of how Magisk can be installed, and a guide for developers to properly deploy Magisk in various different situations)
(Note: This is not a user tutorial for installing Magisk, this is an explanation of how Magisk can be installed, and a guide for developers to properly deploy Magisk in various different situations)
## Systemless
When a user flashes a Magisk zip in custom recoveries or have boot images patched in Magisk Manager, Magisk is installed in the systemless fashion. This is the only officially supported method to install Magisk on a device. The systemless method installs Magisk into a boot image's ramdisk CPIO, sometimes require additional patches to the kernel.
......
This diff is collapsed.
# Frequently Asked Questions
### Q: Why is X app detecting root?
Manually enable MagiskHide in settings (MagiskHide is no longer enabled by default). Also, there are known methods to detect Magisk, so your mileage may vary.
### Q: I installed a module and it bootlooped my device. Help!
If you have USB debugging enabled in developer options, connect your phone to the PC. If your device is detected (check by `adb devices`), enter ADB shell and run the command `magisk --remove-modules`. This will remove all your modules and automatically reboot the device.
If unfortunately you do not have USB debugging enabled, reboot into Safe Mode. Most modern Android devices support pressing a special key combo at boot to enter Safe Mode as an emergency option. Magisk will detect Safe Mode being activated, and all modules will be disabled. Then reboot back to normal mode (the module disable state persists) and manage your modules through Magisk Manager.
# Developer Guides
## BusyBox
Magisk ships with a feature complete BusyBox binary (including full SELinux support). The executable is located at `/data/adb/magisk/busybox`. Magisk's BusyBox supports runtime toggle-able "ASH Standalone Shell Mode". What this standalone mode means is that when running in the `ash` shell of BusyBox, every single command will directly use the applet within BusyBox, regardless of what is set as `PATH`. For example, commands like `ls`, `rm`, `chmod` will **NOT** use what is in `PATH` (in the case of Android by default it will be `/system/bin/ls`, `/system/bin/rm`, and `/system/bin/chmod` respectively), but will instead directly call internal BusyBox applets. This makes sure that scripts always run in a predictable environment and always have the full suite of commands no matter which Android version it is running on. To force a command *not* to use BusyBox, you have to call the executable with full paths.
Every single shell script running in the context of Magisk will be executed in BusyBox's `ash` shell with standalone mode enabled. For what is relevant to 3rd party developers, this includes all boot scripts and module installation scripts.
For those who want to use this "Standalone Mode" feature outside of Magisk, there are 2 ways to enable it:
1. Set environment variable `ASH_STANDALONE` to `1`<br>Example: `ASH_STANDALONE=1 /data/adb/magisk/busybox sh <script>`
2. Toggle with command-line options:<br>`/data/adb/magisk/busybox sh -o standalone <script>`
To make sure all subsequent `sh` shell executed also runs in standalone mode, option 1 is the preferred method (and this is what Magisk and Magisk Manager internally uses) as environment variables are inherited down to child processes.
## Magisk Modules
A Magisk module is a folder placed in `/data/adb/modules` with the structure below:
......@@ -111,7 +124,7 @@ module.zip
│ This script will be sourced by update-binary
├── ...
├── ... /* The rest of module's files */
|
```
#### Customization
......@@ -122,7 +135,7 @@ If you need even more customization and prefer to do everything on your own, dec
#### `customize.sh` Environment
Magisk's internal busybox's path `$BBPATH` is added in the front of `PATH`. The following variables and shell functions are available for convenience:
This script will run in Magisk's BusyBox `ash` shell with "Standalone Mode" enabled. The following variables and shell functions are available for convenience:
##### Variables
- `MAGISK_VER` (string): the version string of current installed Magisk (e.g. `v20.0`)
......@@ -215,25 +228,61 @@ In Magisk, there are also 2 kinds of scripts: **general scripts** and **module s
- 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 in `service.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
- 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, and `service.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 added in the front of `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.
These scripts will run in Magisk's BusyBox `ash` shell with "Standalone Mode" enabled.
## 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:
Since `/` is read-only on system-as-root devices, Magisk provides an overlay system to enable developers to replace files in rootdir or add new `*.rc` scripts. This feature is designed mostly for custom kernel developers.
Overlay files shall be placed in the `overlay.d` folder in boot image ramdisk, and they follow these rules:
1. All `*.rc` files in `overlay.d` will be read and concatenated **AFTER** `init.rc`
2. Existing files can be replaced by files located at the same relative path
3. Files that correspond to a non-existing file will be ignored
In order to have additional files which you want to reference in your custom `*.rc` scripts, add them in `overlay.d/sbin`. The 3 rules above does not apply to everything in this specific folder, as they will directly be copied to Magisk's internal `tmpfs` directory (which used to always be located at `/sbin`).
Due to changes in Android 11, the `/sbin` folder is no longer guaranteed to exist. In that case, Magisk randomly generates the `tmpfs` folder. Every occurrence of the pattern `${MAGISKTMP}` in your `*.rc` scripts will be replaced with the Magisk `tmpfs` folder when `magiskinit` injects it into `init.rc`. This also works on pre Android 11 devices as `${MAGISKTMP}` will simply be replaced with `/sbin` in this case, so the best practice is to **NEVER** hardcode `/sbin` in your `*.rc` scripts when referencing additional files.
- All `*.rc` files in `overlay.d` will be read and concatenated *AFTER* `init.rc`
- Replacing existing files are allowed.<br>
e.g. you can replace `/res/random.png` by adding the file `overlay.d/res/random.png`
- Non-existing files will be ignored (with exceptions detailed in the next point).<br>
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.<br>
e.g. `overlay.d/sbin/libfoo.ko` will be copied to `/sbin/libfoo.ko`.
Here is an example of how to setup `overlay.d` with custom `*.rc` script:
```
ramdisk
├── overlay.d
│   ├── sbin
│ │ ├── libfoo.ko <--- These 2 files will be copied
│   │   └── myscript.sh <--- to Magisk's tmpfs directory
│   ├── custom.rc   <--- This file will be injected into init.rc
│   ├── res
│   │   └── random.png <--- This file will replace /res/random.png
│   └── new_file <--- This file will be ignored because
│ /new_file does not exist
├── res
│   └── random.png <--- This file will be replaced by
│ /overlay.d/res/random.png
├── ...
├── ... /* The rest of initramfs files */
```
Here is an example of the `custom.rc`:
```
# Use ${MAGISKTMP} to refer to Magisk's tmpfs directory
on early-init
setprop sys.example.foo bar
insmod ${MAGISKTMP}/libfoo.ko
start myservice
service myservice ${MAGISKTMP}/myscript.sh
oneshot
```
This diff was suppressed by a .gitattributes entry.
This diff is collapsed.
......@@ -34,4 +34,4 @@ If you decide to start by installing Magisk without touching your recovery parti
- If you have a copy of your stock image dump, install Magisk by using Magisk Manager's "patch images" feature
- Once you restored back to stock recovery and other images, download the OTA. Optionally, once you have downloaded the OTA update zip, find a way to extract the zip (as it usually involved root)
- Apply the OTA and reboot your device. This will use the official stock OTA installation mechanism of your device to upgrade your system.
- Once it's done you will be left with an upgraded, 100% stock, un-rooted device. You will have to manually flash Magisk back. Consider using the methods stated in step 1. to flash Magisk without touching the recovery partition if you want to receive stock OTAs frequently.
\ No newline at end of file
- Once it's done you will be left with an upgraded, 100% stock, un-rooted device. You will have to manually flash Magisk back. Consider using the methods stated in step 1. to flash Magisk without touching the recovery partition if you want to receive stock OTAs frequently.
......@@ -46,7 +46,7 @@ Supported actions:
Search <hexpattern1> in <file>, and replace with <hexpattern2>
cpio <incpio> [commands...]
Do cpio commands to <incpio> (modifications are done directly)
Do cpio commands to <incpio> (modifications are done in-place)
Each command is a single argument, add quotes for each command
Supported commands:
exists ENTRY
......@@ -68,8 +68,8 @@ Supported actions:
Return values:
0:stock 1:Magisk 2:unsupported (phh, SuperSU, Xposed)
patch
Apply ramdisk patches. Configure settings with env variables:
KEEPVERITY KEEPFORCEENCRYPT
Apply ramdisk patches
Configure with env variables: KEEPVERITY KEEPFORCEENCRYPT
backup ORIG
Create ramdisk backups from ORIG
restore
......@@ -83,10 +83,10 @@ Supported actions:
print [-f]
Print all contents of dtb for debugging
Specify [-f] to only print fstab nodes
patch [OUT]
patch
Search for fstab and remove verity/avb
If [OUT] is not specified, it will directly output to <input>
Configure with env variables: KEEPVERITY TWOSTAGEINIT
Modifications are done directly to the file in-place
Configure with env variables: KEEPVERITY
split <input>
Split image.*-dtb into kernel + kernel_dtb
......@@ -138,57 +138,60 @@ If neither --load or --compile-split is specified, it will load
from current live policies (/sys/fs/selinux/policy)
One policy statement should be treated as one parameter;
this means a full policy statement should be enclosed in quotes.
this means each policy statement should be enclosed in quotes.
Multiple policy statements can be provided in a single command.
The statements has a format of "<rule_name> [args...]"
Multiple types and permissions can be grouped into collections
wrapped in curly brackets.
'*' represents a collection containing all valid matches.
Statements has a format of "<rule_name> [args...]".
Arguments labeled with (^) can accept one or more entries. Multiple
entries consist of a space separated list enclosed in braces ({}).
Arguments labeled with (*) are the same as (^), but additionally
support the match-all operator (*).
Example: "allow { s1 s2 } { t1 t2 } class *"
Will be expanded to:
allow s1 t1 class { all-permissions-of-class }
allow s1 t2 class { all-permissions-of-class }
allow s2 t1 class { all-permissions-of-class }
allow s2 t2 class { all-permissions-of-class }
Supported policy statements:
Type 1:
"<rule_name> source_type target_type class perm_set"
Rules: allow, deny, auditallow, dontaudit
"allow *source_type *target_type *class *perm_set"
"deny *source_type *target_type *class *perm_set"
"auditallow *source_type *target_type *class *perm_set"
"dontaudit *source_type *target_type *class *perm_set"
Type 2:
"<rule_name> source_type target_type class operation xperm_set"
Rules: allowxperm, auditallowxperm, dontauditxperm
* The only supported operation is ioctl
* The only supported xperm_set format is range ([low-high])
"allowxperm *source_type *target_type *class operation xperm_set"
"auditallowxperm *source_type *target_type *class operation xperm_set"
"dontauditxperm *source_type *target_type *class operation xperm_set"
- The only supported operation is 'ioctl'
- xperm_set format is either 'low-high', 'value', or '*'.
'*' will be treated as '0x0000-0xFFFF'.
All values should be written in hexadecimal.
Type 3:
"<rule_name> class"
Rules: create, permissive, enforcing
"permissive ^type"
"enforce ^type"
Type 4:
"attradd class attribute"
"typeattribute ^type ^attribute"
Type 5:
"<rule_name> source_type target_type class default_type"
Rules: type_transition, type_change, type_member
"type type_name ^(attribute)"
- Argument 'attribute' is optional, default to 'domain'
Type 6:
"name_transition source_type target_type class default_type object_name"
"attribute attribute_name"
Notes:
* Type 4 - 6 does not support collections
* Object classes cannot be collections
* source_type and target_type can also be attributes
"type_transition source_type target_type class default_type (object_name)"
- Argument 'object_name' is optional
Example: allow { s1 s2 } { t1 t2 } class *
Will be expanded to:
"type_change source_type target_type class default_type"
"type_member source_type target_type class default_type"
allow s1 t1 class { all-permissions }
allow s1 t2 class { all-permissions }
allow s2 t1 class { all-permissions }
allow s2 t2 class { all-permissions }
"genfscon fs_name partial_path fs_context"
```
### magisk
When the magisk binary is called with the name `magisk`, it works as an utility tool with many helper functions and the entry points for several Magisk services.
When the magisk binary is called with the name `magisk`, it works as a utility tool with many helper functions and the entry points for several Magisk services.
```
Usage: magisk [applet [arguments]...]
......@@ -199,21 +202,22 @@ Options:
-v print running daemon version
-V print running daemon version code
--list list all available applets
--daemon manually start magisk daemon
--remove-modules remove all modules and reboot
--[init trigger] start service for init trigger
--install-module ZIP install a module zip file
Advanced Options (Internal APIs):
--daemon manually start magisk daemon
--[init trigger] start service for init trigger
Supported init triggers:
post-fs-data, service, boot-complete
--unlock-blocks set BLKROSET flag to OFF for all block devices
--restorecon restore selinux context on Magisk files
--clone-attr SRC DEST clone permission, owner, and selinux context
--clone SRC DEST clone SRC to DEST
--sqlite SQL exec SQL commands to Magisk database
--path print Magisk tmpfs mount path
Supported init triggers:
post-fs-data, service, boot-complete
Supported applets:
Available applets:
su, resetprop, magiskhide
```
......@@ -254,10 +258,10 @@ Options:
Flags:
-v print verbose output to stderr
-n set properties without init triggers
only affects setprop
-p access actual persist storage
only affects getprop and deleteprop
-n set properties without going through init
affects setprop and prop file loading
-p also access props directly from persist storage
affects getprop and delprop
```
### magiskhide
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment