The information on the Internet is uneven, some who understand it but haven't made it clear, and those who don't understand are just forwarding it blindly. Here, I don't know it very well, but the road to making kernel rpm packages has worked.
There are two ways to modify the kernel source code to open the rpm package:
One is to directly decompress the kernel tar.xz package, directly package and cover the original tar.zx package after modification and editing, and execute the rpmbuild command to build. The other is to decompress the kernel tar.zx package, back up the source files that need to be modified, compare the source files to generate a patch after the modification, and specify the patch file in the kernel.spec configuration, and execute rpmbuild to build.
The first method is more cumbersome, the second method is more convenient and versatile, and the second method is used here.
To talk about the scenario here, a new kernel network module test_rpm is created in the system, but there are some customized modifications in the kernel protocol stack and tun/tap driver.
1. Start by downloading the kernel rpm installation package from the official website:
yum install -y asciidoc audit-libs-devel bash bc binutils binutils-devel bison diffutils elfutils elfutils-devel elfutils-libelf-devel findutils flex gawk gcc gettext gzip hmaccalc hostname java-devel m4 make module-init-tools ncurses-devel net-tools newt-devel numactl-devel openssl patch pciutils-devel perl perl-ExtUtils-Embed pesign python-devel python-docutils redhat-rpm-config rpm-build sh-utils tar xmlto xz zlib-devel
rpm -ivh kernel-3.10.0-1127.el7.src.rpm
tar -xf /root/rpmbuild/SOURCES/linux-3.10.0-1127.el7.tar.xz -C /tmp
cd /tmp/linux-3.10.0-1127.el7
2. Back up the files to be modified. It is useful later, and the suffix can be customized. I used _orig here, you can be .orig or something else.
cp include/linux/netdevice.h include/linux/netdevice_orig.h
cp drivers / net / tun.c drivers / net / tun_orig.c
cp net net_orig (You need to modify and add a batch of files in the net directory, so you can directly back up the net directory)
3. Next replace the target file to be modified
mkdir net/test_rpm
All modified files of test_rpm here are listed here:
include/linux/netdevice.h
drivers / net / tun.c
net/core/dev.c、 net/Makefile、 net/Kconfig
net/test_rpm/test.c、 net/test_rpm/test.h、 net/test_rpm/Makefile、 net/test_rpm/Kconfig
4. Use diff command to generate patch file
diff -up include/linux/netdevice_orig.h include/linux/netdevice.h >> /tmp/custom1.patch
diff -up drivers/net/tun_orig.c drivers/net/tun.c >> /tmp/custom2.patch
diff -up net_orig net >> /tmp/custom3.patch
Then, cd ~/rpmbuild
Manually modify SOURCES: kernel-3.10.0-x86_64.config, kernel-3.10.0-x86_64-debug.config
Add the previous line separately: CONFIG_TEST=m
This involves kernel driver development, please go online to modify and check how to add modules, Makefile and Kconfig
5. Manually modify SPECS: vim kernel.spec
Line 6: %define buildid .local Note: There is no space between %define
Lines 795~797: Note here -p0 search for ApplyOptionalPatch and add the following three lines below
patch -p0 -F1 -s < $RPM_SOURCE_DIR/custom1.patch
patch -p0 -F1 -s < $RPM_SOURCE_DIR/custom2.patch
patch -p0 -F1 -s < $RPM_SOURCE_DIR/custom3.patch
Here is a customized modification, because I keep reporting errors like this:
“1 out of 1 hunk FAILED -- saving rejects to file net/Makefile.rej”
This kind of error is generally an error reported internally by running kernel.spec, here is an error reported by applying a patch file to patch.
6. Start making rpm package. This process takes a long time, and it takes about an hour for a single-core machine
rpmbuild -bb --without kabichk --target=`uname -m` SPECS/kernel.spec
After completion, check the generated rpm package: ll RPMS/x86_64
kernel-3.10.0-1127.el7.local.x86_64.rpm
kernel-devel-3.10.0-1127.el7.local.x86_64.rpm
kernel-headers-3.10.0-1127.el7.local.x86_64.rpm
kernel-tools-3.10.0-1127.el7.local.x86_64.rpm
kernel-tools-libs-3.10.0-1127.el7.local.x86_64.rpm
kernel-tools-libs-devel-3.10.0-1127.el7.local.x86_64.rpm
7. Install the kernel rpm package generated by yourself and test it:
rpm -ivh RPMS/x86_64/kernel-3.10.0-1127.el7.local.src.rpm
ll /boot/ must have these lines:
config-3.10.0-1127.el7.local.x86_64
initramfs-3.10.0-1127.el7.local.x86_64.img
symvers-3.10.0-1127.el7.local.x86_64.gz
System.map-3.10.0-1127.el7.local.x86_64
vmlinuz-3.10.0-1127.el7.local.x86_64
At the same time, vim /boot/grub2/grub.cfg will add a menu corresponding to the kernel version: Of course, it does not need to be exactly the same here. You should refer to your personal machine for details. In fact, there will be two similar kernel versions below these lines, because you The host will have at least two kernel versions
menuentry 'CentOS Linux (3.10.0-1127.el7.local.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-1127.el7.x86_64-advanced-e558a2bf-04c2-4573-9376-8c7ea58f9ae4' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' bcdcab1b-9afa-43b9-86cf-8fbc7567ef9f
else
search --no-floppy --fs-uuid --set=root bcdcab1b-9afa-43b9-86cf-8fbc7567ef9f
be
linux16 /vmlinuz-3.10.0-1127.el7.local.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto spectre_v2=retpoline rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-1127.el7.local.x86_64.img
}
reboot
8. Here you can set the system default boot kernel version:
grub2-deitenv list //View the current kernel version
cat /boot/grub2/grub.cfg | grip menuentry
grub2-set-default 'CentOS Linux (3.10.0-1127.el7.local.x86_64) 7 (Core)'