├── .github └── FUNDING.yml ├── LICENSE ├── META-INF └── com │ └── google │ └── android │ ├── update-binary │ └── updater-script ├── README.md ├── anykernel.sh ├── modules └── system │ └── lib │ └── modules │ └── placeholder ├── patch └── placeholder ├── ramdisk └── placeholder └── tools ├── ak3-core.sh ├── busybox ├── fec ├── httools_static ├── lptools_static ├── magiskboot ├── magiskpolicy └── snapshotupdater_static /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: osm0sis # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://www.paypal.me/osm0sis # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ## AnyKernel3 (AK3), and AnyKernel2/AnyKernel 2.0 (AK2) Scripts License: 2 | 3 | AnyKernel (versions 2.0/2 and later) Android image modifying scripts. 4 | Copyright (c) 2019 Chris Renshaw (osm0sis @ xda-developers), 5 | and additional contributors per readily available commit history/credits. 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted (subject to the limitations in the disclaimer 10 | below) provided that the following conditions are met: 11 | 12 | * Redistributions of source code must retain the above copyright notice, 13 | this list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from this 21 | software without specific prior written permission. 22 | 23 | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 24 | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 25 | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 28 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | POSSIBILITY OF SUCH DAMAGE. 35 | 36 | 37 | ## Included Binary Licenses: 38 | 39 | magiskboot, magiskpolicy (Magisk): GPLv3+ 40 | 41 | Magisk, including all git submodules are free software: 42 | you can redistribute it and/or modify it under the terms of the 43 | GNU General Public License as published by the Free Software Foundation, 44 | either version 3 of the License, or (at your option) any later version. 45 | 46 | This program is distributed in the hope that it will be useful, 47 | but WITHOUT ANY WARRANTY; without even the implied warranty of 48 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49 | GNU General Public License for more details. 50 | 51 | You should have received a copy of the GNU General Public License 52 | along with this program. If not, see . 53 | 54 | Per Section 6(d), official compiled binaries from unmodified source: 55 | https://github.com/topjohnwu/Magisk 56 | 57 | busybox: GPLv2 58 | 59 | BusyBox is distributed under version 2 of the General Public 60 | License. Version 2 is the only version of this license which this 61 | version of BusyBox (or modified versions derived from this one) may 62 | be distributed under. 63 | 64 | This program is free software; you can redistribute it and/or modify 65 | it under the terms of the GNU General Public License as published by 66 | the Free Software Foundation. 67 | 68 | This program is distributed in the hope that it will be useful, 69 | but WITHOUT ANY WARRANTY; without even the implied warranty of 70 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 71 | GNU General Public License for more details. 72 | 73 | Per Section 3(b), self-compiled binary from modified source: 74 | https://git.busybox.net/busybox/ 75 | https://github.com/osm0sis/android-busybox-ndk 76 | (pre-patched source tree used to build available upon request) 77 | 78 | lptools_static: Apache License 2.0 79 | fec: Apache License 2.0 80 | snapshotupdater_static: Apache License 2.0 81 | 82 | Copyright their respective authors, (linked below). 83 | 84 | Licensed under the Apache License, Version 2.0 (the "License"); 85 | you may not use this file except in compliance with the License. 86 | You may obtain a copy of the License at 87 | 88 | http://www.apache.org/licenses/LICENSE-2.0 89 | 90 | Unless required by applicable law or agreed to in writing, software 91 | distributed under the License is distributed on an "AS IS" BASIS, 92 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 93 | See the License for the specific language governing permissions and 94 | limitations under the License. 95 | 96 | Source not required, however, respective sources are provided: 97 | https://github.com/phhusson/vendor_lptools 98 | https://android.googlesource.com/platform/system/extras/+/master/verity/fec/ 99 | https://github.com/capntrips/SnapshotUpdater 100 | 101 | httools_static: MIT License 102 | 103 | Copyright (c) 2022 capntrips 104 | 105 | Permission is hereby granted, free of charge, to any person obtaining a copy 106 | of this software and associated documentation files (the "Software"), to deal 107 | in the Software without restriction, including without limitation the rights 108 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 109 | copies of the Software, and to permit persons to whom the Software is 110 | furnished to do so, subject to the following conditions: 111 | 112 | The above copyright notice and this permission notice shall be included in all 113 | copies or substantial portions of the Software. 114 | 115 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 116 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 117 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 118 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 119 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 120 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 121 | SOFTWARE. 122 | 123 | Source not required, however, respective source is provided: 124 | https://github.com/capntrips/HashtreePatcher 125 | 126 | 127 | ## Optional Binary Licenses: 128 | 129 | mkbootfs, mkbootimg: Apache License 2.0 130 | mkmtkhdr: Apache License 2.0, implied (AOSP mkbootimg derived) 131 | boot_signer*.jar: Apache License 2.0 132 | 133 | Copyright (c) 2008 The Android Open Source Project 134 | 135 | Licensed under the Apache License, Version 2.0 (the "License"); 136 | you may not use this file except in compliance with the License. 137 | You may obtain a copy of the License at 138 | 139 | http://www.apache.org/licenses/LICENSE-2.0 140 | 141 | Unless required by applicable law or agreed to in writing, software 142 | distributed under the License is distributed on an "AS IS" BASIS, 143 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 144 | See the License for the specific language governing permissions and 145 | limitations under the License. 146 | 147 | Source not required, however, respective sources are provided: 148 | https://github.com/osm0sis/mkbootfs 149 | https://github.com/osm0sis/mkbootimg 150 | https://github.com/osm0sis/mkmtkhdr 151 | https://android.googlesource.com/platform/system/extras/+/master/verity/ 152 | 153 | flash_erase, nanddump, nandwrite (mtd-utils): GPLv2 154 | dumpimage, mkimage (U-Boot): GPLv2+ 155 | mboot: GPLv2 (Intel mboot.py derived) 156 | 157 | Copyright their respective authors, (linked below). 158 | 159 | This program is free software; you can redistribute it and/or modify 160 | it under the terms of the GNU General Public License as published by 161 | the Free Software Foundation. 162 | 163 | This program is distributed in the hope that it will be useful, 164 | but WITHOUT ANY WARRANTY; without even the implied warranty of 165 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 166 | GNU General Public License for more details. 167 | 168 | Per Section 3(b), self-compiled binaries from unmodified respective sources: 169 | http://git.infradead.org/mtd-utils.git 170 | https://gitlab.denx.de/u-boot/u-boot 171 | https://github.com/osm0sis/mboot 172 | 173 | futility: BSD 3-Clause License (Chromium OS) 174 | unpackelf, elftool: BSD 3-Clause License, implied (Sony mkelf.py derived) 175 | 176 | Copyright their respective authors, (linked below). 177 | 178 | Redistribution and use in source and binary forms, with or without 179 | modification, are permitted provided that the following conditions are 180 | met: 181 | * Redistributions of source code must retain the above copyright 182 | notice, this list of conditions and the following disclaimer. 183 | * Redistributions in binary form must reproduce the above copyright 184 | notice, this list of conditions and the following disclaimer in 185 | the documentation and/or other materials provided with the 186 | distribution. 187 | * Neither the name of the copyright holder nor the names of its 188 | contributors may be used to endorse or promote products derived 189 | from this software without specific prior written permission. 190 | 191 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 192 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 193 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 194 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 195 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 196 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 197 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 198 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 199 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 200 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 201 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 202 | 203 | Source not required, however, respective sources are provided: 204 | https://github.com/osm0sis/futility 205 | https://github.com/osm0sis/unpackelf 206 | https://github.com/osm0sis/elftool 207 | (https://github.com/sonyxperiadev/device-sony-lt26/tree/master/tools) 208 | 209 | rkcrc: BSD 2-Clause License 210 | 211 | Copyright (c) 2010, 2011 Fukaumi Naoki 212 | Copyright (c) 2013 Ivo van Poorten 213 | All rights reserved. 214 | 215 | Redistribution and use in source and binary forms, with or without 216 | modification, are permitted provided that the following conditions are 217 | met: 218 | 1. Redistributions of source code must retain the above copyright 219 | notice, this list of conditions and the following disclaimer. 220 | 2. Redistributions in binary form must reproduce the above copyright 221 | notice, this list of conditions and the following disclaimer in the 222 | documentation and/or other materials provided with the distribution. 223 | 224 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR 225 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 226 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 227 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 228 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 229 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 230 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 232 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 233 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 234 | 235 | Source not required, however, respective source is provided: 236 | https://github.com/linux-rockchip/rkflashtool 237 | 238 | 239 | ## Additional Build Scripts for Listed Binaries (where used): 240 | 241 | osm0sis' Odds and Ends Thread - Knowledge Base: 242 | https://forum.xda-developers.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/#post-53554719 243 | 244 | -------------------------------------------------------------------------------- /META-INF/com/google/android/update-binary: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | # AnyKernel3 Backend (DO NOT CHANGE) 3 | # osm0sis @ xda-developers 4 | 5 | export OUTFD=$2; 6 | export ZIPFILE="$3"; 7 | 8 | BOOTMODE=false; 9 | ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true; 10 | $BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true; 11 | 12 | DIR=/sdcard; 13 | $BOOTMODE || DIR=$(dirname "$ZIPFILE"); 14 | [ $DIR == "/sideload" ] && DIR=/tmp; 15 | 16 | [ -d /postinstall/tmp ] && POSTINSTALL=/postinstall; 17 | [ "$AKHOME" ] || export AKHOME=$POSTINSTALL/tmp/anykernel; 18 | [ "$ANDROID_ROOT" ] || ANDROID_ROOT=/system; 19 | 20 | ui_print() { 21 | until [ ! "$1" ]; do 22 | echo "ui_print $1 23 | ui_print" >> /proc/self/fd/$OUTFD; 24 | shift; 25 | done; 26 | } 27 | ui_printfile() { 28 | local line losrpad; 29 | $BOOTMODE || [ -e /twres ] || losrpad='| '; # work around LOS Recovery eating leading whitespace 30 | while IFS='' read -r line || [[ -n "$line" ]]; do 31 | ui_print "$losrpad$line"; 32 | done < $1; 33 | } 34 | show_progress() { echo "progress $1 $2" >> /proc/self/fd/$OUTFD; } 35 | file_getprop() { grep "^$2=" "$1" | tail -n1 | cut -d= -f2-; } 36 | find_slot() { 37 | local slot=$(getprop ro.boot.slot_suffix 2>/dev/null); 38 | [ "$slot" ] || slot=$(grep -o 'androidboot.slot_suffix=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); 39 | if [ ! "$slot" ]; then 40 | slot=$(getprop ro.boot.slot 2>/dev/null); 41 | [ "$slot" ] || slot=$(grep -o 'androidboot.slot=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); 42 | [ "$slot" ] && slot=_$slot; 43 | fi; 44 | [ "$slot" == "normal" ] && unset slot; 45 | [ "$slot" ] && echo "$slot"; 46 | } 47 | setup_mountpoint() { 48 | [ -L $1 ] && mv -f $1 ${1}_link; 49 | if [ ! -d $1 ]; then 50 | rm -f $1; 51 | mkdir -p $1; 52 | fi; 53 | } 54 | is_mounted() { mount | grep -q " $1 "; } 55 | mount_apex() { 56 | [ -d /system_root/system/apex ] || return 1; 57 | local apex dest loop minorx num shcon var; 58 | setup_mountpoint /apex; 59 | mount -t tmpfs tmpfs /apex -o mode=755 && touch /apex/apextmp; 60 | shcon=$(cat /proc/self/attr/current); 61 | echo "u:r:su:s0" > /proc/self/attr/current 2>/dev/null; # work around LOS Recovery not allowing loop mounts in recovery context 62 | minorx=1; 63 | [ -e /dev/block/loop1 ] && minorx=$(ls -l /dev/block/loop1 | awk '{ print $6 }'); 64 | num=0; 65 | for apex in /system_root/system/apex/*; do 66 | dest=/apex/$(basename $apex | sed -E -e 's;\.apex$|\.capex$;;' -e 's;\.current$|\.release$;;'); 67 | mkdir -p $dest; 68 | case $apex in 69 | *.apex|*.capex) 70 | unzip -qo $apex original_apex -d /apex; 71 | [ -f /apex/original_apex ] && apex=/apex/original_apex; 72 | unzip -qo $apex apex_payload.img -d /apex; 73 | mv -f /apex/original_apex $dest.apex 2>/dev/null; 74 | mv -f /apex/apex_payload.img $dest.img; 75 | mount -t ext4 -o ro,noatime $dest.img $dest 2>/dev/null && echo "$dest (direct)" >&2; 76 | if [ $? != 0 ]; then 77 | while [ $num -lt 64 ]; do 78 | loop=/dev/block/loop$num; 79 | [ -e $loop ] || mknod $loop b 7 $((num * minorx)); 80 | losetup $loop $dest.img 2>/dev/null; 81 | num=$((num + 1)); 82 | losetup $loop | grep -q $dest.img && break; 83 | done; 84 | mount -t ext4 -o ro,loop,noatime $loop $dest && echo "$dest (loop)" >&2; 85 | if [ $? != 0 ]; then 86 | losetup -d $loop 2>/dev/null; 87 | if [ $num -eq 64 -a $(losetup -f) == "/dev/block/loop0" ]; then 88 | echo "Aborting apex mounts due to broken environment..." >&2; 89 | break; 90 | fi; 91 | fi; 92 | fi; 93 | ;; 94 | *) mount -o bind $apex $dest && echo "$dest (bind)" >&2;; 95 | esac; 96 | done; 97 | echo "$shcon" > /proc/self/attr/current 2>/dev/null; 98 | for var in $(grep -o 'export .* /.*' /system_root/init.environ.rc | awk '{ print $2 }'); do 99 | eval OLD_${var}=\$$var; 100 | done; 101 | $(grep -o 'export .* /.*' /system_root/init.environ.rc | sed 's; /;=/;'); unset export; 102 | touch /apex/apexak3; 103 | } 104 | umount_apex() { 105 | [ -f /apex/apexak3 ] || return 1; 106 | echo "Unmounting apex..." >&2; 107 | local dest loop var; 108 | for var in $(grep -o 'export .* /.*' /system_root/init.environ.rc 2>/dev/null | awk '{ print $2 }'); do 109 | if [ "$(eval echo \$OLD_$var)" ]; then 110 | eval $var=\$OLD_${var}; 111 | else 112 | eval unset $var; 113 | fi; 114 | unset OLD_${var}; 115 | done; 116 | for dest in $(find /apex -type d -mindepth 1 -maxdepth 1); do 117 | loop=$(mount | grep $dest | grep loop | cut -d\ -f1); 118 | umount -l $dest; 119 | losetup $loop >/dev/null 2>&1 && losetup -d $loop; 120 | done; 121 | [ -f /apex/apextmp ] && umount /apex; 122 | rm -rf /apex/apexak3 /apex 2>/dev/null; 123 | } 124 | mount_all() { 125 | local byname mount slot system; 126 | echo "Mounting..." >&2; 127 | byname=bootdevice/by-name; 128 | [ -d /dev/block/$byname ] || byname=$(find /dev/block/platform -type d -name by-name 2>/dev/null | head -n1 | cut -d/ -f4-); 129 | [ -e /dev/block/$byname/super -a -d /dev/block/mapper ] && byname=mapper; 130 | [ -e /dev/block/$byname/system ] || slot=$(find_slot); 131 | for mount in /cache /data /metadata /persist; do 132 | if ! is_mounted $mount; then 133 | mount $mount 2>/dev/null && echo "$mount (fstab)" >&2 && UMOUNTLIST="$UMOUNTLIST $mount"; 134 | if [ $? != 0 -a -e /dev/block/$byname$mount ]; then 135 | setup_mountpoint $mount; 136 | mount -o ro -t auto /dev/block/$byname$mount $mount && echo "$mount (direct)" >&2 && UMOUNTLIST="$UMOUNTLIST $mount"; 137 | fi; 138 | fi; 139 | done; 140 | setup_mountpoint $ANDROID_ROOT; 141 | if ! is_mounted $ANDROID_ROOT; then 142 | mount -o ro -t auto $ANDROID_ROOT 2>/dev/null && echo "$ANDROID_ROOT (\$ANDROID_ROOT)" >&2; 143 | fi; 144 | case $ANDROID_ROOT in 145 | /system_root) setup_mountpoint /system;; 146 | /system) 147 | if ! is_mounted /system && ! is_mounted /system_root; then 148 | setup_mountpoint /system_root; 149 | mount -o ro -t auto /system_root && echo "/system_root (fstab)" >&2; 150 | elif [ -f /system/system/build.prop ]; then 151 | setup_mountpoint /system_root; 152 | mount --move /system /system_root && echo "/system_root (moved)" >&2; 153 | fi; 154 | if [ $? != 0 ]; then 155 | (umount /system; 156 | umount -l /system) 2>/dev/null; 157 | mount -o ro -t auto /dev/block/$byname/system$slot /system_root && echo "/system_root (direct)" >&2; 158 | fi; 159 | ;; 160 | esac; 161 | [ -f /system_root/system/build.prop ] && system=/system; 162 | for mount in /vendor /product /system_ext; do 163 | mount -o ro -t auto $mount 2>/dev/null && echo "$mount (fstab)" >&2; 164 | if [ $? != 0 ] && [ -L /system$mount -o -L /system_root$system$mount ]; then 165 | setup_mountpoint $mount; 166 | mount -o ro -t auto /dev/block/$byname$mount$slot $mount && echo "$mount (direct)" >&2; 167 | fi; 168 | done; 169 | if is_mounted /system_root; then 170 | mount_apex; 171 | mount -o bind /system_root$system /system && echo "/system (bind)" >&2; 172 | fi; 173 | echo " " >&2; 174 | } 175 | umount_all() { 176 | local mount; 177 | echo "Unmounting..." >&2; 178 | (if [ ! -d /postinstall/tmp ]; then 179 | umount /system; 180 | umount -l /system; 181 | fi) 2>/dev/null; 182 | umount_apex; 183 | (if [ ! -d /postinstall/tmp ]; then 184 | umount /system_root; 185 | umount -l /system_root; 186 | fi; 187 | PATH="$OLD_PATH" umount /vendor; # busybox umount /vendor breaks recovery on some hacky devices 188 | PATH="$OLD_PATH" umount -l /vendor; 189 | for mount in /mnt/system /mnt/vendor /product /mnt/product /system_ext /mnt/system_ext $UMOUNTLIST; do 190 | umount $mount; 191 | umount -l $mount; 192 | done) 2>/dev/null; 193 | } 194 | setup_env() { 195 | $BOOTMODE && return 1; 196 | mount -o bind /dev/urandom /dev/random; 197 | if [ -L /etc ]; then 198 | setup_mountpoint /etc; 199 | cp -af /etc_link/* /etc; 200 | sed -i 's; / ; /system_root ;' /etc/fstab; 201 | fi; 202 | umount_all; 203 | mount_all; 204 | OLD_LD_PATH=$LD_LIBRARY_PATH; 205 | OLD_LD_PRE=$LD_PRELOAD; 206 | OLD_LD_CFG=$LD_CONFIG_FILE; 207 | unset LD_LIBRARY_PATH LD_PRELOAD LD_CONFIG_FILE; 208 | if [ ! "$(getprop 2>/dev/null)" ]; then 209 | getprop() { 210 | local propdir propfile propval; 211 | for propdir in / /system_root /system /vendor /product /product/etc /system_ext/etc /odm/etc; do 212 | for propfile in default.prop build.prop; do 213 | if [ "$propval" ]; then 214 | break 2; 215 | else 216 | propval="$(file_getprop $propdir/$propfile $1 2>/dev/null)"; 217 | fi; 218 | done; 219 | done; 220 | echo "$propval"; 221 | } 222 | elif [ ! "$(getprop ro.build.type 2>/dev/null)" ]; then 223 | getprop() { 224 | ($(which getprop) | grep "$1" | cut -d[ -f3 | cut -d] -f1) 2>/dev/null; 225 | } 226 | fi; 227 | } 228 | restore_env() { 229 | $BOOTMODE && return 1; 230 | local dir; 231 | unset -f getprop; 232 | [ "$OLD_LD_PATH" ] && export LD_LIBRARY_PATH=$OLD_LD_PATH; 233 | [ "$OLD_LD_PRE" ] && export LD_PRELOAD=$OLD_LD_PRE; 234 | [ "$OLD_LD_CFG" ] && export LD_CONFIG_FILE=$OLD_LD_CFG; 235 | unset OLD_LD_PATH OLD_LD_PRE OLD_LD_CFG; 236 | sleep 1; 237 | umount_all; 238 | [ -L /etc_link ] && rm -rf /etc/*; 239 | (for dir in /etc /apex /system_root /system /vendor /product /system_ext /metadata /persist; do 240 | if [ -L "${dir}_link" ]; then 241 | rmdir $dir; 242 | mv -f ${dir}_link $dir; 243 | fi; 244 | done; 245 | umount -l /dev/random) 2>/dev/null; 246 | } 247 | setup_bb() { 248 | local arch32 bb; 249 | for arch32 in x86 arm; do 250 | if [ -d $AKHOME/tools/$arch32 ]; then 251 | bb=$AKHOME/tools/$arch32/busybox; 252 | chmod 755 $bb; 253 | $bb >/dev/null 2>&1; 254 | if [ $? == 0 ]; then 255 | $bb mv -f $AKHOME/tools/$arch32/* $AKHOME/tools; 256 | break; 257 | fi; 258 | fi; 259 | done; 260 | bb=$AKHOME/tools/busybox; 261 | chmod 755 $bb; 262 | $bb chmod -R 755 tools bin; 263 | $bb --install -s bin; 264 | } 265 | debugging() { 266 | local debug log path; 267 | case $(basename "$ZIPFILE" .zip) in 268 | *-debugging) debug=1;; 269 | esac; 270 | for path in /tmp /cache /metadata /persist; do 271 | [ -f $path/.ak3-debugging ] && debug=1; 272 | done; 273 | if [ "$debug" ]; then 274 | ui_print " " "Creating debugging archive in $DIR..."; 275 | [ -f /tmp/recovery.log ] && log=/tmp/recovery.log; 276 | tar -czf "$DIR/anykernel3-$(date +%Y-%m-%d_%H%M%S)-debug.tgz" $AKHOME $log; 277 | fi; 278 | } 279 | cleanup() { 280 | cd $AKHOME/../; 281 | rm -rf $AKHOME; 282 | } 283 | abort() { 284 | ui_print "$@"; 285 | debugging; 286 | restore_env; 287 | if [ ! -f anykernel.sh -o "$(file_getprop anykernel.sh do.cleanuponabort 2>/dev/null)" == 1 ]; then 288 | cleanup; 289 | fi; 290 | exit 1; 291 | } 292 | do_devicecheck() { 293 | [ "$(file_getprop anykernel.sh do.devicecheck)" == 1 ] || return 1; 294 | local device devicename match product testname vendordevice vendorproduct; 295 | ui_print "Checking device..."; 296 | device=$(getprop ro.product.device 2>/dev/null); 297 | product=$(getprop ro.build.product 2>/dev/null); 298 | vendordevice=$(getprop ro.product.vendor.device 2>/dev/null); 299 | vendorproduct=$(getprop ro.vendor.product.device 2>/dev/null); 300 | for testname in $(grep '^device.name.*=' anykernel.sh | cut -d= -f2-); do 301 | for devicename in $device $product $vendordevice $vendorproduct; do 302 | if [ "$devicename" == "$testname" ]; then 303 | ui_print "$testname" " "; 304 | match=1; 305 | break 2; 306 | fi; 307 | done; 308 | done; 309 | if [ ! "$match" ]; then 310 | abort " " "Unsupported device. Aborting..."; 311 | fi; 312 | } 313 | int2ver() { 314 | if [ "$1" -eq "$1" ] 2>/dev/null; then 315 | echo "$1.0.0"; 316 | elif [ ! "$(echo "$1" | cut -d. -f3)" ]; then 317 | echo "$1.0"; 318 | else 319 | echo "$1"; 320 | fi; 321 | } 322 | do_versioncheck() { 323 | [ "$(file_getprop anykernel.sh supported.versions)" ] || return 1; 324 | local android_ver hi_ver lo_ver parsed_ver supported supported_ver; 325 | ui_print "Checking Android version..."; 326 | supported_ver=$(file_getprop anykernel.sh supported.versions | tr -d '[:space:]'); 327 | android_ver=$(file_getprop /system/build.prop ro.build.version.release); 328 | parsed_ver=$(int2ver $android_ver); 329 | if echo $supported_ver | grep -q '-'; then 330 | lo_ver=$(int2ver "$(echo $supported_ver | cut -d- -f1)"); 331 | hi_ver=$(int2ver "$(echo $supported_ver | cut -d- -f2)"); 332 | if echo -e "$hi_ver\n$lo_ver\n$parsed_ver" | sort -g | grep -n "$parsed_ver" | grep -q '^2:'; then 333 | supported=1; 334 | fi; 335 | else 336 | for ver in $(echo $supported_ver | sed 's;,; ;g'); do 337 | if [ "$(int2ver $ver)" == "$parsed_ver" ]; then 338 | supported=1; 339 | break; 340 | fi; 341 | done; 342 | fi; 343 | if [ "$supported" ]; then 344 | ui_print "$android_ver" " "; 345 | else 346 | abort " " "Unsupported Android version. Aborting..."; 347 | fi; 348 | } 349 | do_levelcheck() { 350 | [ "$(file_getprop anykernel.sh supported.patchlevels)" ] || return 1; 351 | local android_lvl hi_lvl lo_lvl parsed_lvl supported_lvl; 352 | ui_print "Checking Android security patch level..."; 353 | supported_lvl=$(file_getprop anykernel.sh supported.patchlevels | grep -oE '[0-9]{4}-[0-9]{2}|-'); 354 | android_lvl=$(file_getprop /system/build.prop ro.build.version.security_patch); 355 | parsed_lvl=$(echo $android_lvl | grep -oE '[0-9]{4}-[0-9]{2}'); 356 | if echo $supported_lvl | grep -q '^\-'; then 357 | lo_lvl=0000-00; 358 | hi_lvl=$(echo $supported_lvl | awk '{ print $2 }'); 359 | elif echo $supported_lvl | grep -q ' - '; then 360 | lo_lvl=$(echo $supported_lvl | awk '{ print $1 }'); 361 | hi_lvl=$(echo $supported_lvl | awk '{ print $3 }'); 362 | elif echo $supported_lvl | grep -q '\-$'; then 363 | lo_lvl=$(echo $supported_lvl | awk '{ print $1 }'); 364 | hi_lvl=9999-99; 365 | fi; 366 | if echo -e "$hi_lvl\n$lo_lvl\n$parsed_lvl" | sort -g | grep -n "$parsed_lvl" | grep -q '^2:'; then 367 | ui_print "$android_lvl" " "; 368 | else 369 | abort " " "Unsupported Android security patch level. Aborting..."; 370 | fi; 371 | } 372 | do_vendorlevelcheck() { 373 | [ "$(file_getprop anykernel.sh supported.vendorpatchlevels)" ] || return 1; 374 | local vendor_lvl hi_lvl lo_lvl parsed_lvl supported_lvl; 375 | ui_print "Checking Vendor security patch level..."; 376 | supported_lvl=$(file_getprop anykernel.sh supported.vendorpatchlevels | grep -oE '[0-9]{4}-[0-9]{2}|-'); 377 | vendor_lvl=$(file_getprop /vendor/build.prop ro.vendor.build.security_patch); 378 | parsed_lvl=$(echo $vendor_lvl | grep -oE '[0-9]{4}-[0-9]{2}'); 379 | if echo $supported_lvl | grep -q '^\-'; then 380 | lo_lvl=0000-00; 381 | hi_lvl=$(echo $supported_lvl | awk '{ print $2 }'); 382 | elif echo $supported_lvl | grep -q ' - '; then 383 | lo_lvl=$(echo $supported_lvl | awk '{ print $1 }'); 384 | hi_lvl=$(echo $supported_lvl | awk '{ print $3 }'); 385 | elif echo $supported_lvl | grep -q '\-$'; then 386 | lo_lvl=$(echo $supported_lvl | awk '{ print $1 }'); 387 | hi_lvl=9999-99; 388 | fi; 389 | if echo -e "$hi_lvl\n$lo_lvl\n$parsed_lvl" | sort -g | grep -n "$parsed_lvl" | grep -q '^2:'; then 390 | ui_print "$vendor_lvl" " "; 391 | else 392 | abort " " "Unsupported Vendor security patch level. Aborting..."; 393 | fi; 394 | } 395 | dump_moduleinfo() { 396 | cat < $1; 397 | id=ak3-helper 398 | name=AK3 Helper Module 399 | version=$(awk '{ print $3 }' $AKHOME/vertmp) $(grep -oE '#.[0-9]' $AKHOME/vertmp) 400 | versionCode=1 401 | author=AnyKernel3 402 | description=$KERNEL_STRING 403 | EOF 404 | } 405 | dump_moduleremover() { 406 | cat <<'EOF' > $1; 407 | #!/system/bin/sh 408 | MODDIR=${0%/*}; 409 | if [ "$(cat /proc/version)" != "$(cat $MODDIR/version)" ]; then 410 | rm -rf $MODDIR; 411 | exit; 412 | fi; 413 | rm -f $MODDIR/update; 414 | . $MODDIR/post-fs-data.2.sh; 415 | EOF 416 | } 417 | do_modules() { 418 | [ "$(file_getprop anykernel.sh do.modules)" == 1 ] || return 1; 419 | local block modcon moddir modtarget module mount slot umask umountksu; 420 | if [ "$(file_getprop anykernel.sh do.systemless)" == 1 ]; then 421 | if [ ! -d /data/adb -o ! -d /data/data/android ]; then 422 | ui_print " " "Warning: No /data access for kernel helper systemless module!"; 423 | return 1; 424 | fi; 425 | cd $AKHOME/modules; 426 | ui_print " " "Creating kernel helper systemless module..."; 427 | if [ -d /data/adb/magisk -a -f $AKHOME/magisk_patched ] || [ -d /data/data/me.weishu.kernelsu -a -f $AKHOME/kernelsu_patched ]; then 428 | umask=$(umask); 429 | moddir=/data/adb/modules/ak3-helper; 430 | # this may be the initial KernelSU install or first module so setup as needed 431 | if [ -f $AKHOME/kernelsu_patched ]; then 432 | umask 077; 433 | if [ ! -f /data/adb/ksud ]; then 434 | cp -f /data/app/*/me.weishu.kernelsu*/lib/*/libksud.so /data/adb/ksud; 435 | chmod 755 /data/adb/ksud; 436 | fi; 437 | if [ ! -d /data/adb/modules ]; then 438 | mkdir -p /data/adb/modules; 439 | chmod 777 /data/adb/modules; 440 | fi; 441 | [ -d /data/adb/modules_update ] || mkdir -p /data/adb/modules_update; 442 | [ -d /data/adb/ksu ] || mkdir -p /data/adb/ksu; 443 | [ -f /data/adb/ksu/modules.img ] && cp -f /data/adb/ksu/modules.img /data/adb/ksu/modules_update.img; 444 | if [ ! -f /data/adb/ksu/modules_update.img ]; then 445 | /system/bin/make_ext4fs -b 1024 -l 256M /data/adb/ksu/modules_update.img 2>/dev/null \ 446 | || /system/bin/mke2fs -b 1024 -t ext4 /data/adb/ksu/modules_update.img 256M; 447 | fi; 448 | mount -t ext4 -o rw /data/adb/ksu/modules_update.img /data/adb/modules_update && umountksu=1; 449 | touch /data/adb/ksu/update; 450 | umask 022; 451 | rm -rf $moddir; 452 | mkdir -p $moddir; 453 | dump_moduleinfo $moddir/module.prop; 454 | touch $moddir/update; 455 | moddir=/data/adb/modules_update/ak3-helper; 456 | fi; 457 | umask 022; 458 | rm -rf $moddir; 459 | mkdir -p system $moddir; 460 | (mv -f product system; 461 | mv -f vendor system; 462 | mv -f system_ext system; 463 | mv -f post-fs-data.sh post-fs-data.2.sh) 2>/dev/null; 464 | cp -rLf * $moddir; 465 | dump_moduleinfo $moddir/module.prop; 466 | dump_moduleremover $moddir/post-fs-data.sh; 467 | cp -f $AKHOME/vertmp $moddir/version; 468 | touch $moddir/update; 469 | umask $umask; 470 | /system/bin/chcon -hR "u:object_r:system_file:s0" $moddir; 471 | [ "$umountksu" ] && umount /data/adb/modules_update; 472 | else 473 | ui_print "Magisk/KernelSU installation not found. Skipped!"; 474 | fi; 475 | else 476 | cd $AKHOME/modules; 477 | ui_print " " "Pushing modules..."; 478 | if [ -d /dev/block/mapper ]; then 479 | for block in system vendor product; do 480 | for slot in "" _a _b; do 481 | blockdev --setrw /dev/block/mapper/$block$slot 2>/dev/null; 482 | done; 483 | done; 484 | fi; 485 | if [ ! -d /postinstall/tmp ]; then 486 | for mount in /system /vendor /product; do 487 | if is_mounted $mount; then 488 | mount -o rw,remount -t auto $mount && echo "$mount (rw)" >&2; 489 | fi; 490 | done; 491 | fi; 492 | for module in $(find . -name '*.ko'); do 493 | modtarget=$POSTINSTALL$(echo $module | cut -c2-); 494 | if [ ! -e $modtarget ]; then 495 | case $module in 496 | */vendor/*) modcon=vendor;; 497 | */product/*) modcon=product;; 498 | *) modcon=system;; 499 | esac; 500 | fi; 501 | if is_mounted $modtarget; then 502 | mount -o rw,remount -t auto $modtarget && echo "$modtarget (rw)" >&2; 503 | fi; 504 | mkdir -p $(dirname $modtarget); 505 | cp -rLf $module $modtarget; 506 | chown 0:0 $modtarget; 507 | chmod 644 $modtarget; 508 | if [ "$modcon" ]; then 509 | /system/bin/chcon "u:object_r:${modcon}_file:s0" $modtarget; 510 | fi; 511 | if is_mounted $modtarget; then 512 | mount -o ro,remount -t auto $modtarget && echo "$modtarget (ro)" >&2; 513 | fi; 514 | done; 515 | if [ ! -d /postinstall/tmp ]; then 516 | for mount in /system /vendor /product; do 517 | if is_mounted $mount; then 518 | mount -o ro,remount -t auto $mount && echo "$mount (ro)" >&2; 519 | fi; 520 | done; 521 | fi; 522 | fi; 523 | cd $AKHOME; 524 | } 525 | 526 | show_progress 1.34 25; 527 | ui_print " "; 528 | cleanup; 529 | mkdir -p $AKHOME/bin; 530 | cd $AKHOME; 531 | unzip -o "$ZIPFILE"; 532 | if [ $? != 0 -o ! "$(ls tools)" ]; then 533 | abort "Unzip failed. Aborting..."; 534 | fi; 535 | setup_bb; 536 | if [ $? != 0 -o -z "$(ls bin)" ]; then 537 | abort "Busybox setup failed. Aborting..."; 538 | fi; 539 | OLD_PATH="$PATH"; 540 | export PATH="$AKHOME/tools:$AKHOME/bin:$PATH"; 541 | 542 | if [ -f banner ]; then 543 | ui_printfile banner; 544 | ui_print " " " "; 545 | fi; 546 | 547 | KERNEL_STRING="$(file_getprop anykernel.sh kernel.string)"; 548 | ui_print "$KERNEL_STRING"; 549 | if [ -f version ]; then 550 | ui_print " "; 551 | ui_printfile version; 552 | ui_print " "; 553 | fi; 554 | ui_print " " "AnyKernel3 by osm0sis @ xda-developers" " "; 555 | grep -oE 'AK_BASE.*' META-INF/com/google/android/updater-script >&2; 556 | ui_print " "; 557 | 558 | setup_env; 559 | 560 | do_devicecheck; 561 | do_versioncheck; 562 | do_levelcheck; 563 | do_vendorlevelcheck; 564 | 565 | ui_print "Installing..."; 566 | # hack to maintain support for anykernel.sh files that weren't updated correctly along with the AK core 567 | CORE=$(grep -oE 'ak.*core.sh' anykernel.sh); 568 | [ -f tools/$CORE ] || ln -s $AKHOME/tools/ak*-core.sh $AKHOME/tools/$CORE; 569 | ash anykernel.sh; 570 | if [ $? != 0 ]; then 571 | abort; 572 | fi; 573 | 574 | do_modules; 575 | 576 | debugging; 577 | ui_print " "; 578 | restore_env; 579 | 580 | if [ "$(file_getprop anykernel.sh do.cleanup)" == 1 ]; then 581 | cleanup; 582 | fi; 583 | 584 | ui_print " " "Done!"; 585 | export PATH="$OLD_PATH"; 586 | unset OLD_PATH OUTFD ZIPFILE; 587 | -------------------------------------------------------------------------------- /META-INF/com/google/android/updater-script: -------------------------------------------------------------------------------- 1 | #FLASHAFTERUPDATEV2 2 | # 3 | # Dummy file; update-binary is a shell script (DO NOT CHANGE) 4 | # 5 | # 6 | # AK_BASE_VERSION=20250518 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ---------------------------------------------------------------------------------- 2 | AnyKernel3 - Flashable Zip Template for Kernel Releases with Ramdisk Modifications 3 | ---------------------------------------------------------------------------------- 4 | ### by osm0sis @ xda-developers ### 5 | 6 | "AnyKernel is a template for an update.zip that can apply any kernel to any ROM, regardless of ramdisk." - Koush 7 | 8 | AnyKernel2 pushed the format further by allowing kernel developers to modify the underlying ramdisk for kernel feature support easily using a number of included command methods along with properties and variables to customize the installation experience to their kernel. AnyKernel3 adds the power of topjohnwu's magiskboot for wider format support by default, and to automatically detect and retain Magisk root by patching the new Image.*-dtb as Magisk would. 9 | 10 | _A script based on Galaxy Nexus (tuna) is included for reference. Everything to edit is self-contained in __anykernel.sh__._ 11 | 12 | ## // Properties / Variables ## 13 | ``` 14 | kernel.string=KernelName by YourName @ xda-developers 15 | do.devicecheck=1 16 | do.modules=1 17 | do.systemless=1 18 | do.cleanup=1 19 | do.cleanuponabort=0 20 | device.name1=maguro 21 | device.name2=toro 22 | device.name3=toroplus 23 | device.name4=tuna 24 | supported.versions=6.0 - 7.1.2 25 | supported.patchlevels=2019-07 - 26 | supported.vendorpatchlevels=2013-07 27 | 28 | BLOCK=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot; 29 | IS_SLOT_DEVICE=0; 30 | RAMDISK_COMPRESSION=auto; 31 | PATCH_VBMETA_FLAG=auto; 32 | ``` 33 | 34 | __do.devicecheck=1__ specified requires at least device.name1 to be present. This should match ro.product.device, ro.build.product, ro.product.vendor.device or ro.vendor.product.device from the build.prop files for your device. There is support for as many device.name# properties as needed. You may remove any empty ones that aren't being used. 35 | 36 | __do.modules=1__ will push the .ko contents of the modules directory to the same location relative to root (/) and apply correct permissions. On A/B devices this can only be done to the active slot. 37 | 38 | __do.systemless=1__ (with __do.modules=1__) will instead push the full contents of the modules directory to create a simple "ak3-helper" Magisk/KernelSU module, allowing developers to effectively replace system files, including .ko files. If the current kernel is changed then the kernel helper module automatically removes itself to prevent conflicts. 39 | 40 | __do.cleanup=0__ will keep the zip from removing its working directory in /tmp/anykernel (by default) - this can be useful if trying to debug in adb shell whether the patches worked correctly. 41 | 42 | __do.cleanuponabort=0__ will keep the zip from removing its working directory in /tmp/anykernel (by default) in case of installation abort. 43 | 44 | __supported.versions=__ will match against ro.build.version.release from the current ROM's build.prop. It can be set to a list or range. As a list of one or more entries, e.g. `7.1.2` or `8.1.0, 9` it will look for exact matches, as a range, e.g. `7.1.2 - 9` it will check to make sure the current version falls within those limits. Whitespace optional, and supplied version values should be in the same number format they are in the build.prop value for that Android version. 45 | 46 | __supported.patchlevels=__ and __supported.vendorpatchlevels=__ will match against ro.build.version.security_patch and ro.vendor.build.security_patch, respectively, from the current system/vendor build.prop. They can be set as a closed or open-ended range of dates in the format YYYY-MM, whitespace optional, e.g. `2019-04 - 2019-06`, `2019-04 -` or `- 2019-06` where the last two examples show setting a minimum or maximum. 47 | 48 | `BLOCK=auto` instead of a direct block filepath enables detection of the device boot partition for use with broad, device non-specific zips. Also accepts any partition filename (from by-name), e.g. `boot`, `recovery` or `vendor_boot`. 49 | 50 | `IS_SLOT_DEVICE=1` enables detection of the suffix for the active boot partition on slot-based devices and will add this to the end of the supplied `BLOCK=` path. Also accepts `auto` for use with broad, device non-specific zips. 51 | 52 | `RAMDISK_COMPRESSION=auto` allows automatically repacking the ramdisk with the format detected during unpack. Changing `auto` to `gz`, `lzo`, `lzma`, `xz`, `bz2`, `lz4`, or `lz4-l` (for lz4 legacy) instead forces the repack as that format, and using `cpio` or `none` will (attempt to) force the repack as uncompressed. 53 | 54 | `PATCH_VBMETA_FLAG=auto` allows automatically using the default AVBv2 vbmeta flag on repack, and use the Magisk configuration Canary 23016+. Set to `0` forces keeping whatever is in the original AVBv2 flags, and set to `1` forces patching the flag (only necessary on few devices). 55 | 56 | `CUSTOMDD=""` may be added to allow specifying additional dd parameters for devices that need to hack their kernel directly into a large partition like mmcblk0, or force use of dd for flashing. 57 | 58 | `SLOT_SELECT=active|inactive` may be added to allow specifying the target slot. If omitted the default remains `active`. 59 | 60 | `NO_BLOCK_DISPLAY=1` may be added to disable output of the detected final used partition+slot path for zips which choose to include their own custom output instead. 61 | 62 | `NO_MAGISK_CHECK=1` may be added to disable detection of Magisk and related kernel/dtb repatching for special zips which don't require that. 63 | 64 | `NO_VBMETA_PARTITION_PATCH=1` may be added to skip vbmeta processing using httools, since GKI is bootable with verity/verification ON, as long as AVB is not enforced for boot stage partitions. 65 | 66 | ## // Command Methods ## 67 | ``` 68 | ui_print "" [...] 69 | abort ["" [...]] 70 | contains 71 | file_getprop 72 | 73 | set_perm [ ...] 74 | set_perm_recursive [ ...] 75 | 76 | dump_boot 77 | split_boot 78 | unpack_ramdisk 79 | 80 | backup_file 81 | restore_file 82 | replace_string 83 | replace_section 84 | remove_section 85 | insert_line 86 | replace_line 87 | remove_line 88 | prepend_file 89 | insert_file 90 | append_file 91 | replace_file 92 | patch_fstab block|mount|fstype|options|flags 93 | patch_cmdline 94 | patch_prop 95 | patch_ueventd 96 | 97 | repack_ramdisk 98 | flash_boot 99 | flash_generic 100 | write_boot 101 | 102 | reset_ak [keep] 103 | setup_ak 104 | ``` 105 | 106 | __"if search string"__ is the string it looks for to decide whether it needs to add the tweak or not, so generally something to indicate the tweak already exists. __"cmdline entry name"__ behaves somewhat like this as a match check for the name of the cmdline entry to be changed/added by the _patch_cmdline_ function, followed by the full entry to replace it. __"prop name"__ also serves as a match check in _patch_prop_ for a property in the given prop file, but is only the prop name as the prop value is specified separately. 107 | 108 | Similarly, __"line match string"__ and __"line replace string"__ are the search strings that locate where the modification needs to be made for those commands, __"begin search string"__ and __"end search string"__ are both required to select the first and last lines of the script block to be replaced for _replace_section_, and __"mount match name"__ and __"fs match type"__ are both required to narrow the _patch_fstab_ command down to the correct entry. 109 | 110 | __"scope"__ may be specified as __"global"__ to force all instances of the string/line targeted by _replace_string_, _replace_line_ or _remove_line_ to be replaced/removed accordingly. Omitted or set to anything else and it will perform the default first-match action. 111 | 112 | __"before|after"__ requires you simply specify __"before"__ or __"after"__ for the placement of the inserted line, in relation to __"line match string"__. 113 | 114 | __"block|mount|fstype|options|flags"__ requires you specify which part (listed in order) of the fstab entry you want to check and alter. 115 | 116 | _dump_boot_ and _write_boot_ are the default method of unpacking/repacking, but for more granular control, or omitting ramdisk changes entirely ("OG AK" mode), these can be separated into _split_boot; unpack_ramdisk_ and _repack_ramdisk; flash_boot_ respectively. _flash_generic_ can be used to flash an image to the corresponding partition. It is automatically included for dtbo, system_dlkm and vendor_dlkm in _write_boot_ but can be called separately if using "OG AK" mode or creating a simple partition flashing only zip. 117 | 118 | Multi-partition zips can be created by removing the ramdisk and patch folders from the zip and including instead "-files" folders named for the partition (without slot suffix), e.g. boot-files + recovery-files, or kernel-files + ramdisk-files (on some Treble devices). These then contain Image.gz, and ramdisk, patch, etc. subfolders for each partition. To setup for the next partition, simply set `BLOCK=` (without slot suffix) and `RAMDISK_COMPRESSION=` for the new target partition and use the _reset_ak_ command. 119 | 120 | Similarly, multi-slot zips can be created with the normal zip layout for the active (current) slot, then resetting for the inactive slot by setting `BLOCK=` (without slot suffix) again, `SLOT_SELECT=inactive` and `RAMDISK_COMPRESSION=` for the target slot and using the _reset_ak keep_ command, which will retain the patch and any added ramdisk files for the next slot. 121 | 122 | _backup_file_ may be used for testing to ensure ramdisk changes are made correctly, transparency for the end-user, or in a ramdisk-only "mod" zip. In the latter case _restore_file_ could also be used to create a "restore" zip to undo the changes, but should be used with caution since the underlying patched files could be changed with ROM/kernel updates. 123 | 124 | You may also use _ui_print "\"_ to write messages back to the recovery during the modification process, _abort "\"_ to abort with optional message, and _file_getprop "\" "\"_ and _contains "\" "\"_ to simplify string testing logic you might want in your script. 125 | 126 | ## // Binary Inclusion ## 127 | 128 | The AK3 repo includes current ARM builds of `magiskboot`, `magiskpolicy`, `lptools_static`, `httools_static`, `fec`, `snapshotupdater_static` and `busybox` by default to keep the basic package small. Builds for other architectures and optional binaries (see below) are available from the latest Magisk zip, or my latest AIK-mobile and FlashIt packages, respectively, here: 129 | 130 | https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/ (Android Image Kitchen thread) 131 | https://forum.xda-developers.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/ (Odds and Ends thread) 132 | 133 | Optional supported binaries which may be placed in /tools to enable built-in expanded functionality are as follows: 134 | * `mkbootfs` - for broken recoveries, or, booted flash support for a script/app via bind mount to /tmp (deprecated/use with caution) 135 | * `flash_erase`, `nanddump`, `nandwrite` - MTD block device support for devices where the `dd` command is not sufficient 136 | * `dumpimage`, `mkimage` - DENX U-Boot uImage format support 137 | * `mboot` - Intel OSIP Android image format support 138 | * `unpackelf`, `mkbootimg` - Sony ELF kernel.elf format support, repacking as AOSP standard boot.img for unlocked bootloaders 139 | * `elftool` (with `unpackelf`) - Sony ELF kernel.elf format support, repacking as ELF for older Sony devices 140 | * `mkmtkhdr` (with `unpackelf`) - MTK device boot image section headers support for Sony devices 141 | * `futility` + `chromeos` test keys directory - Google ChromeOS signature support 142 | * `boot_signer-dexed.jar` (deprecated) + `avb` keys directory - Google Android Verified Boot 1.0 (AVBv1) custom signature support 143 | * `rkcrc` - Rockchip KRNL ramdisk image support 144 | 145 | Optionally moving ARM builds to tools/arm and putting x86 builds in tools/x86 will enable architecture detection for use with broad, device non-specific zips. 146 | 147 | ## // Instructions ## 148 | 149 | 1. Place final kernel build product, e.g. Image.gz-dtb or zImage to name a couple, in the zip root (any separate dt, dtb or recovery_dtbo, dtbo, system_dlkm and/or vendor_dlkm should also go here for devices that require custom ones, each will fallback to the original if not included) 150 | 151 | 2. Place any required ramdisk files in /ramdisk (/vendor_ramdisk for simple multi-partition vendor_boot v3 support) and module files in /modules (with the full path like /modules/system/lib/modules) 152 | 153 | 3. Place any required patch files (generally partial files which go with AK3 file editing commands) in /patch (/vendor_patch for simple multi-partition vendor_boot v3 support) 154 | 155 | 4. Modify the anykernel.sh to add your kernel's name, boot partition location, permissions for any added ramdisk files, and use methods for any required ramdisk modifications (optionally, also place banner and/or version files in the root to have these displayed during flash) 156 | 157 | 5. `zip -r9 UPDATE-AnyKernel3.zip * -x .git README.md *placeholder` 158 | 159 | _The LICENSE file must remain in the final zip to comply with licenses for binary redistribution and the license of the AK3 scripts._ 160 | 161 | If supporting a recovery that forces zip signature verification (like Cyanogen Recovery) then you will need to also sign your zip using the method I describe here: 162 | 163 | https://forum.xda-developers.com/t/dev-template-complete-shell-script-flashable-zip-replacement-signing-script.2934449/ 164 | 165 | Not required, but any tweaks you can't hardcode into the source (best practice) should be added with an additional init.tweaks.rc or bootscript.sh to minimize the necessary ramdisk changes. On newer devices Magisk allows these within /overlay.d - see examples. 166 | 167 | It is also extremely important to note that for the broadest AK3 compatibility it is always better to modify a ramdisk file rather than replace it. 168 | 169 | ___If running into trouble when flashing an AK3 zip, the suffix -debugging may be added to the zip's filename to enable creation of a debug .tgz of /tmp for later examination while booted or on desktop.___ 170 | 171 | ## // Staying Up-To-Date ## 172 | 173 | Now that you've got a ready zip for your device, you might be wondering how to keep it up-to-date with the latest AnyKernel commits. AnyKernel2 and AnyKernel3 have been painstakingly developed to allow you to just drop in the latest update-binary and tools directory and have everything "just work" for beginners not overly git or script savvy, but the best practice way is as follows: 174 | 175 | 1. Fork my AnyKernel3 repo on GitHub 176 | 177 | 2. `git clone https://github.com//AnyKernel3` 178 | 179 | 3. `git remote add upstream https://github.com/osm0sis/AnyKernel3` 180 | 181 | 4. `git checkout -b ` 182 | 183 | 5. Set it up like your zip (i.e. remove any folders you don't use like ramdisk or patch, delete README.md, and add your anykernel.sh and optionally your Image.*-dtb if you want it up there) then commit all those changes 184 | 185 | 6. `git push --set-upstream origin ` 186 | 187 | 7. `git checkout master` then repeat steps 4-6 for any other devices you support 188 | 189 | Then you should be able to `git pull upstream master` from your master branch and either merge or cherry-pick the new AK3 commits into your device branches as needed. 190 | 191 | ___For further support and usage examples please see the AnyKernel3 XDA thread:___ _https://forum.xda-developers.com/t/dev-template-anykernel3-easily-mod-rom-ramdisk-pack-image-gz-flashable-zip.2670512/_ 192 | 193 | __Have fun!__ 194 | -------------------------------------------------------------------------------- /anykernel.sh: -------------------------------------------------------------------------------- 1 | ### AnyKernel3 Ramdisk Mod Script 2 | ## osm0sis @ xda-developers 3 | 4 | ### AnyKernel setup 5 | # global properties 6 | properties() { ' 7 | kernel.string=ExampleKernel by osm0sis @ xda-developers 8 | do.devicecheck=1 9 | do.modules=0 10 | do.systemless=1 11 | do.cleanup=1 12 | do.cleanuponabort=0 13 | device.name1=maguro 14 | device.name2=toro 15 | device.name3=toroplus 16 | device.name4=tuna 17 | device.name5= 18 | supported.versions= 19 | supported.patchlevels= 20 | supported.vendorpatchlevels= 21 | '; } # end properties 22 | 23 | 24 | ### AnyKernel install 25 | ## boot files attributes 26 | boot_attributes() { 27 | set_perm_recursive 0 0 755 644 $RAMDISK/*; 28 | set_perm_recursive 0 0 750 750 $RAMDISK/init* $RAMDISK/sbin; 29 | } # end attributes 30 | 31 | # boot shell variables 32 | BLOCK=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot; 33 | IS_SLOT_DEVICE=0; 34 | RAMDISK_COMPRESSION=auto; 35 | PATCH_VBMETA_FLAG=auto; 36 | 37 | # import functions/variables and setup patching - see for reference (DO NOT REMOVE) 38 | . tools/ak3-core.sh; 39 | 40 | # boot install 41 | dump_boot; # use split_boot to skip ramdisk unpack, e.g. for devices with init_boot ramdisk 42 | 43 | # init.rc 44 | backup_file init.rc; 45 | replace_string init.rc "cpuctl cpu,timer_slack" "mount cgroup none /dev/cpuctl cpu" "mount cgroup none /dev/cpuctl cpu,timer_slack"; 46 | 47 | # init.tuna.rc 48 | backup_file init.tuna.rc; 49 | insert_line init.tuna.rc "nodiratime barrier=0" after "mount_all /fstab.tuna" "\tmount ext4 /dev/block/platform/omap/omap_hsmmc.0/by-name/userdata /data remount nosuid nodev noatime nodiratime barrier=0"; 50 | append_file init.tuna.rc "bootscript" init.tuna; 51 | 52 | # fstab.tuna 53 | backup_file fstab.tuna; 54 | patch_fstab fstab.tuna /system ext4 options "noatime,barrier=1" "noatime,nodiratime,barrier=0"; 55 | patch_fstab fstab.tuna /cache ext4 options "barrier=1" "barrier=0,nomblk_io_submit"; 56 | patch_fstab fstab.tuna /data ext4 options "data=ordered" "nomblk_io_submit,data=writeback"; 57 | append_file fstab.tuna "usbdisk" fstab; 58 | 59 | write_boot; # use flash_boot to skip ramdisk repack, e.g. for devices with init_boot ramdisk 60 | ## end boot install 61 | 62 | 63 | ## init_boot files attributes 64 | #init_boot_attributes() { 65 | #set_perm_recursive 0 0 755 644 $RAMDISK/*; 66 | #set_perm_recursive 0 0 750 750 $RAMDISK/init* $RAMDISK/sbin; 67 | #} # end attributes 68 | 69 | # init_boot shell variables 70 | #BLOCK=init_boot; 71 | #IS_SLOT_DEVICE=1; 72 | #RAMDISK_COMPRESSION=auto; 73 | #PATCH_VBMETA_FLAG=auto; 74 | 75 | # reset for init_boot patching 76 | #reset_ak; 77 | 78 | # init_boot install 79 | #dump_boot; # unpack ramdisk since it is the new first stage init ramdisk where overlay.d must go 80 | 81 | #write_boot; 82 | ## end init_boot install 83 | 84 | 85 | ## vendor_kernel_boot shell variables 86 | #BLOCK=vendor_kernel_boot; 87 | #IS_SLOT_DEVICE=1; 88 | #RAMDISK_COMPRESSION=auto; 89 | #PATCH_VBMETA_FLAG=auto; 90 | 91 | # reset for vendor_kernel_boot patching 92 | #reset_ak; 93 | 94 | # vendor_kernel_boot install 95 | #split_boot; # skip unpack/repack ramdisk, e.g. for dtb on devices with hdr v4 and vendor_kernel_boot 96 | 97 | #flash_boot; 98 | ## end vendor_kernel_boot install 99 | 100 | 101 | ## vendor_boot files attributes 102 | #vendor_boot_attributes() { 103 | #set_perm_recursive 0 0 755 644 $RAMDISK/*; 104 | #set_perm_recursive 0 0 750 750 $RAMDISK/init* $RAMDISK/sbin; 105 | #} # end attributes 106 | 107 | # vendor_boot shell variables 108 | #BLOCK=vendor_boot; 109 | #IS_SLOT_DEVICE=1; 110 | #RAMDISK_COMPRESSION=auto; 111 | #PATCH_VBMETA_FLAG=auto; 112 | 113 | # reset for vendor_boot patching 114 | #reset_ak; 115 | 116 | # vendor_boot install 117 | #dump_boot; # use split_boot to skip ramdisk unpack, e.g. for dtb on devices with hdr v4 but no vendor_kernel_boot 118 | 119 | #write_boot; # use flash_boot to skip ramdisk repack, e.g. for dtb on devices with hdr v4 but no vendor_kernel_boot 120 | ## end vendor_boot install 121 | 122 | -------------------------------------------------------------------------------- /modules/system/lib/modules/placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/modules/system/lib/modules/placeholder -------------------------------------------------------------------------------- /patch/placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/patch/placeholder -------------------------------------------------------------------------------- /ramdisk/placeholder: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/ramdisk/placeholder -------------------------------------------------------------------------------- /tools/ak3-core.sh: -------------------------------------------------------------------------------- 1 | ### AnyKernel methods (DO NOT CHANGE) 2 | ## osm0sis @ xda-developers 3 | 4 | [ "$OUTFD" ] || OUTFD=$1; 5 | 6 | # set up working directory variables 7 | [ "$AKHOME" ] || AKHOME=$PWD; 8 | BOOTIMG=$AKHOME/boot.img; 9 | BIN=$AKHOME/tools; 10 | PATCH=$AKHOME/patch; 11 | RAMDISK=$AKHOME/ramdisk; 12 | SPLITIMG=$AKHOME/split_img; 13 | 14 | ### output/testing functions: 15 | # ui_print "" [...] 16 | ui_print() { 17 | until [ ! "$1" ]; do 18 | echo "ui_print $1 19 | ui_print" >> /proc/self/fd/$OUTFD; 20 | shift; 21 | done; 22 | } 23 | 24 | # abort ["" [...]] 25 | abort() { 26 | ui_print " " "$@"; 27 | exit 1; 28 | } 29 | 30 | # contains 31 | contains() { 32 | [ "${1#*$2}" != "$1" ]; 33 | } 34 | 35 | # file_getprop 36 | file_getprop() { 37 | grep "^$2=" "$1" | tail -n1 | cut -d= -f2-; 38 | } 39 | ### 40 | 41 | ### file/directory attributes functions: 42 | # set_perm [ ...] 43 | set_perm() { 44 | local uid gid mod; 45 | uid=$1; gid=$2; mod=$3; 46 | shift 3; 47 | chown $uid:$gid "$@" || chown $uid.$gid "$@"; 48 | chmod $mod "$@"; 49 | } 50 | 51 | # set_perm_recursive [ ...] 52 | set_perm_recursive() { 53 | local uid gid dmod fmod; 54 | uid=$1; gid=$2; dmod=$3; fmod=$4; 55 | shift 4; 56 | while [ "$1" ]; do 57 | chown -R $uid:$gid "$1" || chown -R $uid.$gid "$1"; 58 | find "$1" -type d -exec chmod $dmod {} +; 59 | find "$1" -type f -exec chmod $fmod {} +; 60 | shift; 61 | done; 62 | } 63 | ### 64 | 65 | ### dump_boot functions: 66 | # split_boot (dump and split image only) 67 | split_boot() { 68 | local splitfail; 69 | 70 | if [ ! -e "$(echo "$BLOCK" | cut -d\ -f1)" ]; then 71 | abort "Invalid partition. Aborting..."; 72 | fi; 73 | if echo "$BLOCK" | grep -q ' '; then 74 | BLOCK=$(echo "$BLOCK" | cut -d\ -f1); 75 | CUSTOMDD=$(echo "$BLOCK" | cut -d\ -f2-); 76 | elif [ ! "$CUSTOMDD" ]; then 77 | CUSTOMDD="bs=1048576"; 78 | fi; 79 | if [ -f "$BIN/nanddump" ]; then 80 | nanddump -f $BOOTIMG $BLOCK; 81 | else 82 | dd if=$BLOCK of=$BOOTIMG $CUSTOMDD; 83 | fi; 84 | if [ $? != 0 ]; then 85 | abort "Dumping image failed. Aborting..."; 86 | fi; 87 | 88 | mkdir -p $SPLITIMG; 89 | cd $SPLITIMG; 90 | if [ -f "$BIN/unpackelf" ] && unpackelf -i $BOOTIMG -h -q 2>/dev/null; then 91 | if [ -f "$BIN/elftool" ]; then 92 | mkdir elftool_out; 93 | elftool unpack -i $BOOTIMG -o elftool_out; 94 | fi; 95 | unpackelf -i $BOOTIMG; 96 | [ $? != 0 ] && splitfail=1; 97 | mv -f boot.img-kernel kernel.gz; 98 | mv -f boot.img-ramdisk ramdisk.cpio.gz; 99 | mv -f boot.img-cmdline cmdline.txt 2>/dev/null; 100 | if [ -f boot.img-dt -a ! -f "$BIN/elftool" ]; then 101 | case $(od -ta -An -N4 boot.img-dt | sed -e 's/ del//' -e 's/ //g') in 102 | QCDT|ELF) mv -f boot.img-dt dt;; 103 | *) 104 | gzip -c kernel.gz > kernel.gz-dtb; 105 | cat boot.img-dt >> kernel.gz-dtb; 106 | rm -f boot.img-dt kernel.gz; 107 | ;; 108 | esac; 109 | fi; 110 | elif [ -f "$BIN/mboot" ]; then 111 | mboot -u -f $BOOTIMG; 112 | elif [ -f "$BIN/dumpimage" ]; then 113 | dd bs=$(($(printf '%d\n' 0x$(hexdump -n 4 -s 12 -e '16/1 "%02x""\n"' $BOOTIMG)) + 64)) count=1 conv=notrunc if=$BOOTIMG of=boot-trimmed.img; 114 | dumpimage -l boot-trimmed.img > header; 115 | grep "Name:" header | cut -c15- > boot.img-name; 116 | grep "Type:" header | cut -c15- | cut -d\ -f1 > boot.img-arch; 117 | grep "Type:" header | cut -c15- | cut -d\ -f2 > boot.img-os; 118 | grep "Type:" header | cut -c15- | cut -d\ -f3 | cut -d- -f1 > boot.img-type; 119 | grep "Type:" header | cut -d\( -f2 | cut -d\) -f1 | cut -d\ -f1 | cut -d- -f1 > boot.img-comp; 120 | grep "Address:" header | cut -c15- > boot.img-addr; 121 | grep "Point:" header | cut -c15- > boot.img-ep; 122 | dumpimage -p 0 -o kernel.gz boot-trimmed.img; 123 | [ $? != 0 ] && splitfail=1; 124 | case $(cat boot.img-type) in 125 | Multi) dumpimage -p 1 -o ramdisk.cpio.gz boot-trimmed.img;; 126 | RAMDisk) mv -f kernel.gz ramdisk.cpio.gz;; 127 | esac; 128 | elif [ -f "$BIN/rkcrc" ]; then 129 | dd bs=4096 skip=8 iflag=skip_bytes conv=notrunc if=$BOOTIMG of=ramdisk.cpio.gz; 130 | else 131 | (set -o pipefail; magiskboot unpack -h $BOOTIMG 2>&1 | tee infotmp >&2); 132 | case $? in 133 | 1) splitfail=1;; 134 | 2) touch chromeos;; 135 | esac; 136 | fi; 137 | 138 | if [ $? != 0 -o "$splitfail" ]; then 139 | abort "Splitting image failed. Aborting..."; 140 | fi; 141 | cd $AKHOME; 142 | } 143 | 144 | # unpack_ramdisk (extract ramdisk only) 145 | unpack_ramdisk() { 146 | local comp; 147 | 148 | cd $SPLITIMG; 149 | if [ -f ramdisk.cpio.gz ]; then 150 | if [ -f "$BIN/mkmtkhdr" ]; then 151 | mv -f ramdisk.cpio.gz ramdisk.cpio.gz-mtk; 152 | dd bs=512 skip=1 conv=notrunc if=ramdisk.cpio.gz-mtk of=ramdisk.cpio.gz; 153 | fi; 154 | mv -f ramdisk.cpio.gz ramdisk.cpio; 155 | fi; 156 | 157 | if [ -f ramdisk.cpio ]; then 158 | comp=$(magiskboot decompress ramdisk.cpio 2>&1 | grep -v 'raw' | sed -n 's;.*\[\(.*\)\];\1;p'); 159 | else 160 | abort "No ramdisk found to unpack. Aborting..."; 161 | fi; 162 | if [ "$comp" ]; then 163 | mv -f ramdisk.cpio ramdisk.cpio.$comp; 164 | magiskboot decompress ramdisk.cpio.$comp ramdisk.cpio; 165 | if [ $? != 0 ] && $comp --help 2>/dev/null; then 166 | echo "Attempting ramdisk unpack with busybox $comp..." >&2; 167 | $comp -dc ramdisk.cpio.$comp > ramdisk.cpio; 168 | fi; 169 | fi; 170 | 171 | [ -d $RAMDISK ] && mv -f $RAMDISK $AKHOME/rdtmp; 172 | mkdir -p $RAMDISK; 173 | chmod 755 $RAMDISK; 174 | 175 | cd $RAMDISK; 176 | EXTRACT_UNSAFE_SYMLINKS=1 cpio -d -F $SPLITIMG/ramdisk.cpio -i; 177 | if [ $? != 0 -o ! "$(ls)" ]; then 178 | abort "Unpacking ramdisk failed. Aborting..."; 179 | fi; 180 | if [ -d "$AKHOME/rdtmp" ]; then 181 | cp -af $AKHOME/rdtmp/* .; 182 | fi; 183 | } 184 | ### dump_boot (dump and split image, then extract ramdisk) 185 | dump_boot() { 186 | split_boot; 187 | unpack_ramdisk; 188 | } 189 | ### 190 | 191 | ### write_boot functions: 192 | # repack_ramdisk (repack ramdisk only) 193 | repack_ramdisk() { 194 | local comp packfail mtktype; 195 | 196 | cd $AKHOME; 197 | if [ "$RAMDISK_COMPRESSION" != "auto" ] && [ "$(grep HEADER_VER $SPLITIMG/infotmp | sed -n 's;.*\[\(.*\)\];\1;p')" -gt 3 ]; then 198 | ui_print " " "Warning: Only lz4-l ramdisk compression is allowed with hdr v4+ images. Resetting to auto..."; 199 | RAMDISK_COMPRESSION=auto; 200 | fi; 201 | case $RAMDISK_COMPRESSION in 202 | auto|"") comp=$(ls $SPLITIMG/ramdisk.cpio.* 2>/dev/null | grep -v 'mtk' | rev | cut -d. -f1 | rev);; 203 | none|cpio) comp="";; 204 | gz) comp=gzip;; 205 | lzo) comp=lzop;; 206 | bz2) comp=bzip2;; 207 | lz4-l) comp=lz4_legacy;; 208 | *) comp=$RAMDISK_COMPRESSION;; 209 | esac; 210 | 211 | if [ -f "$BIN/mkbootfs" ]; then 212 | mkbootfs $RAMDISK > ramdisk-new.cpio; 213 | else 214 | cd $RAMDISK; 215 | find . | cpio -H newc -o > $AKHOME/ramdisk-new.cpio; 216 | fi; 217 | [ $? != 0 ] && packfail=1; 218 | 219 | cd $AKHOME; 220 | if [ ! "$NO_MAGISK_CHECK" ]; then 221 | magiskboot cpio ramdisk-new.cpio test; 222 | magisk_patched=$?; 223 | fi; 224 | [ "$magisk_patched" -eq 1 ] && magiskboot cpio ramdisk-new.cpio "extract .backup/.magisk $SPLITIMG/.magisk"; 225 | if [ "$comp" ]; then 226 | magiskboot compress=$comp ramdisk-new.cpio; 227 | if [ $? != 0 ] && $comp --help 2>/dev/null; then 228 | echo "Attempting ramdisk repack with busybox $comp..." >&2; 229 | $comp -9c ramdisk-new.cpio > ramdisk-new.cpio.$comp; 230 | [ $? != 0 ] && packfail=1; 231 | rm -f ramdisk-new.cpio; 232 | fi; 233 | fi; 234 | if [ "$packfail" ]; then 235 | abort "Repacking ramdisk failed. Aborting..."; 236 | fi; 237 | 238 | if [ -f "$BIN/mkmtkhdr" -a -f "$SPLITIMG/boot.img-base" ]; then 239 | mtktype=$(od -ta -An -N8 -j8 $SPLITIMG/ramdisk.cpio.gz-mtk | sed -e 's/ nul//g' -e 's/ //g' | tr '[:upper:]' '[:lower:]'); 240 | case $mtktype in 241 | rootfs|recovery) mkmtkhdr --$mtktype ramdisk-new.cpio*;; 242 | esac; 243 | fi; 244 | } 245 | 246 | # flash_boot (build, sign and write image only) 247 | flash_boot() { 248 | local varlist i kernel ramdisk fdt cmdline comp part0 part1 nocompflag signfail pk8 cert avbtype; 249 | 250 | cd $SPLITIMG; 251 | if [ -f "$BIN/mkimage" ]; then 252 | varlist="name arch os type comp addr ep"; 253 | elif [ -f "$BIN/mk" -a -f "$BIN/unpackelf" -a -f boot.img-base ]; then 254 | mv -f cmdline.txt boot.img-cmdline 2>/dev/null; 255 | varlist="cmdline base pagesize kernel_offset ramdisk_offset tags_offset"; 256 | fi; 257 | for i in $varlist; do 258 | if [ -f boot.img-$i ]; then 259 | eval local $i=\"$(cat boot.img-$i)\"; 260 | fi; 261 | done; 262 | 263 | cd $AKHOME; 264 | for i in zImage zImage-dtb Image Image-dtb Image.gz Image.gz-dtb Image.bz2 Image.bz2-dtb Image.lzo Image.lzo-dtb Image.lzma Image.lzma-dtb Image.xz Image.xz-dtb Image.lz4 Image.lz4-dtb Image.fit; do 265 | if [ -f $i ]; then 266 | kernel=$AKHOME/$i; 267 | break; 268 | fi; 269 | done; 270 | if [ "$kernel" ]; then 271 | if [ -f "$BIN/mkmtkhdr" -a -f "$SPLITIMG/boot.img-base" ]; then 272 | mkmtkhdr --kernel $kernel; 273 | kernel=$kernel-mtk; 274 | fi; 275 | elif [ "$(ls $SPLITIMG/kernel* 2>/dev/null)" ]; then 276 | kernel=$(ls $SPLITIMG/kernel* | grep -v 'kernel_dtb' | tail -n1); 277 | fi; 278 | if [ "$(ls ramdisk-new.cpio* 2>/dev/null)" ]; then 279 | ramdisk=$AKHOME/$(ls ramdisk-new.cpio* | tail -n1); 280 | elif [ -f "$BIN/mkmtkhdr" -a -f "$SPLITIMG/boot.img-base" ]; then 281 | ramdisk=$SPLITIMG/ramdisk.cpio.gz-mtk; 282 | else 283 | ramdisk=$(ls $SPLITIMG/ramdisk.cpio* 2>/dev/null | tail -n1); 284 | fi; 285 | for fdt in dt recovery_dtbo dtb; do 286 | for i in $AKHOME/$fdt $AKHOME/$fdt.img $SPLITIMG/$fdt; do 287 | if [ -f $i ]; then 288 | eval local $fdt=$i; 289 | break; 290 | fi; 291 | done; 292 | done; 293 | 294 | cd $SPLITIMG; 295 | if [ -f "$BIN/mkimage" ]; then 296 | [ "$comp" == "uncompressed" ] && comp=none; 297 | part0=$kernel; 298 | case $type in 299 | Multi) part1=":$ramdisk";; 300 | RAMDisk) part0=$ramdisk;; 301 | esac; 302 | mkimage -A $arch -O $os -T $type -C $comp -a $addr -e $ep -n "$name" -d $part0$part1 $AKHOME/boot-new.img; 303 | elif [ -f "$BIN/elftool" ]; then 304 | [ "$dt" ] && dt="$dt,rpm"; 305 | [ -f cmdline.txt ] && cmdline="cmdline.txt@cmdline"; 306 | elftool pack -o $AKHOME/boot-new.img header=elftool_out/header $kernel $ramdisk,ramdisk $dt $cmdline; 307 | elif [ -f "$BIN/mboot" ]; then 308 | cp -f $kernel kernel; 309 | cp -f $ramdisk ramdisk.cpio.gz; 310 | mboot -d $SPLITIMG -f $AKHOME/boot-new.img; 311 | elif [ -f "$BIN/rkcrc" ]; then 312 | rkcrc -k $ramdisk $AKHOME/boot-new.img; 313 | elif [ -f "$BIN/mkbootimg" -a -f "$BIN/unpackelf" -a -f boot.img-base ]; then 314 | [ "$dt" ] && dt="--dt $dt"; 315 | mkbootimg --kernel $kernel --ramdisk $ramdisk --cmdline "$cmdline" --base $base --pagesize $pagesize --kernel_offset $kernel_offset --ramdisk_offset $ramdisk_offset --tags_offset "$tags_offset" $dt --output $AKHOME/boot-new.img; 316 | else 317 | [ "$kernel" ] && cp -f $kernel kernel; 318 | [ "$ramdisk" ] && cp -f $ramdisk ramdisk.cpio; 319 | [ "$dt" -a -f extra ] && cp -f $dt extra; 320 | for i in dtb recovery_dtbo; do 321 | [ "$(eval echo \$$i)" -a -f $i ] && cp -f $(eval echo \$$i) $i; 322 | done; 323 | case $kernel in 324 | *Image*) 325 | if [ ! "$magisk_patched" -a ! "$NO_MAGISK_CHECK" ]; then 326 | magiskboot cpio ramdisk.cpio test; 327 | magisk_patched=$?; 328 | fi; 329 | if [ "$magisk_patched" -eq 1 ]; then 330 | ui_print " " "Magisk detected! Patching kernel so reflashing Magisk is not necessary..."; 331 | comp=$(magiskboot decompress kernel 2>&1 | grep -vE 'raw|zimage' | sed -n 's;.*\[\(.*\)\];\1;p'); 332 | (magiskboot split $kernel || magiskboot decompress $kernel kernel) 2>/dev/null; 333 | if [ $? != 0 -a "$comp" ] && $comp --help 2>/dev/null; then 334 | echo "Attempting kernel unpack with busybox $comp..." >&2; 335 | $comp -dc $kernel > kernel; 336 | fi; 337 | # legacy SAR kernel string skip_initramfs -> want_initramfs 338 | magiskboot hexpatch kernel 736B69705F696E697472616D6673 77616E745F696E697472616D6673; 339 | if [ "$(file_getprop $AKHOME/anykernel.sh do.modules)" == 1 ] && [ "$(file_getprop $AKHOME/anykernel.sh do.systemless)" == 1 ]; then 340 | strings kernel 2>/dev/null | grep -E -m1 'Linux version.*#' > $AKHOME/vertmp; 341 | fi; 342 | if [ "$comp" ]; then 343 | magiskboot compress=$comp kernel kernel.$comp; 344 | if [ $? != 0 ] && $comp --help 2>/dev/null; then 345 | echo "Attempting kernel repack with busybox $comp..." >&2; 346 | $comp -9c kernel > kernel.$comp; 347 | fi; 348 | mv -f kernel.$comp kernel; 349 | fi; 350 | [ ! -f .magisk ] && magiskboot cpio ramdisk.cpio "extract .backup/.magisk .magisk"; 351 | export $(cat .magisk); 352 | for fdt in dtb extra kernel_dtb recovery_dtbo; do 353 | [ -f $fdt ] && magiskboot dtb $fdt patch; # remove dtb verity/avb 354 | done; 355 | elif [ -d /data/data/me.weishu.kernelsu ] && [ "$(file_getprop $AKHOME/anykernel.sh do.modules)" == 1 ] && [ "$(file_getprop $AKHOME/anykernel.sh do.systemless)" == 1 ]; then 356 | ui_print " " "KernelSU detected! Setting up for kernel helper module..."; 357 | comp=$(magiskboot decompress kernel 2>&1 | grep -vE 'raw|zimage' | sed -n 's;.*\[\(.*\)\];\1;p'); 358 | (magiskboot split $kernel || magiskboot decompress $kernel kernel) 2>/dev/null; 359 | if [ $? != 0 -a "$comp" ] && $comp --help 2>/dev/null; then 360 | echo "Attempting kernel unpack with busybox $comp..." >&2; 361 | $comp -dc $kernel > kernel; 362 | fi; 363 | strings kernel > stringstmp 2>/dev/null; 364 | if grep -q -E '^/data/adb/ksud$' stringstmp; then 365 | touch $AKHOME/kernelsu_patched; 366 | grep -E -m1 'Linux version.*#' stringstmp > $AKHOME/vertmp; 367 | [ -d $RAMDISK/overlay.d ] && ui_print " " "Warning: overlay.d detected in ramdisk but not currently supported by KernelSU!"; 368 | else 369 | ui_print " " "Warning: No KernelSU support detected in kernel!"; 370 | fi; 371 | rm -f stringstmp; 372 | if [ "$comp" ]; then 373 | magiskboot compress=$comp kernel kernel.$comp; 374 | if [ $? != 0 ] && $comp --help 2>/dev/null; then 375 | echo "Attempting kernel repack with busybox $comp..." >&2; 376 | $comp -9c kernel > kernel.$comp; 377 | fi; 378 | mv -f kernel.$comp kernel; 379 | fi; 380 | else 381 | case $kernel in 382 | *-dtb) rm -f kernel_dtb;; 383 | esac; 384 | fi; 385 | unset magisk_patched KEEPVERITY KEEPFORCEENCRYPT RECOVERYMODE PREINITDEVICE SHA1 RANDOMSEED; # leave PATCHVBMETAFLAG set for repack 386 | ;; 387 | esac; 388 | case $RAMDISK_COMPRESSION in 389 | none|cpio) nocompflag="-n";; 390 | esac; 391 | case $PATCH_VBMETA_FLAG in 392 | auto|"") [ "$PATCHVBMETAFLAG" ] || export PATCHVBMETAFLAG=false;; 393 | 1) export PATCHVBMETAFLAG=true;; 394 | *) export PATCHVBMETAFLAG=false;; 395 | esac; 396 | magiskboot repack $nocompflag $BOOTIMG $AKHOME/boot-new.img; 397 | fi; 398 | if [ $? != 0 ]; then 399 | abort "Repacking image failed. Aborting..."; 400 | fi; 401 | [ "$PATCHVBMETAFLAG" ] && unset PATCHVBMETAFLAG; 402 | [ -f .magisk ] && touch $AKHOME/magisk_patched; 403 | 404 | cd $AKHOME; 405 | if [ -f "$BIN/futility" -a -d "$BIN/chromeos" ]; then 406 | if [ -f "$SPLITIMG/chromeos" ]; then 407 | echo "Signing with CHROMEOS..." >&2; 408 | futility vbutil_kernel --pack boot-new-signed.img --keyblock $BIN/chromeos/kernel.keyblock --signprivate $BIN/chromeos/kernel_data_key.vbprivk --version 1 --vmlinuz boot-new.img --bootloader $BIN/chromeos/empty --config $BIN/chromeos/empty --arch arm --flags 0x1; 409 | fi; 410 | [ $? != 0 ] && signfail=1; 411 | fi; 412 | if [ -d "$BIN/avb" ]; then 413 | pk8=$(ls $BIN/avb/*.pk8); 414 | cert=$(ls $BIN/avb/*.x509.*); 415 | case $BLOCK in 416 | *recovery*|*RECOVERY*|*SOS*) avbtype=recovery;; 417 | *) avbtype=boot;; 418 | esac; 419 | if [ -f "$BIN/boot_signer-dexed.jar" ]; then 420 | if [ -f /system/bin/dalvikvm ] && [ "$(/system/bin/dalvikvm -Xnoimage-dex2oat -cp $BIN/boot_signer-dexed.jar com.android.verity.BootSignature -verify boot.img 2>&1 | grep VALID)" ]; then 421 | echo "Signing with AVBv1 /$avbtype..." >&2; 422 | /system/bin/dalvikvm -Xnoimage-dex2oat -cp $BIN/boot_signer-dexed.jar com.android.verity.BootSignature /$avbtype boot-new.img $pk8 $cert boot-new-signed.img; 423 | fi; 424 | else 425 | if magiskboot verify boot.img; then 426 | echo "Signing with AVBv1 /$avbtype..." >&2; 427 | magiskboot sign /$avbtype boot-new.img $cert $pk8; 428 | fi; 429 | fi; 430 | fi; 431 | if [ $? != 0 -o "$signfail" ]; then 432 | abort "Signing image failed. Aborting..."; 433 | fi; 434 | mv -f boot-new-signed.img boot-new.img 2>/dev/null; 435 | 436 | if [ ! -f boot-new.img ]; then 437 | abort "No repacked image found to flash. Aborting..."; 438 | elif [ "$(wc -c < boot-new.img)" -gt "$(wc -c < boot.img)" ]; then 439 | abort "New image larger than target partition. Aborting..."; 440 | fi; 441 | blockdev --setrw $BLOCK 2>/dev/null; 442 | if [ -f "$BIN/flash_erase" -a -f "$BIN/nandwrite" ]; then 443 | flash_erase $BLOCK 0 0; 444 | nandwrite -p $BLOCK boot-new.img; 445 | elif [ "$CUSTOMDD" ]; then 446 | dd if=/dev/zero of=$BLOCK $CUSTOMDD 2>/dev/null; 447 | dd if=boot-new.img of=$BLOCK $CUSTOMDD; 448 | else 449 | cat boot-new.img /dev/zero > $BLOCK 2>/dev/null || true; 450 | fi; 451 | if [ $? != 0 ]; then 452 | abort "Flashing image failed. Aborting..."; 453 | fi; 454 | } 455 | 456 | # flash_generic 457 | flash_generic() { 458 | local avb avbblock avbpath file flags img imgblock imgsz isro isunmounted path; 459 | 460 | cd $AKHOME; 461 | for file in $1 $1.img; do 462 | if [ -f $file ]; then 463 | img=$file; 464 | break; 465 | fi; 466 | done; 467 | 468 | if [ "$img" -a ! -f ${1}_flashed ]; then 469 | for path in /dev/block/mapper /dev/block/by-name /dev/block/bootdevice/by-name; do 470 | for file in $1 $1$SLOT; do 471 | if [ -e $path/$file ]; then 472 | imgblock=$path/$file; 473 | break 2; 474 | fi; 475 | done; 476 | done; 477 | if [ ! "$imgblock" ]; then 478 | abort "$1 partition could not be found. Aborting..."; 479 | fi; 480 | if [ ! "$NO_BLOCK_DISPLAY" ]; then 481 | ui_print " " "$imgblock"; 482 | fi; 483 | if [ "$path" == "/dev/block/mapper" ]; then 484 | avb=$(httools_static avb $1); 485 | [ $? == 0 ] || abort "Failed to parse fstab entry for $1. Aborting..."; 486 | if [ "$avb" ] && [ ! "$NO_VBMETA_PARTITION_PATCH" ]; then 487 | flags=$(httools_static disable-flags); 488 | [ $? == 0 ] || abort "Failed to parse top-level vbmeta. Aborting..."; 489 | if [ "$flags" == "enabled" ]; then 490 | ui_print " " "dm-verity detected! Patching $avb..."; 491 | for avbpath in /dev/block/mapper /dev/block/by-name /dev/block/bootdevice/by-name; do 492 | for file in $avb $avb$SLOT; do 493 | if [ -e $avbpath/$file ]; then 494 | avbblock=$avbpath/$file; 495 | break 2; 496 | fi; 497 | done; 498 | done; 499 | cd $BIN; 500 | httools_static patch $1 $AKHOME/$img $avbblock || abort "Failed to patch $1 on $avb. Aborting..."; 501 | cd $AKHOME; 502 | fi 503 | fi 504 | imgsz=$(wc -c < $img); 505 | if [ "$imgsz" != "$(wc -c < $imgblock)" ]; then 506 | if [ -d /postinstall/tmp -a "$SLOT_SELECT" == "inactive" ]; then 507 | echo "Resizing $1$SLOT snapshot..." >&2; 508 | snapshotupdater_static update $1 $imgsz || abort "Resizing $1$SLOT snapshot failed. Aborting..."; 509 | else 510 | echo "Removing any existing $1_ak3..." >&2; 511 | lptools_static remove $1_ak3; 512 | echo "Clearing any merged cow partitions..." >&2; 513 | lptools_static clear-cow; 514 | echo "Attempting to create $1_ak3..." >&2; 515 | if lptools_static create $1_ak3 $imgsz; then 516 | echo "Replacing $1$SLOT with $1_ak3..." >&2; 517 | lptools_static unmap $1_ak3 || abort "Unmapping $1_ak3 failed. Aborting..."; 518 | lptools_static map $1_ak3 || abort "Mapping $1_ak3 failed. Aborting..."; 519 | lptools_static replace $1_ak3 $1$SLOT || abort "Replacing $1$SLOT failed. Aborting..."; 520 | imgblock=/dev/block/mapper/$1_ak3; 521 | ui_print " " "Warning: $1$SLOT replaced in super. Reboot before further logical partition operations."; 522 | else 523 | echo "Creating $1_ak3 failed. Attempting to resize $1$SLOT..." >&2; 524 | httools_static umount $1 || abort "Unmounting $1 failed. Aborting..."; 525 | if [ -e $path/$1-verity ]; then 526 | lptools_static unmap $1-verity || abort "Unmapping $1-verity failed. Aborting..."; 527 | fi 528 | lptools_static unmap $1$SLOT || abort "Unmapping $1$SLOT failed. Aborting..."; 529 | lptools_static resize $1$SLOT $imgsz || abort "Resizing $1$SLOT failed. Aborting..."; 530 | lptools_static map $1$SLOT || abort "Mapping $1$SLOT failed. Aborting..."; 531 | isunmounted=1; 532 | fi 533 | fi 534 | fi 535 | elif [ "$(wc -c < $img)" -gt "$(wc -c < $imgblock)" ]; then 536 | abort "New $1 image larger than $1 partition. Aborting..."; 537 | fi; 538 | isro=$(blockdev --getro $imgblock 2>/dev/null); 539 | blockdev --setrw $imgblock 2>/dev/null; 540 | if [ -f "$BIN/flash_erase" -a -f "$BIN/nandwrite" ]; then 541 | flash_erase $imgblock 0 0; 542 | nandwrite -p $imgblock $img; 543 | elif [ "$CUSTOMDD" ]; then 544 | dd if=/dev/zero of=$imgblock 2>/dev/null; 545 | dd if=$img of=$imgblock; 546 | else 547 | cat $img /dev/zero > $imgblock 2>/dev/null || true; 548 | fi; 549 | if [ $? != 0 ]; then 550 | abort "Flashing $1 failed. Aborting..."; 551 | fi; 552 | if [ "$isro" != 0 ]; then 553 | blockdev --setro $imgblock 2>/dev/null; 554 | fi; 555 | if [ "$isunmounted" -a "$path" == "/dev/block/mapper" ]; then 556 | httools_static mount $1 || abort "Mounting $1 failed. Aborting..."; 557 | fi 558 | touch ${1}_flashed; 559 | fi; 560 | } 561 | 562 | # flash_dtbo (backwards compatibility for flash_generic) 563 | flash_dtbo() { flash_generic dtbo; } 564 | 565 | ### write_boot (repack ramdisk then build, sign and write image, vendor_dlkm and dtbo) 566 | write_boot() { 567 | repack_ramdisk; 568 | flash_boot; 569 | flash_generic vendor_boot; # temporary until hdr v4 can be unpacked/repacked fully by magiskboot 570 | flash_generic vendor_kernel_boot; # temporary until hdr v4 can be unpacked/repacked fully by magiskboot 571 | flash_generic vendor_dlkm; 572 | flash_generic system_dlkm; 573 | flash_generic dtbo; 574 | } 575 | ### 576 | 577 | ### file editing functions: 578 | # backup_file 579 | backup_file() { [ ! -f $1~ ] && cp -fp $1 $1~; } 580 | 581 | # restore_file 582 | restore_file() { [ -f $1~ ] && cp -fp $1~ $1; rm -f $1~; } 583 | 584 | # replace_string 585 | replace_string() { 586 | [ "$5" == "global" ] && local scope=g; 587 | if ! grep -q "$2" $1; then 588 | sed -i "s;${3};${4};${scope}" $1; 589 | fi; 590 | } 591 | 592 | # replace_section 593 | replace_section() { 594 | local begin endstr last end; 595 | begin=$(grep -n -m1 "$2" $1 | cut -d: -f1); 596 | if [ "$begin" ]; then 597 | if [ "$3" == " " -o ! "$3" ]; then 598 | endstr='^[[:space:]]*$'; 599 | last=$(wc -l $1 | cut -d\ -f1); 600 | else 601 | endstr="$3"; 602 | fi; 603 | for end in $(grep -n "$endstr" $1 | cut -d: -f1) $last; do 604 | if [ "$end" ] && [ "$begin" -lt "$end" ]; then 605 | sed -i "${begin},${end}d" $1; 606 | [ "$end" == "$last" ] && echo >> $1; 607 | sed -i "${begin}s;^;${4}\n;" $1; 608 | break; 609 | fi; 610 | done; 611 | fi; 612 | } 613 | 614 | # remove_section 615 | remove_section() { 616 | local begin endstr last end; 617 | begin=$(grep -n -m1 "$2" $1 | cut -d: -f1); 618 | if [ "$begin" ]; then 619 | if [ "$3" == " " -o ! "$3" ]; then 620 | endstr='^[[:space:]]*$'; 621 | last=$(wc -l $1 | cut -d\ -f1); 622 | else 623 | endstr="$3"; 624 | fi; 625 | for end in $(grep -n "$endstr" $1 | cut -d: -f1) $last; do 626 | if [ "$end" ] && [ "$begin" -lt "$end" ]; then 627 | sed -i "${begin},${end}d" $1; 628 | break; 629 | fi; 630 | done; 631 | fi; 632 | } 633 | 634 | # insert_line 635 | insert_line() { 636 | local offset line; 637 | if ! grep -q "$2" $1; then 638 | case $3 in 639 | before) offset=0;; 640 | after) offset=1;; 641 | esac; 642 | line=$((`grep -n -m1 "$4" $1 | cut -d: -f1` + offset)); 643 | if [ -f $1 -a "$line" ] && [ "$(wc -l $1 | cut -d\ -f1)" -lt "$line" ]; then 644 | echo "$5" >> $1; 645 | else 646 | sed -i "${line}s;^;${5}\n;" $1; 647 | fi; 648 | fi; 649 | } 650 | 651 | # replace_line 652 | replace_line() { 653 | local lines line; 654 | if grep -q "$2" $1; then 655 | lines=$(grep -n "$2" $1 | cut -d: -f1 | sort -nr); 656 | [ "$4" == "global" ] || lines=$(echo "$lines" | tail -n1); 657 | for line in $lines; do 658 | sed -i "${line}s;.*;${3};" $1; 659 | done; 660 | fi; 661 | } 662 | 663 | # remove_line 664 | remove_line() { 665 | local lines line; 666 | if grep -q "$2" $1; then 667 | lines=$(grep -n "$2" $1 | cut -d: -f1 | sort -nr); 668 | [ "$3" == "global" ] || lines=$(echo "$lines" | tail -n1); 669 | for line in $lines; do 670 | sed -i "${line}d" $1; 671 | done; 672 | fi; 673 | } 674 | 675 | # prepend_file 676 | prepend_file() { 677 | if ! grep -q "$2" $1; then 678 | echo "$(cat $PATCH/$3 $1)" > $1; 679 | fi; 680 | } 681 | 682 | # insert_file 683 | insert_file() { 684 | local offset line; 685 | if ! grep -q "$2" $1; then 686 | case $3 in 687 | before) offset=0;; 688 | after) offset=1;; 689 | esac; 690 | line=$((`grep -n -m1 "$4" $1 | cut -d: -f1` + offset)); 691 | sed -i "${line}s;^;\n;" $1; 692 | sed -i "$((line - 1))r $PATCH/$5" $1; 693 | fi; 694 | } 695 | 696 | # append_file 697 | append_file() { 698 | if ! grep -q "$2" $1; then 699 | echo -ne "\n" >> $1; 700 | cat $PATCH/$3 >> $1; 701 | echo -ne "\n" >> $1; 702 | fi; 703 | } 704 | 705 | # replace_file 706 | replace_file() { 707 | cp -pf $PATCH/$3 $1; 708 | chmod $2 $1; 709 | } 710 | 711 | # patch_fstab block|mount|fstype|options|flags 712 | patch_fstab() { 713 | local entry part newpart newentry; 714 | entry=$(grep "$2[[:space:]]" $1 | grep "$3"); 715 | if [ ! "$(echo "$entry" | grep "$6")" -o "$6" == " " -o ! "$6" ]; then 716 | case $4 in 717 | block) part=$(echo "$entry" | awk '{ print $1 }');; 718 | mount) part=$(echo "$entry" | awk '{ print $2 }');; 719 | fstype) part=$(echo "$entry" | awk '{ print $3 }');; 720 | options) part=$(echo "$entry" | awk '{ print $4 }');; 721 | flags) part=$(echo "$entry" | awk '{ print $5 }');; 722 | esac; 723 | newpart=$(echo "$part" | sed -e "s;${5};${6};" -e "s; ;;g" -e 's;,\{2,\};,;g' -e 's;,*$;;g' -e 's;^,;;g'); 724 | newentry=$(echo "$entry" | sed "s;${part};${newpart};"); 725 | sed -i "s;${entry};${newentry};" $1; 726 | fi; 727 | } 728 | 729 | # patch_cmdline 730 | patch_cmdline() { 731 | local cmdfile cmdtmp match; 732 | if [ -f "$SPLITIMG/cmdline.txt" ]; then 733 | cmdfile=$SPLITIMG/cmdline.txt; 734 | else 735 | cmdfile=$AKHOME/cmdtmp; 736 | grep "^cmdline=" $SPLITIMG/header | cut -d= -f2- > $cmdfile; 737 | fi; 738 | if ! grep -q "$1" $cmdfile; then 739 | cmdtmp=$(cat $cmdfile); 740 | echo "$cmdtmp $2" > $cmdfile; 741 | sed -i -e 's;^[ \t]*;;' -e 's; *; ;g' -e 's;[ \t]*$;;' $cmdfile; 742 | else 743 | match=$(grep -o "$1.*$" $cmdfile | cut -d\ -f1); 744 | sed -i -e "s;${match};${2};" -e 's;^[ \t]*;;' -e 's; *; ;g' -e 's;[ \t]*$;;' $cmdfile; 745 | fi; 746 | if [ -f "$AKHOME/cmdtmp" ]; then 747 | sed -i "s|^cmdline=.*|cmdline=$(cat $cmdfile)|" $SPLITIMG/header; 748 | rm -f $cmdfile; 749 | fi; 750 | } 751 | 752 | # patch_prop 753 | patch_prop() { 754 | if ! grep -q "^$2=" $1; then 755 | echo -ne "\n$2=$3\n" >> $1; 756 | else 757 | local line=$(grep -n -m1 "^$2=" $1 | cut -d: -f1); 758 | sed -i "${line}s;.*;${2}=${3};" $1; 759 | fi; 760 | } 761 | 762 | # patch_ueventd 763 | patch_ueventd() { 764 | local file dev perm user group newentry line; 765 | file=$1; dev=$2; perm=$3; user=$4; 766 | shift 4; 767 | group="$@"; 768 | newentry=$(printf "%-23s %-4s %-8s %s\n" "$dev" "$perm" "$user" "$group"); 769 | line=$(grep -n -m1 "$dev" $file | cut -d: -f1); 770 | if [ "$line" ]; then 771 | sed -i "${line}s;.*;${newentry};" $file; 772 | else 773 | echo -ne "\n$newentry\n" >> $file; 774 | fi; 775 | } 776 | ### 777 | 778 | ### configuration/setup functions: 779 | # reset_ak [keep] 780 | reset_ak() { 781 | local current i; 782 | 783 | # Backwards compatibility for old API 784 | [ "$no_block_display" ] && NO_BLOCK_DISPLAY="$no_block_display"; 785 | unset no_block_display; 786 | 787 | current=$(dirname $AKHOME/*-files/current); 788 | if [ -d "$current" ]; then 789 | for i in $BOOTIMG $AKHOME/boot-new.img; do 790 | [ -e $i ] && cp -af $i $current; 791 | done; 792 | for i in $current/*; do 793 | [ -f $i ] && rm -f $AKHOME/$(basename $i); 794 | done; 795 | fi; 796 | [ -d $SPLITIMG ] && rm -rf $RAMDISK; 797 | rm -rf $BOOTIMG $SPLITIMG $AKHOME/*-new* $AKHOME/*-files/current; 798 | 799 | if [ "$1" == "keep" ]; then 800 | [ -d $AKHOME/rdtmp ] && mv -f $AKHOME/rdtmp $RAMDISK; 801 | else 802 | rm -rf $PATCH $AKHOME/rdtmp; 803 | fi; 804 | if [ ! "$NO_BLOCK_DISPLAY" ]; then 805 | ui_print " "; 806 | fi; 807 | setup_ak; 808 | } 809 | 810 | # setup_ak 811 | setup_ak() { 812 | local blockfiles plistboot plistinit plistreco parttype name part mtdmount mtdpart mtdname target; 813 | 814 | # Backwards compatibility for old API 815 | [ "$block" ] && BLOCK="$block"; 816 | [ "$is_slot_device" ] && IS_SLOT_DEVICE="$is_slot_device"; 817 | [ "$ramdisk_compression" ] && RAMDISK_COMPRESSION="$ramdisk_compression"; 818 | [ "$patch_vbmeta_flag" ] && PATCH_VBMETA_FLAG="$patch_vbmeta_flag"; 819 | [ "$customdd" ] && CUSTOMDD="$customdd"; 820 | [ "$slot_select" ] && SLOT_SELECT="$slot_select"; 821 | [ "$no_block_display" ] && NO_BLOCK_DISPLAY="$no_block_display"; 822 | [ "$no_magisk_check" ] && NO_MAGISK_CHECK="$no_magisk_check"; 823 | unset block is_slot_device ramdisk_compression patch_vbmeta_flag customdd slot_select no_block_display no_magisk_check; 824 | 825 | # slot detection enabled by IS_SLOT_DEVICE=1 or auto (from anykernel.sh) 826 | case $IS_SLOT_DEVICE in 827 | 1|auto) 828 | SLOT=$(getprop ro.boot.slot_suffix 2>/dev/null); 829 | [ "$SLOT" ] || SLOT=$(grep -o 'androidboot.slot_suffix=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); 830 | if [ ! "$SLOT" ]; then 831 | SLOT=$(getprop ro.boot.slot 2>/dev/null); 832 | [ "$SLOT" ] || SLOT=$(grep -o 'androidboot.slot=.*$' /proc/cmdline | cut -d\ -f1 | cut -d= -f2); 833 | [ "$SLOT" ] && SLOT=_$SLOT; 834 | fi; 835 | [ "$SLOT" == "normal" ] && unset SLOT; 836 | if [ "$SLOT" ]; then 837 | if [ -d /postinstall/tmp -a ! "$SLOT_SELECT" ]; then 838 | SLOT_SELECT=inactive; 839 | fi; 840 | case $SLOT_SELECT in 841 | inactive) 842 | case $SLOT in 843 | _a) SLOT=_b;; 844 | _b) SLOT=_a;; 845 | esac; 846 | ;; 847 | esac; 848 | fi; 849 | if [ ! "$SLOT" -a "$IS_SLOT_DEVICE" == 1 ]; then 850 | abort "Unable to determine active slot. Aborting..."; 851 | fi; 852 | ;; 853 | esac; 854 | 855 | # clean up any template placeholder files 856 | cd $AKHOME; 857 | rm -f modules/system/lib/modules/placeholder patch/placeholder ramdisk/placeholder; 858 | rmdir -p modules patch ramdisk 2>/dev/null; 859 | 860 | # automate simple multi-partition setup for hdr_v4 boot + init_boot + vendor_kernel_boot (for dtb only until magiskboot supports hdr v4 vendor_ramdisk unpack/repack) 861 | if [ -e "/dev/block/bootdevice/by-name/init_boot$SLOT" -a ! -f init_v4_setup ] && [ -f dtb -o -d vendor_ramdisk -o -d vendor_patch ]; then 862 | echo "Setting up for simple automatic init_boot flashing..." >&2; 863 | (mkdir boot-files; 864 | mv -f Image* boot-files; 865 | mkdir init_boot-files; 866 | mv -f ramdisk patch init_boot-files; 867 | mkdir vendor_kernel_boot-files; 868 | mv -f dtb vendor_kernel_boot-files; 869 | mv -f vendor_ramdisk vendor_kernel_boot-files/ramdisk; 870 | mv -f vendor_patch vendor_kernel_boot-files/patch) 2>/dev/null; 871 | touch init_v4_setup; 872 | # automate simple multi-partition setup for hdr_v3+ boot + vendor_boot with dtb/dlkm (for v3 only until magiskboot supports hdr v4 vendor_ramdisk unpack/repack) 873 | elif [ -e "/dev/block/bootdevice/by-name/vendor_boot$SLOT" -a ! -f vendor_v3_setup ] && [ -f dtb -o -d vendor_ramdisk -o -d vendor_patch ]; then 874 | echo "Setting up for simple automatic vendor_boot flashing..." >&2; 875 | (mkdir boot-files; 876 | mv -f Image* ramdisk patch boot-files; 877 | mkdir vendor_boot-files; 878 | mv -f dtb vendor_boot-files; 879 | mv -f vendor_ramdisk vendor_boot-files/ramdisk; 880 | mv -f vendor_patch vendor_boot-files/patch) 2>/dev/null; 881 | touch vendor_v3_setup; 882 | fi; 883 | 884 | # target block partition detection enabled by BLOCK= or auto (from anykernel.sh) 885 | case $BLOCK in 886 | /dev/*) 887 | if [ "$SLOT" ] && [ -e "$BLOCK$SLOT" ]; then 888 | target=$BLOCK$SLOT; 889 | elif [ -e "$BLOCK" ]; then 890 | target=$BLOCK; 891 | fi; 892 | ;; 893 | *) 894 | # maintain brief lists of historic matching partition type names for boot, recovery and init_boot/ramdisk 895 | plistboot="boot BOOT LNX android_boot bootimg KERN-A kernel KERNEL"; 896 | plistreco="recovery RECOVERY SOS android_recovery recovery_ramdisk"; 897 | plistinit="init_boot ramdisk"; 898 | case $BLOCK in 899 | auto) parttype="$plistinit $plistboot";; 900 | boot|kernel) parttype=$plistboot;; 901 | recovery|recovery_ramdisk) parttype=$plistreco;; 902 | init_boot|ramdisk) parttype=$plistinit;; 903 | *) parttype=$BLOCK;; 904 | esac; 905 | for name in $parttype; do 906 | for part in $name$SLOT $name; do 907 | if [ "$(grep -w "$part" /proc/mtd 2>/dev/null)" ]; then 908 | mtdmount=$(grep -w "$part" /proc/mtd); 909 | mtdpart=$(echo "$mtdmount" | cut -d\" -f2); 910 | if [ "$mtdpart" == "$part" ]; then 911 | mtdname=$(echo "$mtdmount" | cut -d: -f1); 912 | else 913 | abort "Unable to determine mtd $BLOCK partition. Aborting..."; 914 | fi; 915 | [ -e /dev/mtd/$mtdname ] && target=/dev/mtd/$mtdname; 916 | elif [ -e /dev/block/by-name/$part ]; then 917 | target=/dev/block/by-name/$part; 918 | elif [ -e /dev/block/bootdevice/by-name/$part ]; then 919 | target=/dev/block/bootdevice/by-name/$part; 920 | elif [ -e /dev/block/platform/*/by-name/$part ]; then 921 | target=/dev/block/platform/*/by-name/$part; 922 | elif [ -e /dev/block/platform/*/*/by-name/$part ]; then 923 | target=/dev/block/platform/*/*/by-name/$part; 924 | elif [ -e /dev/$part ]; then 925 | target=/dev/$part; 926 | fi; 927 | [ "$target" ] && break 2; 928 | done; 929 | done; 930 | ;; 931 | esac; 932 | if [ "$target" ]; then 933 | BLOCK=$(ls $target 2>/dev/null); 934 | else 935 | abort "Unable to determine $BLOCK partition. Aborting..."; 936 | fi; 937 | if [ ! "$NO_BLOCK_DISPLAY" ]; then 938 | ui_print "$BLOCK"; 939 | fi; 940 | 941 | # allow multi-partition ramdisk modifying configurations (using reset_ak) 942 | name=$(basename $BLOCK | sed -e 's/_a$//' -e 's/_b$//'); 943 | if [ "$BLOCK" ] && [ ! -d "$RAMDISK" -a ! -d "$PATCH" ]; then 944 | blockfiles=$AKHOME/$name-files; 945 | if [ "$(ls $blockfiles 2>/dev/null)" ]; then 946 | cp -af $blockfiles/* $AKHOME; 947 | else 948 | mkdir $blockfiles; 949 | fi; 950 | touch $blockfiles/current; 951 | fi; 952 | 953 | # run attributes function for current block if it exists 954 | type attributes >/dev/null 2>&1 && attributes; # backwards compatibility 955 | type ${name}_attributes >/dev/null 2>&1 && ${name}_attributes; 956 | } 957 | ### 958 | 959 | ### end methods 960 | 961 | setup_ak; 962 | -------------------------------------------------------------------------------- /tools/busybox: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/busybox -------------------------------------------------------------------------------- /tools/fec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/fec -------------------------------------------------------------------------------- /tools/httools_static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/httools_static -------------------------------------------------------------------------------- /tools/lptools_static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/lptools_static -------------------------------------------------------------------------------- /tools/magiskboot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/magiskboot -------------------------------------------------------------------------------- /tools/magiskpolicy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/magiskpolicy -------------------------------------------------------------------------------- /tools/snapshotupdater_static: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/osm0sis/AnyKernel3/6f88dff82b786e879b255a8e1523547c4f62d031/tools/snapshotupdater_static --------------------------------------------------------------------------------