记录一次编译Fedora 32内核的过程
背景
安装了Fedora 32,但是对发行版自带的内核不太满意,因为我想将vfio-pci驱动编译到内核里面(builtin),而不是以module的方式加载(将config里面涉及到vfio的CONFIG项目都设置为y
)。
然后就从 https://mirrors.aliyun.com/fedora/releases/32/Everything/source/tree/Packages/k/kernel-5.6.6-300.fc32.src.rpm 下载了source rpm包。
但是参考 https://fedoraproject.org/wiki/Building_a_custom_kernel/Source_RPM 这里的方法始终不能将想要的vfio-pci built-in 到kernel中。
在这里需要对kernel.spec文件做一点小改动,其他操作流程可以参考:https://fedoraproject.org/wiki/Building_a_custom_kernel/Source_RPM
解决办法
通过make defconfig
或者直接在安装好的fedora32系统的/boot/config-xxxx
拷贝一份config文件,到/root
目录下
然后编辑SPECS/kernel.spec文件,修改为如下:
# and now to start the build process
%{make} %{?_smp_mflags} mrproper
cp /root/kernel-5.6.6-x86_64.config .config
原理很简单,不需要rpmbuild过程中自动生成的config文件,而是使用我们自定义的config文件就可以了。
同时还需要将:
%{make} ARCH=$Arch olddefconfig
改为
%{make} ARCH=$Arch oldconfig
即就是不使用默认的config。
最后就可以执行rpmbuild了。其他部分的操作是可以参考:https://fedoraproject.org/wiki/Building_a_custom_kernel/Source_RPM。
以下步骤是参考自:https://www.zhangfangzhou.cn/how-to-compile-linux-kernel-make-rpm.html,仅供参考:
- 下载内核src rpm
https://mirrors.aliyun.com/fedora/releases/32/Everything/source/tree/Packages/k/
- 步骤:
建议在docker中建立编译环境:
安装一些依赖:
dnf install fedpkg fedora-packager rpmdevtools ncurses-devel pesign grubby
下载kernel src rpm:
yum install wget -y && wget https://mirrors.aliyun.com/fedora/releases/32/Everything/source/tree/Packages/k/kernel-5.6.6-300.fc32.src.rpm
- 首先建立 RPM 的打包环境目录,运行下列命令:
rpmdev-setuptree
该命令会在用户的 HOME 目录下建立 rpmbuild/{SOURCES,SPECS,BUILD,RPMS,SRPMS} 这5个目录,以及一个 .rpmmacros 文件,该文件定义了一些 rpm 打包的环境变量。
安装编译内核所需要的包,运行下列命令:
su -c 'yum-builddep kernel-<version>.src.rpm'
安装 kernel source src.rpm 包,运行下列命令:
rpm -Uvh kernel-<version>.src.rpm
准备内核源代码树
- 运行下列命令来建立内核源代码树:
cd ~/rpmbuild/SPECS
rpmbuild -bp --target=`uname -m` kernel.spec
现在内核源代码树位于 ~/rpmbuild/BUILD/kernel-
- 如果还需要修改内核源代码的话(可选),可按如下步骤操作:
cp -a ~/rpmbuild/BUILD/kernel-2.6.$ver/linux-2.6.$ver.$arch ~/rpmbuild/BUILD/kernel-2.6.$ver.orig
cp -a ~/rpmbuild/BUILD/kernel-2.6.$ver.orig ~/rpmbuild/BUILD/kernel-2.6.$ver.new
在 ~/rpmbuild/BUILD/kernel-2.6.$ver.new 中对 source 作修改,然后作成 patch:
cd ~/rpmbuild/BUILD
diff -uNrp kernel-2.6.x.orig kernel-2.6.x.new > ../SOURCES/linux-2.6-my-new-patch.patch
配置内核选项(可选)
如果需要修改内核的编译选项的话,按如下操作:
- 进入内核源代码树
cd ~/rpmbuild/BUILD/kernel-<version>/linux-<version>.<arch>/
- 从 configs 目录中挑选一个基于其修改的 config 文件,把它复制成内核源代码树中的 .config 文件
cp configs/<desired-config-file> .config
- 配置内核编译选项
make oldconfig
可选:
make menuconfig
- 在新生成的 .config 文件的第一行添加一行指定硬件平台的标识(uname -i 的输出),以 # 号开头,例如:
# x86_64
- 把
.config
文件复制到~/rpmbuild/SOURCES/
目录下,并命名成config-<arch>
,例如config-i686
cp .config ~/rpmbuild/SOURCES/config-<arch>
准备 spec 文件
(需要修改spec文件,将config文件的路径修改下,否则重新rpmbuild会覆盖修改后的config文件。)
进入 ~/rpmbuild/SPECS 目录,编辑 kernel.spec 文件:
- 定义 buildid 为一个唯一的标识,以区别不同的 kernel rpm 包。把
#% define buildid .local
改成
%define buildid .<custom_text>
注意去掉 % 和 define 之间的空格
- 如果之前有生成 patch ,把 patch 加到 kernel.spec 文件中。一般放在所有已有的 patch 最后,并注明注释。例如:
# cputime accounting is broken, revert to 2.6.22 version
Patch2220: linux-2.6-cputime-fix-accounting.patch
Patch9999: linux-2.6-samfw-test.patch
另外在打 patch 那一段也要补上:
ApplyPatch linux-2.6-cputime-fix-accounting.patch
ApplyPatch linux-2.6-samfw-test.patch
编译新的内核
用 rpmbuild 命令来编译 kernel rpm 包,默认的命令为:
rpmbuild -bb --target=`uname -m` kernel.spec
这个命令可能会编译好几遍 kernel,生成不同类型的内核镜像,例如支持 xen、smp 等的 kernel。可以通过添加 --without
rpmbuild -bb --with baseonly --without debug --without debuginfo --target=`uname -m` kernel.spec
编译结束后,新的 rpm 包在 ~rpmbuild/RPMS 目录下。