1527 lines
31 KiB
HTML
1527 lines
31 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<HTML
|
|
><HEAD
|
|
><TITLE
|
|
>How To Insert And Remove LKMs</TITLE
|
|
><META
|
|
NAME="GENERATOR"
|
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
|
|
REL="HOME"
|
|
TITLE="Linux Loadable Kernel Module HOWTO"
|
|
HREF="index.html"><LINK
|
|
REL="PREVIOUS"
|
|
TITLE="LKM Utilities"
|
|
HREF="x146.html"><LINK
|
|
REL="NEXT"
|
|
TITLE="Unresolved Symbols"
|
|
HREF="basekerncompat.html"></HEAD
|
|
><BODY
|
|
CLASS="SECT1"
|
|
BGCOLOR="#FFFFFF"
|
|
TEXT="#000000"
|
|
LINK="#0000FF"
|
|
VLINK="#840084"
|
|
ALINK="#0000FF"
|
|
><DIV
|
|
CLASS="NAVHEADER"
|
|
><TABLE
|
|
SUMMARY="Header navigation table"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
CELLPADDING="0"
|
|
CELLSPACING="0"
|
|
><TR
|
|
><TH
|
|
COLSPAN="3"
|
|
ALIGN="center"
|
|
>Linux Loadable Kernel Module HOWTO</TH
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="10%"
|
|
ALIGN="left"
|
|
VALIGN="bottom"
|
|
><A
|
|
HREF="x146.html"
|
|
ACCESSKEY="P"
|
|
>Prev</A
|
|
></TD
|
|
><TD
|
|
WIDTH="80%"
|
|
ALIGN="center"
|
|
VALIGN="bottom"
|
|
></TD
|
|
><TD
|
|
WIDTH="10%"
|
|
ALIGN="right"
|
|
VALIGN="bottom"
|
|
><A
|
|
HREF="basekerncompat.html"
|
|
ACCESSKEY="N"
|
|
>Next</A
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><HR
|
|
ALIGN="LEFT"
|
|
WIDTH="100%"></DIV
|
|
><DIV
|
|
CLASS="SECT1"
|
|
><H1
|
|
CLASS="SECT1"
|
|
><A
|
|
NAME="AEN197"
|
|
></A
|
|
>5. How To Insert And Remove LKMs</H1
|
|
><P
|
|
>The basic programs for inserting and removing LKMs are
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> and
|
|
<B
|
|
CLASS="COMMAND"
|
|
>rmmod</B
|
|
>. See their man pages for details.</P
|
|
><P
|
|
>Inserting an LKM is conceptually easy: Just type, as superuser, a
|
|
command like
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>insmod serial.o</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
(<TT
|
|
CLASS="FILENAME"
|
|
>serial.o</TT
|
|
> contains the device driver for serial
|
|
ports (UARTs)).</P
|
|
><P
|
|
>However, I would be misleading you if I said the command just works. It
|
|
is very common, and rather maddening, for the command to fail either with
|
|
a message about a module/kernel version mismatch or a pile of unresolved
|
|
symbols.</P
|
|
><P
|
|
>If it does work, though, the way to prove to yourself that you know what
|
|
you're doing is to look at <TT
|
|
CLASS="FILENAME"
|
|
>/proc/modules</TT
|
|
> as
|
|
described in <A
|
|
HREF="x197.html#PROCMODULES"
|
|
>Section 5.5</A
|
|
>.</P
|
|
><P
|
|
>Note that the examples in this section are from Linux 2.4. In Linux 2.6,
|
|
the technical aspects of loading LKMs are considerably different, and
|
|
the most visible manifestation of this is that the LKM file has a suffix
|
|
of ".ko" instead of ".o". From the user point of
|
|
view, it looks quite similar, though.</P
|
|
><P
|
|
>Now lets look at a more difficult insertion. If you try
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>insmod msdos.o</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
you will probably get a raft of error messages like:
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
> msdos.o: unresolved symbol fat_date_unix2dos
|
|
msdos.o: unresolved symbol fat_add_cluster1
|
|
msdos.o: unresolved symbol fat_put_super
|
|
...</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>This is because msdos.o contains external symbol references to the
|
|
symbols mentioned and there are no such symbols exported by the kernel.
|
|
To prove this, do a
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>cat /proc/ksyms</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
to list every symbol that is exported by the kernel (i.e. available
|
|
for binding to LKMs). You will see that 'fat_date_unix2dos' is
|
|
nowhere in the list.</P
|
|
><P
|
|
>(In Linux 2.6, there is no <TT
|
|
CLASS="FILENAME"
|
|
>/proc/ksyms</TT
|
|
>. Use
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/kallsyms</TT
|
|
> instead; the format is like the
|
|
output of <B
|
|
CLASS="COMMAND"
|
|
>nm</B
|
|
>: look for symbols labelled "t").</P
|
|
><P
|
|
>How do you get it into the list? By loading another LKM, one which
|
|
defines those symbols and exports them. In this case, it is the LKM
|
|
in the file <TT
|
|
CLASS="FILENAME"
|
|
>fat.o</TT
|
|
>. So do
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
> insmod fat.o</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
and then see that "fat_date_unix2dos" is in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/ksyms</TT
|
|
>. Now redo the
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>insmod msdos.o</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
and it works. Look at
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/modules</TT
|
|
> and see that both LKMs are loaded
|
|
and one depends on the other:
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>msdos 5632 0 (unused)
|
|
fat 30400 0 [msdos]</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>How did I know <TT
|
|
CLASS="FILENAME"
|
|
>fat.o</TT
|
|
> was the module I was
|
|
missing? Just a little ingenuity. A more robust way to address this
|
|
problem is to use <B
|
|
CLASS="COMMAND"
|
|
>depmod</B
|
|
> and
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> instead of
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
>, as discussed below.</P
|
|
><P
|
|
>When your symbols look like "fat_date_unix2dos_R83fb36a1",
|
|
the problem may be more complex than just getting prerequisite LKMs
|
|
loaded. See <A
|
|
HREF="basekerncompat.html"
|
|
>Section 6</A
|
|
>.</P
|
|
><P
|
|
>When the error message is "kernel/module version mismatch," see
|
|
<A
|
|
HREF="basekerncompat.html"
|
|
>Section 6</A
|
|
>.</P
|
|
><P
|
|
>Often, you need to pass parameters to the LKM when you insert it. For
|
|
example, a device driver wants to know the address and IRQ of the
|
|
device it is supposed to drive. Or the network driver wants to know
|
|
how much diagnostic tracing you want it to do. Here is an example of
|
|
that:</P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>insmod ne.o io=0x300 irq=11</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><P
|
|
>Here, I am loading the device driver for my NE2000-like Ethernet adapter
|
|
and telling it to drive the Ethernet adapter at IO address 0x300, which
|
|
generates interrupts on IRQ 11.</P
|
|
><P
|
|
>There are no standard parameters for LKMs and very few conventions.
|
|
Each LKM author decides what parameters <B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> will
|
|
take for his LKM. Hence, you will find them documented in the
|
|
documentation of the LKM. This HOWTO also compiles a lot of LKM
|
|
parameter information in <A
|
|
HREF="individual.html"
|
|
>Section 15</A
|
|
>. For general
|
|
information about LKM parameters, see <A
|
|
HREF="parm.html"
|
|
>Section 8</A
|
|
>.</P
|
|
><P
|
|
>To remove an LKM from the kernel, the command is like
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>rmmod ne</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>There is a command <B
|
|
CLASS="COMMAND"
|
|
>lsmod</B
|
|
> to list the
|
|
currently loaded LKMs, but all it does is dump the contents of
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/modules</TT
|
|
>, with column headings, so you may
|
|
just want to go to the horse's mouth and forget about
|
|
<B
|
|
CLASS="COMMAND"
|
|
>lsmod</B
|
|
>.</P
|
|
><DIV
|
|
CLASS="SECT2"
|
|
><H2
|
|
CLASS="SECT2"
|
|
><A
|
|
NAME="AEN248"
|
|
></A
|
|
>5.1. Could Not Find Kernel Version...</H2
|
|
><P
|
|
>A common error is to try to insert an object file which is not an LKM.
|
|
For example, you configure your kernel to have the USB core module
|
|
bound into the base kernel instead of generated as an LKM. In that
|
|
case, you end up with a file <TT
|
|
CLASS="FILENAME"
|
|
>usbcore.o</TT
|
|
>, which looks
|
|
pretty much the same as the <TT
|
|
CLASS="FILENAME"
|
|
>usbcore.o</TT
|
|
> you would get if
|
|
you built it as an LKM. But you can't <B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> that
|
|
file.</P
|
|
><P
|
|
>So do you get an error message telling you that you should have
|
|
configured the kernel to make USB core function an LKM? Of course not.
|
|
This is Unix, and explanatory error messages are seen as a sign of
|
|
weakness. The error message is
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>$ insmod usbcore.o
|
|
usbcore.o: couldn't find the kernel version this module was compiled for</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>What <B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> is telling you is that it looked in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>usbcore.o</TT
|
|
> for a piece of information any legitimate
|
|
LKM would have -- the kernel version with which the LKM was intended
|
|
to be used -- and it didn't find it. We know now that the reason it
|
|
didn't find it is that the file isn't an LKM. See
|
|
<A
|
|
HREF="x627.html#MODINFO"
|
|
>Section 10.2</A
|
|
> for information on how you can see what
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> is seeing and confirm that the file is not
|
|
in fact an LKM.</P
|
|
><P
|
|
>If this is a module you created yourself with the intention of it
|
|
being an LKM, the next question you have is: Why isn't an LKM? The
|
|
most usual cause of this is that you did not include
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>linux/module.h</TT
|
|
> at the top of your source code
|
|
and/or did not define the <TT
|
|
CLASS="LITERAL"
|
|
>MODULE></TT
|
|
> macro.
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>MODULE</TT
|
|
> is intended to be set via the compile
|
|
command (<TT
|
|
CLASS="LITERAL"
|
|
>-DMODULE</TT
|
|
>) and determine whether the
|
|
compilation produces an LKM or an object file for binding into the
|
|
base kernel. If your module is like most modern modules and can be
|
|
built <EM
|
|
>only</EM
|
|
> as an LKM, then you should just define
|
|
it in your source code (<TT
|
|
CLASS="LITERAL"
|
|
>#define MODULE</TT
|
|
>) before you
|
|
include <TT
|
|
CLASS="FILENAME"
|
|
>include/module.h</TT
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT2"
|
|
><H2
|
|
CLASS="SECT2"
|
|
><A
|
|
NAME="AEN269"
|
|
></A
|
|
>5.2. What Happens When An LKM Loads</H2
|
|
><P
|
|
>So you've successfully loaded an LKM, and verified that via
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/modules</TT
|
|
>. But how do you know it's working?
|
|
That's up to the LKM, and varies according to what kind of LKM it is,
|
|
but here are some of the more common actions of an LKM upon being loaded.</P
|
|
><P
|
|
>The first thing a device driver LKM does after loading (which is what
|
|
the module would do at boot time if it were bound into the base
|
|
kernel) is usually to search the system for a device it knows how to
|
|
drive. Just how it does this search varies from one driver to the
|
|
next, and can usually be controlled by module parameters. But in any
|
|
case, if the driver doesn't find any device it is capable of driving,
|
|
it causes the load to fail. Otherwise, the driver registers itself
|
|
as the driver for a particular major number and you can start using
|
|
the device it found via a device special file that specifies that
|
|
major number. It may also register itself as the handler for the
|
|
interrupt level that the device uses. It may also send setup commands
|
|
to the device, so you may see lights blink or something like that.</P
|
|
><P
|
|
>You can see that a device driver has registered itself in the file
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/devices</TT
|
|
>. You can see that the device
|
|
driver is handling the device's interrupts in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/interrupts</TT
|
|
>.</P
|
|
><P
|
|
>A nice device driver issues kernel messages telling what devices it
|
|
found and is prepared to drive. (Kernel messages in most systems end
|
|
up on the console and in the file
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/var/log/messages</TT
|
|
>. You can also display recent
|
|
ones with the <B
|
|
CLASS="COMMAND"
|
|
>dmesg</B
|
|
> program). Some drivers, however, are
|
|
silent. A nice device driver also gives you (in kernel messages) some
|
|
details of its search when it fails to find a device, but many just
|
|
fail the load without explanation, and what you get is a list of
|
|
guesses from <B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> as to what the problem might
|
|
have been.</P
|
|
><P
|
|
>A network device (interface) driver works similarly, except that the
|
|
LKM registers a device name of its choosing
|
|
(e.g. <TT
|
|
CLASS="LITERAL"
|
|
>eth0</TT
|
|
>) rather than a major number. You can
|
|
see the currently registered network device names in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/net/dev</TT
|
|
></P
|
|
><P
|
|
>A filesystem driver, upon loading, registers itself as the driver for
|
|
a filesystem type of a certain name. For example, the
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>msdos</TT
|
|
> driver registers itself as the driver for the
|
|
filesystem type named <TT
|
|
CLASS="LITERAL"
|
|
>msdos</TT
|
|
>. (LKM authors typically
|
|
name the LKM the same as the filesystem type it will drive).</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT2"
|
|
><H2
|
|
CLASS="SECT2"
|
|
><A
|
|
NAME="INTELLIGENT"
|
|
></A
|
|
>5.3. Intelligent Loading Of LKMs - Modprobe</H2
|
|
><P
|
|
>Once you have module loading and unloading figured out using
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> and <B
|
|
CLASS="COMMAND"
|
|
>rmmod</B
|
|
>, you can let
|
|
the system do more of the work for you by using the higher level
|
|
program <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>. See the
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> man page for details.</P
|
|
><P
|
|
>The main thing that <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> does is automatically
|
|
load the prerequisites of an LKM you request. It does this with the
|
|
help of a file that you create with <B
|
|
CLASS="COMMAND"
|
|
>depmod</B
|
|
> and keep
|
|
on your system.</P
|
|
><P
|
|
>Example:
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>modprobe msdos</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>This performs an <B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> of
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>msdos.o</TT
|
|
>, but before that does an
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
> of <TT
|
|
CLASS="FILENAME"
|
|
>fat.o</TT
|
|
>, since you
|
|
have to have <TT
|
|
CLASS="FILENAME"
|
|
>fat.o</TT
|
|
> loaded before you can load
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>msdos.o</TT
|
|
>.</P
|
|
><P
|
|
>The other major thing <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> does for you is to
|
|
find the object module containing the LKM given just the name of the
|
|
LKM. For example, <B
|
|
CLASS="COMMAND"
|
|
>modprobe msdos</B
|
|
> might load
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/lib/2.4.2-2/fs/msdos.o</TT
|
|
>.
|
|
In fact, <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>'s argument may be a totally
|
|
symbolic name that you have associated with some actual module. For
|
|
example, <B
|
|
CLASS="COMMAND"
|
|
>modprobe eth0</B
|
|
> loads the appropriate network
|
|
device driver to create and drive your <TT
|
|
CLASS="LITERAL"
|
|
>eth0</TT
|
|
> device,
|
|
assuming you set that up properly in <TT
|
|
CLASS="FILENAME"
|
|
>modules.conf</TT
|
|
>.
|
|
Check out the man pages
|
|
for <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> and the configuration file
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>modules.conf</TT
|
|
> (usually
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/etc/modules.conf</TT
|
|
>) for details on the search
|
|
rules <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> uses.</P
|
|
><P
|
|
><B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> is especially important because it
|
|
is by default the program that the kernel module loader uses to load
|
|
an LKM on demand. So if you use automatic module loading, you will
|
|
need to set up <TT
|
|
CLASS="FILENAME"
|
|
>modules.conf</TT
|
|
> properly or
|
|
things will not work. See <A
|
|
HREF="x197.html#AUTOLOAD"
|
|
>Section 5.4</A
|
|
>.</P
|
|
><P
|
|
><B
|
|
CLASS="COMMAND"
|
|
>depmod</B
|
|
> scans your LKM object files (typically all
|
|
the <TT
|
|
CLASS="FILENAME"
|
|
>.o</TT
|
|
> files in the appropriate <TT
|
|
CLASS="FILENAME"
|
|
>/lib/modules</TT
|
|
> subdirectory) and figures
|
|
out which LKMs prerequire (refer to symbols in) other LKMs. It
|
|
generates a dependency file (typically named
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>modules.dep</TT
|
|
>), which you normally keep in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/lib/modules</TT
|
|
> for use by
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>.</P
|
|
><P
|
|
>You can use <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> to remove stacks of LKMs as
|
|
well.</P
|
|
><P
|
|
>Via the LKM configuration file (typically
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/etc/modules.conf</TT
|
|
>), you can fine tune the
|
|
dependencies and do other fancy things to control LKM selections. And
|
|
you can specify programs to run when you insert and remove LKMs, for
|
|
example to initialize a device driver.</P
|
|
><P
|
|
>If you are maintaining one system and memory is not in short supply,
|
|
it is probably easier to avoid <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> and the
|
|
various files and directories it needs, and just do raw
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
>s in a startup script.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT2"
|
|
><H2
|
|
CLASS="SECT2"
|
|
><A
|
|
NAME="AUTOLOAD"
|
|
></A
|
|
>5.4. Automatic LKM Loading and Unloading</H2
|
|
><DIV
|
|
CLASS="SECT3"
|
|
><H3
|
|
CLASS="SECT3"
|
|
><A
|
|
NAME="AEN338"
|
|
></A
|
|
>5.4.1. Automatic Loading</H3
|
|
><P
|
|
>You can cause an LKM to be loaded automatically when the kernel first
|
|
needs it. You do this with either the kernel module loader, which is
|
|
part of the Linux kernel, or the
|
|
older version of it, a <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
> daemon.</P
|
|
><P
|
|
>As an example, let's say you run a program that executes an open
|
|
system call for a file in an MS-DOS filesystem. But you don't have a
|
|
filesystem driver for the MS-DOS filesystem either bound into your
|
|
base kernel or loaded as an LKM. So the kernel does not know how to
|
|
access the file you're opening on the disk.</P
|
|
><P
|
|
>The kernel recognizes that it has no filesystem driver for MS-DOS, but
|
|
that one of the two automatic module loading facilities are available
|
|
and uses it to cause the LKM to be loaded. The kernel then proceeds
|
|
with the open.</P
|
|
><P
|
|
>Automatic kernel module loading is really not worth the complexity in most
|
|
modern systems. It may make sense in a very small memory system, because
|
|
you can keep parts of the kernel in memory only when you need them. But
|
|
the amount of memory these modules uses is so cheap today that you will
|
|
normally be a lot better off just loading all the modules you might need
|
|
via startup scripts and leaving them loaded.</P
|
|
><P
|
|
>Red Hat Linux uses automatic module loading via the kernel module loader.</P
|
|
><P
|
|
>Both the kernel module loader and <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
> use
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>, ergo <B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
>, to insert
|
|
LKMs. See <A
|
|
HREF="x197.html#INTELLIGENT"
|
|
>Section 5.3</A
|
|
>.</P
|
|
><DIV
|
|
CLASS="SECT4"
|
|
><H4
|
|
CLASS="SECT4"
|
|
><A
|
|
NAME="AEN351"
|
|
></A
|
|
>5.4.1.1. Kernel Module Loader</H4
|
|
><P
|
|
>There is some documentation of the kernel module loader in the file
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>Documentation/kmod.txt</TT
|
|
> in the Linux 2.4 source
|
|
tree. This section is more complete and accurate than that file. You
|
|
can also look at its source code in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>kernel/kmod.c</TT
|
|
>.</P
|
|
><P
|
|
>The kernel module loader is an optional part of the Linux kernel. You
|
|
get it if you select the CONFIG_KMOD feature when you configure the
|
|
kernel at build time.</P
|
|
><P
|
|
>When a kernel that has the kernel module loader needs an LKM, it
|
|
creates a user process (owned by the superuser, though) that executes
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> to load the LKM, then exits. By default,
|
|
it finds <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> as
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/sbin/modprobe</TT
|
|
>, but you can set up any program
|
|
you like as <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> by writing its file name to
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/sys/kernel/modprobe</TT
|
|
>. For example:
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
># echo "sbin/mymodprobe" >/proc/sys/kernel/modprobe</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>The kernel module loader passes the following arguments to the
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>: Argument Zero is the full file name of
|
|
<B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>. The regular arguments are
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>-s</TT
|
|
>, <TT
|
|
CLASS="LITERAL"
|
|
>-k</TT
|
|
>, and the name of the LKM
|
|
that the kernel wants. <TT
|
|
CLASS="LITERAL"
|
|
>-s</TT
|
|
> is the user-hostile
|
|
form of <TT
|
|
CLASS="LITERAL"
|
|
>--syslog</TT
|
|
>; <TT
|
|
CLASS="LITERAL"
|
|
>-k</TT
|
|
> is the
|
|
cryptic way to say <TT
|
|
CLASS="LITERAL"
|
|
>--autoclean</TT
|
|
>. I.e. messages
|
|
from <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> will go to syslog and the loaded
|
|
LKM will have the "autoclean" flag set.</P
|
|
><P
|
|
>The most important part of the <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> invocation
|
|
is, of course, the module name. Note that the "module name"
|
|
argument to <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> is not necessarily a real
|
|
module name. It is often a symbolic name representing the role that
|
|
module plays and you use an <TT
|
|
CLASS="LITERAL"
|
|
>alias</TT
|
|
> statement in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>modules.conf</TT
|
|
> to tell what LKM gets loaded.
|
|
For example, if your Ethernet adapter requires the <TT
|
|
CLASS="LITERAL"
|
|
>3c59x</TT
|
|
>
|
|
LKM, you would have probably need the line
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>alias eth0 3c59x</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
in <TT
|
|
CLASS="FILENAME"
|
|
>/etc/modules.conf</TT
|
|
>.
|
|
Here
|
|
is what the kernel module loader uses for a module name in some of the
|
|
more popular cases (there are about 20 cases in which the kernel calls
|
|
on the kernel module loader to load a module):
|
|
<P
|
|
></P
|
|
><UL
|
|
><LI
|
|
><P
|
|
>When you try access a device and no device driver has
|
|
registered to serve that device's major number, the kernel requests
|
|
the module by the name
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>block-major-</TT
|
|
><TT
|
|
CLASS="VARNAME"
|
|
>N</TT
|
|
> or
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>char-major-</TT
|
|
><TT
|
|
CLASS="VARNAME"
|
|
>N</TT
|
|
> where
|
|
<TT
|
|
CLASS="VARNAME"
|
|
>N</TT
|
|
> is the major number in decimal without leading
|
|
zeroes. </P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>When you try to access a network interface (maybe by running
|
|
<B
|
|
CLASS="COMMAND"
|
|
>ifconfig</B
|
|
> against it) and no network device driver
|
|
has registered to serve an interface by that name, the kernel requests
|
|
the module named the same as the interface name
|
|
(e.g. <TT
|
|
CLASS="LITERAL"
|
|
>eth0</TT
|
|
>). This applies to drivers for non-physical
|
|
interfaces such as <TT
|
|
CLASS="LITERAL"
|
|
>ppp0</TT
|
|
> as well.</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>When you try to access a socket in a protocol family which no
|
|
protocol driver has registered to drive, the kernel requests the
|
|
module named <TT
|
|
CLASS="FILENAME"
|
|
>net-pf-</TT
|
|
><TT
|
|
CLASS="VARNAME"
|
|
>N</TT
|
|
>, where
|
|
<TT
|
|
CLASS="VARNAME"
|
|
>N</TT
|
|
> is the protocol family number (in decimal without
|
|
leading zeroes).</P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>When you try to NFS export a directory or otherwise
|
|
access the NFS server via the NFS system call, the kernel requests the
|
|
module named <TT
|
|
CLASS="FILENAME"
|
|
>nfsd</TT
|
|
>. </P
|
|
></LI
|
|
><LI
|
|
><P
|
|
>The ATA device driver (named <TT
|
|
CLASS="FILENAME"
|
|
>ide</TT
|
|
>)
|
|
loads the relevant drivers for classes of ATA devices by the names:
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>ide-disk</TT
|
|
>, <TT
|
|
CLASS="FILENAME"
|
|
>ide-cd</TT
|
|
>,
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>ide-floppy</TT
|
|
>, <TT
|
|
CLASS="FILENAME"
|
|
>ide-tape</TT
|
|
>, and
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>ide-scsi</TT
|
|
>. </P
|
|
></LI
|
|
></UL
|
|
> </P
|
|
><P
|
|
>The kernel module loader runs <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
> with the
|
|
following environment variables (only): HOME=<TT
|
|
CLASS="LITERAL"
|
|
>/</TT
|
|
>;
|
|
TERM=<TT
|
|
CLASS="LITERAL"
|
|
>linux</TT
|
|
>;
|
|
PATH=<TT
|
|
CLASS="LITERAL"
|
|
>/sbin:/usr/sbin:/bin:/usr/bin</TT
|
|
>.</P
|
|
><P
|
|
>The kernel module loader was new in Linux 2.2 and was designed to take
|
|
the place of <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
>. It does not, however, have all
|
|
the features of <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
>.</P
|
|
><P
|
|
>In Linux 2.2, the kernel module loader creates the above mentioned
|
|
process directly. In Linux 2.4, the kernel module loader submits the
|
|
module loading work to Keventd and it runs as a child process of
|
|
Keventd.</P
|
|
><P
|
|
>The kernel module loader is a pretty strange beast. It violates
|
|
layering as Unix programmers generally understand it and consequently
|
|
is inflexible, hard to understand, and not robust. Many system
|
|
designers would bristle just at the fact that it has the PATH
|
|
hardcoded. You may prefer to use <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
> instead,
|
|
or not bother with automatic loading of LKMs at all.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT4"
|
|
><H4
|
|
CLASS="SECT4"
|
|
><A
|
|
NAME="AEN422"
|
|
></A
|
|
>5.4.1.2. Kerneld</H4
|
|
><P
|
|
><TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
> is explained at length in the Kerneld
|
|
mini-HOWTO, available from the <A
|
|
HREF="http://www.tldp.org"
|
|
TARGET="_top"
|
|
>Linux
|
|
Documentation Project</A
|
|
>.</P
|
|
><P
|
|
><TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
> is a user process, which runs the
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>kerneld</SPAN
|
|
> program from the
|
|
<SPAN
|
|
CLASS="APPLICATION"
|
|
>modutils</SPAN
|
|
> package. <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
>
|
|
sets up an IPC message channel with the kernel. When the kernel needs
|
|
an LKM, it sends a message on that channel to <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
>
|
|
and <TT
|
|
CLASS="LITERAL"
|
|
>kerneld</TT
|
|
> runs <B
|
|
CLASS="COMMAND"
|
|
>modprobe</B
|
|
>
|
|
to load the LKM, then sends a message back to the kernel to say that it
|
|
is done.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT3"
|
|
><H3
|
|
CLASS="SECT3"
|
|
><A
|
|
NAME="AEN435"
|
|
></A
|
|
>5.4.2. Automatic Unloading - Autoclean</H3
|
|
><DIV
|
|
CLASS="SECT4"
|
|
><H4
|
|
CLASS="SECT4"
|
|
><A
|
|
NAME="AEN437"
|
|
></A
|
|
>5.4.2.1. The Autoclean Flag</H4
|
|
><P
|
|
>Each loaded LKM has an autoclean flag which can be set or unset.
|
|
You control this flag with parameters to the
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>init_module</TT
|
|
> system call. Assuming you do that via
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
>, you use the <TT
|
|
CLASS="LITERAL"
|
|
>--autoclean</TT
|
|
>
|
|
option.</P
|
|
><P
|
|
>You can see the state of the autoclean flag in
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/proc/modules</TT
|
|
>. Any LKM that has the flag set has
|
|
the legend <TT
|
|
CLASS="LITERAL"
|
|
>autoclean</TT
|
|
> next to it.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT4"
|
|
><H4
|
|
CLASS="SECT4"
|
|
><A
|
|
NAME="AEN446"
|
|
></A
|
|
>5.4.2.2. Removing The Autoclean LKMs</H4
|
|
><P
|
|
>The purpose of the autoclean flag is to let you automatically
|
|
remove LKMs that haven't been used in a while (typically 1 minute).
|
|
So by using automatic module loading and unloading, you can keep loaded only
|
|
parts of the kernel that are presently needed, and save memory.</P
|
|
><P
|
|
>This is less important than it once was, with memory being much
|
|
cheaper. If you don't need to save memory, you shouldn't bother with
|
|
the complexity of module loader processes. Just load everything you
|
|
might need via an initialization script and keep it loaded.</P
|
|
><P
|
|
>There is a form of the <TT
|
|
CLASS="LITERAL"
|
|
>delete_module</TT
|
|
> system call that
|
|
says, "remove all LKMs that have the autoclean flag set and haven't
|
|
been used in a while." Kerneld typically calls this once per
|
|
minute. You can call it explicitly with an <B
|
|
CLASS="COMMAND"
|
|
>rmmod --all</B
|
|
>
|
|
command.</P
|
|
><P
|
|
>As the kernel module loader does not do any removing of LKMs, if you
|
|
use that you might want to have a cron job that does a <B
|
|
CLASS="COMMAND"
|
|
>rmmod
|
|
--all</B
|
|
> periodically.</P
|
|
></DIV
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT2"
|
|
><H2
|
|
CLASS="SECT2"
|
|
><A
|
|
NAME="PROCMODULES"
|
|
></A
|
|
>5.5. /proc/modules</H2
|
|
><P
|
|
>To see the presently loaded LKMs, do
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>cat /proc/modules</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
></P
|
|
><P
|
|
>You see a line like </P
|
|
><TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>serial 24484 0</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
><P
|
|
>The left column is the name of the LKM, which is normally the name of
|
|
the object file from which you loaded it, minus the ".o" suffix.
|
|
You can, however, choose any name you like with an option on
|
|
<B
|
|
CLASS="COMMAND"
|
|
>insmod</B
|
|
>.</P
|
|
><P
|
|
>The "24484" is the size in bytes of the LKM in memory.</P
|
|
><P
|
|
>The "0" is the use count. It tells how many things presently depend
|
|
on the LKM being loaded. Typical "things" are open devices
|
|
or mounted fileystems. It is important because you cannot remove an
|
|
LKM unless the use count is zero. The LKM itself maintains this
|
|
count, but the module manager uses it to decide whether to permit an
|
|
unload.</P
|
|
><P
|
|
>There is an exception to the above description of the use count. You
|
|
may see -1 in the use count column. What that means is that this LKM
|
|
does not use use counts to determine when it is OK to unload.
|
|
Instead, the LKM has registered a subroutine that the module manager
|
|
can call that will return an indication of whether or not it is OK to
|
|
unload the LKM. In this case, the LKM ought to provide you with some
|
|
custom interface, and some documentation, to determine when the LKM is
|
|
free to be unloaded.</P
|
|
><P
|
|
>Do not confuse use count with "dependencies", which are
|
|
described below.</P
|
|
><P
|
|
>Here is another example, with more information:
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>lp 5280 0 (unused)
|
|
parport_pc 7552 1
|
|
parport 7600 1 [lp parport_pc]</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
The stuff in square brackets ("[lp parport_pc]") describes
|
|
dependencies. Here, the modules <TT
|
|
CLASS="LITERAL"
|
|
>lp</TT
|
|
> and
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>parport_pc</TT
|
|
> both refer to addresses within module
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>parport</TT
|
|
> (via external symbols that
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>parport</TT
|
|
> exports). So <TT
|
|
CLASS="LITERAL"
|
|
>lp</TT
|
|
> and
|
|
<TT
|
|
CLASS="LITERAL"
|
|
>parport_pc</TT
|
|
> are "dependent" on (and are
|
|
"dependencies of") <TT
|
|
CLASS="LITERAL"
|
|
>parport</TT
|
|
>.</P
|
|
><P
|
|
>You cannot unload an LKM that has dependencies. But you can remove those
|
|
dependencies by unloading the dependent LKMs.</P
|
|
><P
|
|
>The "(unused)" legend means the LKM has never been used,
|
|
i.e. it has never been in a state where it could not be unloaded. The
|
|
kernel tracks this information for one simple reason: to assist in
|
|
automatic LKM unloading policy. In a system where LKMs are loaded and
|
|
unloaded automatically (see <A
|
|
HREF="x197.html#AUTOLOAD"
|
|
>Section 5.4</A
|
|
>), you don't want
|
|
to automatically load an LKM and then, before the guy who needed it
|
|
loaded has a chance to use it, unload it because it is not in use.</P
|
|
><P
|
|
>Here is something you won't normally see:
|
|
<TABLE
|
|
BORDER="1"
|
|
BGCOLOR="#E0E0E0"
|
|
WIDTH="100%"
|
|
><TR
|
|
><TD
|
|
><FONT
|
|
COLOR="#000000"
|
|
><PRE
|
|
CLASS="SCREEN"
|
|
>mydriver 8154 0 (deleted)</PRE
|
|
></FONT
|
|
></TD
|
|
></TR
|
|
></TABLE
|
|
>
|
|
This is an LKM that is in "deleted" state. It's something of a
|
|
misnomer -- what it means is that the LKM is in the process of being
|
|
unloaded. You can no longer load LKMs that depend on it, but it's still
|
|
present in the system. Unloading an LKM is usually close to instantaneous,
|
|
so if you see this status, you probably have a broken LKM. Its cleanup
|
|
routine probably got into an infinite loop or stall or crashed (causing a
|
|
kernel oops). If that's the case, the only way to clear this status is to
|
|
reboot.</P
|
|
><P
|
|
>There are similar statuses "initializing" and
|
|
"uninitialized".</P
|
|
><P
|
|
>The legend "(autoclean)" refers to the autoclean flag,
|
|
discussed in <A
|
|
HREF="x197.html#AUTOLOAD"
|
|
>Section 5.4</A
|
|
>.</P
|
|
></DIV
|
|
><DIV
|
|
CLASS="SECT2"
|
|
><H2
|
|
CLASS="SECT2"
|
|
><A
|
|
NAME="MODLOCATION"
|
|
></A
|
|
>5.6. Where Are My LKM Files On My System?</H2
|
|
><P
|
|
>The LKM world is flexible enough that the files you need to load could
|
|
live just about anywhere on your system, but there is a convention
|
|
that most systems follow: The LKM .o files are in the directory
|
|
<TT
|
|
CLASS="FILENAME"
|
|
>/lib/modules</TT
|
|
>, divided
|
|
into subdirectories. There is one subdirectory for each version of
|
|
the kernel, since LKMs are specific to a kernel (see <A
|
|
HREF="basekerncompat.html"
|
|
>Section 6</A
|
|
>). Each subdirectory contains a complete set
|
|
of LKMs.</P
|
|
><P
|
|
>The subdirectory name is the value you get from the <B
|
|
CLASS="COMMAND"
|
|
>uname
|
|
--release</B
|
|
> command, for example <TT
|
|
CLASS="LITERAL"
|
|
>2.2.19</TT
|
|
>.
|
|
<A
|
|
HREF="basekerncompat.html#MULTIPLEKERNELS"
|
|
>Section 6.3</A
|
|
> tells how you control that value.</P
|
|
><P
|
|
>When you build Linux, a standard <B
|
|
CLASS="COMMAND"
|
|
>make modules</B
|
|
> and
|
|
<B
|
|
CLASS="COMMAND"
|
|
>make modules_install</B
|
|
> should install all the LKMs
|
|
that are part of Linux in the proper release subdirectory.</P
|
|
><P
|
|
>If you build a lot of kernels, another organization may be more
|
|
helpful: keep the LKMs together with the base kernel and other kernel-related
|
|
files in a subdirectory of /boot. The only drawback of this is that you
|
|
cannot have /boot reside on a tiny disk partition. In some systems, /boot
|
|
is on a special tiny "boot partition" and contains only enough files
|
|
to get the system up to the point that it can mount other filesystems.</P
|
|
></DIV
|
|
></DIV
|
|
><DIV
|
|
CLASS="NAVFOOTER"
|
|
><HR
|
|
ALIGN="LEFT"
|
|
WIDTH="100%"><TABLE
|
|
SUMMARY="Footer navigation table"
|
|
WIDTH="100%"
|
|
BORDER="0"
|
|
CELLPADDING="0"
|
|
CELLSPACING="0"
|
|
><TR
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="left"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="x146.html"
|
|
ACCESSKEY="P"
|
|
>Prev</A
|
|
></TD
|
|
><TD
|
|
WIDTH="34%"
|
|
ALIGN="center"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="index.html"
|
|
ACCESSKEY="H"
|
|
>Home</A
|
|
></TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
><A
|
|
HREF="basekerncompat.html"
|
|
ACCESSKEY="N"
|
|
>Next</A
|
|
></TD
|
|
></TR
|
|
><TR
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="left"
|
|
VALIGN="top"
|
|
>LKM Utilities</TD
|
|
><TD
|
|
WIDTH="34%"
|
|
ALIGN="center"
|
|
VALIGN="top"
|
|
> </TD
|
|
><TD
|
|
WIDTH="33%"
|
|
ALIGN="right"
|
|
VALIGN="top"
|
|
>Unresolved Symbols</TD
|
|
></TR
|
|
></TABLE
|
|
></DIV
|
|
></BODY
|
|
></HTML
|
|
> |