KernelSU 内核编译

Posted on Aug 5, 2023

编译环境

教程基于 Linux,可以选择实机安装或者使用 wsl2, 如何安装请看使用 WSL 在 Windows 上安装 Linux

🔎 Tip
wsl将系统各盘挂载至``/mnt``目录,通过此挂载点可以实现文件传输

软件包

使用以下命令安装所需软件包

sudo apt install -y bc bison build-essential git libssl-dev

这一步可跳过,等编译出现如xxx not found的错误时再安装

代理

如能直连 Github 可跳过

配置好代理后使用以下命令为终端设置代理

export https_proxy=http://127.0.0.1:<PORT> http_proxy=http://127.0.0.1:<PORT> all_proxy=socks5://127.0.0.1:<PORT>

工作目录

若使用作者提供的编译脚本,则需创建以下目录

mkdir -p ~/kernel  && cd ~/kernel # 创建并进入工作目录
mkdir -p toolchains  # 工具链目录
mkdir -p build  # 内核源码目录
~/kernel
├── build
└── toolchains

源码下载

现在进入~/kernel/build/目录

内核源码

如果你是小米用户,你可以试着下官方的源码,不过官方的源码可能不能成功编译,而且年久失修,大部分新机都没有公布源码,所以还是建议使用第三方的源码

官方源码仓库
https://github.com/MiCode/Xiaomi_Kernel_OpenSource

如果要下载的话请使用 git 命令
git clone --depth=1 https://github.com/MiCode/Xiaomi_Kernel_OpenSource -b cannon-r-oss  

cannon是作者的手机代号,需将cannon-r-oss换成自己源码的分支

因为我们只需要仓库最新的提交而忽略其他分支和历史信息,所以使用--depth=1进行浅克隆

添加KernelSU

KernelSU 1.0 及更高版本已经不再支持非 GKI 内核,最后的支持版本为 v0.9.5,请注意使用正确的版本

在内核根目录执行

curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -s v0.9.5

将KernelSU-v0.9.5添加到内核源码树

这时需要编辑你的配置文件,通常在arch/arm64/configs/,较新的机型也可能在arch/arm64/configs/vendor/

进入文件夹,找到类似设备代号_defconfig的文件,比如我的代号是cannon,配置文件就是cannon_defconfig

打开你的配置文件,查找是否开启以下配置,如果没有开启相关的配置,需要手动添加

CONFIG_KPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_KPROBE_EVENTS=y

工具链下载

现在进入~/kernel/toolchains目录

作者使用 zys-clang14 和 gcc4.9 进行编译,新内核可尝试更新的 clang 版本

我们先使用git下载gcc到./gcc-arm-4.9目录

git clone https://github.com/LineageOS/android_prebuilts_gcc_linux-x86_arm_arm-linux-androideabi-4.9.git gcc-arm-4.9

创建并进入~/kernel/toolchains/clang-14目录

mkdir -p ./clang-14 && cd clang-14

选择任意方式下载 zyc-clang-14

https://github.com/ZyCromerZ/Clang/releases/download/14.0.6-20240212-release/Clang-14.0.6-20240212.tar.gz

下载完成后用tar -zxvf Clang-*.tar.gz解压

编译脚本

现在回到~/kernel/build/目录并进入内核源码目录,创建一个编译脚本

写入以下内容

#!/bin/sh
set -e

export ARCH=arm64
export SUBARCH=arm64

CLANG_PATH="$HOME/kernel/toolchains/clang-14/bin"
GCC_PATH="$HOME/kernel/toolchains/gcc-arm-4.9/bin"

MAKE_ARGS="
    O=$OUT_DIR
    ARCH=$ARCH
    SUBARCH=$SUBARCH
    CC=$CLANG_PATH/clang
    LD=$CLANG_PATH/ld.lld
    AR=$CLANG_PATH/llvm-ar
    NM=$CLANG_PATH/llvm-nm
    OBJCOPY=$CLANG_PATH/llvm-objcopy
    OBJDUMP=$CLANG_PATH/llvm-objdump
    STRIP=$CLANG_PATH/llvm-strip
    CROSS_COMPILE=$CLANG_PATH/aarch64-linux-gnu-
    CROSS_COMPILE_ARM32=$GCC_PATH/arm-linux-androideabi-
