I wrote two blog posts about Linux kernel build on Ubuntu [1,2]. There is also an official wiki page talking about the same thing . Still, things are broken when I try to create a homework assignment for my class. This post is about how to correctly, easily and quickly build Linux kernel on Ubuntu 16.04 and 18.04. This whole process is used and verified by myself. Happy hacking.
1. Install building dependencies
sudo apt-get build-dep linux linux-image-$(uname -r)
sudo apt-get install libncurses-dev flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf
2. Fetch the Linux kernel source
Make sure /etc/apt/sources.list contains at least these 2 source entries (e.g., uncommenting). Note that the CODENAME is “xenial” for 16.04 and “bionic” for 18.04. Once the source entries are there, update the list file and fetch the kernel source.
deb-src http://us.archive.ubuntu.com/ubuntu CODENAME main deb-src http://us.archive.ubuntu.com/ubuntu CODENAME-updates main
sudo apt update sudo apt-get source linux-image-unsigned-$(uname -r)
Note that unlike the typical “linux-image-$(uname -r)”, there is “unsigned” added to fetch the kernel source to work around the bug caused by the kernel signing . You might also wonder why I am not doing git directly. The reason is simple: the apt-get approach gives the exact kernel source files that your system is running now, while git usually provides the most recent version (e.g., master) for certain distro versions. Unless you need to play with cutting-edge features from the most recent kernels, it is wise to stick with the current kernel that proves working on your system. The other benefit of this approach is about generating the config – we could simply reuse the existing config without any trouble.
3. Build the kernel
I do not use the official Ubuntu kernel build procedure , which is tedious and moreover does not support incremental build. Note that X should be the kernel version you have downloaded (apt-get), and Y could be the number of cores available in your system for a parallel build.
cd linux-hwe-X sudo make oldconfig sudo make -jY bindeb-pkg
4. Install the new kernel
cd .. sudo dpkg -i linux*X*.deb sudo reboot
5. Sign kernel modules (optional)
If you are working with Ubuntu 16.04, it is likely that you do not need to deal with kernel module signing. But in case you need to, take a look at . On Ubuntu 18.04, Lockdown is enabled by default to prevent the kernel from loading unsigned kernel modules. A quick and dirty fix is to disable Lockdown to load modules :
sudo bash -c 'echo 1 > /proc/sys/kernel/sysrq' sudo bash -c 'echo x > /proc/sysrq-trigger'
6. Resize VM disk (optional)
To build a kernel, a VM might need at least 32GB space (tested on Ubuntu 16.04, ). qemu-img is a convenient command to resize your VM image size.
sudo qemu-img resize /PATH_TO_YOUR_VM_IMG_FILE +20G sudo qemu-img resize --shrink /PATH_TO_YOUR_VM_IMG_FILE -20G sudo qemu-img info /PATH_TO_YOUR_VM_IMG_FILE
Note that the actual image size change cannot be seen from the host machine using e.g., fdisk. Instead, use qemu-img info to confirm the difference between “virtual size” and “disk size”. The former is changed by the resizing and the later has to be changed as well. We need to boot into the VM and grow the partition.
Once we are inside the VM, use lsblk to confirm the size that we have just grown. In the figure down below, the whole /dev/vda size is 40G but all the partitions only take 20G. We can grow the root partition (/) using parted. Unfortunately, it did not work as you can find in the figure.
Why? Because we could not grow a partition which is not the last. Instead, we need to delete vda5 and vda2 if we wanna grow vda1. Again, parted is your friend here . After we are able to append the extra 20G to the root partition (vda1), we need to fix the partition and resize the filesystem accordingly:
sudo apt-get install cloud-guest-utils sudo growpart /dev/vda 1
sudo resize2fs /dev/vda1