diff --git a/first-boot.sh b/first-boot.sh index 1a4fdae..5736964 100755 --- a/first-boot.sh +++ b/first-boot.sh @@ -41,8 +41,48 @@ prepare_system() { adb remount } -install_gapps() { +magisk_active() { + # Magisk env is ready (binaries populated) — either by install_root in this + # session or by a previously-rooted run. Empty /data/adb/magisk doesn't count. + adb shell 'test -x /data/adb/magisk/magiskinit && echo MAGISK_READY' 2>/dev/null | grep -q MAGISK_READY +} + +install_gapps_magisk_module() { + echo "Installing GAPPS as a Magisk module ..." + local MOD=/data/adb/modules/gapps + adb push gapps-11/etc /data/local/tmp/gapps-etc + adb push gapps-11/framework /data/local/tmp/gapps-framework + adb push gapps-11/app /data/local/tmp/gapps-app + adb push gapps-11/priv-app /data/local/tmp/gapps-priv-app + adb shell " + rm -rf $MOD + mkdir -p $MOD/system + mv /data/local/tmp/gapps-etc $MOD/system/etc + mv /data/local/tmp/gapps-framework $MOD/system/framework + mv /data/local/tmp/gapps-app $MOD/system/app + mv /data/local/tmp/gapps-priv-app $MOD/system/priv-app + cat > $MOD/module.prop <<'PROP' +id=gapps +name=PICO GAPPS +version=20220503 +versionCode=20220503 +author=Open GAPPS +description=Open GAPPS PICO for Android 11 x86_64 +PROP + " +} + +install_gapps_system() { prepare_system + adb push gapps-11/etc /system + adb push gapps-11/framework /system + adb push gapps-11/app /system + adb push gapps-11/priv-app /system +} + +install_gapps() { + adb wait-for-device + adb root echo "Installing GAPPS ..." wget https://sourceforge.net/projects/opengapps/files/x86_64/20220503/open_gapps-x86_64-11.0-pico-20220503.zip/download -O gapps-11.zip unzip gapps-11.zip 'Core/*' -d gapps-11 && rm gapps-11.zip @@ -51,10 +91,11 @@ install_gapps() { for f in gapps-11/Core/*.tar; do tar -x --strip-components 2 -f "$f" -C gapps-11 done - adb push gapps-11/etc /system - adb push gapps-11/framework /system - adb push gapps-11/app /system - adb push gapps-11/priv-app /system + if magisk_active; then + install_gapps_magisk_module + else + install_gapps_system + fi rm -r gapps-11 adb reboot adb wait-for-device @@ -63,6 +104,7 @@ install_gapps() { install_root() { adb wait-for-device + adb root echo "Root Script Starting..." # Root the AVD by patching the ramdisk. git clone https://gitlab.com/newbit/rootAVD.git @@ -70,6 +112,33 @@ install_root() { sed -i 's/read -t 10 choice/choice=1/' rootAVD.sh ./rootAVD.sh system-images/android-30/default/x86_64/ramdisk.img cp /opt/android-sdk/system-images/android-30/default/x86_64/ramdisk.img /data/android.avd/ramdisk.img + + # Pre-populate /data/adb/magisk so Magisk's env-check passes on next boot. + # rootAVD only patches the ramdisk; the "additional setup" tap in the Magisk + # app would normally extract Magisk.zip into /data/adb/magisk/ (with the + # lib*.so files renamed to their binary names). Doing it here means the next + # QEMU restart comes up with a complete Magisk environment, no manual setup + # prompt, and any modules in /data/adb/modules/ are loaded on boot. + echo "Bootstrapping Magisk environment ..." + rm -rf /tmp/magisk-stage + mkdir -p /tmp/magisk-stage + unzip -q -o Magisk.zip 'lib/*' 'assets/*' -d /tmp/magisk-stage + pushd /tmp/magisk-stage/lib/x86_64 + for f in lib*.so; do mv "$f" "$(echo "$f" | sed -e 's/^lib//' -e 's/\.so$//')"; done + cp -f ../x86/libmagisk32.so magisk32 2>/dev/null || true + popd + adb push /tmp/magisk-stage/lib/x86_64/. /data/local/tmp/magiskbin/ + adb push /tmp/magisk-stage/assets/. /data/local/tmp/magiskbin/ + adb shell ' + mkdir -p /data/adb/magisk + cp -a /data/local/tmp/magiskbin/. /data/adb/magisk/ + rm -f /data/adb/magisk/bootctl /data/adb/magisk/main.jar \ + /data/adb/magisk/module_installer.sh /data/adb/magisk/uninstaller.sh + chmod -R 755 /data/adb/magisk + rm -rf /data/local/tmp/magiskbin + ' + rm -rf /tmp/magisk-stage + popd echo "Root Done" sleep 10 @@ -77,7 +146,54 @@ install_root() { touch /data/.root-done } -install_arm_translation() { +install_arm_translation_magisk_module() { + echo "Installing ARM translation as a Magisk module ..." + local MOD=/data/adb/modules/ndk_translation + adb push /opt/ndk-translation /data/local/tmp/ndk + adb shell " + rm -rf $MOD + mkdir -p $MOD/system/bin $MOD/system/etc $MOD/system/lib $MOD/system/lib64 + cp -r /data/local/tmp/ndk/bin/. $MOD/system/bin/ + cp -r /data/local/tmp/ndk/etc/. $MOD/system/etc/ + cp -r /data/local/tmp/ndk/lib/. $MOD/system/lib/ + cp -r /data/local/tmp/ndk/lib64/. $MOD/system/lib64/ + rm -rf /data/local/tmp/ndk + chmod 755 $MOD/system/bin/ndk_translation_program_runner_binfmt_misc $MOD/system/bin/ndk_translation_program_runner_binfmt_misc_arm64 + chmod -R 755 $MOD/system/bin/arm $MOD/system/bin/arm64 + cat > $MOD/module.prop <<'PROP' +id=ndk_translation +name=NDK Translation (ARM on x86) +version=v0.2.3 +versionCode=23 +author=dockerify-android +description=Run ARM/ARM64 apps on x86_64 emulator via libndk_translation native bridge +PROP + cat > $MOD/system.prop <<'PROP' +ro.product.cpu.abilist=x86_64,x86,arm64-v8a,armeabi-v7a,armeabi +ro.product.cpu.abilist32=x86,armeabi-v7a,armeabi +ro.product.cpu.abilist64=x86_64,arm64-v8a +ro.dalvik.vm.isa.arm=x86 +ro.dalvik.vm.isa.arm64=x86_64 +ro.enable.native.bridge.exec=1 +ro.enable.native.bridge.exec64=1 +ro.dalvik.vm.native.bridge=libndk_translation.so +ro.ndk_translation.version=0.2.3 +PROP + cat > $MOD/post-fs-data.sh <<'PFS' +#!/system/bin/sh +# init.rc files aren't parsed when injected via Magisk overlay (init scans +# /system/etc/init early, before module mounts). Register binfmt_misc here. +mount binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc 2>/dev/null +for f in arm_exe arm_dyn arm64_exe arm64_dyn; do + [ -f \"\$MODPATH/system/etc/binfmt_misc/\$f\" ] && + cat \"\$MODPATH/system/etc/binfmt_misc/\$f\" > /proc/sys/fs/binfmt_misc/register 2>/dev/null +done +PFS + chmod 755 $MOD/post-fs-data.sh + " +} + +install_arm_translation_system() { prepare_system echo "Installing ARM translation (ndk_translation) ..." @@ -109,7 +225,18 @@ ro.dalvik.vm.native.bridge=libndk_translation.so ro.ndk_translation.version=0.2.3 EOF ' +} +install_arm_translation() { + adb wait-for-device + adb root + # On a live-Magisk device, /system is wrapped in a read-only magic mount; + # install as a Magisk module so the changes land via Magisk's own overlay. + if magisk_active; then + install_arm_translation_magisk_module + else + install_arm_translation_system + fi adb reboot adb wait-for-device touch /data/.arm-translation-done @@ -144,8 +271,13 @@ fi # Each install is self-contained: prepares the system, applies its changes, # reboots, waits for adbd, then writes its done-marker. Safe to run after the # first boot — only the missing markers will fire. -[ "$gapps_needed" = true ] && install_gapps +# +# Root is installed first so it can bootstrap /data/adb/magisk/; the gapps +# and arm_translation installs then detect a ready Magisk env and write their +# payload to /data/adb/modules// instead of /system. Modules sit dormant +# until the next QEMU restart loads the patched ramdisk and Magisk activates. [ "$root_needed" = true ] && install_root +[ "$gapps_needed" = true ] && install_gapps [ "$arm_translation_needed" = true ] && install_arm_translation apply_settings copy_extras