- with do.systemless prop enabled in anykernel.sh, will push the contents of modules/ to create a simple "ak3-helper" Magisk module, where testing on devices thus far shows it loads early enough that even replacement kernel object .ko modules will get loaded - the ak3-helper module info is populated from the kernel.string and parsed kernel version from the kernel being flashed, and if at boot time a different kernel is detected the module automatically removes itself before being loaded to avoid conflicts - since logical partitions and ext4-dedup on Android 10 now prevent mounting /system or /vendor rw under any circumstances, this feature gives kernel developers back the freedom they had before all this to improve kernel .ko modules, .conf files, etc. with the added bonus of it cleaning up after itself
390 lines
12 KiB
Bash
Executable File
390 lines
12 KiB
Bash
Executable File
#!/sbin/sh
|
|
# AnyKernel3 Backend (DO NOT CHANGE)
|
|
# osm0sis @ xda-developers
|
|
|
|
OUTFD=/proc/self/fd/$2;
|
|
ZIPFILE="$3";
|
|
|
|
ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true || BOOTMODE=false;
|
|
$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true;
|
|
|
|
$BOOTMODE && DIR=/sdcard || DIR=$(dirname "$ZIPFILE");
|
|
|
|
test "$ANDROID_ROOT" || ANDROID_ROOT=/system;
|
|
test "$home" || home=/tmp/anykernel;
|
|
|
|
ui_print() {
|
|
until [ ! "$1" ]; do
|
|
echo -e "ui_print $1\nui_print" > $OUTFD;
|
|
shift;
|
|
done;
|
|
}
|
|
ui_printfile() {
|
|
while IFS='' read -r line || $bb [[ -n "$line" ]]; do
|
|
ui_print "$line";
|
|
done < $1;
|
|
}
|
|
show_progress() { echo "progress $1 $2" > $OUTFD; }
|
|
file_getprop() { $bb grep "^$2=" "$1" | $bb cut -d= -f2-; }
|
|
int2ver() {
|
|
if [ "$1" -eq "$1" ] 2>/dev/null; then
|
|
echo "$1.0.0";
|
|
elif [ ! "$(echo "$1" | $bb cut -d. -f3)" ]; then
|
|
echo "$1.0";
|
|
else
|
|
echo "$1";
|
|
fi;
|
|
}
|
|
cleanup() {
|
|
cd $(dirname $home);
|
|
rm -rf $home;
|
|
}
|
|
debugging() {
|
|
case $(basename "$ZIPFILE" .zip) in
|
|
*-debugging)
|
|
ui_print " " "Creating debugging archive in $DIR...";
|
|
test -f /tmp/recovery.log && log=/tmp/recovery.log;
|
|
$bb tar -czf "$DIR/anykernel3-$(date +%Y-%m-%d_%H%M%S)-debug.tgz" $home $log;
|
|
;;
|
|
esac;
|
|
}
|
|
setup_mountpoint() {
|
|
test -L $1 && $bb mv -f $1 ${1}_link;
|
|
if [ ! -d $1 ]; then
|
|
rm -f $1;
|
|
mkdir $1;
|
|
fi;
|
|
}
|
|
is_mounted() { $bb mount | $bb grep -q " $1 "; }
|
|
umount_all() {
|
|
(if ! $BOOTMODE; then
|
|
umount_apex;
|
|
$bb umount /system;
|
|
$bb umount -l /system;
|
|
if [ -e /system_root ]; then
|
|
$bb umount /system_root;
|
|
$bb umount -l /system_root;
|
|
fi;
|
|
fi;
|
|
umount /vendor;
|
|
umount -l /vendor;
|
|
if [ "$umount_data" ]; then
|
|
$bb umount /data;
|
|
$bb umount -l /data;
|
|
fi) 2>/dev/null;
|
|
}
|
|
mount_apex() {
|
|
test -d /system/apex || return 1;
|
|
local apex dest loop minorx num;
|
|
setup_mountpoint /apex;
|
|
test -e /dev/block/loop1 && minorx=$(ls -l /dev/block/loop1 | $bb awk '{ print $6 }') || minorx=1;
|
|
num=0;
|
|
for apex in /system/apex/*; do
|
|
dest=/apex/$(basename $apex .apex);
|
|
test "$dest" == /apex/com.android.runtime.release && dest=/apex/com.android.runtime;
|
|
mkdir -p $dest;
|
|
case $apex in
|
|
*.apex)
|
|
$bb unzip -qo $apex apex_payload.img -d /apex;
|
|
$bb mv -f /apex/apex_payload.img $dest.img;
|
|
$bb mount -t ext4 -o ro,noatime $dest.img $dest 2>/dev/null;
|
|
if [ $? != 0 ]; then
|
|
while [ $num -lt 64 ]; do
|
|
loop=/dev/block/loop$num;
|
|
($bb mknod $loop b 7 $((num * minorx));
|
|
$bb losetup $loop $dest.img) 2>/dev/null;
|
|
num=$((num + 1));
|
|
$bb losetup $loop | $bb grep -q $dest.img && break;
|
|
done;
|
|
$bb mount -t ext4 -o ro,loop,noatime $loop $dest;
|
|
if [ $? != 0 ]; then
|
|
$bb losetup -d $loop 2>/dev/null;
|
|
fi;
|
|
fi;
|
|
;;
|
|
*) $bb mount -o bind $apex $dest;;
|
|
esac;
|
|
done;
|
|
export ANDROID_RUNTIME_ROOT=/apex/com.android.runtime;
|
|
export ANDROID_TZDATA_ROOT=/apex/com.android.tzdata;
|
|
export BOOTCLASSPATH=/apex/com.android.runtime/javalib/core-oj.jar:/apex/com.android.runtime/javalib/core-libart.jar:/apex/com.android.runtime/javalib/okhttp.jar:/apex/com.android.runtime/javalib/bouncycastle.jar:/apex/com.android.runtime/javalib/apache-xml.jar:/system/framework/framework.jar:/system/framework/ext.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/ims-common.jar:/system/framework/android.test.base.jar:/apex/com.android.conscrypt/javalib/conscrypt.jar:/apex/com.android.media/javalib/updatable-media.jar;
|
|
}
|
|
umount_apex() {
|
|
test -d /apex || return 1;
|
|
local dest loop;
|
|
for dest in $($bb find /apex -type d -mindepth 1 -maxdepth 1); do
|
|
if [ -f $dest.img ]; then
|
|
loop=$($bb mount | $bb grep $dest | $bb cut -d" " -f1);
|
|
fi;
|
|
($bb umount -l $dest;
|
|
$bb losetup -d $loop) 2>/dev/null;
|
|
done;
|
|
rm -rf /apex;
|
|
unset ANDROID_RUNTIME_ROOT ANDROID_TZDATA_ROOT BOOTCLASSPATH;
|
|
}
|
|
restore_env() {
|
|
test "$savedpath" && export LD_LIBRARY_PATH="$savedpath";
|
|
test "$savedpre" && export LD_PRELOAD="$savedpre";
|
|
umount_all;
|
|
($bb mv -f /apex_link /apex;
|
|
$bb mv -f /system_link /system;
|
|
$bb mv -f /system_root_link /system_root;
|
|
$bb umount -l /dev/random) 2>/dev/null;
|
|
}
|
|
abort() {
|
|
ui_print "$@";
|
|
debugging;
|
|
restore_env;
|
|
if [ ! -f anykernel.sh -o "$(file_getprop anykernel.sh do.cleanuponabort 2>/dev/null)" == 1 ]; then
|
|
cleanup;
|
|
fi;
|
|
exit 1;
|
|
}
|
|
dump_moduleinfo() {
|
|
cat <<EOF > $1;
|
|
name=AK3 Helper Module
|
|
version=$($bb awk '{ print $3 }' $home/vertmp) $($bb grep -oE '#.[0-9]' $home/vertmp)
|
|
versionCode=1
|
|
author=AnyKernel3
|
|
description=$kernel_string
|
|
EOF
|
|
}
|
|
dump_moduleremover() {
|
|
cat <<EOF > $1;
|
|
#!/system/bin/sh
|
|
MODDIR=\${0%/*};
|
|
if [ "\$(cat /proc/version)" != "\$(cat \$MODDIR/version)" ]; then
|
|
rm -rf \$MODDIR;
|
|
fi;
|
|
EOF
|
|
}
|
|
|
|
show_progress 1.34 4;
|
|
ui_print " ";
|
|
cleanup;
|
|
mkdir -p $home/bin;
|
|
cd $home;
|
|
unzip -o "$ZIPFILE";
|
|
if [ $? != 0 -o ! "$(ls tools)" ]; then
|
|
abort "Unzip failed. Aborting...";
|
|
fi;
|
|
for arch32 in x86 arm; do
|
|
if [ -d $home/tools/$arch32 ]; then
|
|
bb=$home/tools/$arch32/busybox;
|
|
chmod 755 $bb;
|
|
$bb >/dev/null 2>&1;
|
|
if [ $? == 0 ]; then
|
|
$bb mv -f $home/tools/$arch32/* $home/tools;
|
|
break;
|
|
fi;
|
|
fi;
|
|
done;
|
|
bb=$home/tools/busybox;
|
|
chmod 755 $bb;
|
|
$bb chmod -R 755 tools bin;
|
|
$bb --install -s bin;
|
|
if [ $? != 0 -o -z "$(ls bin)" ]; then
|
|
abort "Busybox setup failed. Aborting...";
|
|
fi;
|
|
|
|
if [ -f banner ]; then
|
|
ui_printfile banner;
|
|
ui_print " " " ";
|
|
fi;
|
|
|
|
kernel_string="$(file_getprop anykernel.sh kernel.string)";
|
|
ui_print "$kernel_string";
|
|
if [ -f version ]; then
|
|
ui_print " ";
|
|
ui_printfile version;
|
|
ui_print " ";
|
|
fi;
|
|
ui_print " " "AnyKernel3 by osm0sis @ xda-developers" " " " ";
|
|
|
|
$BOOTMODE || $bb mount -o bind /dev/urandom /dev/random;
|
|
umount_all;
|
|
setup_mountpoint $ANDROID_ROOT;
|
|
if ! is_mounted $ANDROID_ROOT; then
|
|
$bb mount -o ro -t auto $ANDROID_ROOT;
|
|
fi;
|
|
case $ANDROID_ROOT in
|
|
/system_root) setup_mountpoint /system;;
|
|
/system)
|
|
if [ -f /system/system/build.prop ]; then
|
|
setup_mountpoint /system_root;
|
|
$bb mount --move /system /system_root;
|
|
if [ $? != 0 ]; then
|
|
$bb umount /system;
|
|
$bb umount -l /system 2>/dev/null;
|
|
$bb mount -o ro -t auto /dev/block/bootdevice/by-name/system /system_root;
|
|
fi;
|
|
fi;
|
|
;;
|
|
esac;
|
|
if is_mounted /system_root; then
|
|
$bb mount -o bind /system_root/system /system;
|
|
fi;
|
|
$bb mount -o ro -t auto /vendor 2>/dev/null;
|
|
$BOOTMODE || mount_apex;
|
|
if ! is_mounted /data; then
|
|
$bb mount /data;
|
|
umount_data=1;
|
|
fi;
|
|
|
|
savedpath="$LD_LIBRARY_PATH";
|
|
savedpre="$LD_PRELOAD";
|
|
unset LD_LIBRARY_PATH;
|
|
unset LD_PRELOAD;
|
|
|
|
if [ ! "$(getprop 2>/dev/null)" ]; then
|
|
getprop() {
|
|
local propdir propfile propval;
|
|
for propdir in / /system_root /system /vendor /odm /product; do
|
|
for propfile in default.prop build.prop; do
|
|
test "$propval" && break 2 || propval="$(file_getprop $propdir/$propfile $1 2>/dev/null)";
|
|
done;
|
|
done;
|
|
test "$propval" && echo "$propval" || echo "";
|
|
}
|
|
elif [ ! "$(getprop ro.build.type 2>/dev/null)" ]; then
|
|
getprop() {
|
|
($(which getprop) | $bb grep "$1" | $bb cut -d[ -f3 | $bb cut -d] -f1) 2>/dev/null;
|
|
}
|
|
fi;
|
|
|
|
if [ "$(file_getprop anykernel.sh do.devicecheck)" == 1 ]; then
|
|
ui_print "Checking device...";
|
|
device=$(getprop ro.product.device 2>/dev/null);
|
|
product=$(getprop ro.build.product 2>/dev/null);
|
|
vendordevice=$(getprop ro.product.vendor.device 2>/dev/null);
|
|
vendorproduct=$(getprop ro.vendor.product.device 2>/dev/null);
|
|
for testname in $(file_getprop anykernel.sh 'device.name.*'); do
|
|
for devicename in $device $product $vendordevice $vendorproduct; do
|
|
if [ "$devicename" == "$testname" ]; then
|
|
ui_print "$testname" " ";
|
|
match=1;
|
|
break 2;
|
|
fi;
|
|
done;
|
|
done;
|
|
if [ ! "$match" ]; then
|
|
abort " " "Unsupported device. Aborting...";
|
|
fi;
|
|
fi;
|
|
|
|
supported_ver=$(file_getprop anykernel.sh supported.versions | $bb tr -d '[:space:]');
|
|
if [ "$supported_ver" ]; then
|
|
ui_print "Checking Android version...";
|
|
android_ver=$(file_getprop /system/build.prop ro.build.version.release);
|
|
parsed_ver=$(int2ver $android_ver);
|
|
if echo $supported_ver | $bb grep -q '-'; then
|
|
lo_ver=$(int2ver "$(echo $supported_ver | $bb cut -d- -f1)");
|
|
hi_ver=$(int2ver "$(echo $supported_ver | $bb cut -d- -f2)");
|
|
if echo -e "$hi_ver\n$lo_ver\n$parsed_ver" | $bb sort -g | $bb grep -n "$parsed_ver" | $bb grep -q '^2:'; then
|
|
supported=1;
|
|
fi;
|
|
else
|
|
for ver in $(echo $supported_ver | $bb sed 's;,; ;g'); do
|
|
if [ "$(int2ver $ver)" == "$parsed_ver" ]; then
|
|
supported=1;
|
|
break;
|
|
fi;
|
|
done;
|
|
fi;
|
|
if [ "$supported" ]; then
|
|
ui_print "$android_ver" " ";
|
|
else
|
|
abort " " "Unsupported Android version. Aborting...";
|
|
fi;
|
|
fi;
|
|
|
|
supported_lvl=$(file_getprop anykernel.sh supported.patchlevels | $bb grep -oE '[0-9]{4}-[0-9]{2}|-');
|
|
if [ "$supported_lvl" ]; then
|
|
ui_print "Checking Android security patch level...";
|
|
android_lvl=$(file_getprop /system/build.prop ro.build.version.security_patch);
|
|
parsed_lvl=$(echo $android_lvl | $bb grep -oE '[0-9]{4}-[0-9]{2}');
|
|
if echo $supported_lvl | $bb grep -q '^\-'; then
|
|
lo_lvl=0000-00;
|
|
hi_lvl=$(echo $supported_lvl | $bb awk '{ print $2 }');
|
|
elif echo $supported_lvl | $bb grep -q ' - '; then
|
|
lo_lvl=$(echo $supported_lvl | $bb awk '{ print $1 }');
|
|
hi_lvl=$(echo $supported_lvl | $bb awk '{ print $3 }');
|
|
elif echo $supported_lvl | $bb grep -q '\-$'; then
|
|
lo_lvl=$(echo $supported_lvl | $bb awk '{ print $1 }');
|
|
hi_lvl=9999-99;
|
|
fi;
|
|
if echo -e "$hi_lvl\n$lo_lvl\n$parsed_lvl" | $bb sort -g | $bb grep -n "$parsed_lvl" | $bb grep -q '^2:'; then
|
|
ui_print "$android_lvl" " ";
|
|
else
|
|
abort " " "Unsupported Android security patch level. Aborting...";
|
|
fi;
|
|
fi;
|
|
|
|
ui_print "Installing...";
|
|
core=$($bb grep -oE 'ak.*core.sh' anykernel.sh);
|
|
test -f tools/$core || $bb ln -s $home/tools/ak*-core.sh $home/tools/$core;
|
|
PATH="$home/bin:$PATH" home=$home $bb ash anykernel.sh $2;
|
|
if [ $? != 0 ]; then
|
|
abort;
|
|
fi;
|
|
|
|
if [ "$(file_getprop anykernel.sh do.modules)" == 1 ]; then
|
|
if [ "$(file_getprop anykernel.sh do.systemless)" == 1 ]; then
|
|
cd $home/modules;
|
|
ui_print " " "Creating kernel helper Magisk module...";
|
|
if [ -d /data/adb/magisk -a -f $home/split_img/.magisk ]; then
|
|
umask 022;
|
|
moddir=/data/adb/modules/ak3-helper;
|
|
rm -rf $moddir;
|
|
mkdir -p system $moddir;
|
|
($bb mv -f product system;
|
|
$bb mv -f vendor system) 2>/dev/null;
|
|
$bb cp -rLf * $moddir;
|
|
dump_moduleinfo $moddir/module.prop;
|
|
dump_moduleremover $moddir/post-fs-data.sh;
|
|
cp -f $home/vertmp $moddir/version;
|
|
else
|
|
ui_print "Magisk installation not found. Skipped!";
|
|
fi;
|
|
else
|
|
cd $home/modules;
|
|
ui_print " " "Pushing modules...";
|
|
$bb mount -o rw,remount -t auto /system;
|
|
$bb mount -o rw,remount -t auto /vendor 2>/dev/null;
|
|
for module in $(find . -name '*.ko'); do
|
|
modtarget=$(echo $module | $bb cut -c2-);
|
|
if [ ! -e $modtarget ]; then
|
|
case $module in
|
|
*/vendor/*) modcon=vendor;;
|
|
*) modcon=system;;
|
|
esac;
|
|
fi;
|
|
if is_mounted $modtarget; then
|
|
$bb mount -o rw,remount -t auto $modtarget;
|
|
fi;
|
|
mkdir -p $(dirname $modtarget);
|
|
$bb cp -rLf $module $modtarget;
|
|
$bb chown 0:0 $modtarget;
|
|
$bb chmod 644 $modtarget;
|
|
if [ "$modcon" ]; then
|
|
chcon "u:object_r:${modcon}_file:s0" $modtarget;
|
|
fi;
|
|
if is_mounted $modtarget; then
|
|
$bb mount -o ro,remount -t auto $modtarget;
|
|
fi;
|
|
done;
|
|
$bb mount -o ro,remount -t auto /system;
|
|
$bb mount -o ro,remount -t auto /vendor 2>/dev/null;
|
|
fi;
|
|
cd $home;
|
|
fi;
|
|
|
|
debugging;
|
|
restore_env;
|
|
|
|
if [ "$(file_getprop anykernel.sh do.cleanup)" == 1 ]; then
|
|
cleanup;
|
|
fi;
|
|
|
|
ui_print " " " " "Done!";
|