在学习ebpf的过程中,需要下载linux的源码,但是内核版本带有build版本号(cat /proc/version),如4.19.113-300,在github上只能找到4.19.113这个tag,并不能找到4.19.113-300这个tag,虽然知道这两个的代码相差可能非常小,保险起见,还是找到带build版本号的源码。
那么如何找到这个4.19.113-300对应的内核源码呢?kernel-devel包下也有很多内核源码,他跟4.19.113-300的源码的区别是什么呢?
kernel-devel rpm
从下面rpm的描述信息看,kernel-devel提供了编译内核模块或者驱动需要的头文件和Makefile。由此也可以看出devel应该是development的缩写了。
所以,如果只是编译一个内核模块,那就不需要全部的内核源码,安装kernel-devel的rpm包就足够了。如果是其他用途,如编译bpf,就需要想办法获取到该内核版本对应的源代码了。
[root@localhost linux-4.19.113]# yum info kernel-devel
Installed Packages
Name : kernel-devel
Arch : x86_64
Version : 4.19.113
Release : 300.el7
Size : 50 M
Repo : installed
From repo : /kernel-devel-4.19.113-300.el7.x86_64
Summary : Development package for building kernel modules to match the kernel
URL : https://www.kernel.org/
License : GPLv2 and Redistributable, no modification permitted
Description : This package provides kernel headers and makefiles sufficient to build modules
: against the kernel package.
通过直观的对比内核源码和kernel-devel的目录,也能看到文件大小相差很多,一个是900M,一个是78M。
[root@localhost linux-4.19.113]# du -h --max-depth=1
42M ./Documentation
180K ./LICENSES
126M ./arch
1.9M ./block
48K ./certs
3.4M ./crypto
530M ./drivers
8.0K ./firmware
39M ./fs
41M ./include
188K ./init
256K ./ipc
9.0M ./kernel
4.5M ./lib
3.8M ./mm
30M ./net
1.4M ./samples
3.3M ./scripts
2.8M ./security
36M ./sound
26M ./tools
48K ./usr
708K ./virt
898M .
[root@localhost linux-4.19.113]# du -h --max-depth=1 /usr/src/kernels/4.19.113-300.el7.x86_64/
7.3M /usr/src/kernels/4.19.113-300.el7.x86_64/arch
32K /usr/src/kernels/4.19.113-300.el7.x86_64/block
16K /usr/src/kernels/4.19.113-300.el7.x86_64/certs
80K /usr/src/kernels/4.19.113-300.el7.x86_64/crypto
11M /usr/src/kernels/4.19.113-300.el7.x86_64/drivers
4.0K /usr/src/kernels/4.19.113-300.el7.x86_64/firmware
668K /usr/src/kernels/4.19.113-300.el7.x86_64/fs
42M /usr/src/kernels/4.19.113-300.el7.x86_64/include
68K /usr/src/kernels/4.19.113-300.el7.x86_64/init
4.0K /usr/src/kernels/4.19.113-300.el7.x86_64/ipc
172K /usr/src/kernels/4.19.113-300.el7.x86_64/kernel
176K /usr/src/kernels/4.19.113-300.el7.x86_64/lib
40K /usr/src/kernels/4.19.113-300.el7.x86_64/mm
832K /usr/src/kernels/4.19.113-300.el7.x86_64/net
120K /usr/src/kernels/4.19.113-300.el7.x86_64/samples
4.6M /usr/src/kernels/4.19.113-300.el7.x86_64/scripts
112K /usr/src/kernels/4.19.113-300.el7.x86_64/security
996K /usr/src/kernels/4.19.113-300.el7.x86_64/sound
5.0M /usr/src/kernels/4.19.113-300.el7.x86_64/tools
12K /usr/src/kernels/4.19.113-300.el7.x86_64/usr
16K /usr/src/kernels/4.19.113-300.el7.x86_64/virt
78M /usr/src/kernels/4.19.113-300.el7.x86_64/
[root@localhost linux-4.19.113]#
获取精确匹配系统的内核源码
已4.19.113-300为例,可以直接在google搜索4.19.113-300 src rpm,找一下相关链接,就可以找到对应的内核代码的源码包。centos内核源码包官方链接
更为惊喜的是,这个源码包提供了编译内核rpm(如modules,core,headers,devel,kernel等)所需要的的spec文件。接下来就涉及到一些rpm和rpmbuild的知识,不过也都不难。
按照下文中的描述和步骤安装源码rpm,即可获得源码文件。
官方推荐不要以root用户做以下操作,如果清楚这些操作具体都做了什么,已root用户也没有关系。安装过程可能会有一些问题,根据错误提示信息,稍微查一下基本都能解决,大部分都是缺少相应的工具包。
// 提前创建rpmbuild所需要的目录
mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
// 安装源码rpm包,如果以root用户安装,rpm中的文件会被安装到root目录下,目前没有发现有参数可以更换安装目录。
rpm -ivh kernel-4.19.113-300.el7.src.rpm
// 进入spec文件所在的目录,rpmbuild -bp,简单说就是解压源码后打上patch。
cd /root/rpmbuild/SPECS
rpmbuild -bp kernel.spec
ls /root/rpmbuild/BUILD/kernel-4.19.el7/linux-4.19.113-300.el7.x86_64/
完成上诉步骤后,就可以在/root/rpmbuild/BUILD/kernel-4.19.el7/linux-4.19.113-300.el7.x86_64/目录下看到完整的内核源码。
这里有个建议可以参考下,在编译内核源码时,可以复用boot目录下config配置和kernel-devel中的Makefile文件。执行make前,执行一下make menuconfig,如果是不同的内核版本,该命令会自动处理一些错误的配置项
下面是执行rpmbuild -bp命令的具体执行过程。
orootlocalhost SPECS]# rpmbuild -bp kernel.spec
<string>:1: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
<string>:1: DeprecationWarning: The distutils.sysconfig module is deprecated, use sysconfig instead
<string>:1: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
<string>:1: DeprecationWarning: The distutils.sysconfig module is deprecated, use sysconfig instead
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.OKrrUK
+ umask 022
+ cd /root/rpmbuild/BUILD
+ patch_command='patch -p1 -F1 -s'
++ find /root/rpmbuild/BUILD -maxdepth 1 -type d -name 'kernel-4.*'
++ grep -x -v /root/rpmbuild/BUILD/kernel-4.19.el7
+ sharedirs=
+ :
+ '[' -d kernel-4.19.el7 ']'
+ cd kernel-4.19.el7
+ for i in 'linux-*'
+ '[' -d linux-4.19.113-300.el7.x86_64 ']'
+ rm -rf deleteme.x86_64
+ mv linux-4.19.113-300.el7.x86_64 deleteme-linux-4.19.113-300.el7.x86_64
+ for i in 'linux-*'
+ '[' -d linux-4.19.113-300.tgz ']'
+ cd ..
+ rm -rf deleteme-linux-4.19.113-300.el7.x86_64
+ '[' '!' -d kernel-4.19.el7/vanilla-4.19 ']'
+ cd kernel-4.19.el7
+ cp -al vanilla-4.19 linux-4.19.113-300.el7.x86_64
+ cd linux-4.19.113-300.el7.x86_64
+ '[' '!' -d .git ']'
+ git init
Initialized empty Git repository in /root/rpmbuild/BUILD/kernel-4.19.el7/linux-4.19.113-300.el7.x86_64/.git/
+ git config user.email noreply@centos.org
+ git config user.name 'AltArch Kernel'
+ git config gc.auto 0
+ git add .
+ git commit -a -q -m baseline
+ xzcat /root/rpmbuild/SOURCES/patch-4.19.113.xz
+ patch -p1 -F1 -s
+ git commit -a -m 'Stable update'
....
Applying: drivers: ata: ahci_sunxi: Increased SATA/AHCI DMA TX/RX FIFOs
+ chmod +x scripts/checkpatch.pl
+ chmod +x tools/objtool/sync-check.sh
+ mv COPYING COPYING-4.19.113
+ touch .scmversion
+ mkdir configs
+ cd configs
+ cp /root/rpmbuild/SOURCES/kernel-aarch64-debug.config /root/rpmbuild/SOURCES/kernel-aarch64.config /root/rpmbuild/SOURCES/kernel-armv7hl-debug.config /root/rpmbuild/SOURCES/kernel-armv7hl-lpae-debug.config /root/rpmbuild/SOURCES/kernel-armv7hl-lpae.config /root/rpmbuild/SOURCES/kernel-armv7hl.config /root/rpmbuild/SOURCES/kernel-i686-debug.config /root/rpmbuild/SOURCES/kernel-i686.config /root/rpmbuild/SOURCES/kernel-ppc64le-debug.config /root/rpmbuild/SOURCES/kernel-ppc64le.config /root/rpmbuild/SOURCES/kernel-s390x-debug.config /root/rpmbuild/SOURCES/kernel-s390x.config /root/rpmbuild/SOURCES/kernel-x86_64-debug.config /root/rpmbuild/SOURCES/kernel-x86_64.config .
+ cp /root/rpmbuild/SOURCES/kernel-local .
+ cp /root/rpmbuild/SOURCES/merge.pl .
+ cp /root/rpmbuild/SOURCES/generate_all_configs.sh .
+ cp /root/rpmbuild/SOURCES/generate_debug_configs.sh .
+ cp /root/rpmbuild/SOURCES/generate_bls_conf.sh .
+ VERSION=4.19.113
+ ./generate_all_configs.sh
+ for i in 'kernel-4.19.113-x86_64*.config'
+ mv kernel-4.19.113-x86_64-debug.config kernel-4.19.113-x86_64-debug.config.tmp
+ ./merge.pl /root/rpmbuild/SOURCES/kernel-local kernel-4.19.113-x86_64-debug.config.tmp
+ rm kernel-4.19.113-x86_64-debug.config.tmp
+ for i in 'kernel-4.19.113-x86_64*.config'
+ mv kernel-4.19.113-x86_64.config kernel-4.19.113-x86_64.config.tmp
+ ./merge.pl /root/rpmbuild/SOURCES/kernel-local kernel-4.19.113-x86_64.config.tmp
+ rm kernel-4.19.113-x86_64.config.tmp
+ cp /root/rpmbuild/SOURCES/process_configs.sh .
+ OPTS=
+ OPTS=' -n'
+ OPTS=' -n -c'
+ ./process_configs.sh -n -c kernel 4.19.113
~/rpmbuild/BUILD/kernel-4.19.el7/linux-4.19.113-300.el7.x86_64 ~/rpmbuild/BUILD/kernel-4.19.el7/linux-4.19.113-300.el7.x86_64/configs