Menu

TheFourPhasesOfKernelBuilding

Eugene Wissner

{{note| This originally comes from something I wrote a few years back, and this iteration of it was something I posted to explain things to users on LinuxQuestions?.org. It is hoped that this will help people understand the steps involved (instead of just giving them a recipe to paste into a terminal) so that they will be able to rebuild their kernels in an intelligent way, and be more able to handle any unexpected failures that might develop.}} =Overview= While building a new kernel can seem a daunting task at first, it's really much more simple than you may have been led to believe. The task of compiling and installing a new kernel can be broken down into four stages of operation. Once you understand what these four stages are, the task itself becomes much less arcane. This page will attempt to outline these four stages in a manner user can (hopefully) remember or at least understand so that they may begin to build their own kernels when needed.

It is assumed that the reader will know how to obtain a complete copy of the kernel source from somewhere like http://www.kernel.org. It is also assumed that the user knows how to untar the kernel source, or at least how to reinstall the kernel-source package Slackware ships to remain "true" to the version of the kernel that was shipped with the released version of Slackware. It is further assumed that the user has an understanding of basic Unix/Linux filesystem commands like mv, cp, rm, ln, etc. If you do not understand these things, you really should not attempt to rebuild your kernel. Please proceed to the SlackBook and familiarize yourself with Slackware basics, as well as use Google to read a few Basic Linux Tutorials. The time you spend reading these will save you much more time and frustration later on.

==Source Setup Stage== For reference, Slackware by default installs the kernel source into <TT>/usr/src/linux-w.x.y.z</TT> (where "w.x.y.z" is the version of the kernel) with a symlink at <TT>/usr/src/linux</TT> pointing to it. You may use another directory if you like, but especially at first the fewer changes you make increases your chances of success. For the purposes of keeping this tutorial simple, all commands for building and configuring the kernel should be run while you are in the <TT>/usr/src/linux</TT> directory.

The very first thing one must do when building a kernel is make sure the kernel source is sane. By "sane" I mean the source must be complete and undamaged, with the file permissions set to something the user about to build the kernel can read. It should also be free of any stale object files (previously compiled pieces of code which may or may not be correct with respect to the new configuration) before you begin. There are some times when you will not need to worry about this, and they will be explained further on. On the other hand, redoing this step can not hurt anything so "when in doubt, clear the junk out".

There are basically two commands you need to know about for sanifying ("making sane") the kernel source:

