# Tested on RHEL 6.4 i386
# Notes mainly from http://wiki.centos.org/HowTos/Custom_Kernel

# WARNING: Please note that customizing kernel is not supported by Red Hat Support Services

# NOTE: It is advisable to build packages as a non-root user as the instructions for
#       building a given tarball may silently and invisibly change a shared library, and
#       cause much damage to a system.

# Build preparations
# ——————————————————————————————

# As a non-root user, create a build tree based on a ~/rpmbuild/ directory:

user@myhost:/home/user#> mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
user@myhost:/home/user#> echo ‘%_topdir %(echo $HOME)/rpmbuild’ > ~/.rpmmacros

# As root, install following needed packages:

root@myhost:/#> yum install rpm-build redhat-rpm-config asciidoc hmaccalc \
           perl-ExtUtils-Embed xmlto audit-libs-devel binutils-devel elfutils-devel \
           elfutils-libelf-devel newt-devel python-devel zlib-devel

# Obtain the kernel source rpm package and install it as a non-root user. For instance,
# for my RHEL 6 i386:

user@myhost:/home/user#> rpm -q kernel
kernel-2.6.32-358.el6.i686

user@myhost:/home/user#> rpm -i kernel-2.6.32-431.20.3.el6.src.rpm

# Unpack and prepare the source files:

user@myhost:/home/user#> cd ~/rpmbuild/SPECS

user@myhost:/home/user/rpmbuild/SPECS#> rpmbuild -bp –target=$(uname -m) kernel.spec
Building target platforms: i686
Building for target i686
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.RsE9ro
+ umask 022
+ cd /home/user/rpmbuild/BUILD
+ LANG=C
+ export LANG
+ unset DISPLAY
+ patch_command=’patch -p1 -F1 -s’
+ ‘[‘ ‘!’ -d kernel-2.6.32-431.20.3.el6/vanilla-2.6.32-431.20.3.el6/ ‘]’
+ rm -f pax_global_header
+ cd /home/user/rpmbuild/BUILD
[…]
+ gcc -o scripts/bin2c scripts/bin2c.c
+ scripts/bin2c ksign_def_public_key __initdata
+ cd ..
+ exit 0

# The kernel source tree will now be found under the ~/rpmbuild/BUILD/kernel*/linux*/
# directory.

# If you have any kernel patches to add, copy them now to ~/rpmbuild/SOURCES/ directory.

# Otherwise, if needed, you can create your own kernel patch following this procedure:

# Copy the source tree to preserve the original tree while making changes to the new one

user@myhost:/home/user/#> cd ~/rpmbuild/BUILD

user@myhost:/home/user/rpmbuild/BUILD#> cp -pr kernel-2.6.32-431.20.3.el6 kernel-2.6.32-431.20.3.el6.new

# Make necessary modifications to your custom kernel. Me, for instance, I’m just modifying
# a single commentary line in following file:

user@myhost:/home/user/rpmbuild/BUILD#> vi ./kernel-2.6.32-431.20.3.el6.new/linux-2.6.32-431.20.3.el6.i686/kernel/time.c

# After the .new source tree is modified, generate the patch. To generate the patch,
# run diff against the entire .new and original source trees with the following command:

user@myhost:/home/user/rpmbuild/BUILD#> diff -uNrp kernel-2.6.32-431.20.3.el6 kernel-2.6.32-431.20.3.el6.new > ../SOURCES/mypatch.patch

# Now, edit the patch file to remove the leading directory, this is required because
# the kernel spec file applies patches with ‘-p1’ only.

user@myhost:/home/user/rpmbuild/BUILD#> vi ~/rpmbuild/SOURCES/mypatch.patch

# For example, change the following:

— kernel-2.6.32-431.20.3.el6/linux-2.6.32-431.20.3.el6.i686/kernel/time.c     2014-06-06 23:42:44.000000000 +0200
+++ kernel-2.6.32-431.20.3.el6.new/linux-2.6.32-431.20.3.el6.i686/kernel/time.c 2014-09-25 17:27:06.955461886 +0200

# To:

— linux-2.6.32-431.20.3.el6.i686/kernel/time.c     2014-06-06 23:42:44.000000000 +0200
+++ linux-2.6.32-431.20.3.el6.i686/kernel/time.c     2014-09-25 17:27:06.955461886 +0200

# My new patch is ready

# Configure the kernel
# ——————————————————————————————

# Change directory to ~/rpmbuild/BUILD/kernel-*/linux-*/ and copy into this directory,
# as .config, following file:

user@myhost:/#> cd ~/rpmbuild/BUILD/kernel-*/linux-*/

user@myhost:/#> cp configs/kernel-2.6.32-`uname -m`.config .config

# First run ‘make oldconfig’

user@myhost:/#> make oldconfig
scripts/kconfig/conf -o arch/x86/Kconfig
#
# configuration written to .config
#

# Now you should run ‘make menuconfig’ and do the necessary selections. Once complete,
# remember to save your changes.

