这篇文章上次修改于 461 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

前言

准备编译多个版本的通用内核,获取vmlinux并生成对应的btf文件,没想到还是遇到了一点问题,在此记录

在一年前就想尝试,奈何当时对这方面知之甚少,现在终于有下文了:)

2023-04-11T05:42:19.png

记录

参考KernelSU的workflow文件,gki-kernel.yml,编译通用内核步骤和一般内核编译过程其实是类似的

稍微检查代码,就能发现和之前pixel、xiaomi系列内核代码文件夹结构其实差不多,只是通用内核的build脚本目录不太一样罢了(我好蠢

2023-04-11T05:47:26.png

2023-04-11T05:48:42.png

2023-04-11T05:50:12.png

不过仅仅是文件夹层次结构的不一样,脚本中的一些设置也有些差别,具体也是搞不太清楚

既然有现成的workflow脚本了,那么按照步骤来基本没差的


话不多说,直接开干,运行下面的代码顺利完成编译,得到了vmlinux文件,位于out文件夹下

小提示:要使用清华的源,把下面的android.googlesource.com换成mirrors.tuna.tsinghua.edu.cn/git/AOSP即可,省下大量费用...

git clone https://gerrit.googlesource.com/git-repo
mkdir android-kernel && cd android-kernel
../git-repo/repo init --depth=1 -u https://android.googlesource.com/kernel/manifest -b common-android12-5.10
../git-repo/repo sync -j$(nproc --all)
CCACHE="/usr/bin/ccache" LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

于是信心满满,准备打开BTF再编译,那么位于之前创建的android-kernel文件夹下,执行下面的命令:

cd common
make ARCH=arm64 gki_defconfig
make ARCH=arm64 menuconfig
# 这一步在GUI界面开启BTF选项
make ARCH=arm64 savedefconfig
cp defconfig arch/arm64/configs/gki_defconfig
rm .config
cd ..
CCACHE="/usr/bin/ccache" LTO=thin BUILD_CONFIG=common/build.config.gki.aarch64 build/build.sh

然后就出现了意外,提示说No libelf found

2023-04-11T06:02:29.png

针对这个问题,找到两篇看起来有用的文章:

无非是安装libelf-dev然后到对应的目录下编译,对于安卓通用内核这里就是这个目录:

  • common/tools/bpf/resolve_btfids

确实,在这里单独编译一切安好:

2023-04-11T06:10:04.png

我尝试把CC指定为源码中的clang也是OK的:

2023-04-11T06:10:50.png

2023-04-11T06:11:00.png

但用build/build.sh就是不行,后来根据libbpf: stop using feature-detection Makefiles的讨论,将elfdep等有关检查去掉了,这一回编译走了更远一点,但是出现了新的错误。直接说printf有问题了,对比前面的成功编译的输出看,推测是这个构建脚本有些问题...

2023-04-11T06:11:29.png

实在是无力排查(菜),于是改成和xaga内核编译记录的操作一样来编译,也就是设置独立的CLANG和GCC工具链(这里直接用了源码里面的clang了),并配置环境,指定defconfig编译

这回成功编译,于是信心满满,尝试编译common-android12-5.10-2021-08这个分支的内核

这回90%成功编译,新的问题是:

  LD      .tmp_vmlinux.btf
  BTF     .btf.vmlinux.bin.o
  LD      .tmp_vmlinux.kallsyms1
  KSYMS   .tmp_vmlinux.kallsyms1.S
  AS      .tmp_vmlinux.kallsyms1.S
  LD      .tmp_vmlinux.kallsyms2
  KSYMS   .tmp_vmlinux.kallsyms2.S
  AS      .tmp_vmlinux.kallsyms2.S
  LD      vmlinux
  BTFIDS  vmlinux
FAILED: load BTF from vmlinux: Unknown error -22

怎么回事!pahole怎么出问题了?然后对比common-android12-5.10common-android12-5.10-2021-08两个分支的脚本,发现新分支的common/scripts/link-vmlinux.sh脚本中gen_btf多出一个PAHOLE_FLAGS

2023-04-11T06:20:20.png

也就是版本在v1.18之后需要添加--skip_encoding_btf_vars,在v1.24之后添加--skip_encoding_btf_enum64

2023-04-11T06:21:51.png

我编译安装的pahole是v1.25,所以在common-android12-5.10-2021-08分支里面,得手动添加一下这两个设定

2023-04-11T06:24:35.png

这一次顺利编译通过:)

2023-04-11T06:25:09.png

其他

1. 关于pahole

最开始尝试降级安装pahole,因为根据这个common/scripts/pahole-flags.shcommon/scripts/link-vmlinux.sh,v1.16或者v1.17应该是刚好的,不用加额外的flag

need at least v1.16

结果并没有v1.16或者v1.17

kali@ubuntu:~$ sudo apt list -a dwarves
Listing... Done
dwarves/focal-updates,now 1.21-0ubuntu1~20.04 amd64 [installed]
dwarves/focal 1.15-2 amd64

另外的参考资料:Segfault in pahole 1.18 when building kernel 5.9.1 for arm64

2. 关于cmake

在降级pahole尝试中,涉及卸载编译安装的dwarves包,可以这样做:

sudo xargs rm < install_manifest.txt

3. BTFHubForAndroid

这就是最终想弄的^_^