1.1 环境安装

1.1.1 编译工具安装

1.1.1.1 安装clang 和 lvm

  1. $ yum install clang llvm gcc-toolset-10-elfutils-libelf-devel.x86_64 elfutils-libelf-devel

1.1.1.2 内核头文件包和开发安装

  1. $ yum install kernel-devel kernel-headers

1.1.1.3 centos 8 内核源码包下载安装

去CentOS官网找对应的内核源码包,下面地址,进去找到与版本信息对应的源码目录,找到内核源码包,下载即可

  1. // http://vault.centos.org/ centos 官网
  2. // 查看系统版本
  3. $ lsb_release -a
  4. LSB Version: :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
  5. Distributor ID: CentOS
  6. Description: CentOS Linux release 8.3.2011
  7. Release: 8.3.2011
  8. $ wget https://vault.centos.org/8.3.2011/BaseOS/Source/SPackages/kernel-4.18.0-240.1.1.el8_3.src.rpm
  9. $ sudo useradd -s /sbin/nologin mockbuild
  10. $ sudo rpm -i kernel-4.18.0-240.1.1.el8_3.src.rpm
  11. $ cp rpmbuild/SOURCES/linux-4.18.0-240.1.1.el8_3.tar.xz ~/
  12. $ tar xvf linux-4.18.0-240.1.1.el8_3.tar.xz
  13. $ sudo cp linux-4.18.0-240.1.1.el8_3 /kernel-src

1.1.1.4 编译libbpf环境

  1. $ cd ~/linux-4.18.0-240.1.1.el8_3/tools/lib/bpf
  2. $ make
  3. $ make install prefix=/usr/local/

下载测试代码

下载 《Linux Observability with BPF 》 测试源代码

  1. $ git clone https://github.com/bpftools/linux-observability-with-bpf.git
  2. $ cd ~/learn-bpf/linux-observability-with-bpf/code/chapter-2

编译Hello-word代码

编译代码时候出现 lbpf 失败, 参考libbpf环境编译和安装。 出现 read_trace_pipe 链接失败,可以查看源代码对应函数位置,把对应c文件编译进去就可以了

修改Makefile 解决链接失败问题

  1. CLANG = clang
  2. EXECABLE = monitor-exec
  3. BPFCODE = bpf_program
  4. BPFTOOLS = /kernel-src/samples/bpf
  5. BPFLOADER = $(BPFTOOLS)/bpf_load.c
  6. # 解决 loader.c:(.text+0x4e): undefined reference to `read_trace_pipe'
  7. BPFLOADER += /kernel-src/tools/testing/selftests/bpf/trace_helpers.c
  8. CCINCLUDE += -I/kernel-src/tools/testing/selftests/bpf
  9. LOADINCLUDE += -I/kernel-src/samples/bpf
  10. LOADINCLUDE += -I/kernel-src/tools/lib
  11. LOADINCLUDE += -I/kernel-src/tools/perf
  12. LOADINCLUDE += -I/kernel-src/tools/include
  13. # read_trace_pipe 头文件
  14. LOADINCLUDE += -I/kernel-src/tools/testing/selftests/bpf
  15. LIBRARY_PATH = -L/usr/local/lib64
  16. BPFSO = -lbpf -lelf
  17. # Setting -DHAVE_ATTR_TEST=0 for the kernel containing below patch:
  18. # 06f84d1989b7 perf tools: Make usage of test_attr__* optional for perf-sys.h
  19. #
  20. # The patch was included in Linus's tree starting v5.5-rc1, but was also included
  21. # in stable kernel branch linux-5.4.y. So it's hard to determine whether a kernel
  22. # is affected based on the kernel version alone:
  23. # - for a v5.4 kernel from Linus's tree, no;
  24. # - for a v5.4 kernel from the stable tree (used by many distros), yes.
  25. #
  26. # So let's look at the actual kernel source code to decide.
  27. #
  28. # See more context at:
  29. # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=06f84d1989b7e58d56fa2e448664585749d41221
  30. # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fce9501aec6bdda45ef3a5e365a5e0de7de7fe2d
  31. CFLAGS += $(shell grep -q "define HAVE_ATTR_TEST 1" /kernel-src/tools/perf/perf-sys.h \
  32. && echo "-DHAVE_ATTR_TEST=0")
  33. .PHONY: clean $(CLANG) bpfload build
  34. clean:
  35. rm -f *.o *.so $(EXECABLE)
  36. build: ${BPFCODE.c} ${BPFLOADER}
  37. $(CLANG) -O2 -target bpf -c $(BPFCODE:=.c) $(CCINCLUDE) -o ${BPFCODE:=.o}
  38. bpfload: build
  39. clang $(CFLAGS) -o $(EXECABLE) -lelf $(LOADINCLUDE) $(LIBRARY_PATH) $(BPFSO) \
  40. $(BPFLOADER) loader.c
  41. $(EXECABLE): bpfload
  42. .DEFAULT_GOAL := $(EXECABLE)
  43. [root@node20 hello_world]# make
  44. clang -O2 -target bpf -c bpf_program.c -I/kernel-src/tools/testing/selftests/bpf -o bpf_program.o
  45. clang -DHAVE_ATTR_TEST=0 -o monitor-exec -lelf -I/kernel-src/samples/bpf -I/kernel-src/tools/lib -I/kernel-src/tools/perf -I/kernel-src/tools/include -I/kernel-src/tools/testing/selftests/bpf -L/usr/local/lib64 -lbpf -lelf \
  46. /kernel-src/samples/bpf/bpf_load.c /kernel-src/tools/testing/selftests/bpf/trace_helpers.c loader.c
$ make
$ ./monitor-exec 
    <...>-94976 [006] .... 5170175.585609: 0: Hello, BPF World!
    <...>-94975 [006] .... 5170175.585949: 0: Hello, BPF World!
    <...>-94977 [005] .... 5170186.177157: 0: Hello, BPF World!

1.2 编译BPF示例代码

# 切换到内核源代码根目录
cd /kernel-src/
# 生成内核编译时需要的头文件
make headers_install
# 可视化选择你想为内核添加的内核模块,最终生成保存了相关模块信息的.config文件,为执行后面的命令做准备
make menuconfig
# 使用make命令编译samples/bpf/目录下所有bpf示例代码,注意需要加上最后的/符号
make samples/bpf/ # or  make M=samples/bpf

成功!!!