Compiling a kernel has the advantage to make it as minimal and featureful as you want, you can test kernel patches and tweaks and optimize your system.
* You need the kernel source, build tools, the kernel configuration file (__optional__), and __root__ or __sudo__ privileges for the final stages of the process.
Is standard to download Linux sources under __/usr/src/__, then link the downloaded kernel tree to __/usr/src/linux-<VERSION_NUMBER>__ and work there, but is not a requirement.
* Clean the directory (wont touch the config file just remove all compiled files from the kernel tree).
`make clean`
* Remove compiled files from the kernel tree AND the configuration file if there are any (backup your configuration file before this if you have one in the current directory).
This process makes a "__.config__" file in the kernel source directory, this file determine which drivers are built and other support. There are three options here, you can turn on only the minimal set of options you need.
* __OPTION 3__: Generate a config file disabling all options not loaded by the currently running kernel and will make questions on what kernel options to support when it finds new kernel options. Could have problems with peripherals not in use at that time unless you plug all devices like __USBs__. Attach devices you use or insert modules manually with the insmod command before using this option. Available from kernel version 2.6.32 and up.
* __OPTION 4__: Create a minimal kernel config file which necessarily needs to manually enable options afterwards to have a working system. Available from kernel version 3.17-rc1 and up.
__OPTION 1__: Start a menu and browse options. Requires curses library but likely is already on your computer. Press "__H__" or "__?__" to see help. You can use the space bar to cycle between the available choices or press the appropriate key mentioned above. Pressing "__/__" to search for keywords.
__OPTION 2__: Will make questions on what kernel options to support when it finds new kernel options not marked on an existing config file (takes time and and if you are using a striped down config file it requires you knowledge).
__NOTE__: The __-j\<X>__ flag, where __\<X>__ is the number of cores, __IS OPTIONAL__ and only goes if you have a processor with multiple cores. A trick to get the cores automatically is by including __$(nproc)__ instead of the number. If you install __ccache__ (__THIS IS OPTIONAL__) you can speed up subsequent compilations by including __CC="ccache gcc"__ after the __-j\<X>__ flag.
Compile and move everything to its place. The "__all__" flag makes modules AND the __bzImage__ at the same time (replaces "__bzImage__" and "__modules__" flags).
* If your configuration does not contain answers for all of the options, especially if they are new and not currently included in your running kernel, you will need to answer the prompts for these options.
* __OPTION B2__: Automatically move kernel to __/boot__ (and in certain distros, symlink the new kernel to __/boot/vmlinuz__ and update the bootloader configuration).
__NOTE__: The __vmlinuz__ can be any name but that exact name has to be added to the configuration file of your bootloader of choice. Usually a version number is appended to the new kernel image. This has the advantage to avoid replacing a current kernel and having a fallback as backup to boot. You can set to boot from any image in the bootloader once you configure them in the bootloader.
Module files end with the __.ko__ file extension. They are individual files for each question you answered __M__ during kernel configuration. The object code is linked against your freshly built kernel as separate modules. Questions answered __Y__ were integrated into the kernel (__vmlinuz__), and for questions answered __N__ they were skipped (not compiled).
This section is optional. It shows how to get individual modules and what you can do with them, how to install new modules, update them and automate the process.
This section is also optional. There are cool patches for the kernel out there and here you'll find how to install them. You can find patch files on the __[Linux Kernel Mailing List](https://lkml.org/)__. More patches are provided in other places.
* __[UKSM](https://github.com/dolohow/uksm)__, RAM memory de-duplication reducing memory footprint, but opens side-channel attacks and is recommended to be used on systems disconnected from the network.
* __[Linux-rt](https://wiki.linuxfoundation.org/realtime/preempt_rt_versions)__, maximum latency and responsiveness, users claim avoids any hiccups and stalls.
* __[Liquorix](https://liquorix.net/sources/)__, kernel for desktop, multimedia, and gaming workloads.
* __[linux-tiny](https://elinux.org/Linux_Tiny)__, reduce the memory and disk footprint (only for 2.6 and down, not updated).
* __[Linux-libre](http://linux-libre.fsfla.org/pub/linux-libre/releases/)__, remove non-free, obfuscated or obscured software included without source code.
* __[pf-kernel](https://pfactum.github.io/pf-kernel/)__, patch set improving interactiveness and performance, includes __Kernel_gcc_patch__, __BFQ__ and others.
* The __-p__ flag specifies a number of leading directories to remove, location is at the top of the patch file filename and is relative to the current directory.
The drivers have different names depending on your device (like "iwlwifi" and its "ucode" for WiFi). In part they can be installed from a package usually named "linux-firmware", but they may not be complete (this provides "ucode" but not "iwlwifi").