Rebuilding the kernel sounds like a pastime for hackers, but it is an important skill for any system administrator. First, you should rebuild the kernel on your system to eliminate the device drivers you don’t need. This reduces the amount of memory used by the kernel itself, as described in Section 6.2. The kernel is always present in memory, and the memory it uses cannot be reclaimed for use by programs if necessary.
You also need to occasionally upgrade your kernel to a newer version. As with any piece of your system, if you know of important bug fixes or new features in a kernel release, you may want to upgrade to pick them up. Those people who are actively developing kernel code will also need to keep their kernel up-to-date in case changes are made to the code they are working on. Sometimes, it is necessary to upgrade your kernel to use a new version of the compiler or libraries. Some applications (such as the X Window System) require a certain kernel version to run.
You can find out what kernel version you are running through the command uname -a. This should produce something like:
rutabaga% uname -a
Linux owl 2.4.19-64GB-SMP #2 SMP Fri Aug 9 21:46:03 CEST 2002 i686 unknown
Here, we see a machine running Version 2.4.19 of the kernel
(configured for a machine with more than one processor [SMP] and a
maximum of 64 GB RAM), which was last compiled on August 9. We see
other information as well, such as the hostname of the machine, the
number of times this kernel has been compiled (two), and the fact
that the machine is a Pentium Pro or better (as denoted by
i686
). The manual page for
uname(1) can tell you more.
The Linux kernel is a many-tentacled beast. Many groups of people work on different pieces of it, and some parts of the code are a patchwork of ideas meeting different design goals. Overall, however, the kernel code is clean and uniform, and those interested in exploring its innards should have little trouble doing so. However, because of the great amount of development going on with the kernel, new releases are made very rapidly — sometimes daily! The chief reason for this is that nearly all device drivers are contained within the kernel code, and every time someone updates a driver, a new release is necessary. As the Linux community moves toward loadable device drivers, the maintainers of those drivers can release them independently of the main kernel, alleviating the necessity of such rapid updates.
Currently, Linus Torvalds maintains the “official” kernel release. Although the GPL allows anyone to modify and rerelease the kernel under the same copyright, Linus’s maintenance of an “official” kernel is a helpful convention that keeps version numbers uniform and allows everyone to be on equal footing when talking about kernel revisions. In order for a bug fix or new feature to be included in the kernel, all one must do is send it to Linus (or whoever is in charge for the kernel series in question, Linus himself always maintains the most current kernel), who will usually incorporate the change as long as it doesn’t break anything.
Kernel version numbers follow the convention:
major
.minor
.patchlevel
major
is the major version number, which
rarely changes, minor
is the minor version
number, which indicates the current
“strain” of the kernel release, and
patchlevel
is the number of the patch to
the current kernel version. Some examples of kernel versions are
2.4.4, (patch level 4 of kernel Version 2.4), and 2.5.1 (patch level
1 of kernel Version 2.5).
By convention, even-numbered kernel versions (2.2, 2.4, and so on) are “stable” releases, patches that contain only bug fixes and no new features. Odd-numbered kernel versions (2.3, 2.5, and so on) are “development” releases, patches that contain whatever new code developers wish to add and bug fixes for that code. When a development kernel matures to the point where it is stable enough for wide use, it is renamed with the next highest (even) minor version number, and the development cycle begins again.
For example, kernel Versions 2.2 and 2.3 were worked on concurrently. Patches made to 2.2 were bug fixes — meant only to correct problems in the existing code. Patches to 2.3 included bug fixes as well as a great deal of new code — new device drivers, new features, and so on. When kernel Version 2.3 was stable enough, it was renamed to 2.4; a copy was made and named Version 2.5. Development continued with Versions 2.4 and 2.5. 2.4 is the new “stable” kernel, while 2.5 is a development kernel for new features.[28]
Note that this version-numbering convention applies only to Linus’s official kernel release and only to kernel versions after 1.0. Prior to 1.0 (this is now ancient history), there was only one “current” kernel version and patches were consistently made to it. The kernel development community has found that having two concurrent kernel versions allows those who want to experiment to use the development kernel, and those who need a reliable platform to stick with the stable kernel. In this way, if the development kernel is seriously broken by new code, it shouldn’t affect those who are running the newest stable kernel. The general rule is that you should use development kernels if you want to be on the leading edge of new features and are willing to risk problems with your system. Use the development kernels at your own risk.
If you are interested in how the existing kernel versions have evolved, check out http://www.kernel.org.
On
your system, the kernel sources most probably live in
/usr/src/linux
(unless you use the Debian
distribution, where you can find the kernel sources in
/usr/src/kernel-source
-versionsnumber).
If you are going to rebuild your kernel only from the current
sources, you don’t need to obtain any files or apply
any patches. If you wish to upgrade your kernel to a new version, you
need to follow the instructions
in the following section.
The official kernel is released as a gzipped tar file, containing the sources along with a series of patch files — one per patch level. The tar file contains the source for the unpatched revision; for example, there is a tar file containing the sources for kernel Version 2.4 with no patches applied. Each subsequent patch level is released as a patch file (produced using diff), which can be applied using the patch program. In Section 14.2.8 in Chapter 14, we describe the use of patch in detail.
Let’s
say you’re upgrading to kernel Version 2.4 patch
level 4. You’ll need the sources for 2.4 (the file
might be named v2.4.0.tar.gz
) and the patches
for patch levels 1 through 4. These files would be named
patch1
, patch2
, and so
forth. (You need all the patch files up to the
version to which you’re upgrading. Usually, these
patch files are rather small, and are gzipped on
the archive sites.) All these files can be found in the
kernel
directory of the Linux
FTP archive sites; for example, on ftp://ftp.kernel.org, the directory
containing the 2.4 sources and patches is
/pub/linux/kernel/v2.4
. You will find the kernel
sources here as tar archives, compressed with both
gzip and bzip2.
If you are already at some patch level of the kernel (such as 2.4 patch level 2) and want to upgrade to a newer patch level, you can simply apply the patches from the version you have up to the version to which you’d like to upgrade. If you’re upgrading from, say, 2.4 patch level 2 to 2.4 patch level 4, you need the patch files for 2.4.3 and 2.4.4.
First, you need to unpack the source tar file from
/usr/src
. You do this with commands such as:
rutabaga#cd /usr/src
rutabaga#mv linux linux.old
rutabaga#tar xzf v2.4.0.tar.gz
This saves your old kernel source tree as
/usr/src/linux.old
and creates
/usr/src/linux
containing the new sources. Note
that the tar file containing the sources includes the
linux
subdirectory.
You should keep your current kernel sources in the directory
/usr/src/linux
because there are two symbolic
links — /usr/include/linux
and
/usr/include/asm
— that point into the
current kernel source tree to provide certain header files when
compiling programs. (You should always have your kernel sources
available so that programs using these include files can be
compiled.) If you want to keep several kernel source trees around, be
sure that /usr/src/linux
points to the most
recent one.
If you are applying any patch files, you
use the patch program. Let’s
say that you have the files patch1.gz
through
patch4.gz
, which are
gzipped. These patches should be applied from
the kernel sources main directory. That doesn’t mean
the patch files themselves should be located there, but rather that
patch should be executed from e.g.
/usr/src/linux
. For each patch file, use the
command:
gunzip -c patchfile
| patch -p1
from /usr/src
. The -p1
option
tells patch it shouldn’t strip
any part of the filenames contained within the patch file except for
the first one.
You must apply each patch in numerical order by patch level. This is
very important. Note that using a wildcard such as
patch*
will not work because the
*
wildcard uses ASCII order, not numeric order.
(Otherwise, if you are applying a larger number of patches,
patch1
might be followed by
patch10
and patch11
, as
opposed to patch2
and
patch3
.) It is best to run the previous command
for each patch file in succession, by hand. This way you can ensure
you’re doing things in the right order.
You shouldn’t encounter problems when patching your source tree in this way unless you try to apply patches out of order or apply a patch more than once. Check the patch manual page if you do encounter trouble. If all else fails, remove the new kernel source tree and start over from the original tar file.
To double-check that the patches were applied successfully, use the commands:
find /usr/src/linux -follow -name "*.rej" -print find /usr/src/linux -follow -name "*#" -print
This lists any files that are “rejected” portions of the patch process. If any such files exist, they contain sections of the patch file that could not be applied for some reason. Look into these, and if there’s any doubt, start over from scratch. You cannot expect your kernel to compile or work correctly if the patch process did not complete successfully and without rejections.
A handy script for patching the kernel is available and can be found
in scripts/patch-kernel
. But as always, you
should know what you are doing before using automated tools, even
more so when it comes to the very core of the operating system, the
kernel.
There are six steps to building the kernel, and they should be quite painless. All these steps are described in more detail in the following pages.
Make sure that all the required tools and utilities are installed and
at the appropriate versions. See the file
Documentation/Changes
in the kernel source for
the list of requirements.
Run make config, which asks you various questions about which drivers you wish to include. You could also use the more comfortable variants make menuconfig or (only when you are running the X Window System) make xconfig.
If you have previously built a kernel and then applied patches to a new version, you can run make oldconfig to use your old config but be prompted for any new options that may not have been in the old kernel.
Run make dep to gather dependencies for each source file and include them in the various makefiles.
If you have built a kernel from this source tree before, run make clean to clear out old object files and force a complete rebuild.
Run make bzImage to build the kernel itself.
Go have a coffee (or two, depending on the speed of your machine and amount of available memory).
Install the new kernel image, either on a boot floppy or via LILO. You can use make bzDisk to put the kernel on a boot floppy.
All these commands are executed from
/usr/src/linux
, except for Step 5, which you can
do anywhere.
A README
is included in the kernel sources,
which should be located at /usr/src/linux/README
on your system. Read it. It contains up-to-date notes on kernel
compilation, which may be more current than the information presented
here. Be sure to follow the steps described there, using the
descriptions given later in this section as a guide.
The
first step is to run make config. This executes
a script that asks you a set of yes/no questions about which drivers
to include in the kernel. There are defaults for each question, but
be careful: the defaults probably don’t correspond
to what you want. (When several options are available, the default
will be shown as a capital letter, as in [Y/n]
.)
Your answers to each question will become the default the next time
you build the kernel from this source tree.
Simply answer each question, either by pressing Enter for the
default, or pressing y
or n
(followed by Enter). Some questions don’t have a
yes/no answer; you may be asked to enter a number or some other
value. A number of the configuration questions allow an answer of
m
in addition to y
or
n
. This option allows the corresponding kernel
feature to be compiled as a loadable kernel module, as opposed to
building it into the kernel image itself. Loadable modules, covered
in the following section, Section 7.5, allow portions of the
kernel (such as device drivers) to be loaded and unloaded as needed
on a running system. If you are unsure about an option, type
?
at the prompt; for most options, a message will
be shown that tells you more about the option.
Some people say that make config has so many options now that it is hardly feasible to run it by hand any longer, as you have to concentrate for a long time to press the right keys in response to the right questions. Therefore, people are moving to the alternatives described next.
An alternative to running make config is make xconfig, which compiles and runs an X-Window-based kernel configuration program. In order for this to work, you must have the X Window System running, have the appropriate X11 and Tcl/Tk libraries installed, and so forth. Instead of asking a series of questions, the X-based configuration utility allows you to use checkboxes to select which kernel options you want to enable. The system remembers your configuration options each time you run make config, so if you’re adding or removing only a few features from your kernel, you need not reenter all the options.
Also
available is make menuconfig
, which uses the
text-based curses library, providing a similar
menu-based kernel configuration if you don’t have X
installed. make menuconfig and make xconfig are much more comfortable than make config, especially because you can go back to an option
and change your mind up to the point where you save your
configuration.
The following is part of a session with make config. When using make menuconfig or make xconfig, you will encounter the same options, only presented in a more user-friendly fashion (and we actually recommend the use of these tools if at all possible, as it is very easy to get confused by the myriad of configuration options):
rm -f include/asm
( cd include ; ln -sf asm-i386 asm)
/bin/sh scripts/Configure arch/i386/config.in
#
# Using defaults found in .config
#
*
* Code maturity level options
*
Prompt for development and/or incomplete code/drivers (CONFIG_EXPERIMENTAL) [Y/n/?]
*
* Loadable module support
*
Enable loadable module support (CONFIG_MODULES) [Y/n/?]
Set version information on all module symbols (CONFIG_MODVERSIONS) [N/y/?]
Kernel module loader (CONFIG_KMOD) [Y/n/?]
*
* Processor type and features
*
Processor family (386, 486, 586/K5/5x86/6x86/6x86MX, Pentium-Classic, ...
defined CONFIG_MPENTIUMIII
Toshiba Laptop support (CONFIG_TOSHIBA) [N/y/m/?]
/dev/cpu/microcode - Intel IA32 CPU microcode support (CONFIG_MICROCODE) [M/n/y/?]
/dev/cpu/*/msr - Model-specific register support (CONFIG_X86_MSR) [M/n/y/?]
/dev/cpu/*/cpuid - CPU information support (CONFIG_X86_CPUID) [M/n/y/?]
High Memory Support (off, 4GB, 64GB) [4GB]
defined CONFIG_HIGHMEM4G
Math emulation (CONFIG_MATH_EMULATION) [N/y/?]
MTRR (Memory Type Range Register) support (CONFIG_MTRR) [Y/n/?]
Symmetric multi-processing support (CONFIG_SMP) [Y/n/?]
*
* General setup
*
Networking support (CONFIG_NET) [Y/n/?]
...and so on...
*** End of Linux kernel configuration.
*** Check the top-level Makefile for additional configuration.
*** Next, you may run 'make bzImage', 'make bzdisk', or 'make
install'.
If you have gathered the information about your hardware when
installing Linux, that information is probably sufficient to answer
the configuration questions, most of which should be straightforward.
If you don’t recognize some feature,
it’s a specialized feature that you
don’t need. The following questions are found in the
kernel configuration for Version 2.4.4. If you have applied other
patches, additional questions might appear. The same is true for
later versions of the kernel. Note that in the following list we
don’t show all the kernel configuration options;
there are simply too many of them, and most are self-explanatory. We
have highlighted only those that may require further explanation.
Remember that if you’re not sure how to answer a
particular question, the default answer is often the best choice.
When in doubt, it is also a good idea to type ?
and check the help message.
It should be noted here that not all Linux device drivers are actually built into the kernel. Instead, some drivers are available only as loadable modules, distributed separately from the kernel sources. (As mentioned earlier, some drivers can be either built into the kernel or compiled as modules.) One notable kernel driver available only as a module is the “floppy tape” driver for QIC-117 tape drives that connect to the floppy controller.
If you can’t find support for your favorite hardware device in the list presented by make config, it’s quite possible that the driver is available as a module or a separate kernel patch. Scour the FTP sites and archive CD-ROMs if you can’t find what you’re looking for. In the next section, Section 7.5, kernel modules are covered in detail.
Prompt for development and/or incomplete code/drivers
Answer yes for this item if you want to try new features that aren’t considered stable enough by the developers. You do not want this option unless you want to help test new features.
Processor family (386, 486, 586/K5/5x86/6x86/6x86MX, Pentium-Classic, Pentium-MMX, Pentium-Pro/Celeron/Pentium-II, Pentium-III/Celeron/Coppermine, Pentium-4, K6/K6-II/K6-III, Athlon/Duron/K7, Crusoe, Winchip-C6, Winchip-2, Winchip-2A/Winchip-3, CyrixIII/C3) [Pentium-III/Celeron/Coppermine]
Here, you have to specify the CPU type that you have. The kernel will then be compiled with optimizations especially geared toward your machine. Note that if you specify a higher processor here than you actually have, the kernel might not work. Also, the Pentium II MMX is a 686, not a 586 chip.
Math emulation
Answer no if you have a Pentium or better. Answer yes to this item if you do not have a floating-point coprocessor in your machine. This is necessary for the kernel to emulate the presence of a math coprocessor.
Symmetric multi-processing support
This enables kernel support for more than one CPU. If your machine has more than one CPU, say yes here; if not, say no.
Enable loadable module support
This enables the support for dynamically loading additional modules. You definitely want to enable this.
Set version information on all symbols for modules
This is a special option that makes it possible to use a module compiled for one kernel version with another kernel version. A number of problems are attached to this; say no here unless you know exactly what you are doing.
Kernel module loader
If you enable this option, the kernel can automatically load and unload dynamically loadable modules as needed.
Networking support
Answer yes to this option if you want any sort of networking support in your kernel (including TCP/IP, SLIP, PPP, NFS, and so on).
PCI support
Enable this option if your motherboard includes the PCI bus and you have PCI-bus devices installed in your system. The PCI BIOS is used to detect and enable PCI devices; kernel support for it is necessary for use of any PCI devices in your system.
System V IPC
Answering yes to this option includes kernel support for System V interprocess communication (IPC) functions, such as msgrcv and msgsnd. Some programs ported from System V require this; you should answer yes unless you have a strong aversion to these features.
Sysctl support
This option instructs the kernel to provide a way to change kernel parameters on-the-fly, without rebooting. It is a good idea to enable this unless you have very limited memory and cannot tolerate the extra 8 KB that this option adds to the kernel.
Parallel port support
Enable this option if you have a parallel port in your system and want to access it from Linux. Linux can use the parallel port not only for printers, but also for PLIP (a networking protocol for parallel lines), ZIP drives, scanners, and other things. In most cases, you will need an additional driver to attach a device to the parallel port.
Normal floppy disk support
Answer yes to this option unless you don’t want support for floppy drives (this can save some memory on systems where floppy support isn’t required).
Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support
Answer yes to this option unless you don’t need IDE/MFM/RLL drive support. After answering yes, you will be prompted for types of devices (hard disks, CD-ROM drives, tape drives, and floppy drives) you want to access over the IDE driver. If you have no IDE hardware (only SCSI), it may be safe to disable this option.
XT harddisk support
Answer yes to this only if you have an older XT disk controller and plan to use it with your Linux system.
Parallel port IDE device support
This option enables support for IDE devices that are attached to the parallel port, such as portable CD-ROM drives.
Networking options
If you previously selected networking
support, you will be asked a series of questions about which
networking options you want enabled in your kernel. Unless you have
special networking needs (in which case you’ll know
how to answer the questions appropriately), answering the defaults
for these questions should suffice. A number of the questions are
esoteric in nature (such as IP: Disable Path MTU Discovery
) and you should select the defaults for these in
almost all cases.
SCSI support
If you have a SCSI controller of any kind, answer yes to this option. You will be asked a series of questions about the specific SCSI devices on your system; be sure you know what type of hardware you have installed. All these questions deal with specific SCSI controller chips and boards; if you aren’t sure what sort of SCSI controller you have, check the hardware documentation or consult the Linux HOWTO documents.
You will also be asked if you want support for SCSI disks, tapes, CD-ROMs, and other devices; be sure to enable the options appropriate for your hardware.
If you don’t have any SCSI hardware, you should answer no to this option; it greatly reduces the size of your kernel.
Network device support
This is a series of questions about the specific networking controllers Linux supports. If you plan to use an Ethernet card (or some other networking controller), be sure to enable the options for your hardware. As with SCSI devices, you should consult your hardware documentation or the Linux HOWTO documents (such as the Ethernet HOWTO) to determine which driver is appropriate for your network controller.
Amateur Radio support
This option enables basic support for networking over public radio frequencies. If you have the equipment to use the feature, enable this option and read the AX25 and the HAM HOWTO.
ISDN subsystem
If you have ISDN hardware in your system, enable
this option and select the ISDN hardware
driver suitable for your hardware. You will most probably also want
to select Support synchronous PPP
(see Section 15.3 in Chapter 15).
Old CD-ROM drivers
This is a series of questions dealing with the specific CD-ROM drivers supported by the kernel, such as the Sony CDU31A/33A, Mitsumi, or SoundBlaster Pro CD-ROM, and so on. If you have a SCSI or IDE CD-ROM controller (and have selected support for it earlier), you need not enable any of these options. Some CD-ROM drives have their own interface boards, and these options enable drivers for them.
Character devices
Linux supports a number of special “character” devices, such as serial and parallel port controllers, QIC-02 tape drives, and mice with their own proprietary interfaces (not mice that connect to the serial port, such as the Microsoft serial mouse). This section also includes the joystick support and the “Video for Linux” drivers that support video and frame-grabbing hardware. Be sure to enable the options corresponding to your hardware.
Filesystems
This is a series of questions for
each filesystem type supported by the kernel. As discussed in the
section Section 6.1, a number of filesystem types
are supported by the system, and you can pick and choose which to
include in the kernel. Nearly all systems should include support for
the Second Extended and /proc
filesystems. You
should include support for the MS-DOS filesystem
if you want to access your MS-DOS files directly
from Linux, and the ISO 9660 filesystem to access
files on a CD-ROM (most of which are encoded in
this way).
Console drivers
Make sure you select at least VGA text console
in this section, or you won’t be
able to use your Linux system from the console.
Sound card support
Answering yes to this option presents you with several questions about your sound card, which drivers you wish to have installed, and other details, such as the IRQ and address of the sound hardware.
Kernel hacking
This section contains options that are useful only if you plan on hacking the Linux kernel yourself. If you do not want to do this, answer no.
After running make config or its equivalent,
you’ll be asked to edit “the
top-level Makefile,” which means
/usr/src/linux/Makefile
. In most cases,
it’s not necessary to do this. If you wanted to
alter some of the compilation options for the kernel, or change the
default root device or SVGA mode, you could edit
the makefile to accomplish this. Setting the root device and
SVGA mode can easily be done by running
rdev on a compiled kernel image, as we saw in
Section 5.2.1 in Chapter 5.
If you wish to force a complete recompilation of the kernel, you should issue make clean at this point. This removes from this source tree all object files produced from a previous build. If you have never built the kernel from this tree, you’re probably safe skipping this step (although it can’t hurt to perform it). If you are tweaking minor parts of the kernel, you might want to avoid this step so that only those files that have changed will be recompiled. At any rate, running make clean simply ensures the entire kernel will be recompiled “from scratch,” and if you’re in any doubt, use this command to be on the safe side.
Now you’re ready to compile the kernel. This is done with the command make bzImage. It is best to build your kernel on a lightly loaded system, with most of your memory free for the compilation. If other users are accessing the system, or if you’re trying to run any large applications yourself (such as the X Window System, or another compilation), the build may slow to a crawl. The key here is memory. If a system is low on memory and starts swapping, it will be slow no matter how fast the processor is.
The kernel compilation can take anywhere from a few minutes to many hours, depending on your hardware. There is a great deal of code — well over 10 MB — in the entire kernel, so this should come as no surprise. Slower systems with 4 MB (or less) of RAM can expect to take several hours for a complete rebuild; faster machines with more memory can complete it in less than half an hour. Your mileage will most assuredly vary.
If any errors or warnings occur while compiling, you cannot expect the resulting kernel to work correctly; in most cases, the build will halt if an error occurs. Such errors can be the result of incorrectly applying patches, problems with the make config step, or actual bugs in the code. In the “stock” kernels, this latter case is rare, but is more common if you’re working with development code or new drivers under testing. If you have any doubt, remove the kernel source tree altogether and start over.
When the compilation is complete, you will be left with the file
bzImage
in the directory
/usr/src/linux/arch/i386/boot
. (Of course, if
you’re attempting to build Linux on a platform other
than the Intel x86, the kernel image will be found in the
corresponding subdirectory under arch
.) The
kernel is so named because it is the executable image of the kernel,
and it has been internally compressed using the
bzip2 algorithm. When the kernel boots, it
uncompresses itself into memory: don’t attempt to
use bzip2 or bunzip2 on
bzImage
yourself! The kernel requires much less
disk space when compressed in this way, allowing kernel images to fit
on a floppy. Earlier kernels supported both the
gzip and the bzip2
compression algorithms, the former resulting in a file called
zImage
. Because bzImage
gives better compression results, however, gzip
should not be used, as the resulting kernels are usually too big to
be installed these days.
If you pick too much kernel functionality, you can
get a kernel too big
error at the end of the kernel compilation. This
happens rarely because you need only a very limited amount of
hardware support for one machine, but it can happen. In this case,
there is one way out: compile some kernel functionality as modules
(see Section 7.5).
You should now run rdev on the new kernel image to verify that the root filesystem device, console SVGA mode, and other parameters have been set correctly. This is described in Section 5.2.1 in Chapter 5.
With your new kernel in hand, you’re ready to configure it for booting. This involves either placing the kernel image on a boot floppy, or configuring LILO to boot the kernel from the hard drive. These topics are discussed in Section 5.2 in Chapter 5. To use the new kernel, configure it for booting in one of these ways, and reboot the system.
A warning: you should always keep a known good kernel available for booting. Either keep a previous backup kernel selectable from LILO or test new kernels using a floppy first. This will save you if you make a mistake such as omitting a crucial driver in your new kernel, making your system not bootable.
[28] Actually, the first versions of the 2.4 kernel series were not as stable as the number implies, which is why many users stayed with the 2.2 series for a while. By now, the current 2.4 kernel can be considered very stable, though, if you don’t use any 2.4 kernels before 2.4.16.