Kernel Configuration and Building in Linux PDF
Kernel Configuration and Building in Linux PDF
5
Kai Germaschewski Sam Ravnborg
University of Iowa Ericsson Diax A/S
kai@germaschewski.name sam@ravnborg.org
programmers recognized this a long time ago support in configuration and building of
and invented a tool called make which is still those objects.
the most popular build tool used today. We as-
sume in this paper that the audience is familiar
with the basics of make. In particular the high configurability and sup-
port for loadable modules distinguish the
So even Linux 0.01 came already with a Make- Linux kernel from most other projects, and it
file which took care of building the kernel. thus comes as no surprise that its build system
also evolved away from a standard Makefile.
As time passed and Linux matured, new fea-
However, make is still the underlying tool used
tures were incorporated into the build system,
for building the kernel. In fact, the extensibility
such as
of the GNU version of make [1] in conjunction
with some support scripts / C code renders it
• Automatic generation of dependency possible to meet the goals listed above.
information. make only handles simple
dependencies like the dependency of an 2 A dummy’s guide to kbuild
object file on the corresponding source au-
tomatically, other prerequisites as for ex-
ample included header files need to be This section is addressed to users and will ex-
added to the Makefile explicitly, a task plain how to use the kernel build system in
which can be (and was) automated. Linux-2.5/2.6. “Users” (as opposed to “devel-
opers”) here mean people who download the
• Configurability. As the code base for linux kernel tree source, possibly apply patches
the Linux kernel expanded, a need for a and then build and install their own kernels. Of
user selectable configuration became ap- course, since kernel developers need to build
parent and was introduced before release and run kernels, too, this section is of relevance
of Linux 1.0. This system allows the user for them as well.
to answer questions with respect to which
The build system is based on GNU make, i.e.
components are desired, and then only all commands are given to make by invoking it
builds those components into the kernel. as
Arch maintainers should setup their arch- tween those two steps if a change of configura-
specific Makefile in a way that invoking make tion options is desired.
without parameters will build the commonly
used boot target for the architecture, for exam- The last remaining step is the installation of
ple on i386 just typing the newly built kernel. The procedure to in-
stall the boot image depends of course on the
make bootloader used.
the build system will notice the change and re- to override the SUBDIRS variable on the com-
build whatever is needed. The one exception mand line, which will force make to only de-
to this rule is changing the architecture (by set- scend into the given subtree. This can be very
ting the ARCH variable), which needs an ex- useful for faster build times, but it bypasses
plicit make distclean to work correctly. some dependencies and thus does not guaran-
tee to result in a consistent state.
3 kbuild for kernel developers So while e.g. working on the hisax ISDN
driver, it’s useful to call make as
3.1 kbuild in the daily work
make SUBDIRS=drivers/isdn/hisax \
modules
Since developers tend to build kernels and
modules a lot, the previous section of course
also applies to them, in particular the fact that for compile checks etc. However, before
just running make will recognize all changes installing a new kernel and modules, the
and rebuild whatever is necessary to generate a authors advise to always run a full make
consistent vmlinux and modules. bzImage/vmlinux/modules (or other-
wise, do not complain ;).
Some additional features exist to support the
development / debugging process:
3.2 Integrating a driver
• make some/path/file.o will re- Basically each subdirectory in the Linux ker-
build the single file given, using compiler nel tree contains a file called Makefile, which
flags (e.g. -DMODULE) according to the is included by make during the kernel build
current .config. process. However, these Makefiles are differ-
ent from regular Makefiles in that they nor-
• make some/path/file.i will mally don’t have any targets or rules, but only
generate a preprocessed version of set variables which tell the build process what
/some/path/file.c, again using should be built and the latter takes control of
compiler flags for the current configura- the actual compiling and linking.
tion.
In conjunction with the Makefile there nor-
• make some/path/file.s will gen- mally exists a Kconfig file, these files were
erate a file containing the raw assembler introduced with the configurator rewrite by
code for some/path/file.[cS]. Roman Zippel and replace the old Con-
fig.in/Config.help files used during the config-
• make some/path/file.lst (little uration phase of the kernel build.
known but very useful) gives interspersed
assembler code with the C source, relo- This paper does not intend to elaborate on the
cated to the correct virtual address when a new kernel configuration system, however the
current System.map exists. following examples will provide some basic
usage guidance.
Another useful feature for the daily work, The most common case is adding a new driver
which has existed for a long time, is the ability which is built from a single source file.
Linux Symposium 189
config TIGON3
tristate "Broadcom Tigon3 support"
depends on PCI
help
This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
Figure 1 shows the Kconfig fragment for the be compiled as built-in objects, and will
Tigon3 driver, which defines a config option finally be linked into vmlinux.
TIGON3 (the corresponding variable will be
given the name CONFIG_TIGON3), which is • obj-m. All objects listed in obj-m and
a tristate, i.e. can have the values y, m, or not not listed in obj-y will be compiled
n with the obvious meanings (a config option as modules (so they actually end up being
which has been turned off, actually has the called e.g. tg3.ko in 2.5/2.6).
value "", to be correct here). The fragment • obj-. All objects listed in obj- and not
depends on PCI states that this option is in obj-y or obj-m will be ignored by
only selectable when the option PCI is also set kbuild.
(that is, if the kernel supports the PCI bus).
The Makefile fragment for the Tigon3 driver Since the build system does not have any fur-
ther information on tg3.o, it will try to build
obj-$(CONFIG_TIGON3) += tg3.o
it from a source file called tg3.c (or an as-
sembler source tg3.S, which only happens in
the architecture dependent part of the kernel,
is very short and though a little awkward at though).
first, a very elegant way to quickly express
what files are supposed to be built. The This is all what is needed to integrate a simple
idea dates back to Micheal Elizabeth Castain’s driver into the kernel build, other than of course
dancing Makefiles [2] and was globally intro- writing the driver (tg3.c) itself.
duced into the kernel by Linus shortly before It is also possible to list more than one object to
the release of kernel 2.4. be built in the Makefile statement. The Make-
file line dealing with the eepro100 driver looks
What happens is that depending on the con- like the following:
fig option CONFIG_TIGON3, the value tg3.o
is appended to either of the variables obj-y, obj-$(CONFIG_EEPRO100) += \
obj-m or obj-. eepro100.o mii.o
#
# Makefile for the Intels E100 ethernet driver
obj-$(CONFIG_E100) += e100.o
Figure 2: /drivers/net/e100/Makefile
#
# Makefile for the Linux X.25 Packet layer.
#
obj-$(CONFIG_X25) += x25.o
Figure 3: net/x25/Makefile
(a)
O_TARGET := vmlinux-obj.o
export-objs := isdn_common.o
list-multi := isdn.o
isdn-objs := isdn_net.o isdn_tty.o isdn_v110.o isdn_common.o
isdn-objs-$(CONFIG_ISDN_PPP) += isdn_ppp.o
isdn-objs += $(isdn-objs-y)
obj-$(CONFIG_ISDN) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
mod-subdirs := hisax
subdir-$(CONFIG_ISDN_HISAX) += hisax
subdir-$(CONFIG_ISDN_DRV_ICN) += icn
include $(TOPDIR)/Rules.make
isdn.o: $(isdn-objs)
$(LD) -r -o $@ $(isdn-objs)
(b)
obj-$(CONFIG_ISDN) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
obj-$(CONFIG_ISDN_DRV_HISAX) += hisax/
obj-$(CONFIG_ISDN_DRV_ICN) += icn/
Figure 4: drivers/isdn/Makefile in (a) 2.4.20 and (b) adapted for the build system in 2.5
In Linux 2.4, the name for the object which In kbuild-2.4, we need to explicitly add the
accumulates all built-in objects in and below subdirectories to descend into to the variables
the current subdirectory was chosen by setting subdir-y/m, and then also add the subdir-
generated built-in objects to obj-y so that they
the variable O_TARGET in the local Makefile. get linked. This is redundant and error-prone,
In Linux-2.5, it is instead just set to built-in.o in 2.5 it is sufficient to just add the objects gen-
by the build system. This allows to get rid of erated in the subdirectories to the list of ob-
the assignment of O_TARGET in every subdir jects to be linked, and the build system will de-
Makefile and, more importantly, allows for fur- duce from there that it needs to descend into
the named subdirectories. To simplify things
ther clean-up: further, the name of the O_TARGET (now al-
ways being built-in.o) itself is left out and only
the trailing slash is kept:
Linux Symposium 193
$(multi-used-m) : \
%.o: $(multi-objs-m) FORCE Each subdirectory Makefile in kbuild-2.4
$(call if_changed,link_multi-m) needed to include $(TOPDIR)/Rules.make ex-
plicitly. In 2.5, when descending into subdirec-
tories, the build system now always calls make
multi-used-m contains all multi-part mod- with the same Makefile, scripts/Makefile.build,
ules we want to be built in the current directory which then again includes the local subdi-
and multi-objs-m contains all of the indi- rectory Makefile, so the statement to include
vidual objects those are built of. This makes Rules.make could be dropped.
Linux Symposium 194
Furthermore, in 2.5. the build is still organized 4.5 Compiling built-in objects and modules in
in a recursive way, i.e. make is only invoked a single pass, recognizing changed com-
to build the objects in the local subdirectory mand line arguments
and other instances of make are spawned for
the underlying directories. However, it does The major performance issue for the kernel
not actually descend into the subdirectories, build are the invocations of make (most of the
it always does its work from the top-level time is of course normally spent compiling /
directory and prepends the path as necessary. linking, but this cost is independent of the build
One of the advantages is that the output system used). make has to read the local Make-
includes the correct paths, so a compiler file, the general rules and all the dependencies
warning will not show “inode.c: Warning and figure out the work to be done from there.
...”, but “fs/ext2/inode.c: ...”, which makes it An obvious way to optimize the performance
easier to recognize where the problem occurs. of the build system is thus to avoid unneces-
More importantly, it allows to use relative sary invocations. In 2.4, make needs to do sep-
paths throughout the build, so that paths arate passes for modules and built-in objects
like “BUG in /home/kai/src/kernel/ and within each directory, it will even call it-
v2.5/linux-2.5.isdn/include/linux/ self again, so an about four-times performance
fs.h” are history. Renaming/moving a kernel increase is possible by just combining those in-
tree will not cause spurious rebuilds due to vocations into a single pass.
changing paths as seen above anymore, and
The primary reason why kbuild-2.4 needs two
tools like “ccache” can work more effectively.
passes for built-in and modules lies in its flags
handling. This means that it tries to check not
4.4 Objects exporting symbols only whether prerequisites have changed (e.g.
the C source for an object), but also if the com-
piler flags have changed.
The old module symbol versioning scheme This objective was achieved by generating a
used with Linux 2.4 needed the Makefiles to .<target>.flags file like the following (simpli-
declare which objects export symbols to mod- fied) for each target built:
ules, which was done by listing them in the
variable export-objs. In 2.5, module ver- ifeq (-D__KERNEL__ -DMODULE
sioning was completely redesigned, removing -DEXPORT_SYMTAB,
the need for this explicit declaration. The $(CFLAGS) -DEXPORT_SYMTAB)))
FILES_FLAGS_UP_TO_DATE += config.o
changes are so complex that they are rewarded
endif
their own section in this paper.
Here we conclude the comparison between a On a rebuild, the Makefile would read all those
2.4 and 2.5 subdirectory Makefile, where we .*.flags fragments and forces all files which are
have shown that all the redundant and de- not listed in FILES_FLAGS_UP_TO_DATE to
ducible information has been removed and the be rebuild.
necessary information is revealed to the build
system in a very compact form. The flaw of this method is that it cannot handle
differing flags for different groups of files, so
Two additional important internal changes, make needs to invoked twice, once for the tar-
which did not affect the subdirectory Makefile gets to be built-in with the normal CFLAGS, and
layout will be described in the following: again for the modular targets with -DMODULE
Linux Symposium 195
added to CFLAGS. In the example above it is easier use in a rule as shown above, is that all
also visible that the handling for -DEXPORT_ the checking is done within the context of the
SYMTAB is broken, this method can not de- actual rule and not in a unrelated place later in
the Makefile. This allows for the use and cor-
tect when a file was added / removed from rect checking of GNU make’s per target vari-
the list of files exporting symbols, since the ables, e.g.
-DEXPORT_SYMTAB was hardcoded on both
sides of the comparison and thus useless—the
modkern_cflags := $(CFLAGS_KERNEL)
only way to fix this within in the old frame- $(real-objs-m) : \
work would have been to invoke make four modkern_cflags := $(CFLAGS_MODULE)
times, for all combinations of built-in/module
and export/no-export.
which sets modkern_cflags to
A more flexible scheme to handle changing $(CFLAGS_KERNEL) by default, but to
command lines within GNU make was created: $(CFLAGS_MODULE) for objects listed in
$(real-objs-m), i.e. for objects compiled
As an example, we present the rule which is as modules. The compilation rule can then
responsible for linking built-in objects into a just use $(modkern_cflags) to get the
library in Figure 7. The actual use is pretty right flags for the current object, where the
simple, instead of writing the command di- mechanism described above will take care of
rectly into the command part of the rule, it is recognizing changes and acting accordingly.
instead assigned to the variable cmd_link_
l_target and the build system takes care of 4.6 Dependencies
executing the command as necessary, keeping
track of changes to the command line itself.
Between configuration and building of a ker-
The implementation works as follows: Af- nel, the old kernel build needed the user to
ter executing the command, the macro if_ run “make dep”, which served to purposes:
changed, records the command line into the It generated dependency information for the C
file .<target>.cmd. As make is invoked again source files on headers and other included files,
during a rebuild, it will include those .*.cmd and it generated the version checksums for ex-
files. As it tries to decide whether to rebuild ported symbols.
L_TARGET, it will find FORCE in the prerequi-
sites, which actually forces it to always rerun Both of these task have become unnecessary in
the command part of the rule. 2.5, so the reliance on the user to rerun “make
dep” as needed is gone (additionally, the sys-
However, the command part of the rule now tem in 2.4 is broken that in some modversions
does the actual work: It checks whether any cases it’s not even sufficient to rerun “make
of the prerequisites changed, i.e. $? is non- dep”, the only solution then is to do “make
empty or if the command line changed, which distclean” and start over).
is achieved by the two filter-out state-
2.4 used a small tool called mkdep to generate
ments. Only if either of those two conditions dependencies for C sources. This tools basi-
is met, if_changed expands to a command cally extracted the names of the included files
rebuilding the target, otherwise it is empty and out of the source, but did not actually recur-
the target will not be rebuilt. sively scan those includes then. So, if foo.c in-
cludes foo.h, which itself includes bar.h, mkdep
The advantage of this method, apart from the would only pick up the dependency of foo.c on
foo.h, but foo.c also needs recompiling when
Linux Symposium 196
targets += $(L_TARGET)
[...]
foo.h changes. This problem was solved in to be created (for all files, even for en-
2.4 by assuming that foo.h would reside in in- tire subsystem which may not be selected
clude/* (which is mostly, but not always, true). in the configuration at all), even though
For those files it would generate another set of
dependencies, basically: this information is totally useless for a
first build—it’s only useful for deciding
whether a file needs to be rebuilt.
foo.h: bar.h
@touch $@
• As foo.h is changed to also include baz.h, Using the gcc generated list of dependencies
the dependency information does not get as-is has the drawback that virtually every file
updated, so a subsequent change to baz.h in the kernel includes <linux/config.h> which
will erroneously not cause foo.c to be re- then again includes <linux/autoconf.h>
compiled.
If a user reruns make *config to change a
• Starting from a clean tree, the user has configuration option, linux/autoconf.h will be
to wait for the dependency information regenerated. make will notice this and rebuild
Linux Symposium 197
every file which includes autconf.h, i.e. basi- in-kernel loader in 2.5. A common problem
cally all files. This is correct, but extremely is that Linux does not guarantee a stable
annoying if the user just changed some option binary interface to modules, in fact the binary
CONFIG_THIS_DRIVER from n to m. interface often changes between releases in
a stable kernel series and even depending on
So we use the same trick that “mkdep” ap- the configuration of the kernel. One simple
plied before. We replace the dependency on example is the struct net_device,
linux/autoconf.h by a dependency on every which embeds a spinlock_t. If the kernel
config option which is mentioned in any of the is configured for uni-processor operation, this
listed prerexquisites. lock expands to nothing, so the layout of the
The effect is that if a user changes the struct net_device changes. When
CONFIG_THIS_DRIVER option, only the ob-
calling register_netdev(struct
jects which (themselves, or in any of net_device *) where the in-kernel func-
the included files) reference CONFIG_THIS_ tion register_netdev() assumes the
DRIVER will be rebuilt, which most likely is
SMP layout, though the module set up the
only this one driver. argument in the UP layout, we have an obvious
mismatch which often leads to hard to explain
kernel crashes.
5 Modules and the kernel build
Other operating systems solve this problem by
process prescribing a stable ABI between kernel and
modules, however in Linux it is preferred to not
The implementation of loadable kernel mod- carry around binary compatibility layers and
ules has been substantially rewritten by Rusty cope with unflexible interfaces, instead since
Russell in the development cycle 2.5. These the source is openly accessible, one just needs
changes are so complex that this paper will not to recompile the modules so that they match
attempt to describe them in detail. Instead, we the kernel.
concentrate on the changes which were done in
Now, it is easily possible for users to get this
the build system to accomodate the new con-
wrong and we thus want a way to detect ver-
cepts.
sion mismatches and refuse to load the mod-
ules or at least warn. This is what “module
5.1 Module symbol versions
symbol versioning” accomplishes. The basic
idea is to analyze the exported symbols, includ-
Loadable modules need to interface with the ing the types of the arguments for function calls
kernel. They do this by accessing certain and generate a checksum for a specific layout.
data structures and functions which have been If anything changes in the ABI, the versioning
marked as exported symbols in the source. process will generate a different checksum and
That means not all global symbols in the kernel thus detect the mismatch. The main work in
are accessible to modules, but only an explic- this scheme is done by the program genksyms,
itly exported API. which is basically a C parser that reads a pre-
processed source file and finds the definitions
These symbols remain unresolved in the for the exported symbols from there.
loadable module objects at build time and
are then resolved at load time, either by an This procedure has caused trouble in the
external program, modutils, in 2.4, or by an
Linux Symposium 198
build system for a long time. In Linux 2.4, but it has no way to make sure that it is up-
the “make dep” stage, apart from build- to-date since it is located in a different subdi-
ing dependency information, preprocesses rectory.
all source files which export symbols (that
is why they need to be specifically de- Module versioning is instead implemented as
clared in the Makefiles) and then gener- a two stage process, the first stage is the nor-
ates include/linux/modversions.h which man- mal build, which also generates all the check-
gles the exported symbols with the gen- sums. After this stage is completed, we can
erated checksum, using the C preproces- be sure that all checksums are up-to-date now,
sor. The kernel will then not export the and then just record this up-to-date information
symbol register_netdev, but instead into the modules. This is one of the reasons
register_netdev_R43d2381. A mod- why modules have been renamed with a “.ko”
ule referencing register_netdev will end extension: The first stage just builds the nor-
up with an unresolved symbol register_ mal “.o” objects, and afterwards a postprocess-
netdev_R43d2381, so loading it into the ing step follows, which builds “.ko” modules
kernel will work fine. Has the module how- adding version checksums for unresolved sym-
ever built against a different kernel or a differ- bols and other information.
ent configuration, the checksum has changed In more detail, the following steps are exe-
and any attempt to load it will result in an error cuted:
about unresolved symbols.
The checksums can easily examined at view, is that the actual symbols are not man-
running the command shown in Figure 8. gled, so it became possible to force a module
load even if the checksums do not match—
• Postprocessing though the kernel will set the taint flag in these
After stage one, we have the check- case.
sums for the exported symbols embedded
The module postprocessing step, introduced
within vmlinux and the modules. What
mainly for the module symbol versioning, al-
is yet to be done is recording the check-
lowed for a number of additional features, i.e.
sums into the consumers, that is adding
module aliases / device table handling, addi-
the checksums for unresolved symbols
tional version checks as well as recognition of
into the modules.
unresolved symbols during the build stage.
This step was initially handled by a small
shell script but is now done by a C pro-
gram for performance reasons, which also
handles other postprocessing needs like
generating aliases. 6 Conclusion and Outlook
This program basically reads all the ex-
ported symbols and their checksums from
all modules, and then scans the modules
for unresolved symbols. For each unre- This paper presented an introduction to using
solved symbol, an entry in a table associ- the kernel build system for the Linux kernel
ating the symbol string with the checksum 2.5 and 2.6 for users who want to compile their
is made, this table is output as C source own kernels and developers working on ker-
module.mod.c and compiled and linked nel code. We also showed how in the transi-
into the final .ko module object. tion from kbuild-2.4 to 2.5, features of GNU
make could be applied to remove redundant in-
Figure 9 shows an excerpt from formation and allow for simpler Makefile frag-
drivers/isdn/hisax/hisax.mod.c which ments as well as a more consistent and fool-
calls register_isdn(). The proof build system.
checksum obviously matches the
checksum for the exported symbol Additionally, parts of the internal implementa-
in drivers/isdn/i4l/isdn.ko, so that the tion have been described and an overview over
module will load without complaint. changes related to the new module loader and
new module versioning system has been given.
An additional advantage of the new way of The kernel build system in 2.5 has been im-
handling module version symbols, apart from proved significantly, but some features remain
being cleaner from a build system point of to be implemented.
Linux Symposium 200
Separate source and object directories module post-processing. On the other hand, a
global Makefile which contains also needs to
As opposed to kernel 2.4, source files are not incorporate dependencies for all files will use
altered or touched during the build in 2.5 any- a significant amount of memory and may turn
more, enhancing interoperability with source out to be problematic on low–end systems.
management systems. The next step is to al-
There are two ways to implement a global
low for completely separate source and ob-
Makefile: One possibility is using GNU make
ject directory trees, so that the source can be
itself, replacing the rules to actually compile /
completely read-only and multiple builds at the
link objects by dummy routines recording the
same time from the same source are possible.
necessary actions into a global Makefile. The
The current code in 2.5 has taken preparatory
second possibility is, as the subdir Makefiles
steps for this feature but work is not completed
have a very consistent form by now, to write a
yet.
specialized parser for those files and have that
generate a global Makefile.
Non-recursive build
Whether switching to a non-recursive build
It is an open question whether it is actually ad- system is worth the tradeoffs will be investi-
visable to switch to a non-recursive build sys- gated in the Linux 2.7 development cycle.
tem. Obviously, distributing build information
with the source files is desirable, this trend is References
visible in e.g. the split of the global Con-
figure.help file into per-directory fragments
[1] GNU make http://www.gnu.org/
which eventually were unified with the new
software/make/make.html
Kconfig configuration info. Of course it is es-
sential to keep the build information in the per- [2] Michael Elizabeth Castain:
subdirectory Makefiles distributed as it is cur- dancing-makefiles
rently, it would be a step back to collapse it into http://www.kernel.org/pub/
one big file. linux/kernel/projects/
kbuild/dancing-makefiles-2.
However this does not preclude collecting the
4.0-test10.gz
distributed information when starting a build
and generating a global Makefile, which is then
used as a main stage. The advantage of this
method is that it can handle cross-directory de-
pendencies more easily, whereas the current
system has to resort to a two-stage process for
Proceedings of the
Linux Symposium
Review Committee
Alan Cox, Red Hat, Inc.
Andi Kleen, SuSE, GmbH
Matthew Wilcox, Hewlett-Packard
Gerrit Huizenga, IBM
Andrew J. Hutton, Steamballoon, Inc.
C. Craig Ross, Linux Symposium
Martin K. Petersen, Wild Open Source, Inc.
Authors retain copyright to all submitted papers, but have granted unlimited redistribution rights
to all as a condition of submission.