Linux Kernel compilation mini-HOWTO for RedHat 8-9/Fedora Core (may apply to others)
I post this, because when you are newbie to Linux and have certain problems getting your system to work, you often hear (or read in this case) that you should re-compile your kernel in order to get what you want working. Well that is exactly the reason I'm posting this. To aid those new comers to Linux (the Red Hat way).
Pre requisites
In order to be able to build a software package (and the kernel is no exception) you first must make sure to have all the relevant software packages installed on your Red Hat system to be able to do so. From the compiler (gcc) to the make environment (gmake, automake, autoconf), to diverse libraries needed. In order to accomplish this, and if you are new to Linux, often the recommendation as what to install is install everything!, to certain extent this is accurate, since you will not have to worry about any failed dependencies (some packages relay on very esoteric ones). But if you are limited on hard disk space or simply don't want to install all of the software packages that come with the distribution, you have an ally: redhat-config-packages. Open the program up and you should be presented with a window which contain all of the possible package that either are installed or can be installed on your system (you may have to supply root's password).
So, from here you should go to the develpment tools section and make sure you have at least installed gcc, make, automake, autoconf, etc (there are a total of 46 possible packages, you'll need at the very least 15). The following is a list of what I have installed:
Basic tools: automake autocnf binutils bison byac cdecl dev86 flex gcc gcc-c++ gdb gettex libtool make perl-CPAN pkgconfig python-devel redhat-rpm-config rpm-build strace texinfo Extra tools: automake14 automake15 cvs diffstat doxygen gcc-g77 (fortran) gcc-gnat (Ada95) gcc-java indent ltrace memprof nasm patchutils (to apply patches to source code) rcs splint
Of these you should as a minimum have the Basic tools and diffstat-patchutils in order to apply patches.
Getting the Kernel
To build a fully custom kernel, you should get one of the latest sources from www.kernel.org. Red Hat tends to lay behind regarding kernel releases (because of the custom patches they apply). The latest (stable) kernel version (as of this writing) is 2.4.22 and the latetst test for the stable release is 2.4.23-pre3. So go grab one of these kernel sources.
Once you have the kernel sources on your hard-drive, you can either: copy the sources from that directory to /usr/src (some say it is not recommended) and uncompress them, or uncompress them where you downloaded them. In order to uncompress the tar.bz2 file you just downloaded you'll need to issue this command (for these procedures you don't have to necesarily be root):
$ tar -jxvf linux-.tar.bz2 or $ su password: # cp linux-.tar.bz2 /usr/src && cd /usr/src && tar -jxvf linux-.tar.bz2
You now have the sources for your newly donloaded kernel uncompressed and ready to build. But before building them, you must configure them!
Configuring the kernel
Basically everyone has his/her own way to configure the kernel, depending on expertise level, system needs and even taste! But as a general rule you should first start off with some known parameters... so if this is your first time compiling the kernel under Red Hat you can use a config template from Red Hat. This template is located at /boot/config-. So, lets say you have kernel version 2.4.20-20.9 (latest official kernel for RHL 9), and you just uncompressed the sources at /home/me/kernel/linux-2.4.22. All you would have to do to use this configuration template from Red Hat into your 2.4.22 kernel source tree would be to copy the file over:
$ cp /boot/config-2.4.20-20.9 ~/kernel/linux-2.4.22/
Now you are ready to start making your own changes to the default Red Hat kernel configuration. To do so you need to start one of either tools: oldconfig, config, menuconfig, xconfig. You start these tools with the make command:
$ make oldconfig or $ make config or $ make menuconfig or $ make xconfig
make oldconfig will attempt to configure the current kernel using the parameters fed from an old configuration file .config.old or .config, since the file we copied has not this name making oldconfig will result on a series of text based questions, equivalent to make config
make menuconfig will result in a text based GUI which lets you load up an already existing configuration file (if you have a .config) or an alternate configuration file (like our config-2.4.20-20.9 file). This menu depends on ncurses, so you will have to see if these libraries are installed correctly on your system.
make xconfig is yet another GUI X based configuration tool which makes it easier and clearer to configure the kernel, this option also allows us to load an alternate configuration file (such as config-2.4.20-20.9). This GUI relys on the TCL-TK library (found in the kernel development section of redhat-config-packages).
To the ends of this guide, we'll be using either menuconfig or xconfig (to make it easier on you) to configure the kernel. So lets start by opening one of either:
$ make menuconfig or $ make xconfig
Once the GUI has started, find the button/menu entry that reads load configuration from file. The dialog that appears takes by default the current directory (i.e the kernel sources directory) so just write config-2.4.20-20.9 (or the version of your kernel). The program will load the options found on that file. Now you can navigate the entire tree structure by features and decide whether to include a feature or not. Be warned, you must read all the help entries on the options listed! To do this you can simply press the help button on the side of the feature/option (xconfig) or move with the arrow keys sideways to highlight the help button (menuconfig).
You will notice that you can compile the features in two ways: as modules (m, [M]) or into the kernel (y,[*]), or simply leave out an option (n, []). Compiling as modules has the side effect of making a lighter kernel, with just what it needs to do its job and rely on modules to load or unload drivers on the fly.
Options that you may surely want
First off you will *need*[/b to enable loadable modules support into the kernel, otherwise Red Hat will complaint... a lot (and may not even boot)! And speaking of complaints, you should take a look at your /etc/modules.conf file [b]before deciding whether or not you want something as module or into the kernel (I usually never touch modules.conf and let RH be, except for cases like ALSA, or my IOMEGA Zip Drive). For example, you may decide to compile into the kernel USB support, but when you boot for the first time, the system will complaint about not finding the USB modules (declared in modules.conf). Also remember that the beauty of Linux is that the kernel has the ability of being modular which means that it can load/unload pieces of it (mostly drivers) without requiring you to reboot (sound familiar? And yes I may sound repetitive, but it is a common tendency to compile a whole bunch of things into the kernel, getting a monolithic, unflexible kernel)
Some options are recommended to enable as modules, like the IDE CD-Rom support with SCSI emulation, you will need to either answer yes or module to the scsi support, and SCSI-CD-Rom support as module <-- This is very important to have ide-scsi emulation! for CD-Burners and even some DVD drives!.
As far as IDE chipset support goes, in my experience it is recommended to leave the Red Hat defaults for that part (I messed with them once and ended with a lousy HDD performance), unless you really know what you are doing. You may screw up the UDMA function of your chipset (and end like me with a losy HDD perfomance, recompile needed).
When it comes to sound support, you may want to compile it as module, because in that way if you want to install, for instance ALSA, it will be easier for ALSA to correctly intialize, or simply because you'll be able to trouble shoot if a problem is dependent on the sound modules.
For the cases of us, Radeon users, we "MUST" (and I can't stress that enough!) not compile even as modules, any other DRM driver (tdfx [3dfx] driver often comes compiled into the kernel in some distros), otherwise when we build our fglrx module, it will complaint (yet again) about another module loaded. In this section (character devices) you should also pay close attention to the agpgart driver, compile it as module, not into the kernel (remember fglrx problems regarding agpgart?)
For file systems support, you most surely (now a days it is quite often to do so) want to enable support for Fat, NTFS, Joliet, Transparent decompression, nfs, SMB (samba), etc. What I often do is to compile into the kenrel ext3 and ext2 (second extended) file systems, and leave the rest I'm interrested as modules.
Remember that if in doubt, Read the help!, some options have no help entries, so you may want to leave those as they are if you don't have a clue what do they do.
Note: On modern systems (specially with nForce motherboards) you may want to pay close attention to local APIC for UniProcessor machines (and IOAPIC) and ACPI (notice the different spelling, this is not a typo!). If in doubt consult www.nforcershq.com.
If you consider you are done configuring, procede to the next section. Like in a math test, I recommend you to double check your options before proceding, it can save you a lot of time and headaches. Exit with the save and exit button/menu entry.
Compiling the kernel
I use an abreviated method to compile the kernel, but for the sake of clarity I'll expose first the unzipped method and then the compressed one .
Once you are happy with your kernel configuration you must build the kernel and the sections you selected as modules. They are built in separate states. So lets first build the kernel, shall we?
You noticed that when you saved your configuration file (it is stored in the .config file) a message was displayed stating you should now run make dep. This is to build up the dependencies. This method is deprecated and is no longer used for kenrel 2.6 (the software should be intelligent enough to know where to depend, right). Anyway, we'll do just that:
$ make dep
This command will check the code for a while and when it finishes, you'll have your prompt back. Now you can build either the modules or the compressed kernel image, I usually build first the modules and then the image, the following steps may be run in the order you preffer:
$ make bzImage $ make modules
There are a lot of things that may go wrong, and to help you find out where the problem is, you'll constantly see/hear the recommendation to save the compilation output to a file, to that end you can do this:
$ make bzImage 2> kernel_make.err $ make modules 2> modules_make.err
The "2>" serves to redirect the standard error output to a file, in this case the file will be located on the top level directory of your kernel source tree. If the process finishes too soon or just want to make sure (any ways you should do it) check the contents of those files. If you encounter any Error message it will be there. Because warnings are treated as errors, it is most likely that you will find many lines of output from glibc/gcc complaints, these should not be very important. If everything went Ok, then you can continue with the installation. For these next two steps you will need to become root.
$ su password: # make modules_install # make install
Your kenrel is now installed. To try it out reboot and select it from the GRUB menu.
"Compressed compilation method"
I usually tend to use this method rather than the above, because it fits all steps into one long command line. Problem is that if anything goes wrong I usually have to re-run the part that crashed and send its output a file to see what the error(s) was (were).
$ su password: # make [clean] dep modules modules_install install
Depending if it is a first time compiling this code I omit the clean argument, otherwise I always include it, and finish with a make clean statement to erease from the tree any residual binary file, once the kernel is installed, of course!.
Patches
We often as newbies quick learn also about the existance of kernel patches, in fact this is one of the methods to upgrade your kernel into the next stable release subpatch version. But what are they (apart from the obvious)?? Why do I want to patch the kernel?? How do you apply them??
These questions (among others) are the most commonly asked. To answer that in order:
Patches are files that contain information about the source code of a given program (in this case, the kernel), they contain information like what line does need to be changed, in what file, add lines if necessary in a given section, etc. This is accomplished via two tools: diff and patch. diff (as you may have guessed) highlights the differences between two files when put into comparison. It is specially userful with files that contain hundreds if not 1000's of lines of code, and to apply the changes to just a few lines making this comparison by hand would take for ever. This program helps on automating this task and inserting (or removing) the pertinent lines, to the specified file in the correct path with the aid of the other program patch. Patches usually are composed of one file that contains the information about the file(s) to be patched. NOTE I am, by no means, an expert about patches, so if anyone out there would like to further this explanation would be swell!
You'd may want to patch the kernel for instance, if you wanted to improve a feature, solve a given problem with one feature or just to add another feature to your current kernel, or to upgrade to the next subpatch kernel version. The version of the kernel is determined by the major version number (2), the patch level (current version 4), and the subpatch level (improvements to the current patch level, in this case 22). But ofthen happens that a plain vanilla kernel lacks some features (like CPU scaling for powersaving on laptops), and in order to get those, you need to apply a patch. There are kernel hackers who do just this, they make code to add or improve certain kernel feature/option and publish these as patches. Other kernel hackers make an archive patch, contianing other people's patches into just one file, like the case of Alan Cox, Con Kolivas or the man himself: Linus Torvalds.
To apply a patch is usually simple: Get the patch you are interested in, uncompress it somewhere in your drive and then just change to the directory where you have your kernel sources, then simply issue the command:
cd /path/to/kernel/source patch -p1 < /path/to/patch/file or patch -p1 -i /path/to/patch/file
After applying a kernel patch (or any other source patch for that matter) you will need to confiugre those options added by the patch and rebuild your kernel. A concrete example as to the need for a patch would be the problems that many users were experiencing with the AGPGART driver on nVidia nForce motherboards, that prior to kernel 2.4.22 the only way to solve it was by applying a patch to the kernel.
RPM kenrels
You can also build binary distributable versions of you custom made kenrel in the form of RPM packages. If you pay attention to the top level directory of your kenrel sources you will most likely find a file called kernel.spec. These files are used to build RPM packages. A good reason to build bianary versions of the kenrel would be if you have several computers similar to one-another in terms of hardware and sofware confiugrarions, making it easier to build just once the kernel instead of building it on every one of them.
To build an RPM package of your kernel, you need to pass to the make command the argument rpm. Like this:
# make rpm
Many people have reported that they have trouble when building RPM packages of the kernel (I've been no exception) and there is also another issue with Red Hat 9 (ahd Phoebe): rpmbuild (the RPM builder) has by default turned on debugging information. This has the adverse effect of an abnormal rpm termination, because it can't find any debug lists in the source tree. To overcome this problem you should make an .rpmmacros (note the dot (.)) file in your home directory containing this line:
%debug_package %{null}
So the building process skips the debugging information. Mind that this change may not work for some people, because the process could complaint about a bad exit status from rpm.
Addendum: According to some other users, the make install secuence will just update lilo.conf (if using LILO) but will not re-write the boot sector with the updtated information, so an extra command is needed:
# make [clean] dep modules modules_install install # lilo -v
That should do it, at least for now!.