Compiling the Linux Kernel

[Tux]

Why even bother?

Most people will tell you that compiling your own kernel is a waste of time. For most, the LTS or Zen kernel is perfectly fine. But if you want a system with absolutely zero bloat, stripping out drivers for hardware you'll never own is oddly satisfying. Plus, there is no better way to learn how Linux actually interacts with your hardware.

Preparation

Before touching the source, you need the tools. On Arch, this is pretty straightforward. You'll need base-devel and a few extras for the configuration interface:

sudo pacman -S base-devel xmlto kmod inetutils bc libelf git flex bison

If you're on Gentoo, you're likely already using genkernel or doing it manually anyway. If you're on a binary distro like Debian or Fedora, the process is mostly the same, but you’ll want to install build-essential and libncurses-dev. Just be prepared for the fact that these distros sometimes expect a very specific initrd layout that manual compilation might skip over.

Getting the Source

Grab the latest stable tarball from kernel.org.

wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.x.y.tar.xz
tar -xvf linux-6.x.y.tar.xz
cd linux-6.x.y

Configuration

This is where the magic happens. You have two choices here. You can start with your current distro's config, or start from scratch. If you want a slim kernel, use localmodconfig. This looks at every module currently loaded on your system and disables everything else.

Note: Plug in your USB drives, controllers, and webcams before running this, or their drivers won't be included!

make localmodconfig

After that, run make menuconfig to fine-tune. This is where you might spend some time disabling amateur radio support, weird filesystem drivers, and legacy hardware support from the 90s.

In menuconfig, look under Processor type and features. Instead of the generic 'x86-64', set it to your actual architecture or use Native optimizations. This tells the compiler to use every instruction your specific CPU supports.

Compilation

Use the -j flag to use all your cores, otherwise you'll be here until next Tuesday.

make -j$(nproc)

Once it finishes, build the modules:

sudo make modules_install

Installation and Boot

Now we just need to move the kernel to /boot. We'll call it vmlinuz-linux-custom to avoid any conflicts with the official packages.

sudo cp -v arch/x86/boot/bzImage /boot/vmlinuz-linux-custom

Don't forget to generate your initramfs. You'll need to create a new preset file in /etc/mkinitcpio.d/ or just run it manually:

sudo mkinitcpio -k 6.x.y-custom -g /boot/initramfs-linux-custom.img

Update your Bootloader

If you're using GRUB, just run sudo grub-mkconfig -o /boot/grub/grub.cfg. It should pick up the new "custom" kernel automatically. If you're using EFISTUB or systemd-boot, you'll need to add the entry manually. If you're based and using Limine, (it's incredibly minimalist) to boot your custom kernel with Limine, your limine.conf entry should look something like this:

:Custom Linux
protocol: linux
path: boot():/vmlinuz-linux-custom
cmdline: root=UUID=your-uuid-here rw initrd=boot():/initramfs-linux-custom.img

Reboot, pray, and do uname -r. If it says "custom," you've somehow understood this guide.