Kernel
This page contains all the details necessary to use my script to configure the Linux Kernel, optimizing it to maximize the hardware's performance, and be as light as possible.
Go to:
Introduction Setup Extra
Introduction
My setups are based on a system comprised of the following components:
- Distro: Gentoo Linux
- Kernel Compression: LZ4 for the initramfs, zstd for modules
- Initramfs: Dracut
- Bootloader: GRUB
- Init: OpenRC
- Filesystem: FAT32 for the ESP, XFS for the rootfs, ext4 for various things.
- Logind: elogind
Note: since I use Gentoo, the package names may vary from your distro's (Arch, Debian, Fedora, ...) packages. Please verify whether the names may vary, and take note of them.
There are two default configs:
config
: for my ThinkPad T440p, with CPU i7-4700MQ, no GPU (iGPU), 8GB RAM, SSD M.2 2242 + SSD SATAIII.config.pc
: for my desktop PC, with CPU i5-11400, no GPU (iGPU), 16GB RAM, SSD NVME Samsung 980 Pro.
Since the changes made to the Kernel config, it'll be necessary to verify the desired components are enabled in the Kernel, whenever you'd choose my config as a starting point. For example, components relative to AMD, Nvidia, NUMA, etc. have been disabled.
If you don't know where to start, use an already existing config that you know works on your hardware, if available, or else use any Kernel's default config, like that provided by your distro, or the Kernel's very own default config.
Setup
Make sure to have all the tools necessary to proceed. Verify you have git
, gcc
, make
, etc. Tipically, most compilation tools are provided by packages like base-devel
. I suggest you also verify the presence of linux-firmware
, in order to have the necessary firmware for any nonfree hardware. Don't forget to download the microcode that is most appropriate, whether it be Intel, AMD, or any other. Finally, make sure you have lz4
and zstd
, in order to compress various Kernel components.
1. Get the repository
We'll use the /usr/src/usr-kernel
directory in order to save this project. Make sure you have read and write permissions, in order to create the directory.
git clone --recurse-submodules "https://github.com/saloniamatteo/kernel" /usr/src/usr-kernel
cd /usr/src/usr-kernel
Whenever the chosen directory differs from the default, don't forget to modify the CUSTDIR
variable in build.sh
2. Version selection
Once you get the repository, choose an available version. To see which version is available, you just need to list the directory contents with ls
. In this example, we'll use Linux 6.8.2-gentoo
.
Your Kernel will definitely have a different version.
Don't panic: you just need to copy the folder, and rename it according to your version. For example, if your version would be 6.8.3-zen
, you just need to execute: cp -r 6.8.2-gentoo 6.8.3-zen
.
Don't forget to modify the KVER
variable whenever the primary version differs (e.g.: 6.8.2
-> 6.8.3
), and PVER
whenever the secondary/custom version differs (e.g.: gentoo
-> zen
)
3. Modify the script
Now, we need to verify the contents of build.sh
. Modify the file with any text editor, and note the following variables:
ARCHVER
: CPU architecture code, to optimize the Kernel. Here is the full list of codes:1. AMD Opteron/Athlon64/Hammer/K8 (MK8)
2. AMD Opteron/Athlon64/Hammer/K8 with SSE3 (MK8SSE3)
3. AMD 61xx/7x50/PhenomX3/X4/II/K10 (MK10)
4. AMD Barcelona (MBARCELONA)
5. AMD Bobcat (MBOBCAT)
6. AMD Jaguar (MJAGUAR)
7. AMD Bulldozer (MBULLDOZER)
8. AMD Piledriver (MPILEDRIVER)
9. AMD Steamroller (MSTEAMROLLER)
10. AMD Excavator (MEXCAVATOR)
11. AMD Zen (MZEN)
12. AMD Zen 2 (MZEN2)
13. AMD Zen 3 (MZEN3)
14. AMD Zen 4 (MZEN4)
15. Intel P4 / older Netburst based Xeon (MPSC)
16. Intel Core 2 (MCORE2)
17. Intel Atom (MATOM)
18. Intel Nehalem (MNEHALEM)
19. Intel Westmere (MWESTMERE)
20. Intel Silvermont (MSILVERMONT)
21. Intel Goldmont (MGOLDMONT)
22. Intel Goldmont Plus (MGOLDMONTPLUS)
23. Intel Sandy Bridge (MSANDYBRIDGE)
24. Intel Ivy Bridge (MIVYBRIDGE)
25. Intel Haswell (MHASWELL)
26. Intel Broadwell (MBROADWELL)
27. Intel Skylake (MSKYLAKE)
28. Intel Skylake X (MSKYLAKEX)
29. Intel Cannon Lake (MCANNONLAKE)
30. Intel Ice Lake (MICELAKE)
31. Intel Cascade Lake (MCASCADELAKE)
32. Intel Cooper Lake (MCOOPERLAKE)
33. Intel Tiger Lake (MTIGERLAKE)
34. Intel Sapphire Rapids (MSAPPHIRERAPIDS)
35. Intel Rocket Lake (MROCKETLAKE)
36. Intel Alder Lake (MALDERLAKE)
37. Intel Raptor Lake (MRAPTORLAKE)
38. Intel Meteor Lake (MMETEORLAKE)
39. Intel Emerald Rapids (MEMERALDRAPIDS)
40. Generic-x86-64 (GENERIC_CPU)
41. Generic-x86-64-v2 (GENERIC_CPU2)
42. Generic-x86-64-v3 (GENERIC_CPU3)
43. Generic-x86-64-v4 (GENERIC_CPU4)
44. Intel-Native optimizations autodetected by GCC (MNATIVE_INTEL)
45. AMD-Native optimizations autodetected by GCC (MNATIVE_AMD)CONFIGFILE
: config file name, that will be copied from the directory to the Kernel.JOBS
: how many threads to use for the compilation. I recommend setting the number of cores.KVER
: primary Kernel version.PVER
: secondary/custom Kernel version.KERNVER
: full Kernel version, do not modify.CUSTDIR
: this project's directory, modify whenever it differs from the defaults.CLEARDIR
: Clear Linux directory name, do not modify.PATCHDIR
: patch directory name, do not modify.V4L2DIR
: V4L2loopback directory name, do not modify.CFODIR
: Kernel Compiler Patch directory name, do not modify.USRDIR
: chosen Kernel version directory name, do not modify.KERNELDIR
: set this variable whenever the Kernel directory differs from/usr/src
.
4. Flag selection
After modifying build.sh
, we have to set the correct parameters in order to decide what to do.
Here's a table with all the parameters (flags).
Short flag | Long flag | Description |
---|---|---|
Short flag | Long flag | Description |
-b | --skip-build | Do not build the Kernel. |
-c | --skip-cfg | Do not copy the Kernel config file (config ). |
-d | --distcc | Use distcc to speed up Kernel compilation |
-e | --ccache | Use ccache to speed up Kernel compilation |
-f | --fastmath | Compile the Kernel with unsafe fast math options. |
-h | --help | Show the help menu and exit. |
-l | --clearl-ps | Apply Clear Linux patches. |
-m | --menuconfig | Execute make menuconfig in the Kernel directory and exit without compiling. |
-o | --cpu-opts | Compile the Kernel with CPU family optimizations. |
-p | --patches | Apply user patches. |
-r | --bore | Build Kernel with BORE scheduler |
-v | --v4l2 | Compile the v4l2loopback module. |
-z | --vars | Print variables and exit. |
5. Kernel configuration
Tipically, it'll be necessary to configure the Kernel, starting from a config file. To do so, you need to run the following as root:
./build.sh -l -m -o -p
This will allow us to:-l
: Apply Clear Linux patches-m
: Configure the Kernel, starting from an existing config, or load a custom config file-o
: Apply the CPU family optimization patches-p
: Apply user patches
/usr/src/linux/.config
(or under $KERNELDIR/.config
whenever KERNELDIR
would've been set).Now we need to copy .config
from the Kernel directory to the current directory, to then compare the two files and see any changes.
cp /usr/src/linux/.config config.new
diff -u config config.new | vim
The last command above executes the diff
command, showing the differences between our starting config
file, and the new config.new
file, to then show everything with the Vim editor. Obviously, it's necessary to modify the name of the config
file in the command above whenever appropriate.After verifying the differences, let's replace our config file with the config.new
file, and move on to the actual Kernel compilation.
6. Kernel compilation
After making sure we have everything that's necessary, we can proceed with compiling the Kernel with the following command, executing it as root:
./build.sh -f -l -o -p
Note the repeated presence of the patch options (-l
, -o
, -p
). This is because the script automatically reverts all changes made by the patches present in the Kernel directory, where possible, and removes said patches. I programmed the script this way because I often have to revert and remove various patches, especially after multiple compilations.Note that the script will show any compilation error, as well as showing the true compilation time, not considering patches and so on.
Once the script finishes its execution, it'll install the Kernel, automatially executing dracut
to generate the initramfs, and it'll update grub
, thanks to installkernel
, which most distros tipically have. If your setup does not use dracut nor grub, check your installkernel
config, it'll be set up to use whatever you're currently using.
Extra
This section specifies any extra steps to take after Kernel compilation, that do not depend on the script. Using the script, it won't be necessary to execute dracut
nor grub
manually, because they'll be automatically executed.
V4L2loopback
The script will automatically install this module for the compiled Kernel version. The only step you need to take is add the module settings, because the script does not check whether they exist or not.
Modify /etc/modprobe.d/v4l2loopback.conf
, and add the following:
options v4l2loopback exclusive_caps=1 card_label="Camera2"
Here you can modify card_label
to set the device name, whenever necessary, for example if you want to hide the fact this is a virtual device, or if you simply would like a better name.Initramfs
To run the Kernel an initramfs is necessary. To generate it, I'll use dracut.
First of all, make sure you configured dracut. For example, here's my /etc/dracut.conf
:
# Equivalent to -H
hostonly="yes"
# Add various modules
# Module Description
# base include basic utilities
# bash include /bin/bash as /bin/sh
# fs-lib include filesystem tools like mount
# kernel-modules include kernel modules
# rescue include various utils for rescue mode
# resume allow initramfs to resume from low-power state
# rootfs-block mount block device that contains rootfs
# shutdown set up hooks to run on shutdown
# udev-rules include udev and some basic rules
# uefi-lib include UEFI tools
# usrmount mount /usr
dracutmodules+=" base bash fs-lib kernel-modules rescue resume rootfs-block shutdown udev-rules uefi-lib usrmount "
# Include elogind
install_items="/lib64/elogind/elogind-uaccess-command"
# Use lz4 to compress the initramfs
compress="lz4"
# Add early microcode loading
early_microcode="yes"
It's sufficient to execute the following command as root:
dracut --kver 6.8.2-gentoo -f
Replace 6.8.2-gentoo
whenever the Kernel version is different. Be careful to the -f
flag, that forces the initramfs regeneration, even if it already exists for the chosen Kernel.The initramfs will be available under
/boot
, together with the previously compiled Kernel's files.Bootloader
To boot our new Kernel, we need to configure the bootloader. In this section, I'll only talk about GRUB2.
Most users, at this point, will surely already have a working system, and a configured bootloader. This fact allows us to just update the bootloader config, without modifying any other files.
So, you just need to run as root:
grub-mkconfig -o /boot/grub/grub.cfg
This command will tell us the available Kernels (and any other OS), that will be available once we reboot our system, in addition to telling us which microcode(s) were found.