Hi
NFC does not work on my ASUS Zenfone 8 running AospExtended 9
After enabling NFS the OS will disable it again after a few seconds
In a logcat running while enablinng NFC I see these error messaage:
03-15 16:55:20.905 905 905 D NxpExtns: find found MIFARE_READER_ENABLE=(0x1)
03-15 16:55:20.898 905 905 W [email protected]: type=1400 audit(0.0:488): avc: denied { read write } for name="pn553" dev="tmpfs" ino=3293 scontext=u:r:hal_nfc_default:s0 tcontext=u:object_r:device:s0 tclass=chr_file permissive=0
03-15 16:55:20.905 905 905 D NxpHal : Entering phNxpNciHal_init_monitor
03-15 16:55:20.905 905 905 D NxpHal : Returning with SUCCESS
03-15 16:55:20.905 905 905 D EseHalClient: EseAdaptation::Initialize: enter
03-15 16:55:20.905 905 905 D EseHalClient: EseAdaptation::InitializeHalDeviceContext: enter
03-15 16:55:20.905 905 905 D EseHalClient: EseAdaptation::InitializeHalDeviceContext: Ignored. Reason : eSE Not Supported
03-15 16:55:20.905 905 905 D EseHalClient: EseAdaptation::Initialize: exit
03-15 16:55:20.905 905 905 D NxpExtns: find found NXP_NFC_DEV_NODE=/dev/pn553
03-15 16:55:20.905 905 905 D NxpTml : Opening port=/dev/pn553
03-15 16:55:20.905 905 905 E NxpTml : _i2c_open() Failed: retval ffffffff
The permissions for /dev/pn553 are
[ root @ ASUS_I006D : ~ ] ls -l /dev/pn553
crw-rw---- 1 nfc nfc 10, 121 1970-01-07 23:20 /dev/pn553
[ root @ ASUS_I006D : ~ ]
I tried adding r/w for other to the permissions for /dev/pn553: in that case the error message is gone but it still does not work.
I also tried to set SELinux to permissive but that also does not fix the error.
The NFC works in the original Android 11 and 12 for the phone so the hardware is okay
Any hints how to fix this issue are welcome
I added two logcats to this message
enable_and_disable_nfc.log - trying to enable the NFS without changing anything
enable_and_disable_nfc_with_added_permissions.log - trying to enable NFS after changing the permissions for /dev/pn553 and setting SELinux to permissive
(search for "NfcService: Enabling NFC" in the logcats attached to this message)
regards
Bernd
Hi
fiy:
I found the reason why NFC is not working in AospExtended 9.0 without gapps (https://downloads.aospextended.com/...xtended-v9.0-I006D-OFFICIAL-20220227-0100.zip)
NFC does not work because the SELinux context for the NFC device /dev/pn553 is wrong . The SELinux context is
Code:
ASUS_I006D:/ # ls -lZ /dev/pn553
crw-rw---- 1 nfc nfc u:object_r:device:s0 10, 121 1970-03-18 01:08 /dev/pn553
but it must be
Code:
ASUS_I006D:/ # ls -lZ /dev/pn553
crw-rw---- 1 nfc nfc u:object_r:nfc_device:s0 10, 121 1970-03-18 01:08 /dev/pn553
ASUS_I006D:/ #
I wrote a little script to correct the SELinux context:
Code:
ASUS_I006D:/ # cat /storage/emulated/0/data/scripts/correct_dev_pn553.sh
#!/system/bin/sh
NFC_DEVICE="/dev/pn553"
echo ""
echo "The SELinux context for \"${NFC_DEVICE}\" is now:"
ls -lZ ${NFC_DEVICE}
echo ""
echo "Correcting the SELinux context for the NFC device \"${NFC_DEVICE}\" ..."
chcon -v u:object_r:nfc_device:s0 ${NFC_DEVICE}
echo ""
echo "The SELinux context for \"${NFC_DEVICE}\" is now:"
ls -lZ ${NFC_DEVICE}
ASUS_I006D:/ #
Example output:
Code:
ASUS_I006D:/ # sh /storage/emulated/0/data/scripts/correct_dev_pn553.sh
The SELinux context for "/dev/pn553" is now:
crw-rw---- 1 nfc nfc u:object_r:device:s0 10, 121 1970-03-18 01:08 /dev/pn553
Correcting the SELinux context for the NFC device "/dev/pn553" ...
chcon '/dev/pn553' to u:object_r:nfc_device:s0
The SELinux context for "/dev/pn553" is now:
crw-rw---- 1 nfc nfc u:object_r:nfc_device:s0 10, 121 1970-03-18 01:08 /dev/pn553
ASUS_I006D:/ #
The script must be executed by the user root.
Unfortunately the dev tree is rebuild after each reboot and therefor the change is not persistent so that the script must be executed after each reboot.
So the next step in my journey is to find out how to automate the execution of the script after a reboot in the Android OS.
regards
Bernd
Update 24.05.2022/bs
For phones running Magisk it is sufficient to copy the script into the directory
/data/adb/service.d/
and make it executable to ensure that it is executed after every reboot of the phone
(see also https://github.com/topjohnwu/Magisk/blob/master/docs/guides.md#boot-scripts)
In this post I summarize everything I found out about using Magisk (https://topjohnwu.github.io/Magisk) until now. A lot of the infos in this post are already in my other posts in this board but hopefully this summary is useful anyway.
My main purpose is to configure Magisk as much as possible via scripts so this tutorial is mostly about using Magisk via CLI commands in an adb shell or from within scripts.
Please note that I mirror all my HowTos for Android on my web page:
http://bnsmb.de/My_HowTos_for_Android.html
I will update this post when I found something new and interesting. A history of changes in this post is at the end of the post.
PreRequisites
Most of the instructions below need an enabled adb access for the phone and root permissions for the adb shell. In addition, a working Recovery image that is able to mount the /data partition (like for example TWRP) is strongly recommended before starting to play with Magisk.
The Magisk version used for this tutorial is Magisk 25.1 and Magisk 25.2; the ROM used was OmniROM (Android 12 based).
The phone used was an ASUS Zenfone 8 but the instructions should work on other phones also.
Installation
Magisk consists out of two parts:
The Magisk App and the Magisk files in the boot partition. Without the files in the boot partition Magisk can do more or less nothing.
The Magisk App can be installed using the standard Android tools for installing apps.
The installation of the Magisk files into the boot partition can then be done using the Magisk App.
The official instructions to install Magisk into the boot partition are here:
https://topjohnwu.github.io/Magisk/install.html
Magisk can also be installed via script without user intervention into the boot partition -- see How to install Magisk into the boot partition using a script
Update 18.04.2023/bs
see How to install Magisk v26.0 or newer via script for how to install Magisk v26 via script
Note that the Magisk files for the boot partition must be reinstalled after an OS upgrade but this can be done from within the Magisk App.
Uninstalling Magisk
Use the Button "Uninstall Magisk" in the Magisk App to uninstall Magisk.
The Magisk App can also remove the Magisk files from the boot partition.
To uninstall the Magisk App only via script do
Bash:
adb shell pm uninstall com.topjohnwu.magisk
To remove Magisk from the boot partition manually I suggest to flash the image of the original boot partition.
Installing Magisk Modules
Magisk Modules are extensions for Magisk to for example replace or add files to /system (and much more ... I suggest to study the documentation for Magisk for those that are interested in using Magisk)
Magisk Modules are distributed via ZIP files.
As of Magisk v25 or newer the official method to install Magisk Modules is to manually copy the ZIP file with the Magisk Module to the phone and then use the button "Install from storage" in the "Modules" sub menu in the Magisk App.
In previous versions of Magisk a Module browser to list and install Magisk Modules was part of the Magisk App but unfortunately the developer dropped that feature. Therefor you must search and download the available Magisk Modules using a browser on the phone or a PC.
Repositories with Magisk Modules are for example:
https://github.com/Magisk-Modules-Repo/
and
https://github.com/Magisk-Modules-Alt-Repo
A XDA thread about Magisk Modules (including a list of Magisk Modules) is here:
https://forum.xda-developers.com/t/collection-of-magisk-modules-v2.3575758/
There is now a new App for Android called "Fox's Magisk Module Manager" that can be used to list and download Magisk Modules to the phone (see https://github.com/Fox2Code/FoxMagiskModuleManager).
It's also possible to install a Magisk Module via script. The commands to install an Magisk Module via script are:
Bash:
# copy the Magisk Module to the phone
adb push /data/backup/Android/MagiskModules/Nano_for_Android_NDK-6_3-6300.zip /sdcard/Download/
# install the Module
#
# Note:
#
# The command can also be executed in a script runnning on the phone (without "adb shell")
#
adb shell magisk --install-module /sdcard/Download/Nano_for_Android_NDK-6_3-6300.zip
# reboot the phone
adb reboot
Example:
Code:
[[email protected] ~]$ adb push /data/backup/Android/MagiskModules/Nano_for_Android_NDK-6_3-6300.zip /sdcard/Download/
/data/backup/Android/MagiskModules/Nano_for_Android_NDK-6_3-6300.zip: 1 file pushed, 0 skipped. 37.6 MB/s (380554 bytes in 0.010s)
[[email protected] ~]$ adb shell magisk --install-module /sdcard/Download/Nano_for_Android_NDK-6_3-6300.zip
- Current boot slot: _a
- Device is system-as-root
*****************************
Nano for Android NDK
by osm0sis @ xda-developers
*****************************
*******************
Powered by Magisk
*******************
Archive: /storage/emulated/0/Download/Nano_for_Android_NDK-6_3-6300.zip
inflating: diffusion_config.sh
inflating: module.prop
Mounting...
Extracting files...
Archive: /storage/emulated/0/Download/Nano_for_Android_NDK-6_3-6300.zip
inflating: META-INF/com/google/android/updater-script
inflating: META-INF/com/google/android/update-binary
inflating: sbin/nano
...
inflating: etc/terminfo/l/linux
inflating: customize.sh
inflating: update.json
inflating: bin/nano
inflating: bin/nano.bin
inflating: README.md
inflating: diffusion_config.sh
inflating: module.prop
Installing...
Installing nano to /data/adb/modules_update/nano-ndk/system/bin ...
Installing terminfo to /data/adb/modules_update/nano-ndk/system/etc ...
Unmounting...
Done!
[[email protected] ~]$ adb reboot
[[email protected] ~]$
Uninstalling a Magisk Module
Magisk Modules should be uninstalled via Magisk App if possible because there is no parameter for the magisk binary to uninstall a Magisk Module.
To force Magisk via shell command to remove the module after the next reboot create the file
remove
in the module directory.
If uninstalling the Magisk Module via Magisk does not work or if you want to uninstall a Magisk Module via script you can just delete the directory for the Magisk Module in /data/adb/modules and reboot the phone. This can be done in an adb shell or if that does not work anymore after rebooting the phone from a Recovery Image like TWRP, e.g.
Bash:
# uninstall the module "dummy_module" via adb shell commands
#
# check for an uninstall script for this module
#
if [ -x /data/adb/modules/dummy_module/uninstall.sh ] ; then
echo "Executing the module uninstall script ...."
/data/adb/modules/dummy_module/uninstall.sh
fi
adb shell rm -rf /data/adb/modules/dummy_module/
adb reboot
Note:
You should reboot the phone immediately after removing the directory with the Module.
This method is not really recommended.
List all installed Magisk Modules
The Magisk App will list all installed Magisk Modules
To list the installed Magisk Modules via CLI command use either
Bash:
adb shell ls -d /data/adb/modules/* | cut -f5 -d "/"
e.g.
Code:
[[email protected] ~]$ adb shell ls -d /data/adb/modules/* | cut -f5 -d "/"
PlayStore_for_MicroG
ccbins
dummy_module
initshell
nano-ndk
terminalmods
[[email protected] ~]$
# or
[[email protected] /]$ for i in $( adb shell su - -c ls -d /data/adb/modules/* ); do printf "%-30s %s\n" "${i##*/}" "$( adb shell su - -c grep name= $i/module.prop 2>/dev/null | cut -f2 -d "=" | tr -s " " )" ; done
MiXplorer MiXplorer
PlayStore_for_MicroG Patched Playstore from NanoDroid for MicroG (for ARM64 CPUs only)
ccbins Cross Compiled Binaries
dummy_module Dummy Module for testing a new module
initshell Create writable config files (/etc/profile) for sh
nano-ndk Nano for Android NDK
terminalmods Terminal Modifications
[[email protected] /]$
or on the phone:
Code:
[email protected]_I006D:/ # echo; for i in /data/adb/modules/*; do printf "%-30s %s\n" "${i##*/}" "$( grep name= $i/module.prop 2>/dev/null | cut -f2 -d "=" | tr -s " " )" ; done
PlayStore_for_MicroG Patched Playstore from NanoDroid for MicroG (for ARM64 CPUs only)
ccbins Cross Compiled Binaries
dummy_module
initshell Create writable config files (/etc/profile) for sh
nano-ndk Nano for Android NDK
terminalmods Terminal Modifications
[email protected]_I006D:/ #
How to disable a Magisk Module
To disable a Magisk Module via script create a file called disable in the Module directory, e.g.:
Bash:
touch /data/adb/modules/dummy_module/disable
The Magisk Module will then be disabled after the next reboot.
To re-enable the Magisk Module just delete the file disable in the Module directory and reboot the phone.
To list all disabled Magisk Modules do
Bash:
adb shell ls /data/adb/modules/*/disable | cut -f5 -d "/"
Replacing files in /system using a Dummy Magisk Module
One feature of Magisk Modules is the possibility to change files in the sub directories in the directory /system or also add new files to the sub directories in the directory /system. /system is mounted read-only and in the current Android version it is not possible to remount /system read-write anymore so without Magisk it's very difficult to change files in /system.
Please note that you can not create new files or directories in the directory /system using this Magisk feature.
To test this feature you do not need to create a Magisk Module : It's sufficient to simulate a Magisk Module.
For that just create the necessary directory structure and files manually.
Magisk Modules are are installed in the directory /data/adb/modules. Each Magisk Module use an uniqe sub directory in that directory. To simulate a Magisk Module open an adb shell as user root and create the directories for your Dummy Magisk Module, e.g.:
Bash:
mkdir /data/adb/modules/dummy_module
# Next create the sub directory system in that new directory
mkdir /data/adb/modules/dummy_module/system
Now copy the files for /system to that directory: The files in that directory will overwrite existing files in /system after the next reboot. Files in that directory that not already exist in /system will be created in /system.
e.g.
Code:
# contents of my Dummy Magisk Module
#
[email protected]_I006D:/data/adb/modules/dummy_module/system # pwd
/data/adb/modules/dummy_module/system
[email protected]_I006D:/data/adb/modules/dummy_module/system # find .
.
./bin
./bin/my_new_binary
./etc
./etc/my_new_file_for_systme
[email protected]_I006D:/data/adb/modules/dummy_module/system #
After rebooting the phone the files are visible in /system:
Code:
[email protected]_I006D:/ # ls -l /system/etc/my_new_file_for_systme
-rw-rw-rw- 1 root root 20 2022-07-20 16:55 /system/etc/my_new_file_for_systme
[email protected]_I006D:/ # cat /system/etc/my_new_file_for_systme
This is my new file
[email protected]_I006D:/ #
[email protected]_I006D:/ # ls -l /system/bin/my_new_binary
-rwxr-xr-x 1 root root 41 2022-07-20 16:57 /system/bin/my_new_binary
[email protected]_I006D:/ # my_new_binary
Hello world from my dummy binary
[email protected]_I006D:/ #
The permissions for the new files in /system are equal to the permissions of the original files in
/data/adb/modules/dummy_module so if the original files are writable you can also edit the new files in /system, e.g
Code:
[email protected]_I006D:/ # cat /system/etc/my_new_file_for_systme
This is my new file
[email protected]_I006D:/ #
[email protected]_I006D:/ # echo "Test Test" >> /system/etc/my_new_file_for_systme
[email protected]_I006D:/ # cat /system/etc/my_new_file_for_systme
This is my new file
Test Test
[email protected]_I006D:/ #
These changes are persistent (because they change the original file in /data/adb/modules/<modulename>). You can also edit the files in /data/adb/modules/<modulename> but be aware that you can not use tools that create temporary files for changing the files like for example sed: Changes done with these kind of tools are only visible after a reboot of the phone.
To change the file via script I recommend to create a new file and then replace the existing file with the new file using cp.
This Magisk feature can also be used to make files in sub directories in /system writable -- see How to make files in system writable for detailed instructions.
Make sure that the new files for /system are readable for the user using them; e.g some files (like for example apk files) are used by the user system). IMHO it's recommended to add the read permission (chmod o+r) to all new files for /system.
Notes:
Magisk does not really change the files in /system - instead it uses "bind mounts" to replace the files with others. Therefor you can always restore the original files by deleting the files in /data/adb/modules/<module_name> and rebooting the phone. Another big advantage of this technique is that you do not have to take care about an update of the OS:
changes done via Magisk will also work after an OS upgrade (assuming you reinstalled Magisk to the boot partition after installing the OS update)
Please be careful when changing existing files in /system.
To add the necessary infos for the Magisk App to list your dummy module properly just create the file module.prop for your Dummy Magisk Module, e.g.
Code:
[email protected]_I006D:/ # cat /data/adb/modules/dummy_module/module.prop
id=dummy-module
name=Dummy Module for testing a new module
version=1.0
versionCode=1000
[email protected]
description=Dummy Module ..
[email protected]_I006D:/ #
For some examples for this technique see
How to change files in the directory /system with Magisk
How to replace the Fake Store from OmniROM with MicroG with a patched Playstore
How to change the home directory for the user root on an Android phone
How to use this technique to disable an app that can not be uninstalled
Apps that can not be uninstalled can be disabled by creating empty files for the app.
Example:
My Magisk Module for the patched Playstore must disable the FakeStore installed in the OmniROM with MicroG by default.
That's done by creating an empty file in the Magisk Module for the apk file for the FakeStore, the result looks like this:
Code:
[email protected]_I006D:/ # ls -l /data/adb/modules/PlayStore_for_MicroG/system/priv-app/FakeStore/FakeStore.apk
-rw-r--r-- 1 root root 1 2022-07-15 11:54 /data/adb/modules/PlayStore_for_MicroG/system/priv-app/FakeStore/FakeStore.apk
[email protected]_I006D:/ #
[email protected]_I006D:/ # ls -l /system/priv-app/FakeStore/FakeStore.apk
-rw-r--r-- 1 root root 1 2022-07-15 11:54 /system/priv-app/FakeStore/FakeStore.apk
[email protected]_I006D:/ #
In case there are multiple files in the folder for the app you can also hide the entire folder:
From the original documentation from https://topjohnwu.github.io/Magisk/guides.html:
If you place a file named .replace in any of the folders, instead of merging its contents, that folder will directly replace the one in the real system. This can be very handy for swapping out an entire folder.
Click to expand...
Click to collapse
How to access the files replaced by Magisk
Use another bind mount to access the files replaced by Magisk, e.g:
Code:
[email protected]_I006D:/ # head /data/adb/modules/fmradio/system/etc/public.libraries.txt
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
#
# 04.08.2022 /bs
# added the library libqcomfm_jni.so
#
libandroid.so
libaaudio.so
libamidi.so
libbinder_ndk.so
libc.so
[email protected]_I006D:/ #
[email protected]_I006D:/ #
[email protected]_I006D:/ # head /system/etc/public.libraries.txt
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
#
# 04.08.2022 /bs
# added the library libqcomfm_jni.so
#
libandroid.so
libaaudio.so
libamidi.so
libbinder_ndk.so
libc.so
[email protected]_I006D:/ #
# -> The file /system/etc/public.libraries.txt is replaced by a file from a Magisk Module
# To access the original version of the file /system/etc/public.libraries.txt do
[email protected]_I006D:/ #
[email protected]_I006D:/ # mkdir -p /data/test
[email protected]_I006D:/ #
[email protected]_I006D:/ # mount -o bind /system /data/test
#
# -> /data/test is now bind mounted to /system
#
# -> /data/test/etc/public.libraries.txt is the original version of that file:
#
[email protected]_I006D:/ #
[email protected]_I006D:/ # head /data/test/etc/public.libraries.txt
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
libandroid.so
libaaudio.so
libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
libdl.so
libEGL.so
libGLESv1_CM.so
[email protected]_I006D:/ #
Replacing files in /vendor, /product, or /system_ext using a Dummy Magisk Module
The dummy Magisk Module can also be used to replace files in the directories /vendor, /product, or /system_ext:
from the Magisk documentation at https://topjohnwu.github.io/Magisk/guides.html:
If you want to replace files in /vendor, /product, or /system_ext, please place them under system/vendor, system/product, and system/system_ext respectively. Magisk will transparently handle whether these partitions are in a separate partition or not.
Click to expand...
Click to collapse
Note that this works only to replace existing files in these directories - you can not add new files to these directories using this method.
Example:
Code:
[email protected]_I006D:/ # cd /data/adb/modules/dummy_module/system
#
# files in the Magisk Module
#
[email protected]_I006D:/data/adb/modules/dummy_module/system # find . -type f
./bin/my_new_binary
./etc/my_new_file_for_systme
./product/mynewfile
./product/media/audio/alarms/Krypton.ogg
./vendor/mynewfile
./vendor/etc/sap.conf
./system_ext/mynewfile
./system_ext/etc/dpm/dpm.conf
[email protected]_I006D:/data/adb/modules/dummy_module/system #
#
# the new files for /product, /vendor, and /system_ext in the Magisk Module do not exist:
#
[email protected]_I006D:/data/adb/modules/dummy_module/system # ls -l /product/mynewfile /vendor/mynewfile /system_ext/mynewfile
ls: /product/mynewfile: No such file or directory
ls: /vendor/mynewfile: No such file or directory
ls: /system_ext/mynewfile: No such file or directory
#
# The existing files in /product, /vendor, and /system_ext are replaced with the files from the Magisk Moduel
#
[email protected]_I006D:/data/adb/modules/dummy_module/system # cksum ./product/media/audio/alarms/Krypton.ogg /product/media/audio/alarms/Krypton.ogg
4294967295 0 ./product/media/audio/alarms/Krypton.ogg
4294967295 0 /product/media/audio/alarms/Krypton.ogg
[email protected]_I006D:/data/adb/modules/dummy_module/system #
[email protected]_I006D:/data/adb/modules/dummy_module/system # cksum ./vendor/etc/sap.conf /vendor/etc/sap.conf
1967598015 7121 ./vendor/etc/sap.conf
1967598015 7121 /vendor/etc/sap.conf
[email protected]_I006D:/data/adb/modules/dummy_module/system #
[email protected]_I006D:/data/adb/modules/dummy_module/system # cksum ./system_ext/etc/dpm/dpm.conf /system_ext/etc/dpm/dpm.conf
1970692378 2925 ./system_ext/etc/dpm/dpm.conf
1970692378 2925 /system_ext/etc/dpm/dpm.conf
[email protected]_I006D:/data/adb/modules/dummy_module/system #
[email protected]_I006D:/data/adb/modules/dummy_module/system # grep mynewfile /cache/magisk.log
01-01 00:11:51.764 767 769 W : Unable to add: /product/mynewfile, skipped
01-01 00:11:51.771 767 769 W : Unable to add: /system_ext/mynewfile, skipped
01-01 00:11:51.771 767 769 W : Unable to add: /vendor/mynewfile, skipped
[email protected]_I006D:/data/adb/modules/dummy_module/system #
A work around to create new files in sub directories in /product, /vendor, or /system_ext:
Copy the complete existing folder to the sub directory in
/data/adb/modules/<magisk_module>/system/[product|vendor|system_ext]/
and create the file .replace in that directory and add the new file(s) to that directory.
Example:
Code:
[email protected]_I006D:/ # find /data/adb/modules/testmodule/
/data/adb/modules/testmodule/
/data/adb/modules/testmodule/system
/data/adb/modules/testmodule/system/product
/data/adb/modules/testmodule/system/product/lib
/data/adb/modules/testmodule/system/product/lib/.replace
/data/adb/modules/testmodule/system/product/lib/libframesequence.so
/data/adb/modules/testmodule/system/product/lib/libgiftranscode.so
/data/adb/modules/testmodule/system/product/lib/newfile001
/data/adb/modules/testmodule/system/vendor
/data/adb/modules/testmodule/system/vendor/app
/data/adb/modules/testmodule/system/vendor/app/TimeService
/data/adb/modules/testmodule/system/vendor/app/TimeService/TimeService.apk
/data/adb/modules/testmodule/system/vendor/app/TimeService/oat
/data/adb/modules/testmodule/system/vendor/app/TimeService/oat/arm64
/data/adb/modules/testmodule/system/vendor/app/TimeService/oat/arm64/TimeService.vdex
/data/adb/modules/testmodule/system/vendor/app/TimeService/oat/arm64/TimeService.odex
/data/adb/modules/testmodule/system/vendor/app/TimeService/newfile002
/data/adb/modules/testmodule/system/vendor/app/TimeService/.replace
/data/adb/modules/testmodule/system/system_ext
/data/adb/modules/testmodule/system/system_ext/app
/data/adb/modules/testmodule/system/system_ext/app/FM2
/data/adb/modules/testmodule/system/system_ext/app/FM2/.replace
/data/adb/modules/testmodule/system/system_ext/app/FM2/FM2.apk
/data/adb/modules/testmodule/system/system_ext/app/FM2/lib
/data/adb/modules/testmodule/system/system_ext/app/FM2/lib/arm64
/data/adb/modules/testmodule/system/system_ext/app/FM2/lib/arm64/libqcomfm_jni.so
/data/adb/modules/testmodule/system/system_ext/app/FM2/oat
/data/adb/modules/testmodule/system/system_ext/app/FM2/oat/arm64
/data/adb/modules/testmodule/system/system_ext/app/FM2/oat/arm64/FM2.odex
/data/adb/modules/testmodule/system/system_ext/app/FM2/oat/arm64/FM2.vdex
/data/adb/modules/testmodule/system/system_ext/app/FM2/newfile003
[email protected]_I006D:/ #
[email protected]_I006D:/ # find /data/adb/modules/testmodule/system | grep newfile
/data/adb/modules/testmodule/system/product/lib/newfile001
/data/adb/modules/testmodule/system/vendor/app/TimeService/newfile002
/data/adb/modules/testmodule/system/system_ext/app/FM2/newfile003
[email protected]_I006D:/ #
[email protected]_I006D:/ # pwd
/
[email protected]_I006D:/ # ls -l $( find /data/adb/modules/testmodule/system | grep newfile | cut -f6- -d "/" )
-rw-r--r-- 1 root root 0 2022-08-07 14:34 system/product/lib/newfile001
-rw-r--r-- 1 root root 0 2022-08-07 14:24 system/system_ext/app/FM2/newfile003
-rw-r--r-- 1 root root 0 2022-08-07 14:36 system/vendor/app/TimeService/newfile002
[email protected]_I006D:/ #
See How to change any file or directory using Magisk for another approach to change files on read-only mounted filesystems.
Executing scripts while booting the phone
Magisk also supports executing additional scripts while booting the phone.
The scripts to be executed must be copied to one of these directories
/data/adb/post-fs-data.d/
/data/adb/service.d/
see the description in the original Magisk documentation: https://topjohnwu.github.io/Magisk/details.html
Working examples for this technique are described in these posts:
How to run a script atevery boot using Magisk
How to disable or change the swap device in the Android 12 from ASUS for the Zenfone 8
How to create or change a swap device in the OmniROM 12 using Magisk
Another example for using this technique I found here
https://gist.github.com/niikoo/3f6bd13a69f2d68f3dd51cc667e79bdc :
Bash:
# Boot logging
# Create the file: /data/adb/post-fs-data.d/0001logcatboot
#!/system/bin/sh
mkdir -p /cache/logs
/system/bin/logcat -r 1024 -n 9 -v threadTime -f /cache/logs/log >info.log 2>err.log &
Note that I added commands to create / cleanup the log directory and changed the logcat command on my phone:
Bash:
#!/system/bin/sh
mkdir -p /cache/logs
rm -rf /cache/logs/*
/system/bin/logcat -r 102400 -n 9 -v threadTime -f /cache/logs/log >/cache/logs/info.log 2>/cache/logs/err.log &
To execute additional scripts earlier in the boot process you must add them to the boot image -- see the section Using Magisk to unpack and repack the boot image below for details.
Creating Magisk Modules
The official documentation for creating a Magisk Module is here: https://topjohnwu.github.io/Magisk/guides.html
Creating Magisk Modules that only use the standard features isn't that difficult and the official documentation should be sufficient.
I suggest to download an existing simple Magisk Module; unzip the ZIP file and study the contents.
Using Magisk to unpack and repack the boot image
The binary magiskboot that is part of the Magisk package can be used to unpack and repack the boot partition for every phone supported by Magisk.
For details see here: How to change files in the boot image using Magisk
Magisk also supports changing files in the root directory via Root Directory Overlays (see https://github.com/topjohnwu/Magisk/blob/master/docs/guides.md) :
This feature can be used to create additional start or stop services for the Android OS:
Android uses init *rc files to define the services to start when booting and also to define the services to run when doing the shutdown (like the systemd or initd in other Linux implementations).
These files are read early in the boot process and therefore reside only in the ramdisk on the boot partition. To add new init* rc files the boot image must be modified. This can be done with Magisk:
Just add the new init*rc files and optimal other scripts or files to the boot image using Magisk . Magisk will then take care of processing the new init*rc files by the Android operating system when booting the phone.
See these posts:
How to run a script at shutdown
How to trigger an action when a property is changed
How to enable root access using Magisk in a script
for examples for using that feature.
There are also magiskboot binaries for x86 in the Magisk apk file that can be used on a PC running the Linux OS:
see How to process Android boot image files on a PC running the Linux OS for more details about this feature.
Using Magisk to change the active slot
The Magisk App can also be used to change the active slot on phones with A/B slots -- for details see here :
How to manually switch the active slot
Directories and files used by Magisk
The directories and files used by Magisk are documented here https://topjohnwu.github.io/Magisk/guides.html
Some important directories and files for developing and trouble shooting Magisk Modules are:
The logfile used by Magisk is
/cache/magisk.log
In case something goes wrong with a Magisk Module you should first check that file.
The base directory for the data files for Magisk is
/data/adb
The config setttings for Magisk are stored in the SQLite database
/data/adb/magisk.db
To view (or probably) change the database entries via script you can either use sqlite3 binary (if installed)
Code:
ASUS_I006D:/ # sqlite3 /data/adb/magisk.db
SQLite version 3.7.6.3-Titanium
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .headers on
sqlite> .mode column
sqlite>
sqlite> .tables
denylist policies settings strings
sqlite>
sqlite> .schema
CREATE TABLE denylist (package_name TEXT, process TEXT, PRIMARY KEY(package_name, process));
CREATE TABLE policies (uid INT, policy INT, until INT, logging INT, notification INT, PRIMARY KEY(uid));
CREATE TABLE settings (key TEXT, value INT, PRIMARY KEY(key));
CREATE TABLE strings (key TEXT, value TEXT, PRIMARY KEY(key));
sqlite>
sqlite> select * from denylist ;
sqlite>
sqlite> select * from policies ;
uid policy until logging notification
---------- ---------- ---------- ---------- ------------
2000 2 0 1 1
10134 1 0 1 1
sqlite>
sqlite> select * from settings ;
key value
---------- ----------
denylist 0
su_biometr 0
sqlite>
sqlite> select * from strings ;
sqlite>
or the magisk binary, e.g:
Code:
ASUS_I006D:/ # magisk --sqlite 'select * from policies'
logging=1|notification=1|policy=2|uid=2000|until=0
ASUS_I006D:/ #
ASUS_I006D:/ # magisk --sqlite 'select * from settings'
key=denylist|value=0
key=su_biometric|value=0
ASUS_I006D:/ #
There is a handy little script to list all apps with root access in the XDA thread https://forum.xda-developers.com/t/magisk-general-support-discussion.3432382/page-2681 .
How to create the Magisk database manually
To create the Magisk database manually (e.g. after installing Magisk manually via script) these commands can be used:
Bash:
# start the Magisk daemon if necessary
#
MAGISK_DAEMON_IS_RUNNING=true
/data/adb/magisk/magisk64 -v || /data/adb/magisk/magisk64 --daemon && MAGISK_DAEMON_IS_RUNNING=false
#
# force Magisk to create the Magisk database if it not yet exists
#
/data/adb/magisk/magisk64 --sqlite "PRAGMA user_version"
# stop the Magisk daemon again
#
[ ${MAGISK_DAEMON_IS_RUNNING} = false ] && /data/adb/magisk/magisk64 --stop
To create the Magisk database using sqlite3 use these commands:
SQL:
.open ${CUR_MAGISK_DATABASE_FILE}
CREATE TABLE IF NOT EXISTS policies (uid INT, policy INT, until INT, logging INT,notification INT, PRIMARY KEY(uid));
CREATE TABLE IF NOT EXISTS settings (key TEXT, value INT, PRIMARY KEY(key));
CREATE TABLE IF NOT EXISTS strings (key TEXT, value TEXT, PRIMARY KEY(key));
CREATE TABLE IF NOT EXISTS denylist (package_name TEXT, process TEXT, PRIMARY KEY(package_name, process));
PRAGMA user_version=6;
.exit
Note:
The Magisk database will be upgraded to the latest version automatically by the Magisk daemon after the next restart
Magisk root access configuration details
Magisk uses the table policies in the sqlite database /data/adb/magisk.db to store the list of root enabled apps.
See this post https://forum.xda-developers.com/t/how-to-enable-root-access-using-magisk-in-a-script.4527035/ for details about this feature and how to enable root access via Magisk using a script.
Magisk App installation directory
Use
Bash:
pm list packages -f | grep magisk
to get the Magisk App installation directory.
Credits: https://forum.xda-developers.com/t/magisk-general-support-discussion.3432382/page-2689#post-87694851
The Magisk App Configuration files
The Magisk App stores the configuration (e.g. the app settings) in the default directory for App Settings, on my phone this is
/data/user_de/0/com.topjohnwu.magisk/shared_prefs
The file in that directory used to store the settings is
com.topjohnwu.magisk_preferences.xml
For more details about the file see the post Where does the Magisk App store the settings?.
Temporary Magisk config directory
While running Magisk uses a temporary directory for the configuration.
The path to the config directory can be retrieved via magisk binary:
Code:
ASUS_I006D:/dev/hP3B # magisk --path
/dev/hP3B
ASUS_I006D:/dev/hP3B#
The contents of that directory look like :
Code:
ASUS_I006D:/dev/hP3B # ls -al /dev/hP3B/
total 568
drwx------ 3 root root 200 1970-01-01 04:08 .
drwxr-xr-x 27 root root 5480 2022-11-06 18:32 ..
drwxr-xr-x 8 root root 180 1970-01-01 04:08 .magisk
lrwxrwxrwx 1 root root 10 1970-01-01 04:08 magisk -> ./magisk64
-rwxr-xr-x 1 root root 0 1970-01-01 04:08 magisk32
-rwxr-xr-x 1 root root 247168 1970-01-01 04:08 magisk64
-rwxr-xr-x 1 root root 328240 1970-01-01 04:08 magiskpolicy
lrwxrwxrwx 1 root root 8 1970-01-01 04:08 resetprop -> ./magisk
lrwxrwxrwx 1 root root 8 1970-01-01 04:08 su -> ./magisk
lrwxrwxrwx 1 root root 14 1970-01-01 04:08 supolicy -> ./magiskpolicy
ASUS_I006D:/dev/hP3B # ls -al /dev/hP3B/.magisk/
total 7
drwxr-xr-x 8 root root 180 1970-01-01 04:08 .
drwx------ 3 root root 200 1970-01-01 04:08 ..
d--------- 2 root root 160 1970-01-01 04:08 block
drwxr-xr-x 2 root root 7240 1970-01-01 04:08 busybox
---------- 1 root root 127 1970-01-01 04:08 config
d--------- 7 root root 220 1970-01-01 04:08 mirror
drwxr-xr-x 3 root root 3452 2022-11-06 18:32 modules
drwxr-xr-x 2 root root 0 1970-01-01 04:08 pts
d--------- 2 root root 80 1970-01-01 04:08 selinux
ASUS_I006D:/dev/hP3B # cat /dev/hP3B/.magisk/config
KEEPVERITY=false
KEEPFORCEENCRYPT=false
PATCHVBMETAFLAG=false
RECOVERYMODE=false
SHA1=1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
ASUS_I006D:/dev/hP3B #
Backup of the boot partitions
Magisk creates backups of the boot partitions in sub directories in /data/adb with filenames starting with magisk_backup_, e.g.:
Code:
[email protected]_I006D:/data/adb # ls -l /data/magisk_backup_*
/data/magisk_backup_79f3370cd83d03441325998a8875888780c3182f:
total 31712
-rwxr-xr-x 1 root root 32436260 2022-09-26 12:20 boot.img.gz
/data/magisk_backup_a0c712541fd002c331c25772a3b8609ae2fba546:
total 31712
-rwxr-xr-x 1 root root 32436965 2022-09-27 19:30 boot.img.gz
[email protected]_I006D:/data/adb #
The uniq string after the second underscore in the name of the directory with the backup is the SHA-1 from the boot image that was patched to install Magisk:
Code:
[[email protected] /data/develop/android/scripts_on_linux]$ ./install_magisk_via_twrp.sh
install_magisk_via_twrp.sh version - v2.0.0.1 - add Magisk to the boot partition of a phone running Android using TWRP
....
Creating the boot image file "/sdcard/Download/boot_b.1086412.img" from the partition "/dev/block/by-name/boot_b" ...
196608+0 records in
196608+0 records out
100663296 bytes (96 M) copied, 0.313082 s, 307 M/s
Checking the result ...
-rw-rw---- 1 root media_rw 100663296 2022-11-06 16:01 /sdcard/Download/boot_b.1086412.img
...
OK, patching the boot partition "/dev/block/by-name/boot_b" was successfull
....
[[email protected] /data/develop/android/scripts_on_linux]$
The image file patched by Magisk in this example is /sdcard/Download/boot_b.1086412.img.
The backup of the boot partition on the phone created by Magisk for this installation is:
Code:
ASUS_I006D:/ # ls -ld /data/magisk_backup*
drwxr-xr-x 2 root root 3452 2022-11-06 17:14 /data/magisk_backup_1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
ASUS_I006D:/ #
ASUS_I006D:/ # ls -l /data/magisk_backup_1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
total 50692
-rw-r--r-- 1 root root 51852324 2022-11-06 17:14 boot.img.gz
ASUS_I006D:/ #
1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb is the SHA-1 from the image file used for the installation of Magisk:
Code:
ASUS_I006D:/ # sha1sum /sdcard/Download/boot_b.1086412.img
1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb /sdcard/Download/boot_b.1086412.img
ASUS_I006D:/ #
or
Code:
ASUS_I006D:/data/adb/workdir/unpack/ramdisk # /data/adb/magisk/magiskboot sha1 /sdcard/Download/boot_b.1086412.img
1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
ASUS_I006D:/data/adb/workdir/unpack/ramdisk #
The SHA1 from the previous boot image is stored in the file /dev/hP3B/.magisk/config used by Magisk while running, e.g.:
Code:
ASUS_I006D:/data/adb/workdir/unpack/ramdisk # cat /dev/hP3B/.magisk/config
KEEPVERITY=false
KEEPFORCEENCRYPT=false
PATCHVBMETAFLAG=false
RECOVERYMODE=false
SHA1=1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
ASUS_I006D:/data/adb/workdir/unpack/ramdisk #
/dev/hP3B is a directory on the temporary ramdisk used by Magisk while it is running.
Use the command magisk --path to retrieve the path for the current ramdisk while Magisk is running, e.g.:
Code:
ASUS_I006D:/data/adb/workdir/unpack/ramdisk # magisk --path
/dev/hP3B
ASUS_I006D:/data/adb/workdir/unpack/ramdisk #
The SHA1 from the previous boot image is also stored in the file .backup/.magisk in the ramdisk of a boot image, e.g:
Code:
# Note: unpack the boot image and the ramdisk from the boot image to get that file
#
ASUS_I006D:/data/adb/workdir/unpack/ramdisk # cat .backup/.magisk
KEEPVERITY=false
KEEPFORCEENCRYPT=false
PATCHVBMETAFLAG=false
RECOVERYMODE=false
SHA1=1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
ASUS_I006D:/data/adb/workdir/unpack/ramdisk #
To do it all in once use:
Bash:
grep "^SHA1=" $( magisk --path )/.magisk/config | cut -f2 -d "="
e.g.:
Code:
ASUS_I006D:/data/adb/workdir/unpack/ramdisk # grep "^SHA1=" $( magisk --path )/.magisk/config | cut -f2 -d "="
1a05ccb9844d3ad4f6d1873dfbf76ebf83a5bdeb
ASUS_I006D:/data/adb/workdir/unpack/ramdisk # #
Backup the Magisk config
To backup the Magisk config just copy the directories in /data/adb except the directory /data/adb/magisk (that directory is used for the binaries only)
Code:
adb shell tar --exclude data/adb/magisk/ -czf /sdcard/Download/magisk_config_$( date +%Y-%m-%d).$$.tar /data/adb/
To restore the backup unpack the tar file on the phone and reboot the phone.
To also create a backup the settings from the Magisk App create a backup of the directory with the Magisk App Settings (see above for details).
Start/Stop the Magisk App
To start the Magisk App via CLI command use
Bash:
am start -n com.topjohnwu.magisk/.ui.MainActivity
To stop the Magisk App via CLI command use:
Bash:
am force-stop com.topjohnwu.magisk
Start/Stop the Magisk Daemon
To stop the Magisk Daemon use
Bash:
magisk --stop
Be aware that stopping the magisk daemon will remove all bind mounts for files in /system. To re-enable these bind mounts a reboot is required.
To start the Magisk Daemon use
Bash:
/data/adb/magisk/magisk64 --daemon
To check if the Magisk Daemon is running use
Bash:
/data/adb/magisk/magisk64 -v
Example output:
Code:
# Magisk Daemon is running
ASUS_I006D:/ # /data/adb/magisk/magisk64 -v
25.2:MAGISK:R
ASUS_I006D:/ #
# Magisk Daemon is not running
|ASUS_I006D:/ # /data/adb/magisk/magisk64 -v
No daemon is currently running!
1|ASUS_I006D:/ #
Building Magisk
The Magisk source code is available at
https://github.com/topjohnwu/Magisk
There are also instructions how to create a local copy of the repository and compile Magisk on that page. I've successfully build Magisk using these instructions.
Miscellaneous
magiskboot can also be used compress or decompress files:
Code:
1|ASUS_I006D:/data/adb/magisk # ./magiskboot
MagiskBoot - Boot Image Modification Tool
Usage: ./magiskboot <action> [args...]
Supported actions:
...
compress[=format] <infile> [outfile]
Compress <infile> with [format] to [outfile].
<infile>/[outfile] can be '-' to be STDIN/STDOUT.
If [format] is not specified, then gzip will be used.
If [outfile] is not specified, then <infile> will be replaced
with another file suffixed with a matching file extension.
Supported formats: gzip zopfli xz lzma bzip2 lz4 lz4_legacy lz4_lg
decompress <infile> [outfile]
Detect format and decompress <infile> to [outfile].
<infile>/[outfile] can be '-' to be STDIN/STDOUT.
If [outfile] is not specified, then <infile> will be replaced
with another file removing its archive format file extension.
Supported formats: gzip zopfli xz lzma bzip2 lz4 lz4_legacy lz4_lg
1|ASUS_I006D:/data/adb/magisk #
magiskboot is also used in TWRP to unpack and repack the boot image for installing Magisk
Using the magisk binary while the phone is booted into TWRP
If the used TWRP can mount the volume for /data you can also use the binary magisk while in TWRP. The magisk binary is not in the path while booted into TWRP - therefor you must use the fully qualified filename:
This is
/data/adb/magisk/magisk64
for 64 Bit CPUs and
/data/adb/magisk/magisk32
for 32 Bit CPUs.
Some functions of Magisk are only usable if the Magisk daemon is running. To start the Magisk daemon the Magisk binary can also be used - example:
Code:
# read the policies table from the Magisk squlite database
#
ASUS_I006D:/ # /data/adb/magisk/magisk64 --sqlite "select * from policies ;"
No daemon is currently running!
#
# -> the Magisk daemon is not running -> start it
#
1|ASUS_I006D:/ # /data/adb/magisk/magisk64 --daemon
ASUS_I006D:/ #
ASUS_I006D:/ # /data/adb/magisk/magisk64 --sqlite "select * from policies ;"
logging=1|notification=1|policy=2|uid=2000|until=0
logging=1|notification=1|policy=2|uid=10135|until=0
logging=1|notification=1|policy=2|uid=10143|until=0
logging=1|notification=1|policy=2|uid=10055|until=0
logging=1|notification=1|policy=2|uid=10142|until=0
ASUS_I006D:/ #
Use
Bash:
/data/adb/magisk/magisk64 -V
to check if the Magisk daemon is running
Use
Bash:
/data/adb/magisk/magisk64 --stop
to stop the Magisk Daemon, e.g.:
Code:
ASUS_I006D:/ # /data/adb/magisk/magisk64 -V
25200
# -> The Magisk Daemon is running
ASUS_I006D:/ # /data/adb/magisk/magisk64 --stop
ASUS_I006D:/ #
ASUS_I006D:/ # /data/adb/magisk/magisk64 -V
No daemon is currently running!
1|ASUS_I006D:/ # 2D
Trouble Shooting
If something went wrong and booting the phone does not work anymore after installing a Magisk Module just remove the files in /data/adb/modules/<modulename> and reboot the phone :
Either connect via adb to the not booting phone (this should be possible in most cases even if the boot process does not finish), delete the files, and reboot the phone. Or reboot the phone from a Recovery image like TWRP, delete the files in /data/adb/modules/<modulename>, and reboot the phone.
The same procedure can be used if booting the phone does not work anymore after adding another init script - just delete the new script in /data/adb/post-fs-data.d or /data/adb/service.d and reboot the phone
An error like this
Code:
08-06 18:41:39.341 +0000 1356 1726 W ziparchive: Unable to open '/system/app/AsusFMRadio/AsusFMRadio.apk': Permission denied
08-06 18:41:39.341 +0000 1356 1726 E system_server: Failed to open APK '/system/app/AsusFMRadio/AsusFMRadio.apk': I/O error
08-06 18:41:39.354 +0000 1356 1356 W PackageManager: Failed to parse /system/app/AsusFMRadio: Failed to parse /system/app/AsusFMRadio/AsusFMRadio.apk
is most of the time caused by missing read permissions for the file.
Use
Bash:
chmod o+r /system/app/AsusFMRadio/AsusFMRadio.apk
to fix it.
To catch errors from a script executed by Magisk you might use this technique:
Bash:
# redirect STDERR of all commands in the script to a file
#
exec 2>/data/script_stderr.log
set -x
... rest of your script
To remove all installed Magisk Modules using the official method use:
Code:
magisk --remove-modules
to remove all modules (but not the new init scripts!) and reboot the phone
According to the FAQ Magisk will not start if the phone is booted into safe mode (see
https://topjohnwu.github.io/Magisk/faq.html)
Be aware that after rebooting the phone again in normal mode all Magisk Modules are disabled and must be enabled again using either the Magisk App or a CLI command:
To reenable all Magisk Modules via shell command do
Bash:
adb shell rm /data/adb/modules/*/disable
Spoiler: History
HIstory
07.08.2022 /bs
Added additional infos about the permissions for new files for /system.
Added additional commands to the script for catching the OS logs while booting the phone
Added infos about a workaround to add new files to /product, /vendor, or /system_ext
Added infos about how to access file replaced by a Magisk Module
20.09.2022 /bs
Added new links to posts about configuring swap devices via Magisk script
Added a link to the post about how to use Magisk to unpack and repack the boot image
28.09.2022 /bs
Added infos about the backups of the boot partitions created by Magisk
30.09.2022 /bs
Added a short info about using Magisk Overlays to change files in the root filesystem
Added the URL for the post with how to change the active slot using the Magisk App
02.10.2022 /bs
Added a short info about Root Directory Overlay system from Magisk
04.10.2022 /bs
Add an URL to another post to use the Root Directory Overlay system from Magsik
Fixed some spelling errors and also some errors in the code examples
Added more details about changing files in /system
26.10.2022/bs
Added the section Miscellaneous
28.10.2022/bs
Added the section Start/Stop the Magisk App
Added the section Start/Stop the Magisk Daemon
02.11.2022 /bs
added the infos about the x86 version of the magiskboot executables in the Magisk apk file
fixed some spelling and formatting errors
04.11.2022/bs
add the link to the Howto about making a file in /system writable
corrected some formatting errors
06.11.2022/bs
added more details about the boot partition backups created by Magisk
added missing "su - -c" to some adb shell commands
07.11.2022/bs
added more details about the boot partition backups created by Magisk
added the section about the temporary Magisk config directory
08.11.2022/bs
added the section about how to get the Magisk App installation directory
25.11.2022/bs
added infos about how to build Magisk using a local copy of the repository
02.12.2022 /bs
added the infos about sing the magisk binary while the phone is booted into TWRP
06.12.2022 /bs
added the section Magisk root access configuration details
added infos about the files used to store the settings for the Magisk App
30.12.2022 /bs
added more infos about how to add new start / stop services in Android
07.05.2023 /bs
add infos about how to create the Magisk database manuallay
Nice.
Thank you very much for all the details and explanations.
possible to change "Automatic Response" setting via adb command?
LEENO said:
possible to change "Automatic Response" setting via adb command?
Click to expand...
Click to collapse
What do you mean with "Automatic Response"?
bnsmb said:
What do you mean with "Automatic Response"?
Click to expand...
Click to collapse
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Most probably yes ... I will check that
LEENO said:
View attachment 5778489
Click to expand...
Click to collapse
Where does the Magisk App store the settings?
How to run a script at shutdown
To define additional startup scripts via Magisk the Magisk directories /data/adb/service.d and /data/adb/post-fs-data.d can be used. Unfortunately there is no equivalent for scripts that should be executed during shutdown.
So we must use other methods to implement these kind of scripts.
Using the overlay feature of Magisk to run a script at shutdown
Introduction
in Android it is possible to define actions that will be executed when certain conditions are satisfied.
These definitions are done in the file init.rc (and other .rc files) using the Android Init Language.
And this feature can be used to execute a command when the phone is shutting down.
Note:
For details about the Android Init Language used for these files see here https://android.googlesource.com/platform/system/core/+/master/init/README.md
The .rc files used by Android are in the directories
/system/etc/init/vendor/etc/init/odm/etc/init
Note: The first .rc file read is /system/etc/init/hw/init.rc
Unfortunately it's useless to change the .rc files in these directories using the Magisk features to change files in the directory /system because these files are processed by the OS before the new files are "created" by Magisk.
Therefor the overlay functionality from Magisk must be used to create additional .rc files (see the section Root Directory Overlay System on this page https://github.com/topjohnwu/Magisk/blob/master/docs/guides.md for details about this Magisk Feature).
Preparation
To be able to restore the original boot partition in case of an error create an image of the original boot partition from the phone on your PC before starting the development:
Code:
CUR_SLOT=$( adb shell getprop ro.boot.slot_suffix )
adb shell su - -c dd if=/dev/block/by-name/boot${CUR_SLOT} | cat >boot${CUR_SLOT}
e.g.
Code:
[ OmniRomDev - [email protected] /data/develop/android/test ] $ CUR_SLOT=$( adb shell getprop ro.boot.slot_suffix )
[ OmniRomDev - [email protected] /data/develop/android/test ] $ echo ${CUR_SLOT}
_b
[ OmniRomDev - [email protected] /data/develop/android/test ] $
[ OmniRomDev - [email protected] /data/develop/android/test ] $ adb shell su - -c dd if=/dev/block/by-name/boot${CUR_SLOT} | cat >boot${CUR_SLOT}.img
196608+0 records in
196608+0 records out
100663296 bytes (96 M) copied, 2.668147 s, 36 M/s
[ OmniRomDev - [email protected] /data/develop/android/test ]
[ OmniRomDev - [email protected] /data/develop/android/test ] $ ls -ltr boot${CUR_SLOT}.img
-rw-r--r--. 1 xtrnaw7 xtrnaw7 100663296 Oct 1 12:13 boot_b.img
[ OmniRomDev - [email protected] /data/develop/android/test ] $
To trouble shoot issues with this approach it is highly recommended to create an Magisk init script in the directory
/data/adb/post-fs-data.d
to fetch and store the Android logs into a persistent file. Use these commands to create the script:
Code:
cat >/data/adb/post-fs-data.d/0002logcatboot <<-EOT
mkdir -p /cache/logs
# backup the OS logs from before the reboot:
#
[ -r /cache/logs/log ] && mv /cache/logs/log /cache/logs/oldlog
/system/bin/logcat -r 102400 -n 9 -v threadTime -f /cache/logs/log >/cache/logs/info.log 2>/cache/logs/err.log &
EOT
chmod 755 /data/adb/post-fs-data.d/0001logcatboot
Using this script the log messages from before the last reboot are stored in the file /cache/logs/oldlog.
To activate the script the phone must be rebooted.
Check the contents of the directory /cache/logs/log after the reboot as user root to be sure that it works.
Code:
[email protected]_I006D:/ $ su - -c ls -ltr /cache/logs
total 205008
-rw-rw-rw- 1 root root 0 1970-01-06 08:16 info.log
-rw-rw-rw- 1 root root 0 1970-01-06 08:16 err.log
-rw-r----- 1 root root 4707523 2022-10-01 17:29 log
[email protected]_I006D:/ $
Details
The trigger in the .rc files for the action that should be done while shutting down is
on shutdown
The trigger can be used more then once; the OS will execute all defined actions for the trigger in the order they are found in the rc files.
The action to run an executable in the .rc file is
exec [ <seclabel> [ <user> [ <group>\* ] ] ] -- <command> [ <argument>\* ]
Fork and execute command with the given arguments. The command starts after “--” so that an optional security context, user, and supplementary groups can be provided. No other commands will be run until this one finishes. seclabel can be a - to denote default. Properties are expanded within argument. Init halts executing commands until the forked process exits.
Click to expand...
Click to collapse
In Android SELinux is enabled by default. Therefor it's neccessary to use the correct SELinux context for the files used.
(Note: The SELinux context for the init process executing the action is u:r:init:0 )
It's quite difficult to find the correct SELinux contexts in Android for this approach therefor it's better to use the general SELinux context defined by Magisk: u:r:magisk:s0 .
Implementation
Note:
All commands must be done as user root in an session on the phone or in an adb session.
So first create the neccessary directories and files:
Code:
mkdir -p /data/init_scripts
mkdir -p /data/init_scripts/log
Create the script to execute on shutdown:
Code:
cat >/data/init_scripts/my_shutdown.sh <<-\EOT
#!/system/bin/sh
SHUTDOWN_LOG="/data/init_scripts/log/myshutdown.$$.log"
echo "$0: Shutdown with parameter \"$*\" started at $( date ) " >>${SHUTDOWN_LOG}
echo "*** id : " >>${SHUTDOWN_LOG} 2>&1
id >>${SHUTDOWN_LOG} 2>&1
# ... add necessary commands ...
EOT
chmod 755 /data/init_scripts/my_shutdown.sh
Correct the SELinux context:
Code:
chcon -R u:r:magisk:s0 /data/init_scripts/
Check the result
Code:
[email protected]_I006D:/ # find /data/init_scripts/ -exec ls -ld {} \;
drwxr-xr-x 3 root root u:r:magisk:s0 3452 2022-10-01 16:12 /data/init_scripts/
-rwxr-xr-x 1 root root u:r:magisk:s0 637 2022-10-01 16:12 /data/init_scripts/my_shutdown.sh
drwxr-xr-x 2 root root u:r:magisk:s0 3452 2022-10-01 16:16 /data/init_scripts/log
[email protected]_I006D:/ #
Create a working directory:
Code:
#
# create a working directory
#
mkdir -p /data/adb/workdir
cd /data/adb/workdir
Now create the additional .rc file:
Code:
#
# change the current directory to the working directory
#
cd /data/adb/workdir
cat >init.custom.rc <<-\EOT
on shutdown
exec u:r:magisk:s0 -- /system/bin/sh /data/init_scripts/my_shutdown.sh 0008
on early-init
setprop my_custom_rc_file loaded
EOT
Note:
The additional trigger for early-init is for testing the new .rc file (see the trouble shooting section below for details). Magisk supports more then one .rc file; the name of the .rc file is meaningless but the extension must be .rc.
And now add the new file to the ramdisk on the boot partition:
Code:
#
# change the current directory to the working directory
#
cd /data/adb/workdir
# get the current active slot
#
CURRENT_SLOT=$( getprop ro.boot.slot_suffix )
echo "The current active slot is: ${CURRENT_SLOT}"
# copy the boot partition from the active slot to a file
#
dd if=/dev/block/by-name/boot${CURRENT_SLOT} of=./boot_root.img
# unpack the image file
#
/data/adb/magisk/magiskboot unpack ./boot_root.img
# add the new dirs and files to the ramdisk from the boot partition
#
/data/adb/magisk/magiskboot cpio ramdisk.cpio \
"mkdir 0700 overlay.d" \
"add 0700 overlay.d/init.custom.rc init.custom.rc"
# recreate the image file for the boot partition
#
/data/adb/magisk/magiskboot repack boot_root.img
# write the corrected image file to the boot partition
#
dd if=./new-boot.img of=/dev/block/by-name/boot${CURRENT_SLOT}
Note:
The commands to unpack and pack the ramdisk manually using the cpio command are (if NOT using the Magisk binary magiskboot):
Code:
RAMDISK=$PWD/ramdisk
mkdir ${RAMDISK}
cd ${RAMDISK}
# unpack the ramdisk
#
cpio -idm <../ramdisk.cpio
# ... do what ever is necessary with the files/dirs in ${RAMDISK}
# pack the ramdisk again
#
cd ${RAMDISK}
find . | cpio -o >../ramdisk.cpio
Now reboot the phone to activate the new .rc config and after the reboot check that the .rc file was processed
Code:
getprop my_custom_rc_file
e.g
Code:
[email protected]_I006D:/ $ getprop my_custom_rc_file
loaded
[email protected]_I006D:/ $
If the property defined in the .rc file, my_custom_rc_file, is not set something went wrong and you should check the OS logs and double check your config.
If the new property is defined you can test the shutdown action by rebooting the phone again.
While doing this reboot the new shutdown script should be executed and after the reboot is done there should be the log file from the shutdown script:
Code:
[email protected]_I006D:/ $ su -
[email protected]_I006D:/ # ls -l /data/init_scripts/log
total 0
-rw------- 1 root root 179 2022-10-01 18:23 myshutdown.4617.log
[email protected]_I006D:/ # cat /data/init_scripts/log/myshutdown.4617.log
/data/init_scripts/my_shutdown.sh: Shutdown with parameter "0008" started at Sat Oct 1 18:23:14 CEST 2022
*** id :
uid=0(root) gid=0(root) groups=0(root) context=u:r:magisk:s0
[email protected]_I006D:/ #
That's it.
Note that you can change the script executed while doing the shutdown without changing the boot image again.
But you should always test the script before rebooting -- an error in your script may stop the reboot.
To change the additional .rc files it's necessary to recreate the ramdisk and boot partition.
The filesystems for /data and for /sdcard are still mounted while executing the actions for the trigger "on shutdown" .
To log the current environment while executing the shutdown script you can add code like this to the script:
Code:
(
echo
echo "*** Environment while executing the shutdown script ..."
echo
echo "*** pwd: "
pwd
echo
echo "*** id: "
id
echo
echo "*** df -h: "
df -h
echo
echo "*** ps -efZ : "
ps -efZ
echo
echo "*** env: "
env
echo
echo "*** set: "
set
echo
) >>/data/init_scripts/log/myshutdown_env.log 2>&1
To create a directory in which other actions from the .rc file (like write) can write with SELinux enabled use one of the SELInux contexts the init process can write to, e.g:
Code:
mkdir /data/system_data
chcon u:object_r:system_data_file:s0 /data/system_data
Now the .rc config
Code:
on shutdown
write /data/system_data/myshutdown.log Shutdown_started\n
will work.
See the file ./plat_file_contexts in the ramdisk from the boot partition for other existing SELinux contexts, e.g.:
Code:
[email protected]_I006D:/data/adb/test # /data/adb/magisk/magiskboot cpio ramdisk.cpio "extract plat_file_contexts plat_file_contexts" <
Loading cpio: [ramdisk.cpio]
Extract [plat_file_contexts] to [plat_file_contexts]
[email protected]_I006D:/data/adb/test # ls -l plat_file_contexts
-rw-r--r-- 1 root root 40490 2022-10-03 16:27 plat_file_contexts
[email protected]_I006D:/data/adb/test #
Please be aware that these changes will be gone after the next OS update. But on the other hand it's quite easy to create a script to re-install the shutdown script without user intervention.
Trouble Shooting
The main reason for problems with this approach are invalid SELinux contexts. Therefor you should test your script in permissive SELinux mode if it does not work like expected. To do that temporary disable SELinux before rebooting (SELinux will be automatically enabled again after the reboot), e.g.:
Code:
# set SELinux to permissive
#
setenforce 0
reboot
and check the log messages in the directory /cache/logs/oldlog for SELinux related messages:
Code:
su - -c grep deny /cache/logs/oldlog
Note that you can not disable SELinux in an action in an .rc file.
To check if your additional .rc file is processed by Magisk add a statement like these to the custom .rc file in the overlay directory:
Code:
on early-init
setprop sys.example.foo bar
If this statement is processed by Magisk and Android the property sys.example.foo should be defined after the reboot, e.g.:
Code:
[email protected]_I006D:/ # getprop sys.example.foo
bar
[email protected]_I006D:/ #
To check if the "on shutdown" trigger is processed use :
Code:
on shutdown
write /sdcard/Download/myshutdown.log Shutdown_started\n
and reboot with disabled SELinux:
Code:
setenforce 0
reboot
If the "on shutdown" trigger in your .rc file is processed there should exist the file
/sdcard/Download/myshutdown.log
after the reboot
If the shutdown of the phone hangs open another adb session to the phone and kill the script (the adb daemon should still run while the shutdown script is running).
If the phone does not boot anymore with the new shutdown script reboot the phone from the TWRP image and fix / delete the new shutdown script. Or reflash the boot partition with the image file created before starting the development.
In general you should carefully check your .rc file for syntax errors -- entries in the file after the first syntax error will be ignored
Useful URLs
I used ideas and code from the web pages listed below for this HowTo:
How to run an executable on boot and keep it running?
How to run an Android init service with superuser SELinux context?
Magisk overlay - execute a script or copy files
History
03.10.2022 /bs
added code about to extract a single file (plat_file_contexts) from the ramdisk cpio image using magiskboot
How to trigger an action when a property is changed
In Android it's possible to trigger various actions by changing the value of a property.
This feature is quite handy and the implementation using Magisk is not really difficult.
As an example:
In the original Android from ASUS for the Zenfone 8 you can disable and enable the swap on a ZRAM device by changing the value for the property vendor.zram.enable:
e.g.:
To turn the swap on use
Code:
setprop vendor.zram.enable 1
and to turn the swap off use
Code:
setprop vendor.zram.enable 0
To get the current value use
Code:
getprop vendor.zram.enable
or
check the output of the OS command free.
(see How to disable or change the swap device in the Android 12 from ASUS for the Zenfone 8 for details)
This feature is not implemented in the OmniROM for the ASUS Zenfone 8 but quite useful so let's see how to implement it in the OmniROM.
The Triggers and Action for this Android feature are configured in the init.rc files in the root filesystem for the OS (see https://android.googlesource.com/platform/system/core/+/master/init/README.md for details). The root filesystem for Android is read-only mounted so without creating your own Android OS image for the phone it's not possible to add the functionality to the OS.
But we can use the Root Directory Overlay System from Magisk (see https://github.com/topjohnwu/Magisk/blob/master/docs/guides.md for the documentation) to implement it.
The detailed process for creating additional *.rc files for Android via Magisk is described here:
How to run a script at shutdown
Therefore I will not go into the details here. But please read that post before you continue
First we check how this feature is implemented in the Original Android for the Zenfone:
Enabling and disabling the swap device on ZRAM is configured in the .rc file
/vendor/etc/hw/init.asus.debugtool.rc
using these settings in the original Android OS for the Zenfone 8:
Code:
service asus_zram /system/vendor/bin/sh /vendor/bin/init.asus.zram.sh
user root
group root
disabled
seclabel u:r:vendor_qti_init_shell:s0
oneshot
on property:persist.vendor.zram.enable=1
setprop vendor.zram.enable "1"
setprop vendor.zram.disksize ${persist.vendor.zram.disksize}
on property:persist.vendor.zram.enable=0
setprop vendor.zram.enable "0"
setprop vendor.zram.disksize ${persist.vendor.zram.disksize}
on property:vendor.zram.enable=*
start asus_zram
The script used to enable or disable the swap device on ZRAM in the original Android for the Zenfone 8 is:
/vendor/bin/init.asus.zram.sh
The script is quite simple (see also below):
It uses two properties to configure the swap device:
vendor.zram.enable : if this property is set to 1 the script enables the swap device and if the property is set to 0 it disables the swap device
vendor.zram.disksize : the value of this property is the size of the ramdisk.
Now we can implement this feature for the OmniROM:
Note:
All commands must be done as user root in a shell on the phone or in an adb shell
First we check the prerequisites for the feature:
The used shell for the service exists in the OmniROM:
Code:
[email protected]_I006D:/data/adb/workdir # ls -Zl /vendor/bin/sh
-rwxr-xr-x 1 root shell u:object_r:vendor_shell_exec:s0 318216 2009-01-01 01:00 /vendor/bin/sh
[email protected]_I006D:/data/adb/workdir #
The script to toggle the ramdisk on the swap device also already exists in the OmniROM:
Code:
[email protected]_I006D:/data/adb/test # ls -l /vendor/bin/init.asus.zram.sh
-rwxr-xr-x 1 root shell 1127 2009-01-01 01:00 /vendor/bin/init.asus.zram.sh
[email protected]_I006D:/data/adb/test #
And the necessary SELinux contexts are also already defined in the OmniROM.
So, let's start:
Code:
# create a temporary directory
#
mkdir /data/adb/workdir
cd /data/adb/workdir
# create the additional .rc file
#
cat >init.asus.zram.rc <<-\EOT
#
# Note:
#
# The service definition for an OS without the script init.asus.zram.sh should be
#
# service asus_zram /system/bin/sh /system/sbin/init.asus.zram.sh
#
service asus_zram /system/vendor/bin/sh /vendor/bin/init.asus.zram.sh
user root
group root
disabled
seclabel u:r:vendor_qti_init_shell:s0
oneshot
#
# these properties can be used to define the initial state of the ramdisk on ZRAM
#
on property:persist.vendor.zram.enable=1
setprop vendor.zram.enable "1"
setprop vendor.zram.disksize ${persist.vendor.zram.disksize}
on property:persist.vendor.zram.enable=0
setprop vendor.zram.enable "0"
setprop vendor.zram.disksize ${persist.vendor.zram.disksize}
on property:vendor.zram.enable=*
start asus_zram
# The property persist.vendor.zram.enable is not defined in the OmniROM. If necessary you can add another triger in the .rc file,
# e.g to enable the swap device by default use
#
on early-init
setprop persist.vendor.zram.enable 1
EOT
# get the current active slot
#
CURRENT_SLOT=$( getprop ro.boot.slot_suffix )
echo "The current active slot is: ${CURRENT_SLOT}"
# copy the boot partition from the active slot to a file
dd if=/dev/block/by-name/boot${CURRENT_SLOT} of=./boot_root.img
# unpack the image file
/data/adb/magisk/magiskboot unpack ./boot_root.img
# add the new dir and file to the ramdisk from the boot partition
/data/adb/magisk/magiskboot cpio ramdisk.cpio \
"mkdir 0700 overlay.d" \
"add 0700 overlay.d/init.custom.rc init.asus.zram.rc"
# recreate the image file for the boot partition
/data/adb/magisk/magiskboot repack boot_root.img
# write the corrected image file to the boot partition
dd if=./new-boot.img of=/dev/block/by-name/boot${CURRENT_SLOT}
That's it.
After the next reboot switching the ramdisk on the ZRAM device via an property should be active:
Code:
[email protected]_I006D:/ # reboot
# .....
# start a new adb session
# ....
[email protected]_I006D:/ $ getprop ro.omni.version
12-20220703-zenfone8-MICROG
#
# Note: The property is only visible to the user root
#
[email protected]_I006D:/ $ su -
[email protected]_I006D:/ # id
uid=0(root) gid=0(root) groups=0(root) context=u:r:magisk:s0
[email protected]_I006D:/ #
[email protected]_I006D:/ # free
total used free shared buffers
Mem: 7612493824 4835229696 2777264128 14585856 14487552
-/+ buffers/cache: 4820742144 2791751680
Swap: 4294963200 0 4294963200
[email protected]_I006D:/ #
[email protected]_I006D:/ # getprop vendor.zram.enable
1
[email protected]_I006D:/ #
# -> now disable the swap on ZRAM
[email protected]_I006D:/ # setprop vendor.zram.enable 0
[email protected]_I006D:/ #
[email protected]_I006D:/ # getprop vendor.zram.enable
0
[email protected]_I006D:/ #
[email protected]_I006D:/ # free
total used free shared buffers
Mem: 7612493824 4840824832 2771668992 14524416 14483456
-/+ buffers/cache: 4826341376 2786152448
Swap: 0 0 0
[email protected]_I006D:/ #
# -> now enable the swap on ZRAM again
[email protected]_I006D:/ # setprop vendor.zram.enable 1
[email protected]_I006D:/ #
[email protected]_I006D:/ # getprop vendor.zram.enable
1
[email protected]_I006D:/ #
[email protected]_I006D:/ # free
total used free shared buffers
Mem: 7612493824 4844777472 2767716352 14524416 14512128
-/+ buffers/cache: 4830265344 2782228480
Swap: 4294963200 0 4294963200
[email protected]_I006D:/ #
Workarounds for other configuration
Find below some workarounds for OS versions without the prerequisites for implementing this feature.
1. The script to toggle the swap /vendor/bin/init.asus.zram.sh does not exist
If the script /vendor/bin/init.asus.zram.sh does not exist in your OS create a Magisk Module for the script
To create a (dummy) Magisk Module for the script do:
Code:
mkdir -p /data/adb/modules/toggle_ram/system/bin
#
# create the script to toggle the ramdisk on ZRAM
#
cat >/data/adb/modules/toggle_ram/system/bin/init.asus.zram.sh <<-\EOT
lahaina_set=`getprop vendor.asus.zram_setting`
if test "$lahaina_set" != "1"; then
echo "[asus_zram] init.kernel.post_boot-lahaina.sh not finished yet!"> /dev/kmsg
exit 0
fi
disksize=`getprop vendor.zram.disksize`
zram_enable=`getprop vendor.zram.enable`
MemTotalStr=`cat /proc/meminfo | grep MemTotal`
MemTotal=${MemTotalStr:16:8}
let RamSizeGB="( $MemTotal / 1048576 ) + 1"
if test "$disksize" = ""; then
disksize="4096M"
fi
echo "[asus_zram]RamSizeGB=${RamSizeGB}" > /dev/kmsg
if test "$zram_enable" = "1"; then
if [ $RamSizeGB -le 7 ]; then #this is for 6G; or the value will be 4G(8G,12G,16G,18G,etc)
disksize="( $RamSizeGB * 1024 ) / 2""M"
fi
swapoff /dev/block/zram0 2>/dev/kmsg
echo 1 > sys/block/zram0/reset 2>/dev/kmsg
sleep 1
echo lz4 > /sys/block/zram0/comp_algorithm
echo $disksize > /sys/block/zram0/disksize 2>/dev/kmsg
mkswap /dev/block/zram0 2>/dev/kmsg
swapon /dev/block/zram0 -p 32758 2>/dev/kmsg
echo "[asus_zram]write zram disksize=${disksize}" > /dev/kmsg
fi
if test "$zram_enable" = "0"; then
swapoff /dev/block/zram0 2>/dev/kmsg
echo "[asus_zram]turn off the zram" > /dev/kmsg
fi
EOT
chmod 755 /data/adb/modules/toggle_ram/system/bin/init.asus.zram.sh
chown root:shell /data/adb/modules/toggle_ram/system/bin/init.asus.zram.sh
chcon u:object_r:vendor_file:s0 /data/adb/modules/toggle_ram/system/bin/init.asus.zram.sh
Check the result:
Code:
[email protected]_I006D:/ # ls -lZ /data/adb/modules/toggle_ram/system/bin/init.asus.zram.sh
-rwxr-xr-x 1 root shell u:object_r:vendor_file:s0 1109 2022-10-03 21:14 /data/adb/modules/toggle_ram/system/bin/init.asus.zram.sh
[email protected]_I006D:/ #
Then change the script to execute in the service definition in the .rc file to /system/bin/init.asus.zram.sh:
Code:
service asus_zram /system/vendor/bin/sh /system/bin/init.asus.zram.sh
The rest of the instructions can be be used without changes.
2. The binary /system/vendor/bin/sh does not exist
If the shell /system/vendor/bin/sh does not exist in the OS create an Magisk Module with an approbiate shell:
Note:
The shell /system/bin/sh can not be used because it's configured with another SELinux context:
Code:
[email protected]_I006D:/ # ls -lZ /system/vendor/bin/sh
-rwxr-xr-x 1 root shell u:object_r:vendor_shell_exec:s0 318216 2009-01-01 01:00 /system/vendor/bin/sh
[email protected]_I006D:/ #
# but
[email protected]_I006D:/data/adb/workdir # ls -Zl /system/bin/sh
-rwxr-xr-x 1 root shell u:object_r:shell_exec:s0 307768 2009-01-01 01:00 /system/bin/sh
[email protected]_I006D:/data/adb/workdir #
To create a (dummy) Magisk Module for the necessary shell do:
Code:
mkdir -p /data/adb/modules/vendorshell/system/bin
cp /system/bin/sh /data/adb/modules/vendorshell/system/bin/sh
chcon u:object_r:vendor_shell_exec:s0 /data/adb/modules/vendorshell/system/bin/vendor_sh
Check the result:
Code:
[email protected]_I006D:/data/adb/workdir # ls -lZ /data/adb/modules/vendorshell/system/bin/vendor_sh
-rwxr-xr-x 1 root root u:object_r:vendor_shell_exec:s0 307768 2022-10-03 20:41 /data/adb/modules/vendorshell/system/bin/vendor_sh
[email protected]_I006D:/data/adb/workdir #
Now change the shell in the service definition in the .rc file to /system/bin/vendor_sh:
Code:
service asus_zram /system/bin/vendor_sh /vendor/bin/init.asus.zram.sh
The rest of the instructions can be be used without changes.
3. The necessary shell /system/vendor/bin/sh and the script /vendor/bin/init.asus.zram.sh do both not exist
If the necessary shell /system/vendor/bin/sh and the script /vendor/bin/init.asus.zram.sh do not exist you can also create one (dummy) Magisk module for both.
See
https://topjohnwu.github.io/Magisk/guides.html
and
Some hints for using Magisk on Android phones
for instructions and infos about how to create a real Magisk Module
4. Missing SELinux contexts
These instructions assume that all necessary SELinux contexts are already defined in the used OS.
If there are SELinux contexts missing it might not work without adding the missing SELinux contexts
(that might be difficult and I must admit that I did not test that)
5. only for the records:
The magiskboot command can also be used to add new files to the /sbin directory in the root filesystem.
This can be can be configured like this:
Code:
/data/adb/magisk/magiskboot cpio ramdisk.cpio \
"mkdir 0700 overlay.d" \
"add 0700 overlay.d/init.custom.rc init.asus.zram.rc" \
"mkdir 0700 overlay.d/sbin" \
"add 0700 overlay.d/sbin/my_new_script.sh my_script.sh"
This is useful for adding binaries or scripts for actions that should be executed while the other partitions are not yet mounted and therefor the files in these filesystems not yet available. But for the action defined in this post this is not necessary.
And be aware that the files added to the root filesystem ( /sbin/my_new_script.sh in this example) is only available while booting the phone.
6. Other problems
In case of problems please check the post
How to run a script at shutdown
again.
Also check the restrictions for this approach documented in that post
History
06.10.2022 /bs
corrected some typos
For automatic installation and configuration of a phone running the Android OS the access via adb is required. "Unfortunately" the access via adb is disabled in most Android distributions (in reality it is of course good that the access via adb is disabled in the default setting! See also the notes regarding the LineageOS at the end of this post))
There are (at least) two ways to enable access via adb:
Manually via the GUI of Android on the phone or via the Android command settings executed by the user root in a shell ,e.g.:
Bash:
settings put global development_settings_enabled 1
settings put global adb_enabled 1
The latter can also be done in a script in an adb shell -- but of course we need a working adb connection ....
One way around this problem is to use Magisk:
In principle this could be done using an init script for Magisk:
Magisk allows to run scripts while booting the phone (see How to run a script at every boot using Magisk); this feature could be used to enable adb via script.
Unfortunately, this method no longer works in the latest Android versions (Androd 12 and Android 13; Android 11 not tested):
Android now uses encryption for most of the files in the subdirectories in /data and to initiate the encryption keys for the files in these directories, the phone must boot once from the installed OS.
To use a Magisk init script to enable the access via adb, we need to create files in the directories /data/adb and /data/misc/adb. If you create these files while booting into TWRP recovery without a configured Android operating system, these files will be created unencrypted, making it impossible to boot the installed Android operating system:
If the Android operating system finds unencrpyted files in these directories at the first reboot, it boots into the installed recovery with the famous error message "Cannot load Android system. Your data may be corrupt" (see How to fix the error "Cannot load Android system. Your data may be corrupt" for details)
Fortunately, the Android operating system does not encrypt files in the directory /data/recovery (and therefore continues booting if there are already files in that directory) and the part of Magisk in the boot partition does not need the Magisk files /data/adb.
So to enable the access via adb using Magisk, we can create a script in the directory /data/recovery and a new Init .rc file for the Android operating system to execute that script while the Android OS is booting - for details about how to do that see How to trigger an action when a property is changed.
The working method to enable adb via Magisk is as follows:
- Boot the phone from a recovery (like TWRP)
- Install the new OS image but do not reboot the phone (see How to install an OS image using the TWRP binary twrp for how to install the OS via the cli commands from TWRP)
- Install Magisk into the boot partition of the phone and delete all files in /data/adb afterwards (see How to install Magisk into the boot partition using a script for how to install Magisk via script)
- copy a script to the directory /data/recovery on the phone that will enable access via adb using the Android command settings and copy the public ssl keys for the access via adb to the directory /data/misc/adb on the phone
- install a new init .rc file via Magisk which executes the script in the direcory /data/recovery to enable the access via adb - this script will be executed while doing the 1st reboot of the new installed Android OS.
(see How to trigger an action when a property is changed for how to add a new init .rc file using Magisk)
- reboot the phone
I wrote two scripts to enable adb using this method:
enable_adb_using_magisk.sh
The script enable_adb_using_magisk.sh must run in an adb session in TWRP after the new OS was installed and after Magisk has been installed into the boot partition but before the first reboot of the new installed operating system.
The script enable_adb_using_magisk.sh
- creates the script /data/recover/enable_adb_via_service.sh on the phone to enable adb and install the public ssl key for access via adb
- creates a new init *rc file using Magisk that will run the script /data/recover/enable_adb_via_service.sh on the phone while doing the 1st reboot (after the file encryption for the files /data is initalized by the Android OS)
To use the script enable_adb_using_magisk.sh manually after installing the new OS and Magisk do while the phone is booted into TWRP:
Bash:
#
# copy the script enable_adb_using_magisk.sh to the directory /tmp on the phone
#
adb push enable_adb_using_magisk.sh /tmp/enable_adb_using_magisk.sh
# copy the public ssl key for access via adb to the directory /tmp on the phone
#
adb push $HOME/.android/adbkey.pub /tmp/adbkey.pub
# execute the script /tmp/enable_adb_using_magisk.sh on the phone
#
adb shell sh /tmp/enable_adb_using_magisk.sh
# reboot the phone into the new installed OS
#
adb reboot
Notes:
The script enable_adb_using_magisk.sh installs the init *rc file into the boot partition from the slot for the next reboot: In this scenario this is the slot with the new installed OS.
To specify the boot partition to use add the boot partition as parameter, e.g.
Bash:
adb shell sh /tmp/enable_adb_using_magisk.sh _a
The init *rc service used is:
Spoiler: init *rc service to enable adb
Code:
#
# additional RC service to enable the access via adb after the 1st boot into the new installed Android OS
#
service bnsmb_enable_adb /system/bin/sh /data/recovery/enable_adb_via_service.sh
user root
group root
seclabel u:r:magisk:s0
disabled
oneshot
on zygote-start
setprop sys.bnsmb_enable_adb_done 0
start bnsmb_enable_adb
#
# Note: the following entries are for testing only!
#
on zygote-start
write /data/recovery/semfile Here_I_am
setprop sys.bnsmb.test.okay 0
The script enable_adb_using_magisk.sh creates the files adb_keys and adb_temp_keys.xml in the directory /data/misc/adb if the public ssl key /tmp/adbkey.pub exists on the phone.
Note that the file /data/misc/adb/db_temp_keys.xml is an Android Binary XML fIle (see How to change files in Android XML Binary format for details about Android Binary XML files)
To avoid the manual steps listed above I wrote another script:
enable_access_via_adb.sh
The script enable_access_via_adb.sh does all the steps listed above; the usage for enable_access_via_adb.sh is
Code:
[ OmniRom 13 Dev - [email protected] /data/develop/android/scripts_on_linux ] $ ./enable_access_via_adb.sh -h
enable_access_via_adb.sh version - v1.0.0.0 - shell script to enable adb access via an init .rc file configured via Magisk
enable_access_via_adb.sh [-h|help|-H] [--reboot|--noreboot] [--nopubkey|--pubkey]
[ OmniRom 13 Dev - [email protected] /data/develop/android/scripts_on_linux ] $
Spoiler: Detailed Usage
Code:
[ OmniRom 13 Dev - [email protected] /data/develop/android/scripts_on_linux ] $ ./enable_access_via_adb.sh -H
enable_access_via_adb.sh version - v1.0.0.0 - shell script to enable adb access via an init .rc file configured via Magisk
Usage
enable_access_via_adb.sh [-h|help|-H] [--reboot|--noreboot] [--nopubkey|--pubkey]
All parameter are optional. The parameter can be used in any order.
Use the parameter "help" or "-H" to print the detailed usage help; use the parameter "-h" to print only the short usage help
If the parameter "--reboot" is used the script will reboot the phone after installing Init .rc file; to disable the automatic reboot use the parameter "--noreboot".
Default is to ask the user for confirmation to reboot the phone.
Use the parameter "--nopubkey" to disable configuring the public key of the current user on the PC for the access via adb; use the parameter "--pubkey" to configure
the public key; default is to configure the public key.
The default public ssl key used is the key in the file "${HOME}/.android/adbkey.pub".
To change some of the values used by the script these environment variables can be set before starting the script:
Set the environment variable PUBLIC_KEY_ON_PC to the file with the public ssl key to use for the access via adb if another public key should be used
Set the environment variable REBOOT to "yes" before starting the script to automatically reboot the phone after enabling the root access
Set the environment variable REBOOT to "no" before starting the script to disable the automatic reboot after enabling the root access
See also the source code of the script
boot_phone_from_twrp.sh
for environment variables supported by this script
Prerequisites
- the phone must be connected via USB
- Magisk must be already installed in the boot partition of the phone
- the phone must be either booted into the fastbootd or bootloader with a working fastboot connection
or already booted into a recovery image with working adb connnection
The scripts boot_phone_from_twrp.sh and enable_adb_using_magisk.sh are required by this script -- see the source code of the script
[ OmniRom 13 Dev - [email protected] /data/develop/android/scripts_on_linux ] $
So installing a new OS and enabling access via adb in a script without user intervention can be done using these commands:
Bash:
#
# do a factory reset and install the OS image using the TRWP binary twrp
#
REBOOT=no ./install_os_via_twrp.sh factory_reset /data/backup/ASUS_ZENFONE8/omnirom_local/omni-13/omni-13-20221211-zenfone8-MICROG.zip
# install Magisk into the boot sector of the partition with the new OS and delete all files in /data/adb afterwards
#
# The parameter delete_adb_dir for the script "install_magisk_via_twrp.sh" is only available in version 2.2.0.0 or newer of the script.
#
REBOOT=no ./install_magisk_via_twrp.sh next copy_apk delete_adb_dir
# enable adb and copy the public keys for adb via new init *rc file using Magisk in the boot partition
#
REBOOT=no ./enable_access_via_adb.sh
# reboot the phone
#
adb reboot
# wait until the new OS is booted and adb is enabled
#
adb wait-for-device
# install the Magisk App
#
./install_apk.sh /data/backup/Android/EssentialApps/Magisk-v25.2.apk
# install the Magisk directories and binaries in /data/adb
#
REBOOT=no ./install_magisk_via_twrp.sh adb_only
# (optional) enable root access for the adb shell
#
REBOOT=yes ./init_magisk_db.sh
Notes:
The script enable_access_via_adb.sh needs the helper script boot_phone_from_twrp.sh.sh and the script enable_adb_using_magisk.sh .
The scripts can be downloaded from my homepage:
enable_access_via_adb.sh
enable_adb_using_magisk.sh
boot_phone_from_twrp.sh
The other scripts mentioned in ths post can also be downloaded from my home page:
install_os_via_twrp.sh (see How to install an OS image using the TWRP binary twrp for a descripton of this script)
install_magisk_via_twrp.sh (see How to install Magisk into the boot partition using a script for a description for this script)
install_apk.sh (see How to install packages (apk files) for Android via script for a description for this script)
init_magisk_db.sh (see How to enable root access using Magisk in a script for a description for this script)
Disabling the service to enable access via adb
To only run once, the script enable_adb_using_magisk.sh creates the file /data/recovery/adb_initialized exists on the phone. If that file already exists when enable_adb_using_magisk.sh starts, the script will do nothing and end immediately.
Therefor, it's not necessary to delete the new init *rc service.
It might even be useful to leave the service installed, since it can be used for other purposes later by modifying the script
However, if necessary, you can either delete the script used by the init *rc service enable_adb_using_magisk.sh or reinstall the original boot partition to get rid of the new service completely:
Bash:
#
# while the phone is booted into the Android OS with enabled root access or while the phone is booted into TWRP
#
# use the parameter "yes" for the script to run without requesting user input
#
adb shell su - -c /data/recovery/work/restore_boot_partition.sh
Directories and files used
Name
Type
Content
Comment
/tmp/adbkey.pubfilessl public key that should be configured/tmp is on a ramdisk so this file is lost after booting the phone/data/recovery/workDirectorytemporary files used for enabling adb/data/recovery/work/enable_adb_via_service.rcfileinit *rc file added to the boot partition via Magiks/data/recovery/work/boot_a.imgfileimage of the original boot partition/data/recovery/work/original_boot_partition.imgSymLinklink to the image with the original boot partition/data/recovery/work/restore_boot_partition.shfileScript to restore the boot partition using the image of the original boot partition/data/recovery/work/header
/data/recovery/work/kernel
/data/recovery/work/ramdisk.cpiofilescontents of the boot partition/data/recovery/adbkey.pubfilepublic ssl key to be configured for access via adb/data/recovery/adb_temp_keys.xml.humanfileXML file with the configuration for the access via adb
(will be converted to an XML file in Android binary XML format in /data/misc/adb)/data/recovery/enable_adb_via_service.shfilescript to enable the access via adb and installl the public ssl key for the access via adb
The script is configured in the init*rc file /data/recovery/work/enable_adb_via_service.rc/data/recovery/enable_adb_via_service.logfilelog file created by the script /data/recovery/enable_adb_via_service.sh/data/recovery/adb_initializedfilesemphor file for the script /data/recovery/enable_adb_via_service.sh - if this file exists the script will do nothing/data/recovery/semfilefiletest file created by the new init *rc service/data/recovery/log.gz
/data/recovery/last_log.gz
/data/recovery/recovery.fstab
/data/recovery/storage.fstabfileFiles created by TWRPonly for information
Enabling access via adb in the LineageOS (Update 11.01.2023)
In the LineageOS 19 for the ASUS Zenfone 8 access via adb is enabled in the default configuration.
Therefor these instructions are not necessary. The only configuration that must be done on a phone running the LineageOS is to copy the public ssl keys to /data/misc/adb to enable the access via adb.
Unfortunately the method used for this described in this post seems not to work in the LineageOS.
In addition, root access via adb can be enabled in the developer settings in the LineageOS. Until now I did not find out how to enable the plain root access from the LineageOS from within a script.
userdebug builds
In userdebug builds of Android the access via adb (without authentification) is enabled in the default.
Trouble Shooting
The script enable_adb_using_magisk.sh uses the log file /data/recovery/enable_adb_via_service.log if executed via init *rc service.
To check if the init *rc file was configured successfully check the properties
sys.bnsmb_enable_adb_done
sys.bnsmb.test.okay
in the running Android OS. Both properties should be defined with the value 0:
Code:
ASUS_I006D:/ # getprop sys.bnsmb_enable_adb_done
0
ASUS_I006D:/ #
ASUS_I006D:/ # getprop sys.bnsmb.test.okay
0
ASUS_I006D:/ #
In addition, if everything worked there should exist the file /data/recovery/semfile.
Code:
130|ASUS_I006D:/ # ls -l /data/recovery/semfile
-rw------- 1 root root 9 2022-12-29 11:44 /data/recovery/semfile
ASUS_I006D:/ #
Use the Android command start to check if the service exists and can be started, e.g.
Spoiler: start bnsmb_enable_adb
Code:
ASUS_I006D:/ # start bnsmb_enable_adb ; dmesg | tail -10
[ 3069.861365] [ 3069.861365] (CPU:2-pid:1:init) [12:35:31.711593934] init: Service 'exec 613 (/system/bin/flags_health_check UPDATABLE_CRASHING)' (pid 5734) exited with status 0 waiting took 0.024000 seconds
[ 3069.861402] [ 3069.861402] (CPU:2-pid:1:init) [12:35:31.711630236] init: Sending signal 9 to service 'exec 613 (/system/bin/flags_health_check UPDATABLE_CRASHING)' (pid 5734) process group...
[ 3069.861618] [ 3069.861618] (CPU:2-pid:1:init) [12:35:31.711846069] libprocessgroup: Successfully killed process cgroup uid 1000 pid 5734 in 0ms
[ 3071.202534] [ 3071.202486] (CPU:2-pid:5077:wk:0xffffffe40) [12:35:33.052716433] [BAT][CHG]asus_jeita_cc_worker set BATTMAN_OEM_WORK_EVENT : WORK_JEITA_CC
[ 3071.220807] [ 3071.220807] (CPU:0-pid:350:wk:0xffffffe40) [12:35:33.071038100] [BAT][CHG]handle_message set property:16 successfully
[ 3071.570753] [ 3071.570753] (CPU:2-pid:1:init) [12:35:33.420982631] init: starting service 'bnsmb_enable_adb'...
[ 3071.575971] [ 3071.575971] (CPU:3-pid:1:init) [12:35:33.426199819] init: Control message: Processed ctl.start for 'bnsmb_enable_adb' from pid: 5735 (start bnsmb_enable_adb)
[ 3071.614570] [ 3071.614570] (CPU:3-pid:1:init) [12:35:33.464799298] init: Service 'bnsmb_enable_adb' (pid 5736) exited with status 0 oneshot service took 0.040000 seconds in background
[ 3071.614609] [ 3071.614609] (CPU:3-pid:1:init) [12:35:33.464837267] init: Sending signal 9 to service 'bnsmb_enable_adb' (pid 5736) process group...
[ 3071.614788] [ 3071.614788] (CPU:3-pid:1:init) [12:35:33.465016277] libprocessgroup: Successfully killed process cgroup uid 0 pid 5736 in 0ms
ASUS_I006D:/ #
If something does not work execute the script manually in an adb session to check :
Spoiler: /data/recovery/enable_adb_via_service.sh
Code:
ASUS_I006D:/ # rm -f /data/recovery/adb_initialized
ASUS_I006D:/ #
ASUS_I006D:/ #
ASUS_I006D:/ # sh -x /data/recovery/enable_adb_via_service.sh
+ tty -s
+ '[' 0 -ne 0 ']'
+ PATH=/system/bin:/product/bin:/apex/com.android.runtime/bin:/apex/com.android.art/bin:/system_ext/bin:/system/bin:/system/xbin:/odm/bin:/vendor/bin:/vendor/xbin
+ export PATH
+ '[' ! -r /data/recovery/adb_initialized ']'
+ echo 'Sleeping 30 seconds now ...'
Sleeping 30 seconds now ...
+ sleep 30
+ touch /data/recovery/adb_initialized
+ settings put global development_settings_enabled 1
+ settings put global adb_enabled 1
+ '[' ! -d /data/misc/adb ']'
+ '[' ! -r /data/misc/adb/adb_keys ']'
+ '[' -r /data/recovery/adbkey.pub ']'
+ >>/data/misc/adb/adb_keys
+ cat /data/recovery/adbkey.pub
+ '[' -r /data/recovery/adb_temp_keys.xml.human ']'
+ xml2abx /data/recovery/adb_temp_keys.xml.human /data/misc/adb/adb_temp_keys.xml
+ chmod 0600 /data/misc/adb/adb_temp_keys.xml
+ chown system:shell /data/misc/adb/adb_temp_keys.xml
+ chcon -v u:object_r:adb_keys_file:s0 /data/misc/adb/adb_temp_keys.xml
chcon '/data/misc/adb/adb_temp_keys.xml' to u:object_r:adb_keys_file:s0
ASUS_I006D:/ #
Thank you for your explanation, I leave my footprint, I need this sometimes.