分类

重新编译 linux 内核,开启 btf

2020-04-15 18:13 linux

默认的 archlinux 内核包并不包含对 BTF(BPF Type Format) 的支持,需要我们手动开启,

目前的内核版本是 5.6.4,我们使用 yaourt 来安装。

首先是安装 pahole 这个依赖包:

yaourt -S pahole

目前的 pahole 版本要依赖 libebl 库,而这个库并不是必需的,可以给它创建一个 软链接指向 libelf.so 即可。

之后,安装开发环境:

sudo pacman -S asp base-devel pacman-contrib
  • pacman-contrib 包里面提供了 updpkgsums 命令,用于在更改了本地配置文件后更新其文件哈稀
  • asp 包里提供了 asp 命令,用于拉取包的配置代码

接下来先拉取内核默认配置:

mkdir -v linux-btf
cd linux-btf
asp update linux
asp export linux

这里,就会将下载的内核配置以及 PKGBUILD 脚本下载到 linux 子目录里。我们可以 手动编辑一下 PKGBUILD 文件,修改 pkgbase 变量的名称,以便跟系统仓库里提供的 内核包区分开。比如可以改为 pkgbase=linux-btf

之后是修改 config 内核配置文件,以下是修改后的补丁:

$ diff config.init config
3c3
< # Linux/x86 5.6.3-arch1 Kernel Configuration
---
> # Linux/x86 5.6.4-arch1 Kernel Configuration
10465c10465,10469
< # CONFIG_DEBUG_INFO is not set
---
> CONFIG_DEBUG_INFO=y
> # CONFIG_DEBUG_INFO_REDUCED is not set
> # CONFIG_DEBUG_INFO_SPLIT is not set
> CONFIG_DEBUG_INFO_DWARF4=y
> CONFIG_DEBUG_INFO_BTF=y

要注意的是,要使用 bcc 工具的话,也应确保以下选项都是打开的(默认也是):

$ grep BPF config
184:CONFIG_CGROUP_BPF=y
214:CONFIG_BPF=y
243:CONFIG_BPF_SYSCALL=y
244:CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
245:CONFIG_BPF_JIT_ALWAYS_ON=y
246:CONFIG_BPF_JIT_DEFAULT_ON=y
1173:CONFIG_IPV6_SEG6_BPF=y
1315:CONFIG_NETFILTER_XT_MATCH_BPF=m
1534:# CONFIG_BPFILTER is not set
1696:CONFIG_NET_CLS_BPF=m
1723:CONFIG_NET_ACT_BPF=m
1776:CONFIG_BPF_JIT=y
1777:CONFIG_BPF_STREAM_PARSER=y
2040:CONFIG_LWTUNNEL_BPF=y
2049:CONFIG_HAVE_EBPF_JIT=y
10660:CONFIG_BPF_EVENTS=y
10663:CONFIG_BPF_KPROBE_OVERRIDE=y
10752:# CONFIG_TEST_BPF is not set

修改完内核配置之后,需要重新计算其文件哈稀:

updpkgsums

现在就可以开始下载内核源码并编译了,但有一个问题是,PKGBUILD 脚本里默认是单进程 编译,我们可以修改它,使之支持多核编译:

sed -i -e 's/make all/make -j$(nproc) all/' PKGBUILD

开始编译:

makepkg -s

这里需要下载 2.5G 左右的内核源码仓库,如果网速比较慢的话,可以考虑使用代理服务, 比如像下面这样:

proxychains makepkg -s

如果提示GPG验证失败的话,可以手动导入GPG公钥:

gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys ABAF11C65A2970B130ABE3C479BE3E4300411886
gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 647F28654894E3BD457199BE38DBBDC86092693E
gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 8218F88849AAC522E94CF470A5E9288C4FA415FA

等下载完代码,完成编译任务后,会在目录里生成三个安装包:

$ ls *.xz
linux-btf-5.6.4.arch1-1-x86_64.pkg.tar.xz
linux-btf-docs-5.6.4.arch1-1-x86_64.pkg.tar.xz
linux-btf-headers-5.6.4.arch1-1-x86_64.pkg.tar.xz

可以发现,现在的内核包比系统默认提供的要大很多,因为里面包含了调试信息。 有一点要注意的是,如果自行修改了内核选项的话,不应该打开 CONFIG_DEBUG_INFO_REDUCED 这个选项,不然生成的 BTF 信息是无效的,bcc 工具也会提供出错。

使用 pacman 安装它们:

sudo pacman -U *.xz

之后一切顺利的话,就可以安装内核到本机了。

最后一步是修改启动项,如果使用 grub 来启动系统的话,可以让它重新扫描系统, 会自动识别新的内核:

$ sudo grub-mkconfig -o /boot/grub/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-linux-btf
Found initrd image: /boot/initramfs-linux-btf.img
Found fallback initrd image(s) in /boot: initramfs-linux-btf-fallback.img
Found linux image: /boot/vmlinuz-linux
Found initrd image: /boot/initramfs-linux.img
Found fallback initrd image(s) in /boot: initramfs-linux-fallback.img
done

这里,可以发现它已经识别了新的内核 。

现在重启系统, bcc 工具应该就可以使用内核中的 BTF 信息了。

参考