Centos7 ebpf环境搭建libbpf-bootstrap
内核解析
认识Kernel
所谓Kernel,就是一种操作系统的核心,当然也是一个文件,而这种核心提供了对一些硬件的支持,一般来说其中包含了一些对常见硬件核心驱动的核心代码。启动系统时会通过加载MBR中的bootloader,然后将此核心文件加载到内存中。因为只是保留了核心,所有一般来说,kernel的大小也不会很大。一般kernel文件会保存在/boot目录,格式为:/boot/vmlinuz-XXX,比如Centos7中的:
ls -l /boot/vmlinuz-3.10.0-1160.71.1.el7.x86_64
内核模块(kernel module)
kernel文件中已经包含了一些最基本的硬件探测与驱动模块,但是其中的内容并不能完全是由于所有的硬件驱动,所有,对于一些不常用、较新的驱动,linux中会提供一种模块化的机制,及接需要硬件或者新功能时,可以通过加载这些核心模块来提供对新功能的支持。当然核心模块的各种模块文件是独立存在的,一般存放在/lib/modules/$(uname -r)/kernel/下:
[root@minio1 boot]# ll /lib/modules/3.10.0-1160.71.1.el7.x86_64/kernel/
total 16
drwxr-xr-x. 3 root root 17 Nov 2 23:20 arch
drwxr-xr-x. 3 root root 4096 Nov 2 23:20 crypto
drwxr-xr-x. 72 root root 4096 Nov 2 23:21 drivers
drwxr-xr-x. 26 root root 4096 Nov 2 23:21 fs
drwxr-xr-x. 3 root root 19 Nov 2 23:21 kernel
drwxr-xr-x. 4 root root 249 Nov 2 23:21 lib
drwxr-xr-x. 2 root root 35 Nov 2 23:21 mm
drwxr-xr-x. 34 root root 4096 Nov 2 23:21 net
drwxr-xr-x. 12 root root 173 Nov 2 23:21 sound
drwxr-xr-x. 3 root root 17 Nov 2 23:21 virt
源码包解析
源码包解压及位置放置
系统内核文件位置是在/usr/src/kernels目录下:
[root@minio1 kernels]# ls /usr/src/kernels/
3.10.0-1160.105.1.el7.x86_64.debug
将刚才下载的kernel内核源码文件解压到/usr/src/kernels目录下
内核模块内部目录解析
[root@minio1 linux-5.15.145]# ls
arch certs CREDITS Documentation fs init ipc Kconfig lib MAINTAINERS mm README scripts sound usr
block COPYING crypto drivers include io_uring Kbuild kernel LICENSES Makefile net samples security tools virt
核心原始码下的此目录作用说明:
arch:与硬件平台有关的项目,大部分指的是CPU的类型,例如x86,x86_64,Xen虚拟支持等。
block:与成组设备较相关的设定数据,区块数据通常指一些大量存储媒体,还包括类似ext3等文件系统的支持是否允许等。
crypto:核心所支持的加密技术,如md5、des、sha512等。
Documentation:与核心有关的一堆说明文件,其中包括了对上面所有目录里的说明。
firmware:一些旧式硬件的微脚步数据。
fs:内核所支持的filesystems(文件系统),例如ext系列、ntfs、reisefs等。
include:一些可让其它过程调用的标头(header)定义数据。
init:一些初始化的定义功能,包括挂载和init 程序的呼叫等。
ipc:定义Linux操作系统内各程序进程间的通信。
kernel:定义核心的程序、核心状态、线程、程序的排程(schedule)、程序的讯号(signle)等。
lib:一些函数库。
mm:与内存单元有关的各项数据,包括swap与虚拟内存等。
net:与网络有关的各项协议数据,还有防火墙模块(net/ipv4/netfilter/*) 等。
security:包括selinux等在内的安全性设定。
sound:与音效有关的各项模块。
virt:与虚拟化机器有关的信息,目前核心支持的是KVM( Kernel base Vitual Machine )。
编译内核
安装依赖
yum install gcc bc gcc-c++ ncurses ncurses-devel elfutils-libelf-devel openssl-devel ncurses-devel bison flex elfutils-libelf-devel openssl-devel python3 binutils-devel elfutils-libelf elfutils-libelf-devel elfutils-devel zlib-devel binutils.x86_64 binutils-devel.x86_64 tcpdump libcap-devel libcap libpcap-devel libpcap texinfo -y
升级gcc
yum install centos-release-scl -y
yum install devtoolset-7 -y
//激活gcc当前登陆session生效
scl enable devtoolset-7 bash 或 source /opt/rh/devtoolset-7/enable
echo "source /opt/rh/devtoolset-7/enable" >> ~/.bash_profile
source /opt/rh/devtoolset-7/enable
//查看gcc版本
gcc --version
升级cmake
tar -zxvf cmake-3.14.0.tar.gz
cd cmake-3.14.0
./bootstrap
make && make install
安装libbpf库
git clone https://github.com/libbpf/libbpf
cd libbpf/src
make
make install
清理内核源码目录
注:一般情况下下载的源码包不确定是否已经编译过,或者还残留有生成的一起文件,这里为了编译时不会出现未知的错误,进行清理。
[root@minio1 linux-5.15.145]# pwd
/usr/src/kernels/linux-5.15.145
[root@minio1 linux-5.15.145]# make mrproper
配置内核功能
在当前系统的/boot/目录下存在一个名为conf-xxx 的文件,那个文件其实就是核心功能列表选择文件,如:
[root@minio1 boot]# ll /boot/config-3.10.0-1160.71.1.el7.x86_64
-rw-r--r--. 1 root root 153619 Jun 28 2022 /boot/config-3.10.0-1160.71.1.el7.x86_64
在通过配置内核功能以后,会在源码核心目录下生成一个.config的隐藏文件,使用diff文件比对命令对/boot目录下的conf-xxx文件和对应内核版本目录下的文件进行比对,可以发现这两个文件没有什么不同,可以推断出/boot目录下的conf-xxx文件与对应内核版本目录下的.config文件是一样的
编码内核选择界面(生成.config的方法)
make help: #支持“更新模式进行配置”。
make menuconfig: #基于curses的文本窗口界面
make gconfig: #基于GTK(GOME)环境窗口界面
make xconfig: #基于QT(KDE) 环境的窗口界面
make config: #老旧的命令行遍历方式逐一配置每个可配置的选项
make oldconfig: #透过已经存在的./.config文件内容,并使用该文件内设定值为默认值,只将新版本核心的新功能列出让用户选择,可以简化核心功能挑选过程。对与升级内核很好选择。
make defconfig: #基于内核为目标平台执行提供的“默认”配置进行配置
make allyesconfig: #所有选项均回答为”yes”
make allnoconfig: #所有选项均回答为”no”
make menuconfig
选中kernel hacking --> Compile-time checks and compiler option -->Generate BTF typeinfo后,打开了编译开关CONFIG_DEBUG_INFO_BTF。
执行编译安装
//参数-j$(nproc)表示“使用与(本机CPU线程数)相同的(并行编译任务数)”,提高效率。可通过cat /proc/cpuinfo查看本机的CPU线程数。
参数2>&1 | tee log表示将make过程输出到log文件,如编译过程遇到错误,可通过grep Error log查看。(注:提示tee指令没有权限,此问题尚未解决,影响很小)
make -j$(nproc) 2>&1 | tee log
make -j$(nproc) modules
make modules_install
make install
设置启动内核
grub2-mkconfig -o /boot/grub2/grub.cfg
//查看可用内核
[root@minio1 ~]# cat /boot/grub2/grub.cfg | grep menuentry
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
menuentry_id_option=""
export menuentry_id_option
menuentry 'CentOS Linux (5.15.145) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.15.145-advanced-510c66fd-9009-41a7-bb6f-c992f485708a' {
menuentry 'CentOS Linux (0-rescue-2ad58f5eb77640e4869ad4d4c7ad4130) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-2ad58f5eb77640e4869ad4d4c7ad4130-advanced-510c66fd-9009-41a7-bb6f-c992f485708a' {
[root@minio1 ~]# grub2-set-default 'CentOS Linux (5.15.145) 7 (Core)'
[root@minio1 ~]# reboot
遇到的问题
- BTF: .tmp_vmlinux.btf: pahole (pahole) is not available,需要安装pahole,yum install dwarves安装的版本太老,需要手动安装
git clone https://github.com/acmel/dwarves.git
cd dwarves
git submodule update --init --recursive
mkdir build
cd build
cmake -D__LIB=lib ..
make install
//安装完成后会报错libdwarves_emit.so.1: cannot open shared object file: No such file or directory,这是连接库的问题,默认安装到了/usr/local/lib/下,拷贝文件到/lib64
cp -ar /usr/local/lib/* /lib64/
cp -ar /usr/local/include/* /usr/include