Rolling Your Own Kernel


Posted on Dysfunctional Programming 2019-01-02

I’ve been playing around lately with some C and looking at various kernel related things. It’s a lot of fun. I’m still learning and discovering things and just thinking about all the nice and interesting possibilities there are with all this. More specifically I’m looking around container type things: seccomp, cgroups, capabilities, that sort of thing. I’ll follow up on some of this in a future post.

Anyway, looking at various man pages. I’ve seen many references to the kernel version that the feature was introduced in. So far it’s mostly been 2.x.x references, but this alongsid sysctl configs (to enable user namespaces on my kernel for example), made me think about how to compile my own kernel to change various settings by default. I had a rough idea about a .config file from the last time I tried this a few years ago. but I’d never gone all the way with the process.

There’s a great overview here: https://kernelnewbies.org/KernelBuild that I used for reference but it’s very easy and as long as you know how to boot with another kernel, totally safe. At worst you won’t be able to boot for some reason and you’ll then have to reboot and choose another kernel version at boot time. Also despite what it says on the previously referenced guide at Kernel Newbies, it doesn’t take too long and unless you’re on very low-powered hardware, can always compile your kernel while working on other things.

Step by step

Here’s a streamlined guide based on my experience (and also for my future reference).

Configure the kernel

Download whatever kernel you like from https://www.kernel.org and extract it:

$ curl -L https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.20.10.tar.xz | tar Jx

You now need a .config file, a good starting point is with your current kernel’s config, likely a safer option than wildly turning things on and off:

$ cp /boot/config-$(uname -r)* .config)

…you can then customise your kernel’s option in an ncurses interface which has built-in information about all the different options. It makes it easy to change things but be wary that there are very many options, so take your time and do your research.

$ make menuconfig

Compile

Once you have finished configuring, you can simply make. Ensure you specify via the -j flag an appropriate thread count.

Install

After compiling is done you can install the kernel:

$ sudo make modules_install install

You’ll then have to restart your computer, but before you do I recommend making sure to check your /etc/default/grub file so that it is configured to display its options rather than displaying the splash screen. It just makes things easier if things go wrong and you have to boot into another kernel. For reference the uncommented lines of my grub config file consist of:

GRUB_DEFAULT=0
GRUB_TIMEOUT=15
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""

…meaning grub will wait up to 15 seconds before booting the default kernel. It makes everything more explicit and easier to navigate if things do go wrong.