本贴介绍如何使用Anykernel3,轻松的刷入内核

基础知识

boot.img的组成

此处以v0为例
以下引用自aosp源码

/* When a boot header is of version 0, the structure of boot image is as
 * follows:
 *
 * +-----------------+
 * | boot header     | 1 page
 * +-----------------+
 * | kernel          | n pages
 * +-----------------+
 * | ramdisk         | m pages
 * +-----------------+
 * | second stage    | o pages
 * +-----------------+
  • 可以看到,boot.img包含了多个部分,比较常用的部分是kernelramdisk
  • 当你使用了某些第三方工具解包boot.img后,也许会看到一大堆文件,不要认为你已经真正解包了内核,那堆文件只是ramdisk的内容,而混在其中的某个体积高达十几MB,甚至是几十MB的文件,才是内核本体
  • 内核本体还可以继续被解包,前提是你的工具足够高级。内核本体可以被拆分成dtb和内核镜像两部分,在dtb中,你就已经可以编译许多设备相关的参数(在骁龙82x上,你甚至可以通过单改dtb实现cpu/gpu超频),而内核的主体代码则封装在内核镜像中。内核镜像不能再被继续解包,但是你可以(在解压缩后)以binary的方式hex edit它
  • 内核镜像也有多种格式,包括
Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo
  • 上面的各种格式中,只有Image是未压缩的格式,体积比较大
  • Image、Image.gz和Image.lz4是比较常见的格式,别的格式我还真没怎么见过

内核的编译产物

  • 内核编译完成后,你可以在<输出目录>/arch/<架构>/boot下找到编译产物
  • 在编译产物中,可能存在Image Image.gz Image.gz-dtb等文件,而我们需要的是那个带dtb的文件,也就是Image.gz-dtb。当然,如果你的设备的bootloader支持的压缩方式不同,你所需要的编译产物可能是Image.lz4-dtb抑或Image-dtb,总之,带上dtb总没错

只要你看了上面的boot.img组成,你应该就已经知道这个编译产物应该被丢到内核的哪个部分中,这也正是内核刷写脚本在做的事情

Anykernel3

Anykernel是一个最初由koush编写,后被osm0sis接手并多次迭代的内核刷写工具,目前已经更新到与magisk结合的Anykernel3
Anykernel3相比于Anykernel2的更改主要是使用magisk的解包boot相关工具代替自己造的轮子,不过你并不需要知道这些

下载

你可以使用下述两种方式下载Anykernel3

初始设置

  • Anykernel3本身自带了大量的范例,这是为一些人所诟病的一点,不过不影响我们的使用
  • 作为一个单纯想用它把内核刷进去的人,要使用它其实很简单
  • 设置好它其实只需要编辑根目录下的anykernel.sh
# AnyKernel3 Ramdisk Mod Script
# osm0sis @ xda-developers

## AnyKernel setup
# begin properties
properties() { '
#刷写时显示的文字,内核名称之类的
kernel.string=ExampleKernel by osm0sis @ xda-developers
#是否校验机型,校验的是build.prop中的 ro.product.device, ro.build.product, ro.product.vendor.device 或者是 ro.vendor.product.device,懒得配置请写0
do.devicecheck=1
#是否安装内核模块(假如你没把一些东西build inline的话),我们暂且不管它
do.modules=0
#是否使用magisk模块的方式来应用内核修改(注意,这些修改仅仅只限于系统部分,它并不是说用magisk安装内核),假如你只是用来刷个内核镜像,那么开着关着其实无所谓。。。我们就先关了它吧
do.systemless=0
#下面两个不用管它,除非你想调试解包过程
do.cleanup=1
do.cleanuponabort=0
#接下来是codename,如果你开启了上面的机型验证,它将从这里校验(它支持无数个名称,不过毫无卵用,一般来说一个codename就够了,我们还可以手动删掉一堆没用的)
device.name1=z2_plus
#支持的安卓版本,非常先进的支持跨版本
#甚至支持7.1.2 - 10这样,它非常先进,能够智能判断
supported.versions=9 - 10
#支持的安全补丁程序级别,支持多种格式,比如
#2019-04 - 2019-06
#2019-04 -
#- 2019-06
#分别代表了范围,某补丁以后,或者是某补丁之前
#不想用它就删了它或者空着(其实上面不想要的条目都可以删,没啥问题的)
supported.patchlevels=
'; } # end properties

# shell variables
#此处是最重要的东西,也就是你的bootdevice挂载点,没有它,anykernel压根不知道要把boot往哪里刷(下面给的这个挂载点应该支持820以后所有的高通设备)
block=/dev/block/bootdevice/by-name/boot;
#是否是ab分区的设备
is_slot_device=0;
#ramdisk压缩格式,默认是自动
ramdisk_compression=auto;


## AnyKernel methods (DO NOT CHANGE)
# import patching functions/variables - see for reference
. tools/ak3-core.sh;

#如果你没有加入ramdisk更改(使用根目录下的ramdisk文件夹),你可以删了对应文件夹与下面这4行
## AnyKernel file attributes
# set permissions/ownership for included ramdisk files
set_perm_recursive 0 0 755 644 $ramdisk/*;
set_perm_recursive 0 0 750 750 $ramdisk/init* $ramdisk/sbin;

#核心部分,不要动
## AnyKernel install
dump_boot;

#如果你没有加入ramdisk更改(使用根目录下的ramdisk文件夹),你可以删了下面的东西
# begin ramdisk changes

# init.rc
backup_file init.rc;
replace_string init.rc "cpuctl cpu,timer_slack" "mount cgroup none /dev/cpuctl cpu" "mount cgroup none /dev/cpuctl cpu,timer_slack";

# init.tuna.rc
backup_file init.tuna.rc;
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";
append_file init.tuna.rc "bootscript" init.tuna;

# fstab.tuna
backup_file fstab.tuna;
patch_fstab fstab.tuna /system ext4 options "noatime,barrier=1" "noatime,nodiratime,barrier=0";
patch_fstab fstab.tuna /cache ext4 options "barrier=1" "barrier=0,nomblk_io_submit";
patch_fstab fstab.tuna /data ext4 options "data=ordered" "nomblk_io_submit,data=writeback";
append_file fstab.tuna "usbdisk" fstab;

# end ramdisk changes
#一直删到这里为止

#核心方法,别动
write_boot;
## end install
  • 如果你只是想要单纯的刷入内核,建议随手删了根目录下的ramdisk,modules和patch(占着也没用)
  • 本着尊重作者的态度 请不要删除根目录下的LICENSE

放入内核本体

  • 很简单,把Image.gz-dtb/Image-dtb/Image,lz4-dtb之类的东西丢到Anykernel3的根目录下即可

打包

  • 手动压缩成zip包,就可以直接刷写了(注意,zip包要确保打开后的根目录就能看到anykernel.sh,如果多了一层文件夹,rec是不认的)
  • 或者,在Anykernel3的文件夹中执行zip -r <压缩包名.zip> *即可

进阶玩法