# make menuconfig is one of five similar tools that can configure the Linux kernel source,
# a necessary early step needed to compile the source code. ‘make menuconfig‘, with a
# menu-driven user interface, allows the user to choose the features of the Linux kernel
# (and other options) that will be compiled. It is normally invoked using the command
# ‘make menuconfig‘, ‘menuconfig‘ is a target in the Linux kernel Makefile.

# ‘make menuconfig‘ was not in the first version of the Linux kernel. The predecessor tool
# is a question-and-answer-based utility (‘make config‘, ‘make oldconfig‘). A third tool
# for Linux configuration is ‘make xconfig‘, which requires Qt. There is also
# ‘make gconfig‘, which uses GTK+, and ‘make nconfig‘, which is similar to ‘make menuconfig‘.

user@myhost:/#> make menuconfig
scripts/kconfig/mconf arch/x86/Kconfig
#
# configuration written to .config
#

*** End of Linux kernel configuration.
*** Execute ‘make’ to build the kernel or try ‘make help’.

# If you have installed the full kernel source to build a kernel module, you should do
# it at this point.

# Next, add a line that contains the commented out equivalent of the hardware platform to
# the top of the configuration file (equivalent to the output returned by a ‘uname -i
# command) just before you copy it back to the configs/ directory. This will either be
# “i386” for the 32-bit architecture or “x86_64” for the 64-bit architecture. It needs
# to be commented out with a “#” and must be the first line of the file. Note that there
# must be a space between the hash symbol and the hardware platform descriptor.

user@myhost:/#> vi .config

# Add, as the first line of the .config file, either:

# i386

# – or –

# x86_64

# Copy the .config file back to the configs/ directory:

user@myhost:/#> cp .config configs/kernel-2.6.32-`uname -m`.config

# The final step is to copy the entire contents of the configs/ directory to the
# ~/rpmbuild/SOURCES/ directory.

user@myhost:/#> cp configs/* ~/rpmbuild/SOURCES/

# Modifying the kernel specification file
# ——————————————————————————————

# The kernel specification file should now be modified.

user@myhost:/#> cd ~/rpmbuild/SPECS/
user@myhost:/#> cp kernel.spec kernel.spec.distro

user@myhost:/#> vi kernel.spec

# At line 18, the definition of buildid is commented out. This must be uncommented and
# given a value to avoid a conflict with your currently installed kernel. Change the line
# in a similar manner to the example below:

%define buildid .mykernel

# There should be no space between the “%” and the word “define”.

# If you have any patches to apply, you need to make reference to them in two places:

# 1.- Just before line 613 (which reads “# empty final patch file to facilitate testing of
# kernel patches”), add your declaration starting with the number 40000, so that your
# patch is not in any danger of conflicting with the RHEL kernel patch space. Example:

Patch40000: mypatch.patch

# 2.- Just before line 935 (which reads, “ApplyOptionalPatch linux-kernel-test.patch”),
# add a line to apply your patch. For example:

ApplyOptionalPatch mypatch.patch

# Replace line 929:

cp $RPM_SOURCE_DIR/config-* .

# with:

cp $RPM_SOURCE_DIR/kernel-*.config .

# Comment out line 933:

#make -f %{SOURCE20} VERSION=%{version} configs

# Build the new kernel
# ——————————————————————————————

# WARNING: Pay attention to the free space on the filesystem you are building the new
#          kernel. For me it took about 7GB:
#
# user@myhost:/home/user/rpmbuild#> #> du -hs .
# 6.9G    .

# Start the build:

user@myhost:/#> cd ~/rpmbuild/SPECS/

user@myhost:/#> rpmbuild -bb –target=`uname -m` kernel.spec 2> build-err.log | tee build-out.log
Building target platforms: i686
Building for target i686
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.Ua66Tz
###
[…]
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.8SaeUj
BUILDING A KERNEL FOR i686…
USING ARCH=i386
3f47dc2f8a3f1f9fc4205205cdf132ebb09545ce
2b3af23cd31109682bf94574bed4f13ff25b4c35
abc7b98eb5ff6aaa3cafa8d3c37e7a12428ff496
5b1d6b49a129f51f9db7f96c5ce0160ef02dd17e
cb36c6d75b023a9ad75d5475b2960dd2cbd09a4f
cb36c6d75b023a9ad75d5475b2960dd2cbd09a4f
[…]
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/user/rpmbuild/BUILDROOT/kernel-2.6.32-431.20.3.el6.mykernel.i386
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-headers-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-debuginfo-common-i686-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/perf-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/perf-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/python-perf-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/python-perf-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-devel-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-debug-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-debug-devel-2.6.32-431.20.3.el6.mykernel.i686.rpm
Wrote: /home/user/rpmbuild/RPMS/i686/kernel-debug-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.R5KFyB

# For kernels >= 2.6.18-53.el5, you can add some useful options to the rpmbuild command by
# using the –with and/or –without flags and associated arguments. The main options are:

   –with baseonly
   –with xenonly
   –without up
   –without xen
   –without debug
   –without debuginfo
   –without fips
   –without kabichk

