LJ Archive

Auto-loading Kernel Modules

Preston F. Crow

Issue #28, August 1996

Removing code from the kernel that provides unneeded support is one option long associated with Linux. Now, you can remove code that is not constantly required, putting it in modules loaded on command.

Like many operating systems, Linux offers support for numerous devices, file systems, and network protocols. Unfortunately, this growing support increases the memory requirements of the kernel. Linux partially solves this problem by allowing selection of only the features you need when compiling the kernel. This is further improved by allowing some features to be compiled as modules, so they can be loaded only when they are needed. The loading and unloading of modules can be automated with the use of kerneld, making the use of features compiled as modules just as easy as using those included in the basic kernel.

To use kerneld, you should start by installing the most recent version of the modules package, found at www.pi.se/blox/modules/. I'm using modules-1.3.69f, but there's probably a newer version out by the time you read this article. Also, you'll need a kernel at least as recent as 1.3.57.

Fortunately, kerneld automatically knows about most modules. All you must do is run it in your startup script. For Slackware-based systems, you'll need to edit /etc/rc.d/rc.local. You should include the following:

# Update kernel-module dependencies file
[ -x /sbin/depmod ] && {
        /sbin/depmod -a
}
# Start kerneld
[ -x /sbin/kerneld ] && {
        /sbin/kerneld
}

For Red Hat systems, you can install the contributed modules RPM on ftp.redhat.com in /pub/contrib/RPMS/ called modules-1.3.57-3.i386.rpm which provides support for kerneld. A newer version will probably be released by the time you read this, so look for a later version of the modules utility if you can't find it there. Alternately, read the article “Understanding Red Hat Runlevels” in LJ issue 27 (July 1996) and create a kerneld boot script in /etc/init.d with appropriate links in /etc/rc2.d, /etc/rc3.d, /etc/rc4.d, and /etc/rc5.d.

In either case, this runs depmod, which updates dependency information used by kerneld and then starts kerneld, which forks and hides in the background until the kernel needs it.

Now, all you need to do is reconfigure your kernel to use modules for the features you're not always using, and build and install the kernel and the modules. If you've never built modules before, simply add two steps to the kernel compilation process: make modules and make modules_install.

When you boot the new kernel, you should have all your modules loading automatically whenever you try to use them. The command lsmod will tell you which modules are loaded. Of course, it is a good idea to keep your old kernel bootable in case something doesn't work as expected.

Unfortunately, kerneld doesn't know about every module you might want to install—particularly those not part of the kernel distribution. To install these modules, you'll need to tell kerneld about them in /etc/conf.modules. Kerneld needs to know both where to find the module and what event triggers loading it.

I strongly recommend you use the default directories for your modules. Otherwise, you'll have to add not only the new path to /etc/conf.modules, but all the default paths as well. To see the default paths, use modprobe -c | more.

Telling kerneld what triggers the loading of a module requires adding alias entries in /etc/conf.modules. For device drivers, such as zftape.o or joystick.o, the format is based on the device type (character or block) and major number. For example, I use alias char-major-15 joystick for the joystick driver. You can get a bunch of examples by running modprobe -c to see the defaults. You can have multiple entries for the same module if there are multiple events that should trigger loading it.

You may also need to set an alias if you want to load an optional module, like BSD compression with PPP. The simplest alias to use for BSD compression is alias ppp bsd_comp. This will tell kerneld to load bsd_comp instead of ppp, but since bsd_comp requires the real ppp module (which requires slhc), it will load slhc and ppp first. Of course, if you have trouble with this, you can always load the modules explicitly in your dialing script and unload them in /etc/ppp/ip-down.

You can also use kerneld to set up a dial-on-demand network connection. When the kernel receives a request to send a packet to an IP address for which there is no routing information, it asks kerneld if it can establish a route to that address. When kerneld receives such a request, it runs /sbin/request-route, which should, generally, be a script to start PPP or SLIP, thereby establishing a route.

So, all you have to do is replace /sbin/request-route with your dialing script. Well... not exactly. If you rely completely on an outside nameserver, you can probably get away with that. In general, however, you need to be careful, as kerneld may call request-route several times, once for each IP address the kernel needs to resolve. This can be solved by using a lock file for the modem device, which is an option for chat and pppd. [You should be using that option anyway! —ED]

What Should Be Compiled as a Module?

When configuring your system, at first you may think it would be best to compile everything as a module. This isn't always a good idea, as it won't always save memory. Each module uses memory in 4K pages, so the last page will generally have some space wasted. Therefore, if you'll almost always have the module in use, you might as well compile it into the kernel. Also, keep in mind that kerneld itself consumes some memory (in my experience, at least 12 pages), so if you only have a few small modules to worry about, it would be better to compile them into the kernel or load them explicitly in the startup script.

Modules for file systems must be loaded as long as the file system is mounted, even if you're not using it. So if you keep /dos mounted all the time, don't bother to compile support for FAT as a module. If you don't like that option, you could look into using an automount daemon instead of keeping the file system mounted.

Be careful with modules that include information that may be changed when run. For example, the sound driver keeps track of the volume, and if you compile it as a module, the volume will be reset to the default each time it is loaded.

Finally, be careful not to compile something as a module if it will be used at boot time before kerneld is started. This includes the root file system, of course. For many systems, you'll find that you need both ELF and a.out support before kerneld starts. You may be able to overcome some problems by installing kerneld as one of the first programs executed by the startup scripts, but be careful if you're also doing dial-on-demand, as you may have something like sendmail in your startup scripts that will trigger it. As long as you have your old kernel around as a safety net, though, feel free to experiment.

Preston Crow Preston Crow is a graduate student in computer science at Dartmouth College. He became a happy Linux user in the summer of 1995, shortly before becoming happily married.

LJ Archive