make mrproper - This attempts to revert the source tree to a sane state by deleting all stale object files, configuration data, and some backup files from the kernel source tree. Remember that if you run this command, it will erase whatever configuration you were working on, so be sure to make a backup copy of the configuration file somewhere safe first. You should always run this command after untarring or installing new kernel sources. (...and yes, it's pronounced "Mister Proper")

make clean - This is similar to make mrproper but slightly less aggressive. It will do almost everything make mrproper does, but it will leave the kernel configuration intact so that things which might need to build external kernel modules will still be able to use it. If you want to free up some disk space after you have built and installed a new kernel, this command should do that for you safely.

{{caveat|Warning: If you are modifying a kernel configuration in an already-built tree in a manner that adds or removes from the core (non-modular) part of the kernel, or that changes an option from being in the core kernel to being a module, or vice-versa, you must run one of the two commands above (preferably '''make clean''') to eliminate the stale object files before you start the recompile or the kernel and modules you get will likely not be sane and will very likely malfunction horribly.|}}

==Configuration Stage== Once the kernel source has been extracted somewhere on the disk and any patches have been applied, it's time to begin configuring the kernel. This is easily the most complex part of the entire operation, so read things carefully and don't be afraid to use Google if something you see doesn't seem quite right to you.

{{caveat|Only very seldom will you actually need to patch or modify the kernel source. Always double-check to be sure that you really are supposed to do this before you do so. One excellent example of a source of confusion for users is network card makers who ship driver disks with Linux drivers on them distributed as a patch or standalone driver source--most of the time these drivers are very old, and a much newer version is already available in the latest kernel so you don't need to patch or change anything.}}

As with the previous stage, there are multiple commands that may be used, all of which accomplish the same thing. You should pick the one you are most comfortable with and stick with it to reduce the chances that some momentary confusion on your part doesn't result in mistakes. All of these create the configuration file for the kernel which is stored at <TT>/usr/src/linux/.config</TT>. The primary ones we will discuss are as follows:

make config - Pretty much the oldest configuration mechanism there is. This will ask you about every single option and whether you want it or not, one at a time, seemingly endlessly. If you accidentally answer something wrong once you get to start over at the beginning. This option is primarily only of interest to technological masochists and is mentioned only for the sake of completeness. Don't use it.

make menuconfig - A much more user-friendly text-based (courtesy of something called 'ncurses') configuration tool. This is the tool most people use, and it is particularly useful if you don't yet have X properly configured.

make xconfig - Essentially the same thing as make menuconfig but uses a graphical Qt-based interface. Good for KDE users.

make gconfig - Essentially the same thing as make menuconfig but uses a graphical Gtk+-based interface. Good for GNOME & XFCE users.

{{note|All three of those commands really do manipulate the same data and generate the same file, namely: <TT>/usr/src/linux/.config</TT>}}

make oldconfig - If you already have a configuration file and would like to apply it to an existing source tree, first clean up the source tree with make clean (or make mrproper), copy your configuration file to the root of the kernel source tree as "<TT>.config</TT>", and issue this command. Your screen will scroll madly as the '''make config''' configurator is called and fed all the existing options from your <TT>.config</TT> file. Note that new options will cause this to stop and ask you what you want each new option to be set to. It is usually safe to simply pick the defaults if you are not sure what each new option does. To be safe, when in doubt, pick 'M' for modules.

{{caveat|Warning: Manually tampering with the <TT>.config</TT> file can result in a configuration that is missing options that need to be set, or containing options that should no longer be set and can break things--meaning your build could fail at some point with a very cryptic error, if you're lucky.}}

make silentoldconfig - This is similar to make oldconfig but less spammy on your screen. This makes it very handy for people configuring over a laggy ssh connection.

{{note|Note: The final two commands above are very useful for upgrading between reasonably similar kernels (for example, 2.6.20 to 2.6.22.3) because they will both stop when an option is reached that requires a decision to be made. Usually these options are new features in the kernel, and you can generally assume that if the existing kernel you are trying to recycle was working for you then you can simply hit 'm' to set the new code to be built as a module without having to worry too much about it.}}

==Compiling Stage==

make all - With the 2.6.x kernels, this is pretty much the "do it all" command. Gone is the need to type make dep or any of that other stuff. Like any good Makefile would provide, make all will cause everything you'd reasonably want to be compiled to be compiled, including both the kernel and it's modules. If you'd like to know what specifically is going on, type make help | less and all the targets that 'all' invokes will be listed with an asterisk next to them.

make - Running make with no target mentioned is synonymous with running make all. Use either one you like.

make vmlinux - This compiles the core kernel and only the kernel.

make modules - This compiles just the modules and not the kernel (parts or all of which may actually get compiled anyway if it's needed to build the modules). If you used make menuconfig to alter your kernel configuration and only added new modules that were not on at all before and everything else is already built, you can simply run make modules and it will quickly figure out which new module wasn't built yet, build it, and you can move on to the final stage rather quickly.

==Installation Stage==

make bzImage - Not really an installation target, per se, but close enough since there's not really an option to "just" install the kernel. This will give you a compressed kernel image as arch/i386/boot/bzImage that you can then copy to wherever you want.

make modules_install - This will blow away the entire contents of the /lib/modules/uname -r directory (/lib/modules/2.6.22.2-smp for example) and then install all the modules in there.

make headers_install - This is a command you do not run, ever. The only people who should ever run this are people who build distributions from the ground up who just rebuilt glibc. People reading quick HOWTOs on building a kernel are categorically not such people. Doing this will screw your machine up.

make install - Running this command will likely not do what you want. Without special preparation, this is just going to lob the System.map and kernel into somewhere which is probably not the place you want them to be. If you have done this "special preparation" then this will install both your kernel and the modules in one step. The "special preparation" I mention is that the kernel Makefile looks for a script called 'installkernel' in either ~/bin or /sbin (whichever it finds first) and runs that to install your kernel and re-run lilo. Such a script has been written and can be downloaded from here which you can chmod executable, copy to your /sbin directory and use immediately. It will copy the kernel, the System.map file, and a copy of your config to /boot using symlinks exactly as Pat does so everything stays nice and tidy. It's code is blisteringly simple to avoid any confusion about what it's doing. Your new kernel will be stored as /boot/vmlinuz-x.y.z with a symlink pointing to it from /boot/vmlinuz and so on.

Don't forget that if you didn't use make install you will likely need to edit your /etc/lilo.conf to point at wherever your new kernel is, and run lilo again to update the bootloader. Usually I make the default kernel image for lilo be the symlink of /boot/vmlinuz, and the second item explicitly /boot/vmlinuz-2.6.whatever. After awhile if the new kernel works properly I go back and update the explicitly-named image to point at the new kernel as well. If you are rebuilding the exact same version of the kernel as you did before, feel free to change the $EXTRAVERSION setting slightly, which is the first item under General Setup. This will be reflected in the final filenames and avoid accidentally overwriting a build you intended to keep while fine-tuning things.

=In Review=

Now that we've covered all that, you can pretty much go from the top to the bottom of this list, and things should more or less make sense. Each of the four stages should be performed in order, and I can't stress enough how useful it is to enable (not as a module, you want <*>) "Kernel .config support" and "Enable access to .config through /proc/config.gz" are under General Setup. If you do this, and you want to upgrade at some future point, you don't have to guess which iteration of the kernel you might be running... You can type zcat /proc/config.gz > .config and it will dump the configuration for the kernel you are using right then into place, ready to be absorbed with make oldconfig. Considering how unbelievably important it is to build your kernel and your modules with the same configuration, this can be a lifesaver if you need a new module some months down the road and don't have a copy of the configuration you used previously.

The last hint really worth mentioning is that if you have a SMP machine (either dual-CPU, dual-core, or hyper-threaded--if /proc/cpuinfo believes you have multiple CPUs you do for this purpose) you can use the -j switch to speed things up a bit. Simply specify the number of CPUs you have (plus or minus one at the most, there is a point of diminishing returns you quickly reach using say, -j9 when you only have two cores) like make -j2 all when you build and things will go much faster as make will spawn two children at once when building instead of just one (the default).