Contributing to the Linux Kernel&mdash;The Linux Configuration

The Linux kernel has always been one of
the most prized gems in the Open Source community. Based around a
philosophy of shared resources through modularity, it somehow is
both well-written and written by committee. (Or, at least, by many
individuals and teams which argue/agree over features.) One of the
methods by which Linux keeps everything neat and modular is the
kernel configuration system, often referred to as config,
menuconfig and xconfig. These are the scripts that an installer of
a source kernel must run in order to set up the kernel options, but
you probably know that if you are reading this. On the outside,
these look like three very separate programs with completely
separate interfaces. In reality though, all three draw from the
same fundamental rules that many programmers of the Linux kernel
must know in order to spread their work or even to submit their
patches to Linus. It is this fundamental system that gives Linux
users the options they need to design a Linux system based on their
needs.

Since the Linux kernel is an open-source project, it
obviously accepts submissions from its users for new features.
Often, however, programmers with the desire and the know-how to add
features to the Linux kernel choose not to for a variety of
reasons. In this article, I hope to clear up some of the mysteries
surrounding the kernel configuration system that may be hindering
users and keeping them from becoming developers. Every brain counts
in open-source efforts, and every programmer who adds his or her
changes into the kernel makes the kernel more robust for the rest
of us.

What's in a Patch?

To start off with, there has to be a reason you are mucking
about in the kernel configuration scripts in the first place. Maybe
you are just exploring the system and awaiting the day when you too
will be submitting patches to the kernel. Or maybe (and more
likely) you have added a particular feature to the kernel that you
feel deserves some more widespread use, but you want to have it
ready to integrate for Linus or Alan or another kernel-developing
guru. For the purposes of this article, I will use a hypothetical
patch to make the random device driver a compile-time option,
although I should stress that in reality I had absolutely nothing
to do with the creation of that driver. (This is the driver that
controls the /dev/random and /dev/urandom devices.) Also, I will
not be discussing in depth the creation of kernel modules in this
text—I will assume you can extrapolate how to do it from this
article, especially if you were smart enough to create a
modularized driver in the first place.

Choosing Your Config Name

The first step in modularizing your program should be
obvious: you need some name that the C preprocessor can recognize
to help it sort out the differences between what changes are yours
and what are not. The kernel handles this distinction through the
use of preprocessor instructions: the #ifdef ...
#else .. #endif constructs
throughout the kernel.

The first thing to make sure of when you do this is to be
consistent. In a system as complicated as the Linux kernel, a
little bit of consistency can save a lot of headaches later. You
should look in Documentation/Configure.help for similar options and
check to see if they have a common prefix (after
CONFIG_, of course). For example, all block
device options start with CONFIG_BLK_DEV_. This
is relatively easy to change later, of course.

Once the name is selected, you should make
#ifdef...#endif blocks around
portions of the code that your patch changes (having a Linus tree
around when you do this helps, as you can diff it and easily see
what you changed). If you removed existing code, you'll need to
integrate the #else blocks from the real tree, unless you were
smart enough to keep them around while you were writing your patch.
(I usually use the construct “#if 0” early in the programming
stage.) At this point, compiling the kernel should work, and your
option will be correctly disabled and we can continue to the next
step. If it doesn't work or portions of your patch are still
present, you obviously need to go back and double-check your
diffs.

For the purposes of my example, I would choose the name
CONFIG_RANDOM for the option. The random devices are character
devices, and at the time of this writing, there was no
CONFIG_CHAR_( or similar) prefix in common
use.

The Configure Scripts (Config.in)

The next step we need to take is to add the new configuration
option to the configure system. Fortunately, this is fairly easy
with only a couple of warnings. In the directory where you have the
majority of your patch (in my example, drivers/char), there will be
a file called 'Config.in' which contains the configuration options
for the code in that directory. It is possible to put the config
option in a different directory's config file, but it obscures the
readability a little and may make it difficult to locate your code
later. However, if it definitely belongs somewhere other than where
you have it (or if the location of your code does not have one of
those files), you should use your own best judgment and be prepared
to move it later. Browsing through this file, you will see that it
contains what appears to be a rough scripting language similar to
Bash or another shell script. This scripting language is called,
easily enough, “Config Language” and should not be terribly
difficult to get your arms around. For the purposes of our
non-modular example, we don't need to work with the full vocabulary
of the language and can concentrate on only a few keywords (defined
below). For a more complete guide to the language, a complete
reference is provided with newer kernels
(Documentation/kbuild/config-language.txt). There are plenty of
examples provided in the actual configuration files, however, and
the language is simple enough that a real understanding of the
language and syntax is not required for normal maintenance. In
general, lines in this file are formatted with one or more keywords
(called verbs) followed by some arguments. Here is a partial list
of verbs and their meanings:

comment: An unparsed comment except when preceded
by the mainmenu_option command
which would cause the comment to be used as a heading.

mainmenu_option: A verb that makes the next comment
into a heading. I cannot explain enough how odd this seems to
me.

bool: Boolean (yes/no) configuration option. This
verb is always followed by a question and a configuration variable
to put the result (“y” or “n”) in.

tristate: A value similar to a bool but with the
additional “make as module” possibility denoted as “m”. This is
applicable only to device drivers.

if... fi: A conditional block that is evaluated
only if a certain configuration variable is set.

The idea here is to locate the section of the file which
corresponds to where you would like your option to be in the
configuration programs. This should naturally be the location where
your patch is most related to the other options provided. Once you
have located where it would go, you should format a line similar to
the following with your own information thrown in:

bool 'Random driver support' CONFIG_RANDOM

(Please note here that a' is used as the quote character. This can
be easy to miss.)

If your configuration option relies on another to be set,
this model becomes more complicated. You will need to surround your
options with an if ... fi block that tests the prerequisite option.
There are a number of examples in the assorted configuration files
to help you with this process; when in doubt, copy. One final word:
you should be aware that this file is used not only to generate the
selection lists in the configuration processes, but also to
generate the include/linux/autoconf.h file. In order to preserve
the readability of that file, you should be careful that options
you add do not come after other subheadings or the configuration
option will not appear in the right place when that file is
generated. (Of course, it will still work no matter where it is in
the file, but for readability, this is something to
consider.)

Trending Topics

Webinar: 8 Signs You’re Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
11am CDT, April 29th

Join Linux Journal and Pat Cameron, Director of Automation Technology at HelpSystems, as they discuss the eight primary advantages of moving beyond cron job scheduling. In this webinar, you’ll learn about integrating cron with an enterprise scheduler.