Ubuntu 16.04: Rebuild kernel with devscripts

This article will describe rebuilding kernel with devscripts.

Because trying rebuilding kernel with devscripts as much as possible, this is a bit strange way besides rebuilding mainline kernel.

 

1 Install package for building kernel

"make menuconfig" needs libncurses5-dev.

$ sudo apt build-dep -y linux
$ sudo apt install -y libncurses5-dev

2 Download kernel source code

Download kernel with git is better than with deb-src because git tag is available for switching release version.

If you run "fakeroot debian/rules distclean", you need to run below command again.

If you run "fakeroot debian/rules clean", you do not need to run.

$ fakeroot debian/rules debian/control
$ cp debian.master/changelog debian/

2.1 Download with deb-src

You need to run "chmod -R u+x debian/scripts/*".

You need to run "fakeroot debian/rules distclean" for avoiding compile error because of generated files remaining.

$ mkdir linux.ubuntu-16.04
$ cd linux.ubuntu-16.04
$ apt source linux
$ cd linux-4.4.0
$ chmod -R u+x debian/scripts/*
$ fakeroot debian/rules distclean
$ fakeroot debian/rules debian/control
$ cp debian.master/changelog debian/

2.2 Download with git

Download with git is nearly the same with deb-src.

$ git clone git://git.launchpad.net/~ubuntu-kernel/ubuntu/+source/linux/+git/xenial
$ cd xenial
$ fakeroot debian/rules debian/control
$ cp debian.master/changelog debian/

3 Edit changelog

debian/changelog will change the deb file name suffix.

You can edit changelog with debchange command.

$ sudo apt-get install -y devscripts
$ EDITOR=emacs debchange

Append below log to debian/changelog.

This will change the suffix from 4.4.0-22.39 to 4.4.0-22.39ubuntu1.

linux (4.4.0-22.39ubuntu1) UNRELEASED; urgency=medium

  * Hello, Linux

 --  <hiroom2@ubuntu-16.04>  Mon, 16 May 2016 17:52:06 +0900

4 Edit kernel configuration

You can edit kernel configuration with "fakeroot debian/rules editconfigs".

Edit only amd64/config.flavour.generic.

$ fakeroot debian/rules editconfigs
dh_testdir;
/bin/bash -e debian/scripts/misc/kernelconfig editconfigs
Do you want to edit config: amd64/config.flavour.generic? [Y/n] Y

"make menuconfig" dialog is displayed.

0001_make-menuconfig.png

Save the kernel configuration. Skip other configuration.

Do you want to edit config: amd64/config.flavour.lowlatency? [Y/n] n
<snip>
check-config: 31/43 checks passed -- exit 1

*** ERROR: 12 config-check failures detected

The config-check scripts will output error but it also outputs error with default configuration.

5 Edit source code

If you already built kernel, you need to remove debian/stamp/stamp-build-generic for recompiling source code.

Change source code as below.

diff --git a/init/main.c b/init/main.c
index 9e64d70..1ecc819 100644
--- a/init/main.c
+++ b/init/main.c
@@ -933,6 +933,8 @@ static int __ref kernel_init(void *unused)
 {
        int ret;

+       printk("Hello, Linux");
+
        kernel_init_freeable();
        /* need to finish all async __init code before freeing the memory */
        async_synchronize_full();

6 Change file name version (bad know-how)

Editing changelog can change deb file name but not change file name in deb file.

If you install deb file which name is changed by editing changelog, vmlinux-xxx and initrd-xxx will be overwrite because vmlinux-xxx and initrd-xxx name is not changed by editing changelog.

 

CONFIG_LOCALVERSION is used for changing vmlinux-xxx and initrd-xxx on mainline kernel, but devscripts will output error when CONFIG_LOCALVERSION is enabled.

 

So use abi_suffix variable which is used for suffix name of vmlinux-xxx and initrd-xxx in debian/rules. Export abi_suffix as "-hello" for append "-hello" to suffix.

$ export abi_suffix=-hello

