五一假期,闲里偷闲,在Windows电脑上将EBPF环境在WSL2上调试成功了,这里记录下调试过程,以待后续查阅。
WSL2 (Windows Subsystem for Linux 2)
适用于 Linux 的 Windows 子系统,是在Win10、Win11系统支持的轻量化的Linux环境,相比较VMWare、Hyper-V而言更加轻量。
同时,常用开发软件比如 VSCode
、IDEA
等 对WSL的支持是非常优秀的,个人认为比远程SSH的支持还要优秀。
我这里选择的是WSL2 中的Ubuntu系统,安装命令 wsl --install -d Ubuntu
,也可以通过微软软件商店来安装。经过测试微软软件商店的成功率更高,因为wsl
命令要访问raw.githubusercontent.com
,而该域名经常由于高科技原因造成无法在中国大陆访问。
将WSL默认使用Root用户:
1C:\> ubuntu.exe config --default-user root
由于背景全白,这里调整Bash的提示符以作醒目:
1export PS1="[\[\033[01;32m\]\u❄\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]]☭ "
eBPF (extended Berkeley Packet Filter)
允许程序在不修改内核源代码的情况下,向内核添加eBPF模块来扩展内核的功能。
当在WSL中安装并执行bpftool时,提示如下:
bpftool会查找/lib/modules/5.10.16.3-microsoft-standard-WSL2
路径的kernel header
文件,但由于linux kernel 5.10.16.3-microsoft
并不在Ubuntu的官方仓库里,所以唯一的办法就是自己从源代码编译kernel,并将kernel header安装到/lib/modules目录。
1# 我这里选择了当前WSL2的最新版本的Kernel
2$ wget https://codeload.github.com/microsoft/WSL2-Linux-Kernel/tar.gz/refs/tags/linux-msft-wsl-6.1.21.1 -O /usr/src/linux-msft-wsl-6.1.21.1.tar.gz
3$ cd /usr/src && tar zxvf linux-msft-wsl-6.1.21.1.tar.gz && rm -fr linux-msft-wsl-6.1.21.1.tar.gz
4$ cd /usr/srcWSL2-Linux-Kernel-linux-msft-wsl-6.1.21.1/
5$ cp -af Microsoft/config-wsl .config
修改.config
文件,增加BPF相关的配置:
1CONFIG_BPF=y
2CONFIG_BPF_SYSCALL=y
3# [for tc filters]
4CONFIG_NET_CLS_BPF=y
5# [for tc actions]
6CONFIG_NET_ACT_BPF=y
7CONFIG_BPF_JIT=y
8# [for Linux kernel versions 4.1 through 4.6]
9CONFIG_HAVE_BPF_JIT=y
10# [for Linux kernel versions 4.7 and later]
11CONFIG_HAVE_EBPF_JIT=y
12# [for kprobes]
13CONFIG_BPF_EVENTS=y
14# Need kernel headers through /sys/kernel/kheaders.tar.xz
15CONFIG_IKHEADERS=y
安装必要的工具链及BPF需要的依赖包,并编译内核:
1$ apt install make build-essential flex bison bc pahole pkg-config libelf-dev libssl-dev clang llvm
2$ make -j 4
3$ make modules_install
WSL2的Kernel启动,需要将Kernel拷贝到Windows系统中,并修改在Windows中的wsl配置文件。
1$ mkdir -p /mnt/c/WSL2Kernel/
2$ cp -af arch/x86/boot/bzImage /mnt/c/WSL2Kernel/
修改 WSL2的配置文件: C:\Users\{UserName}\.wslconfig
:
1[wsl2]
2kernel=C:\\WSL2Kernel\\bzImage
重启WSL2
1C:\> wsl --shutdown
2C:\> bash
检查内核:
1$ ls /lib/modules/$(uname -r)
由于BPFTool依赖Kernel,所以需要从源码安装BPFTOOL
1$ git clone https://github.com/libbpf/bpftool.git
2$ cd bpftool && git submodule update --init
3$ cd src && make && cp -af bpftool /usr/sbin/bpftool
验证一下:
使用Ubuntu包管理器安装的bpftrace,是一个strip掉sym的版本,在执行bpftrace -e 'BEGIN { printf("hi\n") }'
时会报错:
所以这里也需要从源码编译bpftrace:
1$ apt install -y libbpfcc-dev
2$ apt install -y cmake g++ git zlib1g-dev libfl-dev systemtap-sdt-dev \
3 binutils-dev libcereal-dev llvm-dev llvm-runtime libclang-dev \
4 libpcap-dev libgtest-dev libgmock-dev asciidoctor
5$ git clone https://github.com/iovisor/bpftrace --recurse-submodules
6$ mkdir bpftrace/build; cd bpftrace/build;
7$ ../build-libs.sh
8$ cmake -DCMAKE_BUILD_TYPE=Release ..
9$ make -j8
10$ make install && cp -af src/bpftrace /usr/bin/bpftrace
再次验证,则显示正常:
PERF也是依赖内核源代码的,直接使用Ubuntu包管理的perf命令会报错:
我们这里直接使用Kernel 源码中的perf进行编译并安装即可:
1$ cd /usr/src/WSL2-Linux-Kernel-linux-msft-wsl-6.1.21.1/tools/perf/
2$ make && cp perf /usr/bin/perf
再次验证则显示正常:
至此,EBPF On WSL2环境算是搭建完毕,可以在这个轻量级Linux系统中使用EBPF随意的玩耍了。