Build a custom kernel package for Debian

Last updated on 2019-09-22 Tagged under  # debian  # linux

Perhaps it is hardware unsupported by any of the Linux kernels provided by Debian. Or trying to troubleshoot a kernel's misbehaviour by running the latest and greatest. Or a desire to try out a brand new kernel capability. Or simple curiosity!

Whatever the reason, this is how I build a custom kernel package for Debian from the "vanilla" kernel source available on

Download build tools

$ sudo apt install build-essential bison flex gnupg libncurses-dev libelf-dev libssl-dev wget


Import crypto signing keys belonging to kernel release developers ...

$ gpg --locate-keys


Download to my home directory the latest stable kernel source and signature (5.3 as of 2019-09-22) ...

$ mkdir ~/kernel
$ cd ~/kernel
$ wget
$ wget

Verify ...

$ unxz -c linux-5.3.tar.xz | gpg --verify linux-5.3.tar.sign -
gpg: Signature made Mon 16 Sep 2019 02:01:09 AM EDT
gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E
gpg: Good signature from "Greg Kroah-Hartman <>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E

Unpack kernel ...

$ tar xaf linux-5.3.tar.xz
$ cd linux-5.3


Rather than configure everything from scratch, copy the /boot/config-VERSION of the kernel currently in use to the kernel source directory ...

$ uname -r
$ cp /boot/config-5.2.0-2-amd64 ~/kernel/linux-5.3/.config

If anything needs to be modified in the configuration, bring up the configuration menu by running ...

$ make nconfig

Otherwise, when using a .config file that has been generated with another (older) kernel version, it needs to be updated with any changes that have been been made to the newer kernel. Running ...

$ make oldconfig

... interactively asks questions relating to the new options.

To preemptively accept the default answer to all those questions, run ...

$ make olddefconfig

Modify the copied Debian kernel configuration and set ...


... or the build fails with the error ...

make[4]: *** No rule to make target 'debian/certs/debian-uefi-certs.pem', needed by 'certs/x509_certificate_list'.  Stop.

Optional: skip debugging

Skip building the linux-image-VERSION-dbg package which contains the debugging symbols for the kernel image and its modules. Not required unless debugging kernel code. Significant savings in compile time and space. Building binary packages for a single kernel flavour that includes *-dbg package requires upwards of 24GB of space in the package directory vs roughly 3-4GB without.

To disable the build of *-dbg package, modify the configuration by setting ...



Build the kernel (LOCALVERSION parameter appends custom text to the generated package name) ...

$ make clean
$ make deb-pkg LOCALVERSION=-custom

New packages ...

$ ls ../*deb
../linux-headers-5.3.0-custom_5.3.0-custom-1_amd64.deb      # header files required to build external modules
../linux-image-5.3.0-custom_5.3.0-custom-1_amd64.deb        # kernel image and the associated modules
../linux-image-5.3.0-custom-dbg_5.3.0-custom-1_amd64.deb    # if CONFIG_DEBUG_INFO=y
../linux-libc-dev_5.3.0-custom-1_amd64.deb                  # headers relevant to some user-space libraries like GNU glibc


$ sudo dpkg -i ../linux-image-5.3.0-custom_5.3.0-custom-1_amd64.deb

... which unpacks the kernel, generates the initrd, and configures the bootloader to make the new kernel the default one.



» Later: Moving day

« Earlier: Heavenly breezes