21 May 2002
Revision History | ||
---|---|---|
Revision v1.02 | 2002-05-21 | Revised by: bjh |
Correct explanation of symbol versioning. Correct author of Linux Device Drivers. Add info about memory allocation penalty of LKM vs bound-in. Add LKM-to-LKM symbol matching requirement. Add open source licensing issue in LKM symbol resolution. Add SMP symbol versioning info. | ||
Revision v1.01 | 2001-08-18 | Revised by: bjh |
Add material on various features created in the last few years: kernel module loader, ksymoops symbols, kernel-version-dependent LKM file location. | ||
Revision v1.00 | 2001-06-14 | Revised by: bjh |
Initial release. |
Copyright and license information, as well as credits, are at the end of this document.
This HOWTO is maintained by Bryan Henderson, bryanh@giraffe-data.com. It was released May 31, 2001. You can get the current version of this HOWTO from the Linux Documentation Project.
In some other operating systems, the equivalent of a Linux LKM is called a "kernel extension."
LKMs are not slower, by the way, than base kernel modules. Calling either one is simply a branch to the memory location where it resides. [1]
Sometimes you have to build something into the base kernel instead of making it an LKM. Anything that is necessary to get the system up far enough to load LKMs must obviously be built into the base kernel. For example, the driver for the disk drive that contains the root filesystem must be built into the base kernel.
make modules |
This results in a bunch of LKM object files (*.o) throughout the Linux source tree. (In older versions of Linux, there would be symbolic links in the modules directory of the Linux source tree pointing to all those LKM object files). These LKMs are ready to load, but you probably want to install them in some appropriate directory. The conventional place is described in Section 5.5. The command make modules_install will copy them all over to the conventional locations.
Part of configuring the Linux kernel (at build time) is choosing which parts of the kernel to bind into the base kernel and which parts to generate as separate LKMs. In the basic question-and-answer configuration (make config), you are asked, for each optional part of the kernel, whether you want it bound into the kernel (a "Y" response), created as an LKM (an "M" response), or just skipped completely (an "N" response). Other configuration methods are similar.
As explained in Section 2.3, you should have only the bare minimum bound into the base kernel. And only skip completely the parts that you're sure you'll never want. There is very little to lose by building an LKM that you won't use. Some compile time, some disk space, some chance of a problem in the code killing the kernel build. That's it.
As part of the configuration dialog you also must choose whether to use symbol versioning or not. This choice affects building both the base kernel and the LKMs and it is crucial you get it right. See Section 6.
LKMs that are not part of Linux (i.e. not distributed with the Linux kernel) have their own build procedures which I will not cover. The goal of any such procedure, though, is always to end up with an ELF object file.
You don't necessarily have to rebuild all your LKMs and your base kernel image at the same time (e.g. you could build just the base kernel and use LKMs you built earlier with it) but it is always a good idea. See Section 6.
The programs you need to load and unload and otherwise work with LKMs are in the package modutils. You can find this package in this directory.
This package contains the following programs to help you use LKMs:
Insert an LKM into the kernel.
Remove an LKM from the kernel.
Determine interdependencies between LKMs.
Kerneld daemon program
Display symbols that are exported by the kernel for use by new LKMs.
List currently loaded LKMs.
Display contents of .modinfo section in an LKM object file.
Insert or remove an LKM or set of LKMs intelligently. For example, if you must load A before loading B, Modprobe will automatically load A when you tell it to load B.
Changes to the kernel often require changes to modutils, so be sure you're using a current version of modutils whenever you upgrade your kernel. modutils is always backward compatible (it works with older kernels), so there's no such thing as having too new a modutils.
Warning: modprobe invokes insmod and has its location hardcoded as /sbin/insmod. There may be other instances in modutils of the PATH not being used to find programs. So either modify the source code of modutils before you build it, or make sure you install the programs in their conventional directories.
Inserting an LKM is conceptually easy: Just type, as superuser, a command like
insmod serial.o |
If it does work, though, the way to prove to yourself that you know what you're doing is to look at /proc/modules as described in Section 5.4.
Now lets look at a more difficult insertion. If you try
insmod msdos.o |
msdos.o: unresolved symbol fat_date_unix2dos msdos.o: unresolved symbol fat_add_cluster1 msdos.o: unresolved symbol fat_put_super ... |
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
cat /proc/ksyms |
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 fat.o. So do
insmod fat.o |
insmod msdos.o |
msdos 5632 0 (unused) fat 30400 0 [msdos] |
How did I know fat.o was the module I was missing? Just a little ingenuity. A more robust way to address this problem is to use depmod and modprobe instead of insmod, as discussed below.
When your symbols look like "fat_date_unix2dos_R83fb36a1", the problem may be more complex than just getting prerequisite LKMs loaded. See Section 6.
When the error message is "kernel/module version mismatch," see Section 6.
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:
insmod ne.o io=0x300 irq=11 |
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.
There are no standard parameters for LKMs and very few conventions. Each LKM author decides what parameters insmod 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 Section 13. For general information about LKM parameters, see Section 8.
To remove an LKM from the kernel, the command is like
rmmod ne |
There is a command lsmod to list the currently loaded LKMs, but all it does is dump the contents of /proc/modules, with column headings, so you may just want to go to the horse's mouth and forget about lsmod.
$ insmod usbcore.o usbcore.o: couldn't find the kernel version this module was compiled for |
What insmod is telling you is that it looked in usbcore.o 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 Section 10.2.
modprobe msdos |
Both kerneld and the kernel module loader use modprobe, ergo insmod, to insert LKMs.
kerneld is explained at length in the Kerneld mini-HOWTO, available from the Linux Documentation Project.
kerneld is a user process, which runs the kerneld program from the modutils package. kerneld sets up an IPC message channel with the kernel. When the kernel needs an LKM, it sends a message on that channel to kerneld and kerneld runs modprobe to load the LKM, then sends a message back to the kernel to say that it is done.
To see the presently loaded LKMs, do
cat /proc/modules |
serial 24484 0 |
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 /lib/modules, divided into subdirectories. There is one subdirectory for each version of the kernel, since LKMs are specific to a kernel (see Section 6). Each subdirectory contains a complete set of LKMs.
The subdirectory name is the value you get from the uname --release command, for example 2.2.19. Section 6.3 tells how you control that value.
When you build Linux, a standard make modules and make modules_install should install all the LKMs that are part of Linux in the proper release subdirectory.
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.
msdos.o: unresolved symbol fat_date_unix2dos msdos.o: unresolved symbol fat_add_cluster1 msdos.o: unresolved symbol fat_put_super ... |
#define register_chrdev register_chrdev_Rc8dc8350 |
And there's no way an option like -f on insmod can get around this.
The most common way to do this is with the LKM-hunting feature of modprobe. modprobe understands the conventional LKM file organization described in Section 5.5 and loads LKMs from the appropriate subdirectory depending on the kernel that is running.
You set the uname --release value, which is the name of the subdirectory in which modprobe looks, by editing the main kernel makefile when you build the kernel and setting the VERSION, PATCHLEVEL, SUBLEVEL, and EXTRAVERSION variables at the top.
For most systems, the ATA disk device driver must be bound into the base kernel because the root filesystem is on an ATA disk [2] and the kernel cannot mount the root filesystem, much less read any LKMs from it, without the ATA disk driver. But if you really want the device driver for your root filesystem to be an LKM, here's how to do it with Initrd:
"Initrd" is the name of the "initial ramdisk" feature of Linux. With this, you have your loader (probably LILO) load a filesystem into memory (as a ramdisk) before starting the kernel. When it starts the kernel, it tells it to mount the ramdisk as the root filesystem. You put the disk device driver for your real root filesystem and all the software you need to load it in that ramdisk filesystem. Your startup programs (which live in the ramdisk) eventually mount the real (disk) filesystem as the root filesystem. Note that a ramdisk doesn't require any device driver.
This does not free you, however, from having to bind into the base kernel 1) the filesystem driver for the filesystem in your ramdisk, and 2) the executable interpreter for the programs in the ramdisk.
insmod mcd mcd=0x340 |
To see all the sections in the object file for the msdos LKM:
objdump msdos.o --section-headers |
objdump msdos.o --full-contents --section=.modinfo |
You can use the modinfo program to interpret the contents of the .modinfo section.
It describes the form of the LKM's parameters. insmod uses this information to format the parameters you supply on the insmod command line into data structure initial values, which insmod inserts into the LKM as it loads it.
See Section 10.1 for more mind-numbing details of symbol binding.
__insmod_name_Ssectionname_Llength
name is the LKM name (as you would see in /proc/modules.
sectionname is the section name, e.g. .text (don't forget the leading period).
length is the length of the section, in decimal.
The value of the symbol is, of course, the address of the section.
__insmod_name_Ofilespec_Mmtime_Vversion
The code to handle LKMs is in the source files kernel/module.c in the Linux source tree.
The kernel module loader (see Section 5.3) lives in kernel/kmod.c.
(Ok, that wasn't much of a start, but at least I have a framework here for adding this information in the future).
The Linux Kernel Module Programming Guide by Ori Pomerantz is a complete explanation of writing your own LKM. This book is also available in print.
It is, however, a little out of date and contains an error or two. Here are a few things about writing an LKM that aren't in there.
Here is an improved version of hello.c. Compile this with the simple command
$ gcc -c -Wall hello.c |
/* hello.c * * "Hello, world" - the loadable kernel module version. * * Compile this with * * gcc -c hello.c -Wall */ /* Declare what kind of code we want from the header files */ #define __KERNEL__ /* We're part of the kernel */ #define MODULE /* Not a permanent part, though. */ /* Standard headers for LKMs */ #include <linux/modversions.h> #include <linux/module.h> #define _LOOSE_KERNEL_NAMES /* With some combinations of Linux and gcc, tty.h will not compile if you don't define _LOOSE_KERNEL_NAMES. It's a bug somewhere. */ #include <linux/tty.h> /* console_print() interface */ /* Initialize the LKM */ int init_module() { console_print("Hello, world - this is the kernel speaking\n"); /* More normal is printk(), but there's less that can go wrong with console_print(), so let's start simple. */ /* If we return a non zero value, it means that * init_module failed and the LKM can't be loaded */ return 0; } /* Cleanup - undo whatever init_module did */ void cleanup_module() { console_print("Short is the life of an LKM\n"); } |
This book is available under the FDL. You can read it at http://www.xml.com/ldd/chapter/book/.
Many LKMs can be alternatively bound into the base kernel. If you do that, you will pass parameters to them via the kernel "command line," which in its most basic form means via a prompt at boot time. The BootPrompt HOWTO by Paul Gortmaker <Paul.Gortmaker@anu.edu.au> will help you with that. It is available from the Linux Documentation Project.
Don't forget that the source code of Linux and any LKM is always the documentation of last resort, and the most trustworthy.
ELF is the normal executable format on Linux systems.
modprobe binfmt_elf |
modprobe floppy 'floppy="daring two_fdc 0,thinkpad 0x8,fifo_depth"' |
Tells the floppy driver that your floppy controller should be used with caution.
Tells the floppy driver that you have only floppy controller (default).
Tells the floppy driver that a workable DMA channel is available (the default).
(Note: there are two valid types for ED drives. This is because 5 was initially chosen to represent floppy tapes, and 6 for ED drives. AMI ignored this, and used 5 for ED drives. That's why the floppy driver handles both)
Print a warning message when an unexpected interrupt is received. (default behavior)
Tells the driver to expect interrupts on IRQ nr instead of the conventional IRQ 6.
Tells the driver to use DMA channel nr instead of the conventional DMA channel 2.
This driver lets you combine several disk partitions into one logical block device.
modprobe linear |
This driver lets you combine several disk partitions into one logical block device.
modprobe raid0 |
Detailed information about SCSI drivers is in SCSI-2.4-HOWTO.
Linux's SCSI function is implemented in three layers, and there are LKMs for all of them.
See the explanation of this special high-level driver above.
modprobe sg |
modprobe aha1740 |
modprobe advansys asc_iopflag=1 asc_ioport=0x110,0x330 asc_dbglvl=1 |
modprobe in2000 |
modprobe BusLogic |
This driver handles DPT PM2011/021/012/022/122/322.
modprobe eata |
This driver handles DPT, NEC, AT&T, SNI, AST, Olivetti, and Alphatronix.
This driver handles DPT Smartcache, Smartcache III and SmartRAID.
modprobe eata_dma |
This driver handles old DPT PM2001, PM2012A.
modprobe eata_pio |
modprobe fdomain |
There are no module parameters.
This driver autoprobes the card and requires installed BIOS.
modprobe NCR5380 ncr_irq=xx ncr_addr=xx ncr_dma=xx ncr_5380=1 \ ncr_53c400=1 |
modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1 |
modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 |
modprobe 53c7,8xx |
This driver autoprobes the card and requires installed BIOS.
See the file drivers/scsi/README.ppa in the Linux source tree for details.
modprobe ppa ppa_base=0x378 ppa_nybble=1 |
This driver is for Seagate ST-02 and Future Domain TMC-8xx.
modprobe seagate |
This driver autoprobes for address only. The IRQ is fixed at 5. The driver requires installed BIOS.
modprobe t128 |
This driver autoprobes the card. The driver requires installed BIOS.
You can have multiple dummy interfaces. They are named dummy0, dummy1, etc.
modprobe dummy |
modprobe plip io=0x378 irq=7 |
Along with this kernel driver, you need the user space program pppd running.
modprobe ppp |
There are no module parameters.
SLIP (Serial Line Internet Protocol) is like PPP, only older and simpler.
modprobe slip slip_maxdev=1 |
For more information, see http://www.baycom.org/~tom.
Example:
modprobe baycom modem=1 iobase=0x3f8 irq=4 options=1 |
Parameters:
major number the driver should use; default 60
modem type of the first channel (minor 0):
ser12
par96/par97
base address of the port the driver is to drive. Common values are for ser12 0x3f8, 0x2f8, 0x3e8, 0x2e8 and for par96/par97 0x378, 0x278, 0x3bc.
IRQ the driver is to service. Common values are 3 and 4 for ser12 and 7 for for par96/par97.
use hardware DCD
use software DCD
STRIP is a radio protocol developed for the MosquitoNet project to send Internet traffic using Metricom radios. Metricom radios are small, battery powered, 100kbit/sec packet radio transceivers, about the size and weight of a wireless telephone. (You may also have heard them called "Metricom modems" but we avoid the term "modem" because it misleads many people into thinking that you can plug a Metricom modem into a phone line and use it as a modem.) You can use STRIP on any Linux machine with a serial port, although it is obviously most useful for people with laptop computers.
Example:
modprobe strip |
There are no module parameters.
This is a driver for the WIC parallel port radio bridge.
modprobe wic |
It appears that devices wic0, wic1 and wic2 are directly related to corresponding lpN ports.
modprobe ne io=0x300 irq=11 |
You may repeat the options and full_duplex
parameters once per network adapter, for up to 8 network adapter.This driver can drive the following chipsets:
RealTek RTL-8029
Winbond 89C940
Winbond W89C940F
KTI ET32P2
NetVin NV5000SC
Via 86C926
SureCom NE34
Holtek HT80232
Holtek HT80229
Compex RL2000
This module depends on module 8390.
This is a driver for 3COM's 3c501 Ethernet adapter.
Example: modprobe 3c501 io=0x280 irq=5
If you don't specify an I/O port, the driver probes addresses 0x280 and 0x300.This is a driver for 3COM's 3c503 Ethernet adapter.
modprobe 3c503 io=0x300 irq=5 xcvr=0 |
This module depends on module 8390.
This is a driver for 3COM's 3c505 Ethernet adapter.
modprobe 3c503 io=0x300 irq=5 xcvr=0 |
This module depends on module 8390.
This is a driver for 3COM's 3c507 Ethernet adapter.
modprobe 3c503 io=0x300 irq=5 xcvr=0 |
This module depends on module 8390.
This is a driver for 3COM's 3c507 and 3c579 Ethernet adapters.
modprobe 3c503 io=0x300 irq=5 xcvr=0 |
This is a driver for the following 3COM Ethernet adapters:
modprobe 3c59x debug=1 options=0,,12 |
Details of the device driver implementation are at the top of the source file.
This is a driver for the Western Digital WD80*3 Ethernet adapters.
modprobe wd io=0x300 irq=5 mem=0x0D0000 mem_end=0x0D8000 |
If you don't specify an I/O port, the driver probes 0x300, 0x280, 0x380, and 0x240.
This is a driver for the Western Digital WD80*3 Ethernet adapters.
modprobe smc-ultra io=0x200 irq=5 |
This is a driver for SMC's 9000 series of Ethernet cards.
modprobe smc9194 io=0x200 irq=5 ifport=0 |
This is a driver for the AT1700 Ethernet adapter.
modprobe at1700 io=0x260 irq=5 |
This is a driver for the DEPCA, DE10x, DE200, DE201, DE202, and DE422 Ethernet adapters.
modprobe depca io=0x200 irq=7 |
This is a driver for the EtherWORKS 3 (DE203, D3204, and DE205) Ethernet adapters.
modprobe ewrk3 io=0x300 irq=5 |
This is a driver for the EtherExpress 16 Ethernet adapter.
modprobe eexpress io=0x300 irq=5 |
This is a driver for the EtherExpressPro Ethernet adapter.
modprobe eepro io=0x200 irq=5 |
This is a driver for the Fujitsu FMV-181, FMV-182, FMV-183, FMV-183, and FMV-184 Ethernet adapters.
modprobe fmv18x io=0x220 irq=5 |
This is a driver for HP's PCLAN+ (27247B and 27252A) Ethernet adapters.
modprobe hp-plus io=0x200 irq=5 |
This is a driver for HP's PCLAN (27245 and other 27xxx series) Ethernet adapters.
modprobe hp io=0x300 irq=5 |
This is a driver for ICL's EtherTeam 16i (eth16i) and 32i (eth32i) Ethernet adapters.
modprobe eth16i io=0x2a0 irq=5 |
This is a driver for the NI5210 Ethernet adapter.
modprobe ni52 io=0x360 irq=9 memstart=0xd0000 memend=0xd4000 |
This is a driver for the Ansel Communications EISA 3200 Ethernet adapter.
modprobe ac3200 |
This is a driver for the DE425, DE434, DE435, DE450, and DE500 Ethernet adapters.
modprobe de4x5 io=0x000b irq=10 is_not_dec=0 |
modprobe tulip |
Read Documentation/networking/tulip.txt in the Linux source tree.
There is a tool for setting up input and output packet filters on each port, called dgrsfilt.
There is also a companion management tool, called xrightswitch.
modprobe dgrs debug=1 dma=0 spantree=0 hashexpire=300 ipaddr=199,86,8,221 modprobe ipxnet=111 |
This is a driver for the D-Link DE600 pocket Ethernet adapter.
modprobe de600 de600_debug=0 |
This is a driver for the D-Link DE620 pocket Ethernet adapter.
modprobe de620 bnc=0 utp=0 io=0x378 irq=7 |
modprobe arcnet io=0x300 irq=2 shmem=0xd0000 device=arc1 |
This module provides ISDN functions used by ISDN adapter drivers.
modprobe isdn |
This is a driver for the ICN 2B and ICN 4B ISDN adapters.
modprobe icn portbase=0x320 membase=0xd0000 icn_id=idstring icn_id2=idstring2 |
This is a driver for the PCBIT-D ISDN adapter driver.
modprobe pcbit mem=0xd0000 irq=5 |
This is a driver for the Teles/NICCY1016PC/Creatix ISDN adapter. It can drive up to 16 cards.
modprobe teles io=0xd0000,15,0xd80,2 teles_id=idstring |
The driver determines the type of card from the port, irq and shared memory address:
modprobe aztcd aztcd=0x340 |
Read Documentation/cdrom/aztcd in the Linux source tree for full information.
This driver is like mcd, only it has XA and multisession functions.
modprobe mcdx mcdx=0x300,11,0x304,5 |
This is a driver for the ISP16 or MAD16 or Mozart soft configurable cdrom interface.
modprobe isp16 isp16_cdrom_base=0x340 isp16_cdrom_irq=3 isp16_cdrom_dma=0 isp16_cdrom_type=Sanyo |
address of base I/O port the driver is to drive. Valid values are 0x340, 0x320, 0x330, and 0x360.
IRQ the driver is to service. Valid values are 0, 3, 5, 7, 9, 10, and 11.
DMA channel the driver is to use with the device. Valid values are 0, 3, 5, 6, and 7.
This module provides services for use by the MSDOS and VFAT filesystem drivers.
modprobe fat |
SMBFS is a filesystem type which has an SMB protocol interface. This is the protocol Windows for Workgroups, Windows NT or Lan Manager use to talk to each other. SMBFS was inspired by Samba, the program written by Andrew Tridgell that turns any unix host into a file server for DOS or Windows clients. See ftp://nimbus.anu.edu.au/pub/tridge/samba/ for this interesting program suite and lots of more information on SMB and NetBIOS over TCP/IP. There you also find explanation for concepts like netbios name or share.
To use SMBFS, you need a special mount program, which can be found in the ksmbfs package, found on ftp://ibiblio.org/pub/Linux/system/Filesystems/smbfs.
Example:
modprobe smbfs |
There are no module parameters
NCPFS is a filesystem type which has an NCP protocol interface, designed by the Novell Corporation for their NetWare product. NCP is functionally similar to the NFS used in the TCP/IP community. To mount a Netware filesystem, you need a special mount program, which can be found in the ncpfs package. Homesite for ncpfs is ftp.gwdg.de/pub/linux/misc/ncpfs, but Ibiblio and its many mirrors will have it as well.
Related products are Linware and Mars_nwe, which will give Linux partial NetWare Server functionality.
Mars_nwe can be found on ftp.gwdg.de/pub/linux/misc/ncpfs.
Example:
modprobe ncpfs |
There are no module parameters.
This module depends on module ipx.
This filesystem driver for OS/2's HPFS filesystem provides only read-only access.
modprobe hpfs |
modprobe cyclades |
There are no module parameters.
Read the information in the file Documentation/stallion.txt in the Linux source tree.
Read the information in the file Documentation/stallion.txt in the Linux source tree.
modprobe stallion |
Read the information at /usr/src/linux/drivers/char/README.stallion.
modprobe istallion |
modprobe riscom8 iobase=0xXXX iobase1=0xXXX iobase2=... |
modprobe atixlmouse |
For SCSI tape device drivers, see Section 13.3. There are no LKMs for QIC-02 tape devices, but there is a device driver you can bind into the base kernel.
This HOWTO is enthusiastically maintained by Bryan Henderson <bryanh@giraffe-data.com>. If you find something incorrect or incomplete or can't understand something, Bryan wants to know so maybe the next reader can be saved the trouble you had.
The source for this document is DocBook SGML, and is available from the Linux Documentation Project.
[1] | For the pedantic, see Section 10.6. |
[2] | You probably know this type of disk as "IDE". Strictly speaking, IDE is an incorrect appelation. IDE refers to the "Integrated Drive Electronics" which all modern disk drives, notably all SCSI disk drives, use. The first IDE drives in common usage were ATA, and the names kind of got confused. ATA, like SCSI, is a precise specification of electrical signals, commands, etc. |