mload - dynamically loadable kernel modules
IRIX supports dynamic loading and unloading of modules into a running
kernel. Kernel modules can be registered and then loaded automatically
by the kernel when the corresponding device is opened, or they can be
loaded manually. Similarly, dynamically loaded modules can be unloaded
automatically or manually if the module includes an unload entry point.
A loadable kernel module can be a character, block or streams device
driver, a streams module, a library module or the idbg.o module.
Module Configuration [Toc] [Back]
Each loadable module should contain the string:
char *prefix<b>mversion = M_VERSION;
M_VERSION is defined in the mload.h header file, which should be included
by the loadable module.
A number of cc flags must be defined correctly when compiling loadable
modules for Irix. To ensure that you get the correct flags, use the
sample makefile in /var/sysgen/Makefile.kernloadio from the eoe.hdr.lib
subsystem. Instructions for using the makefile are at the beginning of
the Makefile.kernloadio file.
A loadable module must not be dependent on any loadable module, other
than a library module. In order to load a module comprised of multiple
object files, the object files should be linked together into a single
object file, using the following ld options: -G0 -r -d
Loading a Dynamically Loadable Kernel Module [Toc] [Back]
Either lboot or the ml command can be used to load, register, unload,
unregister, and list loadable kernel modules. The lboot command parses
module type, prefix and major number information from the module's master
file found in the /var/sysgen/master.d directory. The loadable object
file is expected to be found in the /var/sysgen/boot directory. The ml
command also provides a means of loading, registering and unloading
loadable modules, without the need for creating a master file or
reconfiguring the kernel.
When a module is loaded, the object file's header is read; memory is
allocated for the module's text, data and bss; the module's text and
data are read; the module's text and data are relocated and
unresolved references into the kernel are resolved; a symbol table
is created for the module; the module is added to the appropriate
kernel switch table; and the module's init routine is called.
A module is loaded using the following ml command:
ml ld [-v] -[cbBfmi] module.o <b>-p prefix [-s major major ...]
If a module is loaded successfully, an id number is returned which
can be used to unload the module.
A module can also be loaded using lboot:
lboot -L master
The register command is used to register a module for loading when
its corresponding device is opened. When a module is registered, a
stub routine is entered into the appropriate kernel switch table.
When the corresponding device is opened, the module is actually
A module is registered using the following ml command:
ml reg [-v] -[cbBfmi] module.o <b>-p prefix [-s major major ...]
[-a modname] [-t autounload_delay]
If a module is registered successfully, an id number is returned
which can be used to unregister the module.
A module can also be registered using lboot:
lboot -R master
A module can be unloaded only if it provides an unload entry point.
A module is unloaded using:
ml unld id [id id ...]
lboot -U id [id id ...]
A module can be unregistered using:
ml unreg id [id id ...]
lboot -W id [id id ...]
All loaded and/or registered modules can be listed using:
ml list [-rlb]
Master File Configuration [Toc] [Back]
If a dynamically loadable module has an associated master file, the
master file should include a d in Field 1. The d flag indicates to lboot
that the module is a dynamically loadable kernel module. If the d flag
is present lboot will parse the module's master file, but will not fill
in the entry in the corresponding kernel switch table for the module.
All global data defined in the master file will be included in the
generated master.c file. The kernel should be configured with master
files that contain the d option for each module that will be a
dynamically loadable module, if lboot will be used to load, register,
unload, unregister or autoregister the module. If the ml(1M) command
will be used, then it is not necessary to create a master file for the
Loadable modules can be registered by lboot automatically at system
startup when autoconfig is run. In order for a module to be autoregistered,
its master file should contain an R in Field 1, in addition
to d, which indicates that the module is loadable. When lboot runs at
system startup, it registers each module that contains an R in its master
file. Modules which specify a particular major number are registered
before modules which pick a major number dynamically. If an rc2 script
is added, which registers or loads dynamically loadable modules, it
should be run after the autoconfig rc2 script is run.
For more detailed information, see the lboot(1M), ml(1M), and master(4)
All registered modules that include an unload routine are automatically
unloaded after last close, unless they have been configured not to.
Modules are unloaded five minutes after last close by default. The
default auto-unload delay can be changed by using systune to change the
module_unld_delay variable. For more information about systune, see the
systune(1M) reference page. A particular module can be configured with a
specific auto-unload delay by using the ml command. A module can be
configured to not be auto-unloaded by either placing an N in the flags
field of its master.d file, if it is registered using lboot, or by using
ml to register the module and using the -t option.
Kernel Configuration [Toc] [Back]
A kernel which supports loadable modules, should be configured so that
the kernel switch tables generated by lboot(1M) contain "extra" entries
for the loadable modules. Extra entries are generated by lboot based on
the values of the following kernel tuneable parameters:
* name default minimum maximum
bdevsw_extra 21 1 254
cdevsw_extra 23 3 254
fmodsw_extra 20 0
vfssw_extra 5 0
These tuneable parameters are found in the kernel
/var/sysgen/mtune/kernel file and are set to the defaults listed above.
For more information about changing tuneable parameters, see the mtune(4)
and systune(1M) reference pages.
Module Entry Points
Loadable device drivers should conform to the SVR4 DDI/DKI standard. In
addition to the entry points specified by the DDI/DKI standard, if a
loadable module is to be unloaded, the module needs to contain an unload
int prefix<b>unload (void)
An unload routine should be treated as an interrupt routine and should
not call any routines that would cause it to sleep, such as: biowait(),
sleep(), psema() or delay().
An unload routine should free any resources allocated by the driver,
including freeing interrupt vectors and allocated memory and return 0.
Module Initialization [Toc] [Back]
After a module is loaded, linked into the kernel and sanity checking is
done, the modules' initialization routines, prefixinit(), prefixedtinit()
and prefixstart() are called, if they exist. For more information on
these routines, refer to the SVR4 DDI/DKI Reference Manual and the IRIX
Device Driver Programmer's Guide.
Edt Type Drivers [Toc] [Back]
For drivers that have an edtinit entry point, which get passed a pointer
to an edt structure, lboot must be used to load the driver. A vector
line should be added to the system file for the driver, as it would for
any driver. When the module is loaded, using lboot, lboot parses the
vector line from the system file to create an edt structure which is
passed through the kernel and to the driver's edtinit routine. For more
information, see the system(4) reference page.
Library Modules [Toc] [Back]
A library module is a loadable module which contains a collection of
functions and data that other loaded modules can link against. A library
module can be loaded using the following ml command:
ml ld [-v] -l library.o
A library module must be loaded before other modules that link against it
are loaded. Library modules can not be unloaded, registered or
unregistered. Only regular object files are supported as loadable
The idbg.o Module [Toc] [Back]
The idbg.o module can be dynamically loaded into a running kernel, so
that the kernel print utility, idbg(1M), can be used without
reconfiguring and rebooting a new kernel. The idbg.o module can be
dynamically loaded using the ml command:
ml ld -i /var/sysgen/boot/idbg.o -p idbg
The idbg.o module can also be unloaded.
Other idbg modules, such as xfsidbg.o, xlvidbg.o, mloadidbg.o, and so on,
can be loaded after idbg.o is loaded. For example:
ml ld -i /var/sysgen/boot/xfsidbg.o -p xfsidbg.o
For more information, see the idbg(1M) reference page.
Loadable Modules and Hardware Inventory
Many device drivers add to the hardware inventory in their init or
edtinit routines. If a driver is a dynamically loadable driver and is
auto-registered, it will not show up in the hardware inventory until the
driver has been loaded on the first open of the corresponding device. If
a clean install or a diskless install is done, a /dev entry will not get
created by MAKEDEV for such a driver since it doesn't appear in the
hardware inventory. If such a situation arises, the D master.d flag can
be used to indicate that the driver should be loaded, then unloaded by
autoconfig. If the R master.d flag, which indicates that the driver
should be auto-registered, is also used, then the driver will be autoregistered
as usual. A startup script can then be added that will run
MAKEDEV after autoconfig, if necessary. For an example, see the
/etc/init.d/chkdev startup script.
Kernel Runtime Symbol Table [Toc] [Back]
A runtime symbol table which contains kernel routines and global data
that modules can link against is created from the ELF symbol information
in the kernel that was booted. The runtime symbol table is created
automatically by the kernel from the file indicated by the kernname
environment variable, which is set by sash to the name of the file that
The symbol table is loaded with a default auto-unload timeout of five
minutes, after which the symbol table is automatically unloaded. The
symbol table is automatically reloaded when needed to resolve symbols
(for example when a new or registered module is loaded).
The kernel runtime symbol table can also be loaded manually, using the ml
ml ld -r /unix
Or unloaded manually:
ml unld id
Note that only one kernel runtime symbol table can exist at one time.
Auto-loading and unloading of the kernel runtime symbol table can be
disabled using the mload_auto_rtsyms systune variable. For more
information about tuneable variables, see the systune(1M) reference page.
Debugging Loadable Modules [Toc] [Back]
symmon(1M) supports debugging of loadable modules. symmon commands that
do a symbol table lookup, such as: brk, lkup, lkaddr, hx and nm, also
search the symbol tables created for loadable modules. The msyms command
can also be used to list the symbols for a particular loaded module:
The mlist command can be used to list all of the modules that are
currently loaded and/or registered.
For more information, see the symmon(1M) reference page.
If a registered module fails to load, it is suggested that the module be
unregistered and then loaded using ml ld or lboot -L, in order to get a
more detailed error message about the failure. All of the error codes,
including a description of each, are listed in the mload.h header file,
found in the /usr/include/sys directory.
The kernel will fail to load or register a module for any of the
1. If autoconfig is not run at system startup, none of the dynamically
loadable modules will be registered or loaded.
2. If autoconfig fails for some reason, before it has processed the
dynamically loadable module master.d files, the modules will not be
registered or loaded.
3. The major number specified either in the master file, or by the ml
command, is already in use.
4. The object file is not compiled with the correct options, such as
-G0 and -jalr.
5. The module is an "old style" driver, with either xxxdevflag set to
D_OLD, or no xxxdevflag exists in the driver.
6. A corrupted object file could cause "invalid JMPADDR" errors.
7. Not all of the module's symbols were resolved by the kernel.
8. The device switch table is full and has no more room to add a
9. Required entry points for the particular type of module are not
found in the object file, such as xxxopen for a character device
10. All major numbers are in use.
11. An old sash is used to boot the kernel, which does not set the
kernname environment variable, which indicates the on-disk kernel
image to load the runtime symbol table from (for example, /unix).
This will cause all loadable modules to fail to load or be
registered. To find out what the kernname environment variable is
set to, use the nvram(1M) command:
12. The runtime symbol table can not be loaded from the file indicated
by the kernname environment variable, because the file does not
exist, the file is not the same as the running kernel or the kernel
was bootp'ed from another machine.
The following example lists the steps necessary to build a kernel and
load a character device driver, called dlkm, using the lboot command:
1. Add d to the dlkm master file:
*FLAG PREFIX SOFT #DEV DEPENDENCIES
cd dlkm 38 2
2. Make sure that the cdevsw_extra kernel tuneable parameter allows for
extra entries in the cdevsw table, the default setting in
cdevsw_extra 23 3 254
The systune(1M) command also lists the current values of all of the
tuneable parameters. If the kernel is not configured to allow extra
entries in the cdevsw table, use the systune command to change the
> systune -i
systune-> cdevsw_extra 3
3. Build a new kernel and boot the target system with the new kernel.
4. Compile the dlkm.c driver. It should be noted that linking either
64bit or 32bit objects the "-non_shared" flag is not needed.
For 32-bit modules:
cc -non_shared -elf -G0 -r -d -jalr -c dlkm.c
For 64-bit modules:
cc -non_shared -elf -G 0 -jalr -c dlkm.c
5. Copy dlkm.o to /var/sysgen/boot.
6. Load the driver into the kernel:
lboot -L dlkm
7. List the currently loaded modules to verify that the module was
The following example lists the steps necessary to load a character
device driver, called dlkm, using the ml command:
1. Follow step 2 from example 1.
2. Follow step 4 from example 1.
3. Load the driver into the kernel:
ml ld -c dlkm.o -p dlkm -s 38
If a major number is not specified, the first free major number in
the MAJOR table is used. If the load was successful, an id number
is returned, which can be used to unload the driver.
4. List the currently loaded modules to verify that the module was
1. Loadable modules must not have any dependencies on loadable modules,
other than library modules. When a module is loaded, it is linked
against the kernel symbol table and any loaded library modules'
symbol tables, but it is not linked against other modules' symbol
2. Only character, block and streams device drivers, streams modules
and library modules are supported as loadable modules at this time.
3. Old style drivers (devflag set to D_OLD) are not loadable.
4. Kernel profiling does not support loadable modules.
5. Memory allocated may be in either K0SEG or in K2SEG. If the module
is loaded into K2SEG static buffers are not necessarily in
physically contiguous memory. Also, depending on machine
configuration, K2SEG addresses may map to high physical memory
addresses, in which case, PHYS_TO_K0 and PHYS_TO_K1 macros will not
cc(1), lboot(1M), ld(1), ml(1M), symmon(1M), systune(1M), master(4),
IRIX Device Driver Programmer's Guide
PPPPaaaaggggeeee 9999 [ Back ]