From 1cd45b53b1764c7ec30fd6de403c3d12dece89ba Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sat, 30 Mar 2019 00:49:48 -0400 Subject: [PATCH] Support recovery based Magisk Some devices (mainly new Samsung phones we're talking here...) using A only system-as-root refuse to load ramdisk when booted with boot no matter what we do. With many A only system-as-root devices, even though their boot image is kernel only, we can still be able to add a ramdisk section into the image and force the kernel to use it as rootfs. However the bootloader on devices like the S10 simply does not load anything within boot image into memory other than the kernel. This gives as the only option is to install Magisk on the recovery partition. This commits adds proper support for these kind of scenarios. --- .../magisk/tasks/MagiskInstaller.java | 9 +++++---- native/jni/core/init.cpp | 19 ++++++++++++++----- scripts/boot_patch.sh | 8 +++++--- scripts/util_functions.sh | 6 ++++-- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java b/app/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java index 273b21123..beaadd3df 100644 --- a/app/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java +++ b/app/src/main/java/com/topjohnwu/magisk/tasks/MagiskInstaller.java @@ -79,12 +79,12 @@ public abstract class MagiskInstaller { } protected boolean findImage() { - console.add("- Detecting target image"); srcBoot = ShellUtils.fastCmd("find_boot_image", "echo \"$BOOTIMAGE\""); if (srcBoot.isEmpty()) { console.add("! Unable to detect target image"); return false; } + console.add("- Target image: " + srcBoot); return true; } @@ -92,7 +92,6 @@ public abstract class MagiskInstaller { String slot = ShellUtils.fastCmd("echo $SLOT"); String target = (TextUtils.equals(slot, "_a") ? "_b" : "_a"); console.add("- Target slot: " + target); - console.add("- Detecting target image"); srcBoot = ShellUtils.fastCmd( "SLOT=" + target, "find_boot_image", @@ -103,6 +102,7 @@ public abstract class MagiskInstaller { console.add("! Unable to detect target image"); return false; } + console.add("- Target image: " + srcBoot); return true; } @@ -216,8 +216,9 @@ public abstract class MagiskInstaller { } if (!Shell.sh("cd " + installDir, Utils.fmt( - "KEEPFORCEENCRYPT=%b KEEPVERITY=%b sh update-binary sh boot_patch.sh %s", - Config.keepEnc, Config.keepVerity, srcBoot)) + "KEEPFORCEENCRYPT=%b KEEPVERITY=%b RECOVERYMODE=%b " + + "sh update-binary sh boot_patch.sh %s", + Config.keepEnc, Config.keepVerity, Config.recovery, srcBoot)) .to(console, logs).exec().isSuccess()) return false; diff --git a/native/jni/core/init.cpp b/native/jni/core/init.cpp index 01c62df88..316386e98 100644 --- a/native/jni/core/init.cpp +++ b/native/jni/core/init.cpp @@ -231,13 +231,21 @@ void MagiskInit::load_kernel_info() { } }); + parse_prop_file("/.backup/.magisk", [&](auto key, auto value) -> bool { + if (key == "RECOVERYMODE" && value == "true") + cmd.system_as_root = true; + return true; + }); + if (kirin && enter_recovery) { // Inform that we are actually booting as recovery - if (FILE *f = fopen("/.backup/.magisk", "ae"); f) { - fprintf(f, "RECOVERYMODE=true\n"); - fclose(f); + if (!cmd.system_as_root) { + if (FILE *f = fopen("/.backup/.magisk", "ae"); f) { + fprintf(f, "RECOVERYMODE=true\n"); + fclose(f); + } + cmd.system_as_root = true; } - cmd.system_as_root = true; } cmd.system_as_root |= skip_initramfs; @@ -602,10 +610,11 @@ void MagiskInit::start() { if (null > STDERR_FILENO) close(null); + load_kernel_info(); + full_read("/init", &init.buf, &init.sz); full_read("/.backup/.magisk", &config.buf, &config.sz); - load_kernel_info(); preset(); early_mount(); setup_rootfs(); diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index db4748d84..2129f852e 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -58,6 +58,7 @@ BOOTIMAGE="$1" # Flags [ -z $KEEPVERITY ] && KEEPVERITY=false [ -z $KEEPFORCEENCRYPT ] && KEEPFORCEENCRYPT=false +[ -z $RECOVERYMODE ] && RECOVERYMODE=false chmod -R 755 . @@ -133,6 +134,7 @@ ui_print "- Patching ramdisk" echo "KEEPVERITY=$KEEPVERITY" > config echo "KEEPFORCEENCRYPT=$KEEPFORCEENCRYPT" >> config [ ! -z $SHA1 ] && echo "SHA1=$SHA1" >> config +[ -f recovery_dtbo ] && echo "RECOVERYMODE=true" >> config ./magiskboot cpio ramdisk.cpio \ "add 750 init magiskinit" \ @@ -153,9 +155,9 @@ rm -f ramdisk.cpio.orig config ########################################################################################## if ! $KEEPVERITY; then - [ -f dtb ] && ./magiskboot dtb-patch dtb && ui_print "- Removing dm(avb)-verity in dtb" - [ -f kernel_dtb ] && ./magiskboot dtb-patch kernel_dtb && ui_print "- Removing dm(avb)-verity in dtb" - [ -f extra ] && ./magiskboot dtb-patch extra && ui_print "- Removing dm(avb)-verity in extra-dtb" + for dt in dtb kernel_dtb extra recovery_dtbo; do + [ -f $dt ] && ./magiskboot dtb-patch $dt && ui_print "- Removing dm(avb)-verity in $dt" + done fi if [ -f kernel ]; then diff --git a/scripts/util_functions.sh b/scripts/util_functions.sh index cf8a84ce4..b40617f7a 100644 --- a/scripts/util_functions.sh +++ b/scripts/util_functions.sh @@ -232,10 +232,12 @@ get_flags() { find_boot_image() { BOOTIMAGE= - if [ ! -z $SLOT ]; then + if $RECOVERYMODE; then + BOOTIMAGE=`find_block recovery_ramdisk$SLOT recovery` + elif [ ! -z $SLOT ]; then BOOTIMAGE=`find_block ramdisk$SLOT recovery_ramdisk$SLOT boot$SLOT` else - BOOTIMAGE=`find_block ramdisk recovery_ramdisk boot boot_a kern-a android_boot kernel lnx bootimg` + BOOTIMAGE=`find_block ramdisk recovery_ramdisk kern-a android_boot kernel boot lnx bootimg boot_a` fi if [ -z $BOOTIMAGE ]; then # Lets see what fstabs tells me