Linux Performance Tuning for the Faint of Heart
Have you ever wondered why in the blazes someone would want to recompile a Linux system kernel? For some, that is a challenging question. Many new users to Linux are under the impression that when they install Linux, the installation itself is perfect. Don't assume that Linux is set up efficiently for your exact setup out of the box. Here's why (and how) to change it.
Let's say you have bought a new laptop, and you want to run Linux on it. You've got only 4MB of RAM, and you've got only 100MB of hard drive space. A finely tuned Linux kernel is key to having all possible memory space available on your system, and thus is the key to having a faster system for a small-time investment.
You are probably aware that Linux provides “virtual memory” (also known as swap space or paging space) that allows programs to use more memory than is really on the system by temporarily moving the contents of some of that memory to disk. You may not be aware, however, that no parts of the kernel can be paged out to disk. Every byte taken up by the kernel is a byte that can't be used by anything else.
If the kernel you are running has SCSI support, networking, and sound all compiled in, but you don't have or use SCSI, networking, or a sound card, you are wasting memory. This is probably the case if your kernel came with your Linux distribution, because those kernels are generally compiled to work with a very wide selection of devices, and are not tuned to your hardware.
If you only have 4MB of memory, you are also likely wasting a lot of time as other programs get swapped out to disk and then back into memory. By compiling a new kernel without the unnecessary pieces, you can make your Linux computer run a lot faster.
Fortunately, Linux makes this easy.
First of all, you need to consider the hardware you have. What types of peripherals do you have? What type of mouse do you have? Do you have a sound card?
To build and compile the best kernel for your system, you must be aware of your hardware make-up. You may find it helpful to sit down and list all the parts of your computer. Not only will this help you now, but it will also help you post good problem reports if you encounter a problem or bug, since you need the same information about your configuration when posting problem reports.
To configure your system, you first need to have the Linux source code installed on your system. This is available via ftp from nic.funet.fi in /pub/OS/Linux/PEOPLE/Linus, tsx-11.mit.edu in the directory /pub/linux/sources/system, or sunsite.unc.edu in /pub/Linux/kernel, or other mirrors around the world. The directory name will depend on the kernel version: Linux versions 1.1.x are kept in the v1.1 directory, and have names like linux-1.1.45.tar.gz, with patch named like patch46.gz. You only need to get patches with numbers later than the version of the tar file you get.
Alternately, if you bought Linux from someone, they are required by Linux's GPL copyright to have provided the source, or to provide it (possibly for a nominal fee) upon request.
The source code should be unpacked into /usr/src/linux, because it expects to be there. See the sidebar “Unpacking the Linux Source” if you do not know how to do this.
After unpacking the source, you should apply any kernel patches that are needed to get the version you want. You should insert your patches (while they are still compressed, or gzipped) into /usr/src/linux. Then from /usr/src/linux, type:
gunzip -c patch?.gz | patch -s -p1gunzip -c patch??.gz | patch -s -p1
The ? gets patches 1-9 in order, and should be done only if you are using one of those patches. The ?? will get all patches (that exist, and that you have downloaded) between 10 and 99 in order. It is important that all the patches be applied in order. The -s argument to patch tells patch to work silently, and only complain about errors. The -p1 tells patch that we are in the /usr/src/linux directory, so that it knows how to find files, and puts new files in the right place. The -s flag is optional; the -p1 argument is mandatory.
Alternately, you can run each patch separately:
gunzip -c patch8.gz | patch -p1gunzip -c patch9.gz | patch -p1...gunzip -c patch46.gz | patch -p1
and so on.
Once you've completed the patches, you may want to remove any unnecessary files created by the patches. These files are the original versions of the files that are changed in any way, so they can take up a substantial amount of space. You can find and remove them by typing:
find /usr/src/linux -name '*.orig' -o -name '*~'-exec rm -f {} ;
You can look for any files that did not patch correctly, and thus find out in advance that there has been a problem that will likely make it impossible to compile your kernel, by typing:
find /usr/src/linux -name '*.rej' -print
That will list any files for which there were “rejected hunks”; patches that could not be fitted into the source correctly. If you find any of these files, start over. If you still see these files, ask someone for help; there are too many things that could be wrong to cover in this article.
Now, from within /usr/src/linux, type make config. You are now prompted to answer many questions about your system. If you say you don't have hardware that you do have, that particular hardware will not be supported by the new kernel. Likewise, if you say you have hardware that you don't have, you will waste memory. Also, you want to enable only the software features that you are going to use.
I will attempt to point out some of the most significant configuration questions. One of the first questions is:
'Kernel math emulation' CONFIG_MATH_EMULATION ?
If you don't have a math co-processor, you should answer this question YES. Those who do have a math co-processor chould answer NO. A kernel with math-emulation compiled in it will still use the processor if one is present. The math-emulation simply won't get used in that instance. This will result however in a somewhat larger kernel and a waste of memory.
There are a couple of questions about hard disk support. One in particular can cause a bit of confusion:
'XT harddisk support' CONFIG_BLK_DEV_XD
I answer this question NO. This really doesn't have to do with hard disks—it has to do with your controller card. AT controller cards are 16-bit cards supported by the standard hard disk driver. XT controller cards are 8-bit cards that are very rare in 386-class machines.
'TCP/IP networking' CONFIG_INET :
Answer YES if you plan to have your system interactive on the net. This includes SLIP and PPP connections. Answer NO if you aren't going to connect to the net right now; you can always compile another kernel later.
'System V IPC' CONFIG_SYSVIPC :
This isn't used for many things, but doesn't use much memory. YES is recommended.
'Use -m486 flag for 486-specific optimizations' CONFIG_M486 :
If you have an i386 system, answer NO. Otherwise you should select YES. This uses a little bit of memory. Adding this flag will not slow a 386 down, other than using extra memory, but will speed up a 486 quite a bit.
There are a series of questions which have to do with different types of SCSI drivers and interfaces. If you have a SCSI controller, then you would want to enable the drivers via the configuration process. For those who don't have a SCSI controller, select NO, and move on to the next step in the configuration. If you don't select SCSI support, you won't be asked whether or not to include SCSI devices.
Network device support mainly has to do with selecting the proper Ethernet device or other network connection. PPP and SLIP are used to connect to TCP/IP networks over the serial port; PLIP is used to connect TCP/IP networks over the parallel port, and the rest are ethernet controllers. Do not select drivers of devices you do not have. This can sometimes cause conflict later when you are booting.
Another important section in the kernel config process has to do with the different filesystems. There is an advantage to compiling the kernel to have only the filesystems you need. There are several different filesystems supported by Linux:
'Standard (minix) fs support' CONFIG_MINIX_FS :
This is the original Linux filesystem. It is considered to be one of the more stable filesystems, and is still widely used. You probably want this unless you are really desperate for space or will really never use it.
'Extended fs support' CONFIG_EXT_FS :
Only select this if you still have filesystems from the 'old days' that will use this precursor of the second extended filesystem. This filesystem is slow and no longer actively maintained. It is there only for backwards compatibility. NO.
'Second extended fs support' CONFIG_EXT2_FS :
The ext2 filesystem is the most 'full-featured' of the filesystems. It is a super rewrite of the original extended filesystem, with improved speed as well. This is by far the most popular filesystem. A filesystem debugging package is available for this filesystem that can help you recover from fairly bad filesystem crashes. YES.
'xiafs filesystem support' CONFIG_XIA_FS :
This is a modification of the Minix filesystem (allowing for such things as longer filenames). If you plan to use it (YES), otherwise (NO).
'msdos fs support' CONFIG_MSDOS_FS :
This filesystem allows for access to the FAT filesystem used by MS-DOS. It is a great advantage for those who need to access floppies or hard disk partitions that use that filesystem. In addition, if you use the UMSDOS filesystem (usually because you installed Linux on an MSDOS partition), you need to include MSDOS filesystem support.
'/proc filesystem support' CONFIG_PROC_FS :
The PROC filesystem does not touch your disk. It is used by the kernel to provide data kept within the kernel itself to system programs that need that information. Many standard utilities will not function without this filesystem. YES.
'NFS filesystem support' CONFIG_NFS_FS :
The NFS filesystem is necessary for those who have a physical network and need to mount NFS filesystems from other computers. If you are on a TCP/IP network, you probably want this option. Otherwise, you don't.
'Kernel profiling support' CONFIG_PROFILE :
This is used only by seasoned kernel hackers. You don't need this if you need to read this article...
'Selection (cut and paste for virtual consoles)' :
Self explanatory. If you want to be able to use your mouse in any of your VC's, then you would select YES. Note that this requires a separate selection program to work. Your mouse will be inactive without this program. This has nothing to do with X-windows.
The last section of the configuration process that needs insight has to do with sound card options. If you want sound card support, then you would definitely select YES. The confusing part are the next two questions; confusing because of the order they fall in.
Full driver? NO. I select NO because I want to configure my kernel to handle only my particular sound card. I don't want to enable drivers for cards I don't have. This simply wastes space.
Immediately following is: Disable? NO. It seemed strange to me that the driver question would come before a question about disabling the sound drivers altogether. Nonetheless, you should select NO, and answer the questions that follow accordingly, depending on what hardware you have.
That was the last part of the configuration process. All that remains is to make the system dependencies. After that, the actual kernel compile!
There isn't any confusing part about making the dependencies. All you do is type make depend (in the /usr/src/linux directory, which you should already be in); this sets up the system dependencies that all the files have. This allows make to intelligently recompile only the right files if you have to make changes to the source code.
After the system dependencies have been created, you are ready to compile the newly configured kernel. At this point, you should type make zImage to create a compressed kernel. This helps in the process of keeping your kernel small. Depending on the speed of your machine, the amount of memory you have, and how many things you are compiling into your kernel, your compile could take anywhere from around 15 minutes on a fast 486 or Pentium to several hours on a slow 386sx with 4MB of memory.
When the compiling process is complete, you will find a newly created kernel, zImage, in the /usr/src/linux directory. The process of installing the new kernel however is not yet complete. If you reboot right now, even though you have compiled a new kernel, you will still boot your old kernel. You still need to install the new kernel.
Before you install the new kernel, you should rename your old kernel, so that you can use it in the case of an emergency. In the / directory, there should be an image of your old kernel (zImage). Simply rename it to zImage.old using the mv command. This will be useful in the event that your new kernel will not boot up; you at least have a backup that still allows for a functional system.
Now, you must edit (if necessary) the LILO configuration file, so that it will accept your new kernel. It is most often found in the file /etc/lilo/config, but may be found as /etc/lilo.conf. Basically, editing the configuration file and running lilo tells the LILO which kernel to use upon bootup. The first image to be set up in the config file will be the default. By putting the new kernel image first, we will ensure that the new kernel boots by default; if we were to put the DOS entry first, DOS would boot by default. Here's an example:
boot = /dev/hda
#This is the path to the NEW kernel image to be bootedimage = /zImagelabel = linux
#This is the path to the OLD kernel image to be booted#if the other should fail to bootimage = /zImage.oldlabel = linux.old
#This is the path to the DOS operating systemother = /dev/hda1table = /dev/hdalabel = dos
Once you've edited the configuration file, copy or move the new kernel image to the / directory. Make sure that /zImage and /zImage.old are present before going any further. Next, you need to go back into the /etc/lilo directory and type ./lilo to run lilo. Alternately (if /etc/lilo doesn't exit), you may need to cd to /etc and run /sbin/lilo. In either case, this is the “installation” step which makes it possible for you to boot your new kernel.
You are now ready to boot your new kernel. To do this, type shutdown -r now.
If you have not installed your new kernel as the default kernel by making it the first entry in /etc/lilo/config, you will need to manually select your new kernel as you boot up. You activate the LILO menu by pressing <shift>, <control>, or <alt keys> as LILO is starting, or by pressing the <CapsLock> or <ScrollLock> key before LILO starts.
At the LILO prompt, make sure you type the label of the image, and not the filename of the image. If LILO can't find the image you ask for, it will tell you. Typing ? will give you a list of labels to choose from.
During the boot process, be sure to look at the information that relates the version of the kernel being booted, and the day that it was compiled (it's all on the same line). Mine looks like this:
Linux version 1.0.9 (root@HoMiEz.ShOpPiN.NeT) Thu Jul 14 22:45:16 1994
This particular line tells which version of the kernel is being booted, and the date and time that it was last compiled. The information shown here should coincide with the compile process you just recently completed. If there is an inconsistency, be sure to check your /etc/lilo/config file. Make sure that you put the proper label name for the particular table on the hard drive.
Once the new kernel is booted, you are free to hack away. Kernel compiling can be a confusing process. Some new administrators are intimidated by compiling a new kernel, but it is a prerequisite to running an optimized system. After a few kernel upgrades, you can become skilled in maintaining your system optimally. Then you can pass that knowledge to those who are as unsure as you once were. Remember, the more you know about your own system, the more optimized you become in using it.
Before you unpack the kernel source, it is a good idea first to backup you old kernel. You should do this, just for the moment, until you completely get the new kernel functioning properly. You can even shrink the size of the old kernel source by using tar and then compressing it. It is better to use both, as a double strength method:
cd /usr/srctar cvf linux-old.tar linuxgzip -9 linux-old.tar
The resulting file should be linux-old.tar.gz. After you've done this, it is safe to remove the old source directory by typing:
rm -rf linux
After you've done this, you can uncompress the new kernel. You must first move the new kernel source to /usr/src. Then type the following:
gunzip -c new-kernel-name.gz | tar xvof -
Once this process is complete, you are ready to move on. I'd also suggest keeping the new compressed kernel source in a backup directory. This way, if an error occurs in the process of upgrading and compiling your new kernel, you always have un-patched, “virgin” source to start over with. This eliminates the time it takes to download the kernel source again and also leaves you more time to concentrate on the task at hand.
The kernel sources are available at a large number of Linux ftp sites, including sunsite.unc.edu in /pub/Linux/kernel, tsx-11.mit.edu in /pub/linux/sources/system, and nic.funet.fi in /pub/OS/Linux/kernel/src. Kernel sources stored at these sites are typically gzipped tar files with filenames of linux-version.tar.gz.
If you got Linux from a distributor, they may have already given you the kernel source. If they haven't, they are required by the GNU General Public License to make it available to you.
Clarence Smith, Jr. is a student at the University of Washington, working on a Public Relations and Sociology degree. He hopes to develop an increased knowledge of the Linux Operating System by the development of some useful software tools. Clarence lives by the hacker ethic of striving for perfection, based on a beutiful line of code and functionality.