Linux
by Kamran Husain and Tim Parker
IN THIS CHAPTER
- Upgrading and Installing New Kernel Software
- Compiling the Kernel from Source Code
- Adding Drivers to the Kernel
- Upgrading Libraries
- An Introduction to the Linux Source Tree
- Making Loadable Modules for Linux
- The rc.modules File
This chapter will look at
- How to install and recompile the kernel of Linux
- How to add new software to the kernel
- How to install new versions of the shared libraries
- The steps necessary to create a new Linux kernel
- How to use the kernel source files
- Using dynamic modules
- An introduction to the ELF format
Usually, you will want to leave the kernel alone, except when you are performing
a major upgrade or installing a new device driver that has special kernel modifications.
The details of the process are usually supplied with the software. However, this
chapter gives you a good idea of the general process.
Few people will want to change the details in the kernel source code, because
they lack the knowledge to do so (or have enough knowledge to know that hacking the
kernel can severely damage the system). However, most users will want to install
new versions of Linux, add patches, or modify the kernel's behavior a little.
-
WARNING: Don't modify
the kernel unless you know what you are doing. If you damage the source code, your
kernel may be unusable, and in the worst cases, your file system may be affected.
Take care and follow instructions carefully. You need to know several things about
kernel manipulation, and we can only look at the basics in this chapter.
Several versions of Linux are commonly used, with a few inconsistencies between
them. For that reason, the exact instructions given here may not work with your version
of Linux. However, the general approach is the same, and only the directory or utility
names may be different. Most versions of Linux supply documentation that lists the
recompilation process and the locations of the source code and compiled programs.
Before you do anything with the kernel or utilities, make sure you have a good
set of emergency boot disks, and preferably a complete backup on tape or diskette.
Although the process of modifying the kernel is not difficult, every now and then
it does cause problems that can leave you stranded without a working system. Boot
disks are the best way to recover, so make at least one extra set.
Linux is a dynamic operating system. New releases of the kernel, or parts of the
operating system that can be linked into the kernel, are made available at regular
intervals to users. Whether or not you want to upgrade to the new releases is up
to you and usually depends on the features or bug fixes that the new release offers.
You will probably have to recompile and relink the kernel when new software is added,
unless it is loaded as a utility or device driver.
-
CAUTION: You should avoid
upgrading your system with every new release for a couple of reasons. The most common
problem with constant upgrades is that you may be stuck with a new software package
that causes backward compatibility problems with your existing system or that has
a major problem with it that was not patched before the new software was released.
This can cause you no end of trouble. Most new software releases wipe out existing
configuration information, so you have to reconfigure the packages that are being
installed from scratch.
Another problem with constant upgrades is that the frequency with which new releases
are made available is so high that you can probably spend more time simply loading
and recompiling kernels and utilities than actually using the system. This becomes
tiresome after a while. Because most major releases of the Linux operating system
are available, the number of changes to the system is usually quite small. Therefore,
you should read the release notes carefully to ensure that the release is worth the
installation time and trouble.
The best advice is to upgrade only once or twice a year, and only when there is
a new feature or enhancement to your system that will make a significant difference
in the way you use Linux. It's tempting to always have the latest and newest version
of the operating system, but there is a lot to be said for having a stable, functioning
operating system, too.
If you do upgrade to a new release, bear in mind that you don't have to upgrade
everything. The last few Linux releases have changed only about 5 percent of the
operating system with each new major package upgrade. Instead of replacing the entire
system, just install those parts that will have a definite effect, such as the kernel,
compilers and their libraries, and frequently used utilities. This saves time and
reconfiguration.
Upgrading, replacing, or adding new code to the kernel is usually a simple process:
You obtain the source for the kernel, make any configuration changes, compile it,
and then place it in the proper location on the file system to run the system properly.
The process is often automated for you by a shell script or installation program,
and some upgrades are completely automated--you don't need to do anything except
start the upgrade utility.
Kernel sources for new releases of Linux are available from CD-ROM distributions,
FTP sites (see Appendix A, "FTP Sites and Newsgroups"), user groups, and
many other locations. Most kernel versions are numbered with a version and a patch
level, so you will see kernel names such as 1.12.123, where 1 is the major release,
12 is the minor version release, and 123 is the patch number. Most sites of kernel
source code maintain several versions simultaneously, so check through the source
directories for the latest version of the kernel.
Patch releases are sometimes numbered differently and do not require the entire
source of the kernel to install. They require just the source of the patch. In most
cases, the patch overlays a section of existing source code and a simple recompilation
is all that's necessary to install the patch. Patches are released quite frequently.
Most kernel source programs are maintained as a gzipped tar file. Unpack
the files into a subdirectory called /usr/src, which is where most of the
source code is kept for Linux. Some versions of Linux keep other directories for
the kernel source, so you may want to check any documentation supplied with the system
or look for a README file in the /usr/src directory for more instructions.
Often, unpacking the gzipped tar file in /usr/src creates a
subdirectory called /usr/src/linux, which can overwrite your last version
of the kernel source. Before starting the unpacking process, rename or copy any existing
/usr/src/linux (or whatever name is used with the new kernel) so you have
a backup version in case of problems.
After the kernel source has been unpacked, you need to create two symbolic links
to the /usr/include directory, if they are not created already or set by
the installation procedure. Usually, the link commands required are
ln -sf /usr/src/linux/include/linux /usr/include/linux
ln -sf /usr/src/linux/include/asm /usr/include/asm
If the directory names shown are different from your version of Linux, substitute
the new directory names for /usr/src/linux. Without these links, the upgrade
or installation of a new kernel cannot proceed.
After the source code has been ungzipped and untarred and the links have been
established, the compilation process can begin. You must have a version of gcc
or g++ (the GNU C and C++ compilers) or some other compatible compiler available
for the compilation. You may have to check with the source code documentation to
make sure you have the correct versions of the compilers, because occasionally new
kernel features are added that are not supported by older versions of gcc
or g++.
Check the file /usr/src/linux/Makefile (or whatever path the Makefile
is in with your source distribution). There will be a line in the file that defines
the ROOT_DEV, which is the device that is used as the root file
system when Linux boots. Usually the line looks like this:
ROOT_DEV = CURRENT
If you have any other value, make sure it is correct for your file system configuration.
If the Makefile has no value, set it as shown in the preceding code line.
The compilation process begins when you change to the /usr/src/linux
directory and issue the following command:
make config
This command invokes the make utility for the C compiler. The process
may be slightly different for some versions of Linux, so you should check with any
release or installation notes supplied with the source code.
The config program issues a series of questions and prompts that you
need to answer to indicate any configuration issues that need to be completed before
the actual compilation begins. These may be about the type of disk drive you are
using, the CPU, any partitions, or other devices, such as CD-ROMs. Answer the questions
as well as you can. If you are unsure, choose the default values or the choice that
makes the most sense. The worst case is that you might have to redo the process if
the system doesn't run properly. (You do have an emergency boot disk ready, don't
you?)
Next, you have to set all the source dependencies. This is a step that is commonly
skipped, and it can cause several problems if it is not performed for each software
release. Issue the following command:
make dep
If the software you are installing does not have a dep file, check with
the release or installation notes to ensure that the dependencies are correctly handled
by the other steps.
After that, you can finally compile the new kernel. The command to start the process
is
make zImage
make zdisk
make zlilo
This compiles the source code and leaves the new kernel image file in the current
directory (usually /usr/src/linux). If you want to create a compressed kernel
image, you can use the command
make zImage
Not all releases or upgrades to the kernel support compressed image compilation.
The last step in the process is to copy the new kernel image file to the boot
device or a boot floppy. Use the following command to place the file on a floppy:
cp Image /dev/fd0
Use a different device driver, if necessary, to place it somewhere else on the
hard drive file system. Alternatively, if you plan to use LILO to boot the operating
system, you can install the new kernel by running a setup program or the utility
/usr/lilo/lilo. (See Chapter 4, "Booting Linux.")
Now all that remains is to reboot the system and see if the new kernel loads properly.
If there are any problems, boot from a floppy, restore the old kernel, and start
the process again. Check the documentation supplied with the release source code
for any information about problems you may encounter or steps that may have been
added to the process.
You may want to link in new device drivers or special software to the kernel without
going through the upgrade process of the kernel itself. This is often necessary when
you add a new device to the system (such as a multiport board or an optical drive)
that should be loaded during the boot process. Alternatively, you may be adding special
security software that must be linked into the kernel.
The add-in kernel software usually has installation instructions provided, but
the general process is to locate the source in a directory that can be found by the
kernel recompilation process (such as the /usr/src directory). To instruct
the make utility to add the new code to the kernel, you often need to modify
the Makefile. These modifications may be performed manually or by an installation
script. Some software has its own Makefile supplied for this reason.
Then, it's time to begin the kernel recompilation with the new software added
into the load. The process is the same as shown in the preceding section; the kernel
is installed in the boot location or is set by LILO. Typically, the entire process
takes about 10 minutes and is quite trouble-free, unless the vendor of the kernel
modification did a sloppy job. Make sure that the source code provided for the modification
will work with your version of the Linux kernel by reading any text files that accompany
the code as well as the software compatibility files included with most distributions
of Linux.
Most of the software on a Linux system is set to use shared libraries (a set of
subroutines used by many programs). When you see the message
Incompatible library version
displayed after you have performed an upgrade to the system and you try to execute
a utility, it means that the libraries have been updated and need to be recompiled.
Most libraries are backward-compatible, so existing software should work properly
even after a library upgrade.
Library upgrades occur less frequently than kernel upgrades, and you can find
them in the same places. There are usually documents that guide you to the latest
version of a library, or there may be a file explaining which libraries are necessary
with new versions of the operating system kernel.
Most library upgrades are gzipped tar files, and the process for unpacking
them is the same as for kernel source code--except that the target directories are
usually /lib, /usr/lib, and /usr/include. Usually, any
files that have the extension .a or .aa belong in the /usr/lib
directory. Shared library image files, which have the format libc.so.version,
are installed into /lib.
You may have to change symbolic links within the file system to point to the latest
version of the library. For example, if you are running library version libc.so.4.4.1
and upgrade to libc.so.4.4.2, you must alter the symbolic link set in /lib
to this file. The command is
ln -sf /lib/libc/so/4/4/1 /lib/libc.so.4
where the last filename in the link command is the name of the current library
file in /lib. Your library name may be different, so check the directory
and release or installation notes first.
You would also need to change the symbolic link for the file libm.so.version
in the same manner. Do not delete the symbolic links because all programs that depend
on the shared library (including ls) would be unable to function without
them.
You will need to look at the source code if you want to make enhancements to the
kernel. The Linux source code can be found in the /usr/src/linux directory.
For the reader interested in kernels, this directory is a very good reference.
The first place to start is to see what header files you have available in the
include directory. This way, you can tell what system services are available.
(See Table 56.1.) I have deliberately left out redundant or unused header files.
By examining the header files, you can see what files and hardward configurations
are available for you in Linux.
Table 56.1. Linux header files in /usr/src/linux/include/linux.
File |
Description |
a.out.h |
Generated for the GNU C compilers. |
atalk.h |
Appletalk network structures and definitions. |
autoconf.h |
Automatically generated C config file. Don't edit it! |
ax25.h |
Definitions for the AX.25 protocol. |
aztcd.h |
Definitions for a AztechCD268 CD-ROM interface. |
binfmts.h |
Binary formats for the files. |
bios32.h |
BIOS32, PCI BIOS functions and defines. |
blkdev.h |
Block device information. |
busmouse.h |
Header file for Logitech Bus Mouse driver. |
cdrom.h |
General header for all CD-ROM drives. |
cdu31a.h |
Definitions for a Sony interface CD-ROM drive. |
cm206.h |
Definitions for a CM206 CD-ROM drive and adapter. |
coff.h |
The COFF file format definitions. |
config.h |
Linux kernel configuration header. |
ctype.h |
Standard C types header. |
cyclades.h |
For the Cyclades devices. |
debugreg.h |
Debug registers header file. |
delay.h |
Delay routines using a precomputed loops_per_second value. |
elf.h |
The Executable and Linking Format (ELF) definitions. |
errno.h |
The standard error return definitions. |
etherdevice.h |
Ethernet device handlers declarations. |
ext2_fs.h |
The new extended file system (e2fs) declarations. |
ext_fs.h |
The ext file system (efs) definitions for older Linux versions.
|
fcntl.h |
The standard file control declaration. |
fd.h |
Floppy disk software control definitions. |
fdreg.h |
Definitions for the floppy disk controller. |
fs.h |
Definitions for some important file table structures. |
genhd.h |
Generic hard disk header declarations. |
gscd.h |
Definitions for a GoldStar R420 CD-ROM interface. |
hdreg.h |
Declarations for the AT hard disk controllers. |
head.h |
Headers for Intel Global and Interrupt Descriptor tables. |
hpfs_fs.h |
OS/2 HPFS file system. |
icmp.h |
Definitions for the ICMP protocol. |
if.h |
Definitions for the INET interface module. |
if_arp.h |
Definitions for the ARP (RFC 826) protocol. |
if_ether.h |
Definitions for the Ethernet IEEE 802.3 interface. |
if_fw.h |
Definitions for an IP firewall module. |
if_plip.h |
PLIP tuning facilities for the new Niibe PLIP. |
if_ppp.h |
Constants and structures for use with the PPP module. |
if_slip.h |
Constants for special use with the SLIP/CSLIP/KISS TNC driver. |
igmp.h |
Internet Gateway Management Protocol (IGMP). |
in.h |
Definitions of the Internet Protocol. |
in_systm.h |
Miscellaneous Internetwork definitions for the Linux kernel. |
inet.h |
Internet Protocol headers. |
interrupt.h |
For Linux interrupt drivers. |
ioctl.h |
Standard I/O control definitions. |
ioport.h |
For detecting, reserving, and allocating system resources. |
ip.h |
Definitions for the IP protocol. |
ipc.h |
For interprocess communication. |
ipx.h |
For sockets in network programming. |
iso_fs.h |
The ISO file system headers. |
kd.h |
Kernel development declarations. |
kernel.h |
Kernel header file declarations. |
kernel_stat.h |
More kernel statistics header file declarations. |
keyboard.h |
Declaration for using the keyboard. |
ldt.h |
Definitions for use with Local Descriptor Tables. |
limits.h |
Limits for the kernel to use. |
linkage.h |
Linking declarations for the kernel. |
locks.h |
File locking definitions. |
lp.h |
Line printer support header. |
major.h |
Major device number header. |
malloc.h |
Standard memory management function header. |
math_emu.h |
Math emulation declarations. |
mc146818rtc.h |
Register definitions for RealTime Clock and CMOS RAM. |
mcd.h |
Definitions for a Mitsumi CD-ROM interface. |
mcdx.h |
Definitions for the Mitsumi CD-ROM interface. |
minix.h |
The minix file system constants/structures. |
mm.h |
Memory manager for kernel. |
mman.h |
Memory mapping definitions. |
module.h |
For use with dynamic loading of modules into the kernel. |
mouse.h |
For use with serial mouse. |
msdos_fs.h |
The MS-DOS file system constants/structures. |
msg.h |
For message processing in Linux IPC. |
mtio.h |
Definitions for magnetic tape I/O functions. |
net.h |
Implementation file for the networking portion of the Linux kernel. |
optcd.h |
Definitions for the Optics Storage 8000AT CD-ROM drive. |
param.h |
Internal Linux parameters header. |
pci.h |
PCI bus defines and function prototypes. |
personality.h |
Linux file personality declarations. |
pipe_fs_i.h |
For use with Linux file pipes. |
ppp.h |
For use with Point-to-Point Protocol with Linux. |
proc_fs.h |
The proc file system constants/structures. |
ptrace.h |
Defines to help the user use the ptrace system call. |
resource.h |
Resource control/accounting header file for Linux. |
route.h |
Global definitions for the IP router interface. |
sbpcd.h |
For Panasonic CD-ROM drives. |
sched.h |
The Linux task scheduler. |
scsicam.h |
SCSI CAM support functions, use for HDIO_GETGEO, and so on. |
sem.h |
For use with semaphores on Linux. |
serial.h |
Linux serial I/O definitions. |
serial_reg.h |
For the UART port assignments. |
shm.h |
For shared memory use on Linux. |
signal.h |
For Linux signal information. |
sjcd.h |
Definitions for a Sanyo CD-ROM drive. |
skbuff.h |
Definitions for the struct sk_buff memory handlers. |
socket.h |
More declarations of the socket-level I/O control calls. |
sockios.h |
More declarations of the socket-level I/O control calls. |
sonycd535.h |
Defines all of the commands for the CD-ROMs by Sony (CDU-531-5). |
soundcard.h |
For interfacing with soundcards. |
stat.h |
Standard C and UNIX definitions. |
stddef.h |
Standard C definitions. |
string.h |
String functions declarations for C programmers. |
symtab_begin.h |
Symbol table entries. |
symtab_end.h |
Symbol table entries. |
sys.h |
System call entry points. |
sysv_fs.h |
The SystemV/Coherent file system definitions. |
tasks.h |
For specifying the maximum number of tasks at one time in Linux. |
tcp.h |
Definitions for the TCP protocol. |
termios.h |
Terminal I/O declarations. |
time.h |
Standard declarations for use with timers. |
timer.h |
Do not modify this timer declarations file. |
times.h |
For use with Linux kernel timers. |
timex.h |
For TIMEX devices. |
tpqic02.h |
include file for the QIC-02 driver for Linux. |
tqueue.h |
The task queue handling information for Linux. |
tty.h |
Defines some structures used by tty_io.c. |
tty_driver.h |
Defines interface between low-level tty driver and its routines. |
types.h |
Standard Linux variable type definitions. |
udp.h |
Definitions for the UDP protocol. |
ultrasound.h |
For Ultrasound CD-ROM devices. |
umsdos_fs.h |
The UMSDOS file system header. |
un.h |
Linux header for socket programming. |
unistd.h |
Standard UNIX file header. |
user.h |
For use with core dumps and user segments. |
utime.h |
Time information. |
utsname.h |
Time information and structures. |
version.h |
Linux version information. |
vfs.h |
Virtual file system headers. |
vm86.h |
Virtual memory management routines. |
vt.h |
For use with virtual terminals. |
xd.h |
Definitions for the I/O ports, and so forth, for XT hard disk contollers. |
modules/ |
Contains the file ksyms.ver, a symbol version table generated by genksyms.
|
Let's give an example of how you would use this header file information. Suppose
that using the default kernel for the sbcpd (Panasonic CD-ROM) drive takes
a long time to boot because it probes the I/O ports to see where the drive is in
the I/O port memory space. You know you have set your jumpers on the drive to 0x260,
so why not just have it look there and keep going? You are sick of typing in the
sbpcd=0x260,SoundBlaster sequence every time you boot.
Sounds good. Let's look at the sbpcd.h file in /usr/src/linux/include/linux.
First, log in as root and make sure that you have write privileges to this header
file to save your changes. Look at the part of the file where it says to define your
CD-ROM port base I/O address as CDROM_PORT and specify the type of your
interface card as SBPRO. You can change the address lines in file after
line 90 as the following:
#undef CDROM_PORT /* get rid of previous declarations. */
#undef SBPRO /* get rid of previous declarations. */
#undef SOUND_BASE /* get rid of previous declarations. */
/* override these values. */
#define CDROM_PORT 0x230 /* port address */
#define SBPRO 0 /* interface type */
#define SOUND_BASE 0x220 /* sound address of this card or 0 */
Now exit the editor after making the changes. Rebuild the kernel and install it
as discussed earlier in this chapter. Reboot, and there you have it--a fast boot.
This is only a quick example of how to use this valuable resource of information
to customize your Linux system. I am sure that with some exploring, you can come
across some more examples.
We briefly covered modules in Chapter 5, "Special Installations." This
section describes the basic strategy for making dynamically loadable modules in the
Linux kernel. Let's look at how to use them. However, how modules work is really
beyond the scope of this book. Sorry.
In this kernel version (2.0.0 or later versions), you can also create modules
by enabling CONFIG_MODVERSIONS when making a kernel. Also, you have to install
the latest module support package modules-2.0.0.tar.gz (or later version.)
Next, compile and install the kernel (as explained earlier).
When you have made the kernel, create the modules by typing the following command:
make modules
This compiles all modules and updates the modules directory. In this directory,
you can then find a bunch of symbolic links, pointing to the various object files
in the kernel tree.
The set of modules is rapidly increasing, and you have the following list of items
with this CD-ROM. You can find descriptions for each of these modules by following
each of the links in the files in the directory usr/src/linux/modules:
- 3c501
- 3c509
- BLOCK_MODULES
- FS_MODULES
NET_MODULE
- apricot
- arcnet
- aztcd
- de4x5
- de600
- de620
- depca
- eexpress
- ewrk3
- plip
- sonycd535
- sysv
- wavelan
- xiafs
As soon as you have rebooted the newly made kernel, you can install and remove
modules at will with the utilities insmod and rmmod.
Now, after you have made all modules, you can also type the following command:
make modules_install
This copies all newly made modules into subdirectories under /lib/modules/kernel_release/where
kernel_release is something like 1.2.13, or later.
Using the modprobe utility, you can load any module like this:
/sbin/modprobe module
To use modprobe successfully, you should place the following command
in your /etc/rc.d/rc.S script:
/sbin/depmod -a
This computes the dependencies between the different modules. Then type the following
line, for example:
/sbin/modprobe umsdos
Now you automatically load both the MS-DOS and UMSDOS modules, because UMSDOS
runs piggyback on MS-DOS.
Another important file to look at is the rc.modules file. This file is
located in the /etc/rc.d directory and is executed when the system first
boots up. The latest version of this rc.modules file is version 1.11 by
Sam Volkerding for Slackware Linux. More documentation for specific modules is listed
in the /docs directory on the CD-ROM.
Edit the rc.modules file carefully and keep a backup copy of this file
before you make too many edits. Each line in the rc.modules corresponds
to a binary file to execute to load a module into Linux. Most of the entries in the
rc.modules file will be commented out. Uncomment only the lines you need.
It'll probably be easier if you uncomment one line at a time instead of uncommenting
all the lines at once. Some modules might require other modules to be loaded before
being loaded themselves, or might not allow the code to be loaded more than once.
These exceptions are special cases indeed. For example, you have to load the MS-DOS
module before you load USMSDOS. For example, you cannot load the NE2000 module twice
if you have more than one Ethernet card in your system. In some cases, you will simply
have to rebuild a kernel and statically link in the features you need.
Be prepared to boot several times to get the exact sequence of loaded modules
for your custom setup. In general, the modules in rc.modules are listed
in the order they should be in to satisfy any interdependencies between modules.
Recompiling kernel source and adding new features to the kernel proceeds smoothly,
as long as you know what you are doing. Don't let the process scare you, but always
keep boot disks on hand. Follow instructions wherever available, because most new
software has special requirements for linking into the kernel or replacing existing
systems.
Contact
reference@developer.com with questions or comments.
Copyright 1998
EarthWeb Inc., All rights reserved.
PLEASE READ THE ACCEPTABLE USAGE STATEMENT.
Copyright 1998 Macmillan Computer Publishing. All rights reserved.