"

make $MAKE_ARGS cannon_defconfig
make -j$(nproc) $MAKE_ARGS

需要注意的是,cannon_defconfig配置文件的路径位于arch/arm64/configs/

假设你的配置文件是arch/arm64/configs/example_defconfig那你只需要填写example_defconfig即可

但如果你的配置文件位于arch/arm64/configs/vendor/example_defconfig则需要填写vendor/example_defconfig

开始编译

用chmod +x <SCRIPT>设置可执行权限后运行,编译产物在out/arch/arm64/boot目录

打包内核

能来到这一步,你应该能成功编译出内核,接下来我们需要将它打包成boot或内核刷入

AnyKernel3

在完成编译后,我们回到~/kernel目录,并克隆AnyKernel3

项目地址:https://github.com/osm0sis/AnyKernel3

用 git 下载AnyKernel3

git clone https://github.com/osm0sis/AnyKernel3.git --depth=1

你需要把编译出的 Image 放到 AnyKernel3 的根目录,然后编辑anykernel.sh
需要改的是以下几点

kernel.string=KernelSU-cannon-inuyasha #内核名称
do.devicecheck=1 #设备检测,为0时关闭
do.modules=0
do.systemless=1
do.cleanup=1
do.cleanuponabort=0
device.name1=cannon  #设备代号,可以设置多个
device.name2=cannong
device.name3=
device.name4=
supported.versions=
supported.patchlevels=
supported.vendorpatchlevels=

block=auto;   
is_slot_device=auto;  
ramdisk_compression=auto; 
patch_vbmeta_flag=auto; 

配置完后使用zip -r9 UPDATE-AnyKernel3.zip * -x .git README.md *placeholder即可打包内核

如果使用zsh,可能会报错not matches found,只需要在.zshrc中添加

setopt no_nomatch

然后再source ~/.zshrc即可解决

MagiskBoot

如果你不喜欢用 anykernel3,你也可以提取原版的 boot.img 使用编译出来的 image 替换原厂 kernel

  1. 首先到Magisk下载 magisk.apk,重命名为 magisk.zip 并解压
  2. 把解压后的Magisk-v26.1/lib/arm64-v8a/libmagiskboot.so文件,用adb push到手机
adb push Magisk-v26.1/lib/arm64-v8a/libmagiskboot.so /data/local/tmp/magiskboot 

Magisk-v26.1需要改成下载的版本号

  1. 按照上面的方法把提取的 boot.img 和编译出的 Image 都推送到手机
  2. 用adb shell进入adb,然后进入手机/data/local/tmp/目录,赋予 magiskboot 可执行权限chmod +x magiskboot
  3. 执行./magiskboot unpack boot.img解包 boot.img 得到 kernel 文件
  4. 用 Image 替换 kernel mv -f Image kernel
  5. 最后执行./magiskboot repack boot.img命令重新打包boot.img,得到 new-boot.img ,备份原厂 boot 后在 fastboot 中刷入即可

拓展

如果 kprobe 不正常工作,就会出现无限重启,不开机,替换boot后仍显示不支持等错误,接下来我们将手动修改源码集成ksu

首先让我们验证是否 为kprobe 的问题,

  1. 打开KernelSU/kernel/ksu.c
  2. 找到ksu_enable_sucompat() 和 ksu_enable_ksud()这两行,使用//注释掉
// ksu_enable_sucompat();
// ksu_enable_ksud()

就像这样

重新编译你的内核,看能否开机,如果能正常开机就是kprobe的问题,如果还是不能开机,检查你的源码是否适用你的系统

修改内核源码

  1. 使用这条命添加KSU
curl -LSs "https://raw.githubusercontent.com/tiann/KernelSU/main/kernel/setup.sh" | bash -
  1. 因为要改的比较多,推荐去看官方文档,写的比较详细

BugReport

如果手动集成还是失败,你可以去Github提供一个BugReport给作者,在管理其设置,发送日志即可发送错误日志

Docker支持

在手机终端中执行check-config.sh脚本,将所有missing的配置添加到内核配置文件,并重新编译内核

参考

如何为非 GKI 内核集成 KernelSU