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.