Here's a bit of fun.
For any wondering how those kernel manager apps were flashing AK2/3 zips and other flashable zips here's the script version of the implementation I wrote that we were using in FKM.
Note this can't just be run as-is because you need to switch into the `su -mm` root shell at the top, so it's more for use copy/pasting into `adb shell`.
# app unzips busybox and update-binary from target zip ($Z) to app dir ($F)
# app may also either unzip a premade empty ext4 .img or generate a new one
## setup for testing:
Z=/sdcard/franco.kernel_updater/fk-r*.zip; Z="$(echo $Z | cut -d\ -f1)";
unzip -p $Z tools*/busybox > $F/busybox;
unzip -p $Z META-INF/com/google/android/update-binary > $F/update-binary;
/system/bin/make_ext4fs -b 4096 -l 400M $F/ak3-tmp.img || /system/bin/mke2fs -b 4096 -t ext4 $F/ak3-tmp.img 400M || exit 1;
chmod 755 $F/busybox;
$F/busybox chmod 755 $F/update-binary;
$F/busybox chown root:root $F/busybox $F/ak3-tmp.img $F/update-binary;
# work around Android passing the app what is actually a non-absolute path
F=$($F/busybox readlink -f $F);
# AK3 allows the zip to be flashed from anywhere so avoids any need to remount /
if $F/busybox grep -q AnyKernel3 $F/update-binary; then
# work around more restrictive upstream SELinux policies for Magisk <19306
magiskpolicy --live "allow kernel app_data_file file write";
# work around SAR Magisk 19303-19305 rootfs context bug
magiskpolicy --live "allow rootfs labeledfs filesystem associate";
$F/busybox mount -o rw,remount -t auto /;
$F/busybox umount $TMP 2>/dev/null;
$F/busybox rm -rf $TMP $F/bbin 2>/dev/null;
$F/busybox mkdir -p $TMP $F/bbin;
$F/busybox --install -s $F/bbin;
$F/busybox mount -t ext4 -o rw,noatime $F/ak3-tmp.img $TMP;
if [ $? != 0 ]; then
while [ $i -lt 16 ]; do
$F/busybox mknod $loop b 7 $i;
$F/busybox losetup $loop $F/ak3-tmp.img;
$F/busybox losetup $loop | $F/busybox grep -q ak3-tmp.img && break;
i=$((i + 1));
$F/busybox mount -t ext4 -o loop,noatime $loop $TMP;
$F/busybox mount | $F/busybox grep -q " $TMP " || exit 1;
# update-binary <RECOVERY_API_VERSION> <OUTFD> <ZIPFILE>
PATH="$F/bbin:$PATH" home=$TMP/anykernel $F/busybox ash $F/update-binary 3 1 "$Z";
$F/busybox umount $TMP;
test "$loop" && $F/busybox losetup -d $loop;
$F/busybox rm -rf $TMP $F/bbin;
$F/busybox mount -o ro,remount -t auto /;
$F/busybox rm -f $F/ak3-tmp.img $F/update-binary $F/busybox;
Apps will be switching to a new implementation using the new not-yet-officially-released switchroot binary from @topjohnwu
, but for the demonstration of AK3's ability to be flashed from anywhere this is still handy and I wanted to show people how it could/should be done.
There's also a debate of whether the loop mounted ext4 .img is better than using a tmpfs mount instead (e.g. `mount -t tmpfs -o size=400M,noatime tmpfs $TMP`), but that depends on whether your devices might have a bottleneck on free space on /data to hold the ext4 .img vs. free RAM to hold the tmpfs. I went with ext4 .img since that should help on low-end devices (provided they have the space). switchroot uses tmpfs; AIK-mobile will continue to use ext4 .img since people need to be able to pick up where they left off.
Big thanks to @MSF Jarvis
for working with me for awhile to figure out that the Pixel 2 XL on Android Q now fills up a lot of its /dev/block/loop* nodes (with only the info of "8192"
), and also goes up to loop15 instead of the loop7 previous devices/OS versions have, leading to the above while loop to fix it which will also make it into the next AIK-mobile.