# When the build completes, your custom kernel rpm files will be found in the
# ~/rpmbuild/RPMS/`uname -m`/ directory. Make sure that you install those files, as root,
# using an ‘rpm -ivh kernel-*.rpm‘ command.

# Note: If you have built a kernel version that is older than a currently installed
# version you will also have to use the –oldpackage flag with the rpm command.

# UNDER NO CIRCUMSTANCES use an ‘rpm -Uvh‘ command to install your kernel as this will
# update (overwrite) the currently installed version. Hence if you have a problem with
# your custom kernel, you will not be able to revert to the previous, working, version.

root@myhost:/#> cd /home/user/rpmbuild/RPMS/`uname -m`

root@myhost:/home/user/rpmbuild/RPMS/i686#> ll
total 628924
-rw-rw-r– 1 user group  26844728 Sep 19 04:49 kernel-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group  27460356 Sep 19 05:02 kernel-debug-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group 261491476 Sep 19 05:11 kernel-debug-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   9221168 Sep 19 05:02 kernel-debug-devel-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group 255223848 Sep 19 05:01 kernel-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group  40208252 Sep 19 04:51 kernel-debuginfo-common-i686-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   9181032 Sep 19 04:52 kernel-devel-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   2996324 Sep 19 04:49 kernel-headers-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   3067580 Sep 19 04:51 perf-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   3673100 Sep 19 04:51 perf-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   2292360 Sep 19 04:51 python-perf-2.6.32-431.20.3.el6.mykernel.i686.rpm
-rw-rw-r– 1 user group   2338372 Sep 19 04:51 python-perf-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm

root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv <rpms>

# Note: Starting from kernel-2.6.32-358.el6, if “bfa-firmware” package is already installed on the system,
# then it has to be above a certain version, otherwise the installation of kernel will cause a conflict:
#
#        bfa-firmware < 3.2.21.1-2 conflicts with kernel-2.6.32-431.20.3.el6.mykernel.i686
#
# If bfa-firmware is not required for other packages, we can remove it from our system

root@myhost:/#> rpm -q –whatrequires bfa-firmware
no package requires bfa-firmware

root@myhost:/#> rpm -e bfa-firmware

# Apart from that I’m running into problems because kernel requires a newer version of kernel-firmware
# This is the message I’m receiving:
#
#        kernel-firmware >= 2.6.32-431.20.3.el6.mykernel is needed by kernel-2.6.32-431.20.3.el6.mykernel.i686
#
# so I decided to rebuild the kernel adding the option –with firmware in order to generate the
# kernel-firmware package too

# Connected as our non-root user:

user@myhost:/#> cd ~/rpmbuild/SPECS/

user@myhost:/home/user/rpmbuild/SPECS#> rpmbuild -bb –target=`uname -m` –with firmware kernel.spec 2> build-err2.log | tee build-out2.log

# As root

root@myhost:/#> cd /home/user/rpmbuild/RPMS/`uname -m`

root@myhost:/home/user/rpmbuild/RPMS/i686#> ll kernel-firmware*
-rw-rw-r– 1 user group 13627368 Sep 25 03:47 kernel-firmware-2.6.32-431.20.3.el6.mykernel.i686.rpm

# Now, we can start installing packages normally

root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-firmware-2.6.32-431.20.3.el6.mykernel.i686.rpm
Preparing…                ########################################### [100%]
file /usr/share/doc/kernel-firmware-2.6.32/WHENCE from install of kernel-firmware-2.6.32-431.20.3.el6.mykernel.i686 conflicts with file from package kernel-firmware-2.6.32-358.el6.noarch

root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm –replacefiles -ihv kernel-firmware-2.6.32-431.20.3.el6.mykernel.i686.rpm
Preparing…                ########################################### [100%]
1:kernel-firmware        ########################################### [100%]

root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-debug-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-debuginfo-common-i686-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-debug-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-debug-devel-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv kernel-devel-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm –replacefiles -ihv kernel-headers-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv perf-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv perf-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv python-perf-2.6.32-431.20.3.el6.mykernel.i686.rpm
root@myhost:/home/user/rpmbuild/RPMS/i686#> rpm -ihv python-perf-debuginfo-2.6.32-431.20.3.el6.mykernel.i686.rpm

# Verify/modify grub’s grub.conf file to add new custom kernel:

title CentOS (2.6.32-431.20.3.el6.mykernel.i686)
root (hd0,0)
kernel /vmlinuz-2.6.32-431.20.3.el6.mykernel.i686 ro root=/dev/mapper/rootvg-lv_root rd_NO_LUKS  KEYBOARDTYPE=pc KEYTABLE=fr LANG=en_US.UTF-8 rd_LVM_LV=rootvg/lv_swap rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto rd_LVM_LV=rootvg/lv_root rd_NO_DM quiet
initrd /initramfs-2.6.32-431.20.3.el6.mykernel.i686.img

ZOSTAW ODPOWIEDŹ

Please enter your comment!
Please enter your name here