If abi_suffix is used, xenial/drivers/hv/hv.c will be compile error.

Edit debian/rules.d/0-common-vars.mk as below for avoid this error.

diff --git a/debian/rules.d/0-common-vars.mk b/debian/rules.d/0-common-vars.mk
index 1c87ebd..2b1fa67 100644
--- a/debian/rules.d/0-common-vars.mk
+++ b/debian/rules.d/0-common-vars.mk
@@ -224,7 +224,7 @@ kmake = make ARCH=$(build_arch) \
        CONFIG_DEBUG_SECTION_MISMATCH=y \
        KBUILD_BUILD_VERSION="$(uploadnum)" \
        LOCALVERSION= localver-extra= \
-       CFLAGS_MODULE="-DPKG_ABI=$(abinum)"
+       CFLAGS_MODULE="-DPKG_ABI=$(shell echo $(abinum) | sed 's/$(abi_suffix)//g')"
 ifneq ($(LOCAL_ENV_CC),)
 kmake += CC=$(LOCAL_ENV_CC) DISTCC_HOSTS=$(LOCAL_ENV_DISTCC_HOSTS)
 endif

If export abi_suffix, you need to run "fakeroot debian/rules debian/control" for update package name in control information.

$ fakeroot debian/rules debian/control

7 Build kernel

If you already build kernel, you need to remove below files for compiling source code again.

$ rm -rf debian/stamps/stamp-build-generic
$ rm -rf debian/linux-image-extra-*/lib/modules/*/kernel/kernel

For reducing compile time, do_tools=false could stop build linux-cloud-tools.

If you have many cpu cores, making paralles be more lager and compile time is shorter.

$ DEB_BUILD_OPTIONS=parallel=2 do_tools=false no_dumpfile=1 \
fakeroot debian/rules binary-generic

After build is completed, deb file is created.

$ ls ../*.deb
linux-headers-4.4.0-22-hello-generic_4.4.0-22.39ubuntu1_amd64.deb
linux-image-4.4.0-22-hello-generic_4.4.0-22.39ubuntu1_amd64.deb
linux-image-extra-4.4.0-22-hello-generic_4.4.0-22.39ubuntu1_amd64.deb

Install linux-image deb file and files which have a "-hello" suffix are copied to /boot

$ sudo dpkg -i linux-image-4.4.0-22-hello-generic_4.4.0-22.39ubuntu1_amd64.deb
$ ls /boot/
System.map-4.4.0-21-generic        initrd.img-4.4.0-22-generic
System.map-4.4.0-22-generic        initrd.img-4.4.0-22-hello-generic
System.map-4.4.0-22-hello-generic
initrd.img-4.4.0-22-mykernel-generic
abi-4.4.0-21-generic               lost+found
abi-4.4.0-22-generic               memtest86+.bin
abi-4.4.0-22-hello-generic         memtest86+.elf
config-4.4.0-21-generic            memtest86+_multiboot.bin
config-4.4.0-22-generic            vmlinuz-4.4.0-21-generic
config-4.4.0-22-hello-generic      vmlinuz-4.4.0-22-generic
grub                               vmlinuz-4.4.0-22-hello-generic
initrd.img-4.4.0-21-generic

Reboot Ubuntu 16.04.

$ sudo reboot

Display GRUB menu with ESC key after BIOS boot. Select "Advanced options for Ubuntu" and you can find "-hello" kernel entry.

0002_GRUB-menu.png

"Hello, Linux" is output to kernel log and kernel version is changed.

$ dmesg | grep -2 "Hello, Linux"
[    0.029550] Freeing SMP alternatives memory: 28K (ffffffff820b3000 - ffffffff820ba000)
[    0.034677] ftrace: allocating 31906 entries in 125 pages
[    0.064341] Hello, Linux
[    0.064360] smpboot: Max logical packages: 1
[    0.064362] smpboot: APIC(0) Converting physical 0 to logical package 0
$ $ uname -r
4.4.0-22-hello-generic