Table of Contents
- 1. Install packages for building kernel
- 2. Download kernel src.rpm
- 3. Change kernel version
- 4. Change kernel configuration
- 5. Change kernel source code
- 6. Build kernel
- 7. Execution result
1 Install packages for building kernel
Install packages for building kernel with dnf.
$ sudo dnf install -y rpmdevtools$ sudo dnf install -y numactl-devel pesign$ sudo dnf builddep -y kernel
2 Download kernel src.rpm
Download kernel src.rpm.
$ dnf download –source kernel$ rpm -i kernel-*.src.rpm$ cd rpmbuild
3 Change kernel version
Define buildid variable in spec file. The buildid variable change not only rpm file name but also kernel file name.
$ diff -uprN SPECS/kernel.spec{.org,}— SPECS/kernel.spec.org 2016-06-24 14:59:18.778477097 +0900+++ SPECS/kernel.spec 2016-06-24 15:01:04.257355709 +0900@@ -24,7 +24,7 @@ Summary: The Linux kernel %global zipsed -e ‘s/.ko$/.ko.xz/’ %endif-# define buildid .local+%define buildid .local # baserelease defines which build revision of this kernel version we’re # building. We used to call this fedora_build, but the magical name
4 Change kernel configuration
Run “rpmbuild -bp” for extracting source tree and applying patches. The .config file is created from config-x86_64-generic in x86_64 system.
$ rpmbuild -bp SPECS/kernel.spec$ cd BUILD/kernel-*/linux-*$ cp .config{,.org}$ make menuconfig # Change config
This article appends CONFIG_IKCONFIG=y and CONFIG_IKCONFIG_PROC=y with make menuconfig.
General setup —> Kernel .config support # Change to y Enable access to .config through /proc/config.gz # Change to y
Check difference from original .config.
$ diff -uprN .config{.org,}— .config.org 2016-06-24 15:36:48.185480769 +0900+++ .config 2016-06-24 15:42:39.928537381 +0900@@ -1,6 +1,6 @@ # # Automatically generated file; DO NOT EDIT.-# Linux/x86_64 4.5.7 Kernel Configuration+# Linux/x86 4.5.7 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y@@ -147,7 +147,8 @@ CONFIG_RCU_NOCB_CPU=y CONFIG_RCU_NOCB_CPU_ALL=y # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y-# CONFIG_IKCONFIG is not set+CONFIG_IKCONFIG=y+CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
In this case, it needs to append only CONFIG_IKCONFIG=y and CONFIG_IKCONFIG_PROC=y to config-x86_64-generic. In other cases, it needs to delete CONFIG_XXX from config-x86_64-generic.
$ cd ../../..$ echo “CONFIG_IKCONFIG=y” >> SOURCES/config-x86_64-generic$ echo “CONFIG_IKCONFIG_PROC=y” >> SOURCES/config-x86_64-generic$ diff -uprN SOURCES/config-x86_64-generic{.org,}— SOURCES/config-x86_64-generic.org 2016-06-24 15:31:00.094273529 +0900+++ SOURCES/config-x86_64-generic 2016-06-24 15:45:57.139900141 +0900@@ -234,3 +234,5 @@ CONFIG_HFI1_VERBS_31BIT_PSN=y # Temporary workaround until SND_SOC_INTEL_HASWELL_MACH no longer requires builtin CONFIG_DW_DMAC=y+CONFIG_IKCONFIG=y+CONFIG_IKCONFIG_PROC=y#+END_SRC
Run rpmbuild -pb again for checking new .config.
$ rpmbuild -bp SPECS/kernel.spec# No error$ grep -nr ‘CONFIG_IKCONFIG’ BUILD/kernel-*/linux-*/.config150:CONFIG_IKCONFIG=y151:CONFIG_IKCONFIG_PROC=y
5 Change kernel source code
Run “rpmbuild -bp” for extracting source tree and applying patches. The extracted source tree is a git repository which can be used for patch creatation.
$ rpmbuild -bp SPECS/kernel.spec$ cd BUILD/kernel-*/linux-*
Commit uncommitted files like config-xxx and .gitignore (or erase them) for cleanup main branch.
$ git add * .[^.]* .gitignore$ git commit -m “Cleanup main branch”$ git statusOn branch masternothing to commit, working directory clean
Create new branch which names “hello” from main branch.
$ git checkout master -b helloSwitched to a new branch ‘hello’$ git branch* hello master
Change source code and commit them to repository. This article add printk which outputs “Hello, World” before ramdisk.
$ git diffdiff –git a/init/main.c b/init/main.cindex 58c9e37..d1254da 100644— a/init/main.c+++ b/init/main.c@@ -945,6 +945,8 @@ static int __ref kernel_init(void *unused) rcu_end_inkernel_boot();+ printk(“Hello, Worldn”);+ if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); if (!ret)$ git add *$ git commit -m “Hello, World”[hello 2fa1c98] Hello, World 1 file changed, 2 insertions(+)
Create patch with to SOURCES directory.
$ git format-patch master –start-number 1000 -o ../../../SOURCES/../../../SOURCES/1000-Hello-World.patch
Add the patch entry to kernel.spec
$ diff -uprN SPECS/kernel.spec{.org,}— SPECS/kernel.spec.org 2016-06-24 16:45:44.303806793 +0900+++ SPECS/kernel.spec 2016-06-24 17:45:46.523021602 +0900@@ -663,6 +663,9 @@ Patch721: tipc-fix-an-infoleak-in-tipc_n #CVE-2016-5244 rhbz 1343338 1343337 Patch722: rds-fix-an-infoleak-in-rds_inc_info_copy.txt+#Hello, World+Patch1000: 1000-Hello-World.patch+ # END OF PATCH DEFINITIONS %endif
Make a backup of source tree. Remove BUILD directory and run rpmbuild -bp again for checking whether the patch can be applied.
$ # mv BUILD/kernel-*/linux-* ~/$ rm -rf BUILD/*$ rpmbuild -bp SPECS/kernel.spec$ # No error
6 Build kernel
Reduce build time with using –without option. It takes 6 hours without –without option and 3 hour without –without option.
$ rpmbuild -ba –without debug –without doc –without perf –without tools –without debuginfo –without kdump –without bootwrapper –without cross_headers SPECS/kernel.spec $ ls RPMS/x86_64/kernel-4.5.7-300.local.fc24.x86_64.rpmkernel-core-4.5.7-300.local.fc24.x86_64.rpmkernel-devel-4.5.7-300.local.fc24.x86_64.rpmkernel-headers-4.5.7-300.local.fc24.x86_64.rpmkernel-modules-4.5.7-300.local.fc24.x86_64.rpmkernel-modules-extra-4.5.7-300.local.fc24.x86_64.rpm
Install rpm and reboot Fedora 24.
$ sudo dnf install -y RPMS/x86_64/*.rpm$ sudo reboot
7 Execution result
Kernel prints “Hello, World”.
[ 1.472560] Freeing unused kernel memory: 164K (ffff8800017d7000 – ffff880001800000)[ 1.475601]
Freeing unused kernel memory: 544K (ffff880001b78000 – ffff880001c00000)[ 1.477372] Hello, World[ 1.480600] random: systemd urandom read with 4 bits of entropyavailable[ 1.483575] systemd[1]: systemd 229 running in systemmode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP+LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS+KMOD +IDN)
Kernel version has a string of “.local”.
$ uname -r4.5.7-300.local.fc24.x86_64
/proc/config.gz is readable.
$ ls -l /proc/config.gz-r–r–r–. 1 root root 42418 6月 25 04:03 /proc/config.gz