009: Magisk ship pack through US-S5-1 + US-S4 OpenSSH/Jelly/Gallery2.
Release-keys/AVB, CVE clean+hi batches, Yama/slabrand, Pro branding, bundled apps, and AXP-class product surface docs/scripts.
This commit is contained in:
1 parent
fd793b9471
commit
deaaf42caa
129 files changed
+11769
-141
No files matched your search
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
# Magisk preroot (sunfish-a16 / 009)
|
||||
|
||||
**Policy:** clone AXP / EXTENDROM `EXTENDROM_PREROOT_BOOT` — do not invent.
|
||||
Diverge only if LOS23 or Magisk version breaks that path.
|
||||
|
||||
**Clean Magisk**, stock UI. No GOLDEN modules. No KernelSU in ship kernel.
|
||||
|
||||
| File | Role |
|
||||
|------|------|
|
||||
| `prepare_magisk.sh` | Unzip Magisk APK → `$OUT_DIR/.magisk` (same as extendrom `er.sh`) |
|
||||
| `patch.sh` | From sfX extendrom — patches boot.img via Magisk `boot_patch.sh` |
|
||||
| `apply_releasetools_hook.py` | Inject into releasetools `common.py` (A16) |
|
||||
|
||||
AXP virgin UX: Magisk not a `PRODUCT_PACKAGE`; root inactive until user
|
||||
Additional Setup. See `docs/009-magisk-preinstall-runbook.md`.
|
||||
|
||||
```bash
|
||||
export SUNFISH_A16_MAGISK_PREROOT=1 # optional; READY file is the real gate
|
||||
MAGISK_STAGE_DIR=$ANDROID_BUILD_TOP/out/.magisk \
|
||||
vendor/sunfish-a16/magisk/prepare_magisk.sh
|
||||
python3 vendor/sunfish-a16/magisk/apply_releasetools_hook.py --top "$ANDROID_BUILD_TOP" --force
|
||||
```
|
||||
|
||||
Hook **v2** runs when `out/.magisk/READY` exists (preferred) and/or
|
||||
`SUNFISH_A16_MAGISK_PREROOT=1`. Env alone is unreliable under soong/ninja.
|
||||
Without READY / env the hook no-ops.
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Idempotent Magisk preroot hook into releasetools common.py (LOS 23.2 / A16).
|
||||
|
||||
Gate (either is enough):
|
||||
- ``out/.magisk/READY`` present (preferred — survives ninja/soong env scrubbing)
|
||||
- ``SUNFISH_A16_MAGISK_PREROOT=1``
|
||||
|
||||
Matches sfX extendrom inject (always-on once staged), adapted for A16 + our
|
||||
vendor path. ``RunAndCheckOutput`` env is merged with ``os.environ`` so PATH /
|
||||
ANDROID_BUILD_TOP survive (extendrom only passed ``system_root_image``; that
|
||||
works via shebang but is fragile under sandboxes).
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
MARKER = "SUNFISH_A16: Magisk preroot hook"
|
||||
MARKER_VER = "SUNFISH_A16: Magisk preroot hook v2"
|
||||
|
||||
BUILD_HOOK = '''
|
||||
# SUNFISH_A16: Magisk preroot hook v2 (before AVB)
|
||||
# Gate: staged out/.magisk/READY and/or SUNFISH_A16_MAGISK_PREROOT=1
|
||||
_sf_top = os.getenv("ANDROID_BUILD_TOP") or os.environ.get("PWD") or os.getcwd()
|
||||
_sf_ready = os.path.isfile(os.path.join(_sf_top, "out", ".magisk", "READY"))
|
||||
_sf_env = os.environ.get("SUNFISH_A16_MAGISK_PREROOT") == "1"
|
||||
if _sf_ready or _sf_env:
|
||||
if ((partition_name == "boot" and info_dict.get("init_boot") != "true")
|
||||
or partition_name == "init_boot"):
|
||||
mpatcher = [
|
||||
os.path.join(_sf_top, "vendor/sunfish-a16/magisk/patch.sh"),
|
||||
img.name,
|
||||
_sf_top,
|
||||
]
|
||||
logger.info("SUNFISH_A16 Magisk patching (build): %s", img.name)
|
||||
_sf_penv = os.environ.copy()
|
||||
_sf_penv["system_root_image"] = info_dict.get("system_root_image", "false")
|
||||
_sf_penv.setdefault("ANDROID_BUILD_TOP", _sf_top)
|
||||
RunAndCheckOutput(mpatcher, verbose=True, env=_sf_penv)
|
||||
'''
|
||||
|
||||
PREBUILT_HOOK = '''
|
||||
# SUNFISH_A16: Magisk preroot hook v2 (prebuilt)
|
||||
_sf_top = os.getenv("ANDROID_BUILD_TOP") or os.environ.get("PWD") or os.getcwd()
|
||||
_sf_ready = os.path.isfile(os.path.join(_sf_top, "out", ".magisk", "READY"))
|
||||
_sf_env = os.environ.get("SUNFISH_A16_MAGISK_PREROOT") == "1"
|
||||
if _sf_ready or _sf_env:
|
||||
if ((prebuilt_name == "boot.img" or prebuilt_name == "init_boot.img")
|
||||
and os.path.exists(prebuilt_path)):
|
||||
if info_dict is None:
|
||||
info_dict = OPTIONS.info_dict
|
||||
bimg = os.path.join(_sf_top, prebuilt_path)
|
||||
logger.info("SUNFISH_A16 Magisk patching (prebuilt): %s", bimg)
|
||||
mpatcher = [
|
||||
os.path.join(_sf_top, "vendor/sunfish-a16/magisk/patch.sh"),
|
||||
bimg,
|
||||
_sf_top,
|
||||
]
|
||||
_sf_penv = os.environ.copy()
|
||||
_sf_penv["system_root_image"] = info_dict.get("system_root_image", "false")
|
||||
_sf_penv.setdefault("ANDROID_BUILD_TOP", _sf_top)
|
||||
RunAndCheckOutput(mpatcher, verbose=True, env=_sf_penv)
|
||||
'''
|
||||
|
||||
|
||||
def _strip_old_hooks(text: str) -> str:
|
||||
"""Remove prior SUNFISH Magisk hook blocks (v1 gated or v2)."""
|
||||
# Build hook: from our comment through just before AVB block
|
||||
text = re.sub(
|
||||
r"\n # SUNFISH_A16: Magisk preroot hook(?: v2)? \(before AVB\).*?"
|
||||
r"(?=\n # AVB: if enabled)",
|
||||
"\n",
|
||||
text,
|
||||
count=1,
|
||||
flags=re.S,
|
||||
)
|
||||
# Prebuilt hook: after BOOTABLE_IMAGES assign, before "if os.path.exists(prebuilt_path)"
|
||||
text = re.sub(
|
||||
r"( prebuilt_path = os\.path\.join\(unpack_dir, \"BOOTABLE_IMAGES\", prebuilt_name\)\n)"
|
||||
r"\n # SUNFISH_A16: Magisk preroot hook(?: v2)? \(prebuilt\).*?"
|
||||
r"(?=\n if os\.path\.exists\(prebuilt_path\):)",
|
||||
r"\1",
|
||||
text,
|
||||
count=1,
|
||||
flags=re.S,
|
||||
)
|
||||
return text
|
||||
|
||||
|
||||
def main() -> int:
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--top", default=os.environ.get("ANDROID_BUILD_TOP", ""))
|
||||
ap.add_argument("--dry-run", action="store_true")
|
||||
ap.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Replace an existing SUNFISH Magisk hook with v2",
|
||||
)
|
||||
args = ap.parse_args()
|
||||
top = pathlib.Path(args.top or ".")
|
||||
target = top / "build/make/tools/releasetools/common.py"
|
||||
if not target.is_file():
|
||||
print(f"ERROR: missing {target}", file=sys.stderr)
|
||||
return 2
|
||||
text = target.read_text()
|
||||
|
||||
if MARKER_VER in text and not args.force:
|
||||
print(f"already applied (v2): {target}")
|
||||
return 0
|
||||
|
||||
if MARKER in text or MARKER_VER in text:
|
||||
if not args.force and MARKER_VER not in text:
|
||||
# old v1 present — upgrade
|
||||
pass
|
||||
text = _strip_old_hooks(text)
|
||||
|
||||
needle_avb = (
|
||||
' # AVB: if enabled, calculate and add hash to boot.img or recovery.img.\n'
|
||||
' if info_dict.get("avb_enable") == "true":\n'
|
||||
' avbtool = info_dict["avb_avbtool"]\n'
|
||||
' if partition_name == "recovery":'
|
||||
)
|
||||
idx = text.find(needle_avb)
|
||||
if idx < 0:
|
||||
print("ERROR: AVB anchor not found", file=sys.stderr)
|
||||
return 3
|
||||
text = text[:idx] + BUILD_HOOK + "\n" + text[idx:]
|
||||
|
||||
assign = ' prebuilt_path = os.path.join(unpack_dir, "BOOTABLE_IMAGES", prebuilt_name)\n'
|
||||
idx2 = text.find(assign)
|
||||
if idx2 < 0:
|
||||
print("ERROR: prebuilt assign not found", file=sys.stderr)
|
||||
return 4
|
||||
insert_at = idx2 + len(assign)
|
||||
text = text[:insert_at] + PREBUILT_HOOK + "\n" + text[insert_at:]
|
||||
|
||||
if args.dry_run:
|
||||
print("dry-run OK (v2)")
|
||||
return 0
|
||||
target.write_text(text)
|
||||
print(f"applied v2 -> {target}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
#########################################################################################################
|
||||
#
|
||||
# simple patch wrapper for patching a boot.img during the build process
|
||||
#
|
||||
#########################################################################################################
|
||||
#
|
||||
# Copyright (C) 2023-2024 steadfasterX <steadfasterX -AT- binbash #DOT# rocks>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#########################################################################################################
|
||||
#
|
||||
# usage:
|
||||
# ./patch.sh <full-path-of-boot.img>
|
||||
#
|
||||
#########################################################################################################
|
||||
|
||||
# DO NOT set -e !
|
||||
|
||||
# parse calling params
|
||||
export BOOTIMG="$1"
|
||||
export TOP="$2"
|
||||
[ -z "$TOP" -o ! -d "$TOP" ] && TOP=$PWD
|
||||
|
||||
# colored (optional) output
|
||||
PRINT(){
|
||||
MSG="$2"
|
||||
case $1 in
|
||||
[1-9]*|E|ERROR)
|
||||
echo -e "\e[0;31m$0 - ERROR: ${MSG}\e[0m" ;;
|
||||
I|INFO)
|
||||
echo -e "\e[1;34m$0 - INFO: ${MSG}\e[0m" ;;
|
||||
0|OK|SUCCESS)
|
||||
echo -e "\e[0;32m$0 - OK: ${MSG}\e[0m" ;;
|
||||
*)
|
||||
echo -e "$0 - ${MSG}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
PRINT I "Starting: $0 with: >$BOOTIMG< (TOP=$TOP)"
|
||||
|
||||
# LEGACYSAR can't be detected by the magisk patcher so must be set by us where needed (e.g. fajita).
|
||||
# LEGACYSAR ensures kernel gets patched if required.
|
||||
# https://github.com/topjohnwu/Magisk/blob/9aa466c7730ef4ef73195b476f9804ebf86932d2/scripts/boot_patch.sh#L220-L243
|
||||
export LEGACYSAR=${system_root_image}
|
||||
PRINT I "system_root_image=$LEGACYSAR"
|
||||
|
||||
# PREINITDEVICE can't be detected during build so must be set manually
|
||||
# otherwise "Requires Additional Setup" on first start will not be able to patch w/o direct flash
|
||||
# which is a problem on locked devices (obviously)
|
||||
# https://github.com/AXP-OS/build/wiki/Frequently-Asked-Questions#magisk-requires-additional-setup-on-start
|
||||
export PREINITDEVICE=userdata
|
||||
|
||||
# tell magisk that we are not in booted android
|
||||
export BOOTMODE=false
|
||||
|
||||
# set output file descriptor to pts0 which *should* be the current shell
|
||||
export OUTFD=0
|
||||
|
||||
# do not remove verity nor encryption
|
||||
export KEEPVERITY=true
|
||||
export KEEPFORCEENCRYPT=true
|
||||
|
||||
# set magisk environment
|
||||
export OUT_DIR=$TOP/out
|
||||
export MAG_DIR="$OUT_DIR/.magisk"
|
||||
|
||||
# disable due to not allowed binary or useless within the build process
|
||||
alias dos2unix=
|
||||
alias mount=echo
|
||||
alias umount=echo
|
||||
|
||||
# enable a fallback to get properties, according to:
|
||||
# https://github.com/topjohnwu/Magisk/blob/4eaf701cb79cd9255333abad8482e69987f86280/scripts/util_functions.sh#L59
|
||||
getprop(){
|
||||
find $OUT_DIR/target/product -type f -name build.prop -exec grep $1 {} \; | tail -n1
|
||||
}; export -f getprop
|
||||
|
||||
test -e $BOOTIMG
|
||||
PRINT $? "testing existence of >$BOOTIMG< returned: $?"
|
||||
|
||||
# do the magisk magic
|
||||
/bin/bash $MAG_DIR/boot_patch.sh "$BOOTIMG" \
|
||||
&& cp -v $MAG_DIR/new-boot.img "$BOOTIMG"
|
||||
RET=$?
|
||||
|
||||
# simple check if magisk can be found in the resulting boot.img
|
||||
grep -q --text 'magisk' $BOOTIMG
|
||||
MCHK=$?
|
||||
|
||||
# sometimes the above is not valid even though patching was successful
|
||||
if [ $MCHK -ne 0 ];then
|
||||
PRINT I "Simple magisk check failed, unpacking for a detailed test..\n"
|
||||
[ -d "$MAG_DIR/test" ] && rm -rf $MAG_DIR/test
|
||||
mkdir $MAG_DIR/test
|
||||
cd $MAG_DIR/test
|
||||
$MAG_DIR/magiskboot unpack $BOOTIMG && $MAG_DIR/magiskboot cpio ramdisk.cpio test
|
||||
case $? in
|
||||
1|4) MCHK=0;;
|
||||
*) ;;
|
||||
esac
|
||||
cd $TOP
|
||||
rm -rf $MAG_DIR/test
|
||||
fi
|
||||
|
||||
# check & print result
|
||||
if [ "$MCHK" -eq 0 ];then PRINT OK "MAGISK found in $BOOTIMG!";else PRINT E "Magisk not found in $BOOTIMG!";fi
|
||||
RET=$((RET + $MCHK))
|
||||
|
||||
PRINT $RET "ended with: $RET\n\n"
|
||||
exit $RET
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
# Stage Magisk v22+ APK into $OUT_DIR/.magisk (or MAGISK_STAGE_DIR) for preroot.
|
||||
# Attribute: sfX-android extendrom er.sh MAGISK block + Magisk upstream.
|
||||
set -euo pipefail
|
||||
TOP="${ANDROID_BUILD_TOP:-${1:-}}"
|
||||
OUT_DIR="${OUT_DIR:-$TOP/out}"
|
||||
STAGE="${MAGISK_STAGE_DIR:-$OUT_DIR/.magisk}"
|
||||
APK="${MAGISK_APK:-/srv/rom/prebuilts/magisk/Magisk-v30.7.apk}"
|
||||
ARCH="${MAGISK_TARGET_ARCH:-arm64}"
|
||||
|
||||
if [ -z "$TOP" ] || [ ! -d "$TOP" ]; then
|
||||
echo "Usage: ANDROID_BUILD_TOP=/path prepare_magisk.sh" >&2
|
||||
exit 2
|
||||
fi
|
||||
test -f "$APK" || { echo "Missing Magisk APK: $APK" >&2; exit 4; }
|
||||
|
||||
rm -rf "$STAGE"
|
||||
mkdir -p "$STAGE"
|
||||
unzip -q "$APK" -d "$STAGE/src"
|
||||
|
||||
# Host tools (x86_64) for patching during build
|
||||
cp "$STAGE/src/lib/x86_64/libmagiskboot.so" "$STAGE/magiskboot" 2>/dev/null \
|
||||
|| cp "$STAGE/src/lib/x86/libmagiskboot.so" "$STAGE/magiskboot"
|
||||
chmod 755 "$STAGE/magiskboot"
|
||||
|
||||
if [ "$ARCH" = "arm64" ]; then
|
||||
if [ -f "$STAGE/src/lib/arm64-v8a/libmagisk64.so" ]; then
|
||||
cp "$STAGE/src/lib/arm64-v8a/libmagisk64.so" "$STAGE/magisk64"
|
||||
else
|
||||
cp "$STAGE/src/lib/arm64-v8a/libmagisk.so" "$STAGE/magisk"
|
||||
fi
|
||||
cp "$STAGE/src/lib/arm64-v8a/libmagiskinit.so" "$STAGE/magiskinit"
|
||||
[ -f "$STAGE/src/lib/arm64-v8a/libinit-ld.so" ] && cp "$STAGE/src/lib/arm64-v8a/libinit-ld.so" "$STAGE/init-ld"
|
||||
[ -f "$STAGE/src/lib/arm64-v8a/libmagiskpolicy.so" ] && cp "$STAGE/src/lib/arm64-v8a/libmagiskpolicy.so" "$STAGE/magiskpolicy"
|
||||
else
|
||||
echo "Unsupported MAGISK_TARGET_ARCH=$ARCH" >&2
|
||||
exit 4
|
||||
fi
|
||||
|
||||
chmod 755 "$STAGE/src/assets/boot_patch.sh"
|
||||
rm -rf "$STAGE/src/assets/dexopt" "$STAGE/src/assets/chromeos" 2>/dev/null || true
|
||||
cp "$STAGE/src/assets/"* "$STAGE/"
|
||||
cp "$STAGE/src/assets/boot_patch.sh" "$STAGE/root_boot.sh"
|
||||
chmod 755 "$STAGE/boot_patch.sh" "$STAGE/magiskinit" "$STAGE/magiskboot"
|
||||
[ -f "$STAGE/magisk64" ] && chmod 755 "$STAGE/magisk64"
|
||||
[ -f "$STAGE/magisk" ] && chmod 755 "$STAGE/magisk"
|
||||
[ -f "$STAGE/init-ld" ] && chmod 755 "$STAGE/init-ld"
|
||||
|
||||
# Point patch.sh at our vendor copy
|
||||
MARKER="$STAGE/READY"
|
||||
echo "apk=$(basename "$APK")" > "$MARKER"
|
||||
echo "arch=$ARCH" >> "$MARKER"
|
||||
echo "staged=$(date -u -Iseconds)" >> "$MARKER"
|
||||
echo "OK Magisk staged at $STAGE"
|
||||
cat "$MARKER"
|
||||
Reference in new issue
Block a user