AnyKernel, Evolved
AnyKernel3 - 适用于内核发布的带 Ramdisk 修改的刷机包模板
由 osm0sis @ xda-developers
"AnyKernel 是一个用于应用任何内核到任何 ROM 的 update.zip 模板,不受 ramdisk 限制。" - Koush
AnyKernel2 进一步推进了格式的发展,通过允许内核开发者轻松地使用一系列内置的命令方法以及属性和变量来修改底层 ramdisk,从而支持内核功能,并定制安装体验。AnyKernel3 通过默认集成 topjohnwu 的 magiskboot,提供了更广泛的格式支持,并自动检测并通过修补新的 Image.*-dtb 来保留 Magisk root,就像 Magisk 会做的那样。
包含了一个基于 Galaxy Nexus (tuna) 的脚本作为参考。所有需要编辑的内容都内置于 anykernel.sh 中。
// 属性 / 变量 //
kernel.string=KernelName by YourName @ xda-developers
do.devicecheck=1
do.modules=1
do.systemless=1
do.cleanup=1
do.cleanuponabort=0
device.name1=maguro
device.name2=toro
device.name3=toroplus
device.name4=tuna
supported.versions=6.0 - 7.1.2
supported.patchlevels=2019-07 -
supported.vendorpatchlevels=2013-07
BLOCK=/dev/block/platform/omap/omap_hsmmc.0/by-name/boot;
IS_SLOT_DEVICE=0;
RAMDISK_COMPRESSION=auto;
PATCH_VBMETA_FLAG=auto;
do.devicecheck=1 指定至少需要存在 device.name1。这应与 ro.product.device、ro.build.product、ro.product.vendor.device 或 ro.vendor.product.device 从设备的 build.prop 文件中匹配。支持所需数量的 device.name# 属性。您可能需要删除任何未使用的空属性。
do.modules=1 将把模块目录下的 .ko 内容推送到相对于根 (/) 的相同位置并应用正确的权限。在 A/B 设备上,这只能对活动槽位执行。
do.systemless=1(与 do.modules=1 一起使用)将改为推送模块目录的全部内容以创建一个简单的 "ak3-helper" Magisk/KernelSU 模块,允许开发者有效地替换系统文件,包括 .ko 文件。如果当前内核被更改,内核帮助模块将自动移除自身以防止冲突。
do.cleanup=0 将使 zip 文件在默认情况下保留其位于 /tmp/anykernel 的工作目录 - 这在通过 adb shell 调试修补程序是否正确工作时很有用。
do.cleanuponabort=0 在安装中断的情况下,将使 zip 文件在默认情况下保留其位于 /tmp/anykernel 的工作目录。
supported.versions 将与当前 ROM 的 build.prop 中的 ro.build.version.release 匹配。它可以设置为列表或范围。作为一个或多个条目的列表,例如 7.1.2 或 8.1.0, 9,它将寻找确切匹配;作为一个范围,例如 7.1.2 - 9,它将检查以确保当前版本落在这两个限制之内。空白可选,提供的版本值应与 build.prop 值中该 Android 版本的数字格式相同。
supported.patchlevels 和 supported.vendorpatchlevels 将分别与当前系统/vendor build.prop 中的 ro.build.version.security_patch 和 ro.vendor.build.security_patch 匹配。它们可以设置为日期的闭区间或开区间范围,格式为 YYYY-MM,空白可选,例如 2019-04 - 2019-06、2019-04 - 或 - 2019-06,最后两个示例显示了设置最小值或最大值。
BLOCK=auto 代替直接的块文件路径,使得可以检测设备的引导分区,用于广泛的、与设备无关的 zip 包。同时也接受任何分区文件名(来自 by-name),例如 boot、recovery 或 vendor_boot。
IS_SLOT_DEVICE=1 启用检测基于槽的设备上活动引导分区的后缀,并将此添加到提供的 BLOCK= 路径末尾。也接受 auto 用于广泛的、与设备无关的 zip 包。
RAMDISK_COMPRESSION=auto 允许在解包时自动重新打包 ramdisk,使用检测到的格式。将 auto 更改为 gz、lzo、lzma、xz、bz2、lz4 或 lz4-l(对于 lz4 旧版)将强制以该格式重新打包,而使用 cpio 或 none 将(尝试)强制以未压缩格式重新打包。
PATCH_VBMETA_FLAG=auto 允许在重新打包时自动使用默认的 AVBv2 vbmeta 标志,并使用 Magisk 配置 Canary 23016+。设置为 0 强制保留原始 AVBv2 标志,设置为 1 强制修补标志(仅在少数设备上必要)。
CUSTOMDD="<参数>" 可用于指定需要直接将内核黑客到大型分区(如 mmcblk0)或强制使用 dd 烧录的设备的额外 dd 参数。
SLOT_SELECT=active|inactive 可用于指定目标槽位。如果省略,默认保持 active。
NO_BLOCK_DISPLAY=1 可用于禁用输出检测到的最终使用的分区+槽路径,以便 zip 包选择包含它们自己的自定义输出。
NO_MAGISK_CHECK=1 可用于禁用 Magisk 及相关内核/dtb 修补的检测,针对不需要这些的特殊 zip 包。
NO_VBMETA_PARTITION_PATCH=1 可用于跳过使用 httools 的 vbmeta 处理,因为只要 AVB 对引导阶段分区没有强制要求,GKI 是可引导且具有 verity/verification 开启的。
// 命令方法 //
ui_print "<text>" [...]
abort ["<text>" [...]]
contains <string> <substring>
file_getprop <file> <property>
set_perm <owner> <group> <mode> <file> [<file2> ...]
set_perm_recursive <owner> <group> <dir_mode> <file_mode> <dir> [<dir2> ...]
dump_boot
split_boot
unpack_ramdisk
backup_file <file>
restore_file <file>
replace_string <file> <if search string> <original string> <replacement string> <scope>
replace_section <file> <begin search string> <end search string> <replacement string>
remove_section <file> <begin search string> <end search string>
insert_line <file> <if search string> <before|after> <line match string> <inserted line>
replace_line <file> <line replace string> <replacement line> <scope>
remove_line <file> <line match string> <scope>
prepend_file <file> <if search string> <patch file>
insert_file <file> <if search string> <before|after> <line match string> <patch file>
append_file <file> <if search string> <patch file>
replace_file <file> <permissions> <patch file>
patch_fstab <fstab file> <mount match name> <fs match type> block|mount|fstype|options|flags <original string> <replacement string>
patch_cmdline <cmdline entry name> <replacement string>
patch_prop <prop file> <prop name> <new prop value>
patch_ueventd <ueventd file> <device node> <permissions> <chown> <chgrp>
repack_ramdisk
flash_boot
flash_generic <partition name>
write_boot
reset_ak [keep]
setup_ak
如果搜索字符串("if search string")是用来判断是否需要添加调整的字符串,那么通常这个字符串表明调整已经存在。"命令行条目名称"("cmdline entry name")的行为有点像这样,用于匹配需要由 patch_cmdline 函数更改/添加的命令行条目名称,随后是用于替换的完整条目。同样,属性名称("prop name")也作为 patch_prop 中的匹配检查,用于给定属性文件中的属性,但仅限于属性名称,因为属性值是单独指定的。
类似地,行匹配字符串("line match string")和行替换字符串("line replace string")是搜索字符串,用于定位需要修改的命令位置,"开始搜索字符串"("begin search string")和"结束搜索字符串"("end search string")都是必须的,用于选择要替换的脚本块的第一行和最后一行,而"挂载匹配名称"("mount match name")和"文件系统匹配类型"("fs match type")都是必须的,用于将 patch_fstab 命令缩小到正确的条目。
"作用域"("scope")可以指定为"全局"("global"),以强制替换/删除所有由 replace_string、replace_line 或 remove_line 针对的字符串/行的实例。如果省略或设置为其他值,它将执行默认的第一个匹配操作。
"之前|之后"("before|after")需要您简单地指定"之前"("before")或"之后"("after"),以确定插入行的位置,相对于"行匹配字符串"。
"块|挂载|文件系统类型|选项|标志"("block|mount|fstype|options|flags")需要您指定想要检查和更改的 fstab 条目的部分(按顺序列出)。
dump_boot 和 write_boot 是默认的解包/重新打包方法,但对于更细粒度的控制,或者完全省略 ramdisk 更改("OG AK"模式),这些可以分别分离为 split_boot; unpack_ramdisk 和 repack_ramdisk; flash_boot。flash_generic 可以用来将镜像闪存到相应的分区。它在 write_boot 中自动包含 dtbo、system_dlkm 和 vendor_dlkm,但如果使用"OG AK"模式或创建简单的分区闪存仅 zip 文件,可以单独调用。
通过从 zip 中移除 ramdisk 和 patch 文件夹,并包括名为分区的"-files"文件夹(不带槽后缀),例如 boot-files + recovery-files,或者 kernel-files + ramdisk-files(在某些 Treble 设备上),可以创建多分区 zip。然后这些文件夹包含 Image.gz 和 ramdisk、patch 等子文件夹。要为下一个分区设置,只需将 BLOCK=(不带槽后缀)和 RAMDISK_COMPRESSION= 设置为新目标分区,并使用 reset_ak 命令。
类似地,可以通过为活动(当前)槽使用正常 zip 布局创建多槽 zip,然后通过设置 BLOCK=(不带槽后缀)、SLOT_SELECT=inactive 和 RAMDISK_COMPRESSION= 为目标槽,并使用 reset_ak keep 命令重置为非活动槽,这将保留下一个槽的补丁和任何添加的 ramdisk 文件。
backup_file 可用于测试以确保 ramdisk 更改正确无误,为最终用户提供透明度,或仅在 ramdisk-only "mod" zip 中使用。在后一种情况下,也可以使用 restore_file 创建一个"恢复" zip 以撤消更改,但应谨慎使用,因为底层修补文件可能会随着 ROM/kernel 更新而更改。
您还可以使用 ui_print "<文本>" 在修改过程中将消息写回恢复,abort "<文本>" 以可选消息中止,以及 file_getprop "<文件>" "<属性>" 和 contains "<字符串>" "<子字符串>" 以简化脚本中可能需要的字符串测试逻辑。
// 二进制包含 //
AK3 仓库默认包含当前 ARM 构建的 magiskboot、magiskpolicy、lptools_static、httools_static、fec、snapshotupdater_static 和 busybox,以保持基本包的大小。其他架构和可选二进制文件(如下所示)可以从最新的 Magisk zip 或我的最新 AIK-mobile 和 FlashIt 包中获取:
https://forum.xda-developers.com/t/tool-android-image-kitchen-unpack-repack-kernel-ramdisk-win-android-linux-mac.2073775/ (Android Image Kitchen 主题)
https://forum.xda-developers.com/t/tools-zips-scripts-osm0sis-odds-and-ends-multiple-devices-platforms.2239421/ (Odds and Ends 主题)
可选支持的可执行文件可以放置在 /tools 中以启用内置扩展功能,如下所示:
mkbootfs- 用于损坏的恢复,或通过绑定挂载到 /tmp 为脚本/应用程序提供引导闪存支持(不推荐/谨慎使用)flash_erase、nanddump、nandwrite- 针对那些dd命令不足够的设备的 MTD 块设备支持dumpimage、mkimage- DENX U-Boot uImage 格式支持mboot- Intel OSIP Android 图像格式支持unpackelf、mkbootimg- Sony ELF 内核.elf 格式支持,重新打包为 AOSP 标准的 boot.img 以适用于解锁的引导加载程序elftool(与unpackelf配合使用)- Sony ELF 内核.elf 格式支持,重新打包为 ELF 以适用于旧款 Sony 设备mkmtkhdr(与unpackelf配合使用)- MTK 设备引导图像部分头支持,适用于 Sony 设备futility+chromeos测试密钥目录 - Google ChromeOS 签名支持boot_signer-dexed.jar(不推荐)+avb密钥目录 - Google Android 验证启动 1.0(AVBv1)自定义签名支持rkcrc- Rockchip KRNL ramdisk 图像支持
可选地将 ARM 构建移动到 tools/arm 并将 x86 构建放入 tools/x86 将启用架构检测,用于广泛的、设备无关的 zip。
// 指南 //
-
将最终内核构建产品(例如 Image.gz-dtb 或 zImage)放置在 zip 根目录中(任何单独的 dt、dtb 或 recovery_dtbo、dtbo、system_dlkm 和/或 vendor_dlkm 也应放置在此处,以供需要自定义它们的设备使用,每个如果未包含则回退到原始文件)
-
将任何需要的 ramdisk 文件放置在 /ramdisk 中(对于简单的多分区 vendor_boot v3 支持,使用 /vendor_ramdisk),将模块文件放置在 /modules 中(包含完整路径,如 /modules/system/lib/modules)
-
将任何需要的补丁文件(通常是与 AK3 文件编辑命令配合使用的部分文件)放置在 /patch 中(对于简单的多分区 vendor_boot v3 支持,使用 /vendor_patch)
-
修改 anykernel.sh 以添加您的内核名称、引导分区位置、对任何添加的 ramdisk 文件的权限,以及用于任何需要的 ramdisk 修改的方法(可选地,还可以在根目录放置横幅和/或版本文件,以在刷机时显示这些信息)
-
zip -r9 UPDATE-AnyKernel3.zip * -x .git README.md *placeholder
许可文件必须在最终的 zip 中,以符合二进制重新分发和 AK3 脚本许可的要求。
如果支持需要 zip 签名验证的恢复(如 Cyanogen Recovery),那么您还需要按照我描述的方法在此处签名您的 zip:
不是必需的,但任何无法硬编码到源代码中的调整(最佳实践)都应该通过额外的 init.tweaks.rc 或 bootscript.sh 添加,以最小化必要的 ramdisk 更改。在新款设备上,Magisk 允许这些在 /overlay.d 中 - 请参阅示例。
还需要特别注意的是,为了确保 AK3 的广泛兼容性,最好修改 ramdisk 文件而不是替换它。
如果在刷写 AK3 zip 时遇到问题,可以将 -debugging 后缀添加到 zip 文件名中以启用创建包含 /tmp 的调试 .tgz,以便在引导或桌面状态下进行后续检查。
// 保持更新
现在你有了适用于设备的zip文件,你可能想知道如何让设备与最新的AnyKernel提交保持同步。AnyKernel2和AnyKernel3经过精心开发,允许你只需将最新的update-binary和工具目录放入,即可实现“即插即用”,这对于不熟悉git或脚本的初学者来说非常方便,但最佳实践方法如下:
-
在GitHub上复制我的AnyKernel3仓库
-
git clone https://github.com/<你的用户名>/AnyKernel3 -
git remote add upstream https://github.com/osm0sis/AnyKernel3 -
git checkout -b <设备名称> -
设置你的<设备名称>,类似于你的zip(即移除不使用的文件夹,如ramdisk或patch,删除README.md,并添加你的anykernel.sh以及可选的Image.*-dtb,如果你希望它在那里)然后提交所有更改
-
git push --set-upstream origin <设备名称> -
git checkout master,然后对支持的任何其他设备重复步骤4-6
之后,你应该能够从你的主分支执行git pull upstream master,并根据需要将新的AK3提交合并或挑拣到你的设备分支。
要获取更多支持和使用示例,请查看AnyKernel3的XDA主题: _https://forum.xda-developers.com/t/dev-template-anykernel3-easily-mod-rom-ramdisk-pack-image-gz-flashable-zip.2670512/_
祝玩得开心!