Dysfunctional Programming


Rolling Your Own Kernel

Posted by roryrjb - Saturday, 2nd January 2019

I’ve been playing around lately with some C and looking at various kernel related things, it’s a lot of fun especially as 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. From what I’ve encountered so far it’s mostly 2.x.x references, but this alongside sysctl configs (I wanted to enable user namespaces on my kernel), 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 when I tried this the last time a few years ago, but I’d never gone all the way with the process.

Incidentally I was thinking along similar lines a while ago (see: my post here), where I was experimenting with up-to-date kernels pre-packaged by Ubuntu.

There’s a great overview here 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 long and you can potentially 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 kernel.org and extract it:

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

We now need a .config file, I think the best place to start 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 a 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 many many options, so take your time and do your research and of course it only really makes sense to change the things that you need, rather than blind experimentation, unless of course you have the time:

$ make menuconfig

Compile

Once you have finished configuring, you can simply make -jX with X being how many threads you want to dedicate to the compiling process. I’m currently using a laptop with an Intel Core i7-6500U which has two physical cores but with Hyperthreading has 4 cores. Whenever I compile a kernel I use 4 here, which uses a lot of processor time but I can still comfortably continue doing whatever I was doing before (for me that doesn’t include any gaming!).

Install

After compiling is done you can finally install the kernel:

$ sudo make modules_install install

You’ll then have to restart your computer. However 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. There is no mention of splash here, also meaning it won’t show the splash screen, it just makes everything more explicit and easier to navigate if things do go wrong.


Last updated: Sat 08 Jun 2019 08:03:59 BST