Linux famously runs everywhere, but is compiled from one collection of source code. How can that be possible?
For a long time I might have guessed that this was accomplished in two ways:
- Clever hardware detection within the kernel that could figure out which hardware was installed on the computer.
- Edit the kernel itself in the case of the more obscure installation targets.
Although each of these is partly true, the real mechanism allowing this tremendous flexibility is the ability to configure the process of building the kernel. Each kernel build requires a
.config file, and it is this that is edited by the user in advance of starting the compilation.
On many Linux distributions, a copy of the
.config file used to compile the kernel is kept at
$ zcat /proc/config.gz | grep CONFIG | wc -l
Yikes! 4246 configuration options…
Expecting you to correctly set each of those 4246 configuration options is clearly unreasonable, however the little code snippet above should give you a clue as to how to move forward. Since you’re already in possession of a successfully compiled Linux kernel (the one you’re running right now), we can use that as a jumping off point.
Using the running configuration
First untar the file you downloaded in the last post, and change into that folder.
tar -xf linux-4.20.tar
There are two ways to springboard off the config file we saw earlier. If this is your first time building a kernel, I’d recommend using a copy of the config file with no significant changes. That way, if anything goes wrong you know that it’s more likely to be a mistake you made in the remainder of the process, rather than in the kernel itself
zcat /proc/config.gz > .config
BUT PLEASE BE CAREFUL WITH THIS OPTION! Since the config is exactly the same as the running kernel, installing this may overwrite it! Make sure to change the value of
CONFIG_LOCALVERSION in the
.config file. This string will be added to the name of the kernel, so choosing something appropriate here will make sure to remove the risk of a clash.
This can also be done via
make nconfig but instructions for that will have to wait for a post on advanced kernel configuration. (And so will have to wait for me to educate myself enough that I could even dream of pulling off an “advanced” tutorial.)
The configuration you get from
/proc is that used to compile the kernel now running on your system. More likely than not, this kernel is from one of the major distributions, and so probably contains drivers for a bajillion devices that you don’t need.
To get a smaller kernel with a shorter compilation time, it would be better if we could only compile in those modules that are actually running on your system. It turns out that this is something that the kernel maintainers already thought of. The following command creates a configuration that only includes the modules that you are using.
Note that this really will only bring in modules that are loaded at the time the command is run. In other words, you should make sure to plug in, switch on, activate, etc., any and all devices that you use and would like to continue to work in the new kernel.
After this, make sure to change
CONFIG_LOCALVERSIONto something that won’t clash. Either alter this value in the
.config directly, or configure it via
Congratulations! You now have a ready-for-compilation kernel configuration!