重新编译 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
信息了。