613 lines
18 KiB
Groff
613 lines
18 KiB
Groff
.\" $NetBSD: module.9,v 1.53 2021/07/22 01:38:45 pgoyette Exp $
|
|
.\"
|
|
.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" This code is derived from software contributed to The NetBSD Foundation
|
|
.\" by Andrew Doran.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd July 21, 2021
|
|
.Dt MODULE 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm module ,
|
|
.Nm module_load ,
|
|
.Nm module_autoload ,
|
|
.Nm module_unload ,
|
|
.Nm module_init_class ,
|
|
.Nm module_hold ,
|
|
.Nm module_rele ,
|
|
.Nm module_find_section ,
|
|
.Nm module_kernel ,
|
|
.Nm module_name ,
|
|
.Nm module_source ,
|
|
.Nm module_register_callbacks ,
|
|
.Nm module_unregister_callbacks ,
|
|
.Nm module_specific_key_create ,
|
|
.Nm module_specific_key_delete ,
|
|
.Nm module_getspecific ,
|
|
.Nm module_setspecific
|
|
.Nd kernel module loader
|
|
.Sh SYNOPSIS
|
|
.In sys/module.h
|
|
.Fn MODULE "class" "name" "required"
|
|
.Ft int
|
|
.Fn module_load "const char *name" "int flags" "prop_dictionary_t props" \
|
|
"modclass_t class"
|
|
.Ft int
|
|
.Fn module_autoload "const char *name" "modclass_t class"
|
|
.Ft int
|
|
.Fn module_unload "const char *name"
|
|
.Ft void
|
|
.Fn module_init_class "modclass_t class"
|
|
.Ft void
|
|
.Fn module_hold "module_t *module"
|
|
.Ft void
|
|
.Fn module_rele "module_t *module"
|
|
.Ft int
|
|
.Fn module_find_section "const char *" "void **" "size_t *"
|
|
.Ft "module_t *"
|
|
.Fn module_kernel "void"
|
|
.Ft "const char *"
|
|
.Fn module_name "struct module *module"
|
|
.Ft modsrc_t
|
|
.Fn module_source "struct module *module"
|
|
.Ft void
|
|
.Fn module_init "void"
|
|
.Ft void
|
|
.Fn module_start_unload_thread "void"
|
|
.Ft void
|
|
.Fn module_builtin_require_force "void"
|
|
.Ft void
|
|
.Fn module_load_vfs_init "void"
|
|
.Ft "void *"
|
|
.Fn module_register_callbacks "void (*)(struct module *)" \
|
|
"void (*unload)(struct module *)"
|
|
.Ft void
|
|
.Fn module_unregister_callbacks "void *"
|
|
.Ft specificdata_key_t
|
|
.Fn module_specific_key_create "specificdata_key_t *keyp" \
|
|
"specificdata_dtor_t dtor"
|
|
.Ft void
|
|
.Fn module_specific_key_delete "specificdata_key_t key"
|
|
.Ft "void *"
|
|
.Fn module_getspecific "module_t *mod" "specificdata_key_t key"
|
|
.Ft "void *"
|
|
.Fn module_setspecific "module_t *mod" "specificdata_key_t key" "void *data"
|
|
.Sh DESCRIPTION
|
|
Modules are sections of code that can be independently linked and selectively
|
|
loaded into or unloaded from a running kernel.
|
|
This provides a mechanism to update the module without having to relink
|
|
the kernel and reboot.
|
|
Modules can be loaded from within the kernel image, provided by the boot
|
|
loader, or loaded from the file system.
|
|
.Pp
|
|
The
|
|
.Nm
|
|
subsystem includes two data types:
|
|
.Bl -enum -offset indent
|
|
.It
|
|
The
|
|
.Vt module_t
|
|
type provides storage to describe a module.
|
|
.It
|
|
The
|
|
.Vt modinfo_t
|
|
type resides within
|
|
.Vt module_t
|
|
and contains module header info.
|
|
.El
|
|
.Pp
|
|
The module subsystem is protected by the global
|
|
.Va kernconfig_mutex .
|
|
.Sh FUNCTIONS
|
|
.Bl -tag -width abcd
|
|
.It Fn MODULE "class" "name" "required"
|
|
The
|
|
.Fn MODULE
|
|
macro creates and initializes a
|
|
.Vt modinfo_t
|
|
structure.
|
|
The
|
|
.Fa class
|
|
argument identifies the class of module, and must be one of the following
|
|
(note that
|
|
.Dv MODULE_CLASS_ANY
|
|
should not be used here):
|
|
.Bl -tag -width MODULE_CLASS_SECMODEL -offset indent
|
|
.It Dv MODULE_CLASS_VFS
|
|
The module provide a virtual file system - see
|
|
.Xr vfs 9
|
|
.It Dv MODULE_CLASS_DRIVER
|
|
The module is a device driver - see
|
|
.Xr driver 9
|
|
.It Dv MODULE_CLASS_EXEC
|
|
The module provides an alternate execution environment - see the various
|
|
.Dv COMPAT_xxx
|
|
options in
|
|
.Xr options 4
|
|
.It Dv MODULE_CLASS_SECMODEL
|
|
The module provides a security model - see
|
|
.Xr secmodel 9
|
|
.It Dv MODULE_CLASS_BUFQ
|
|
The module provides a buffer queue strategy - see
|
|
.Xr bufq 9
|
|
.It Dv MODULE_CLASS_MISC
|
|
The module provides miscellaneous kernel services
|
|
.El
|
|
.Pp
|
|
The
|
|
.Fa name
|
|
argument provides the name of the module.
|
|
Loaded modules, including those that are built-in to the kernel, must all
|
|
have unique names.
|
|
.Pp
|
|
The
|
|
.Fa required
|
|
argument is a quoted string containing a comma-separated list of module
|
|
names that are required by this module.
|
|
The list must not contain any white-space.
|
|
When a module is loaded, all of its required modules are auto-loaded and
|
|
initialized before the module itself is loaded.
|
|
Loading of required modules is a recursive operation.
|
|
.Pp
|
|
If there are no required modules, this argument should be specified as
|
|
.Dv NULL .
|
|
.Pp
|
|
In addition to the explicit arguments, the
|
|
.Fn MODULE
|
|
macro creates a reference to the module's
|
|
.Fn modcmd
|
|
function.
|
|
This function is defined as:
|
|
.Bl -tag -width modcmd -offset indent
|
|
.It Ft modcmd_t
|
|
.Fn xxx_modcmd "modcmd_t cmd" "void *data"
|
|
.El
|
|
.Pp
|
|
(where xxx is the name of the module, from the
|
|
.Dv MODULE
|
|
macro).
|
|
.Pp
|
|
The
|
|
.Fa cmd
|
|
argument requests one of the following operations:
|
|
.Bl -tag -width MODULE_CMD_AUTOUNLOAD -offset indent
|
|
.It Dv MODULE_CMD_INIT
|
|
Perform module-specific initialization when the module is loaded.
|
|
.It Dv MODULE_CMD_FINI
|
|
Perform module-specific clean-up before the module is unloaded.
|
|
.It Dv MODULE_CMD_AUTOUNLOAD
|
|
Notify the module that it is about to be unloaded.
|
|
.It Dv MODULE_CMD_STAT
|
|
Request the module to provide status information (not currently implemented).
|
|
.El
|
|
.Pp
|
|
All modules'
|
|
.Fn modcmd
|
|
functions must implement the
|
|
.Dv MODULE_CMD_INIT
|
|
and
|
|
.Dv MODULE_CMD_FINI
|
|
commands.
|
|
The other commands are optional,
|
|
and should return
|
|
.Er ENOTTY
|
|
if not implemented.
|
|
.Pp
|
|
For the
|
|
.Dv MODULE_CMD_INIT
|
|
command, the
|
|
.Fa data
|
|
argument is used to pass a pointer to the module's
|
|
.Xr prop_dictionary 3 .
|
|
For the
|
|
.Dv MODULE_CMD_STAT
|
|
command, the
|
|
.Fa data
|
|
argument points to a buffer where the status information should be placed.
|
|
.Pp
|
|
The __link_set mechanism is used to enable the
|
|
.Nm
|
|
subsystem to locate the
|
|
.Vt modinfo_t
|
|
structure.
|
|
.It Fn module_load "name" "flags" "props" "class"
|
|
Load a module, link it into the running kernel, and call the module's
|
|
.Fn modcmd
|
|
routine with a
|
|
.Fa cmd
|
|
argument of
|
|
.Dv MODULE_CMD_INIT .
|
|
If the specified module requires other modules, they are loaded first; if
|
|
any required module cannot be loaded or if any of their
|
|
.Fn modcmd
|
|
control routines returns a non-zero status, loading of this module and
|
|
the specific required module will fail.
|
|
The required modules are marked for automatic unloading.
|
|
Thus, if the loading of the module failed, the required modules will
|
|
be automatically unloaded after a short delay.
|
|
.Pp
|
|
The loader will look first for a built-in module with the specified
|
|
.Fa name
|
|
that has not been disabled (see
|
|
.Fn module_unload
|
|
below).
|
|
If a built-in module with that
|
|
.Fa name
|
|
is not found, the list of modules prepared by the boot loader is searched.
|
|
If the named module is still not found, an attempt is made to locate the
|
|
module within the file system, provided it has been mounted by the
|
|
initialization code.
|
|
.Pp
|
|
The
|
|
.Fa flags
|
|
argument can include:
|
|
.Bl -tag -width MODCTL_LOAD_FORCE -offset indent
|
|
.It Dv MODCTL_NO_PROP
|
|
When loading a module from the file system, do not attempt to locate a
|
|
corresponding prop_dictionary file.
|
|
.It Dv MODCTL_LOAD_FORCE
|
|
Force loading of disabled built-in modules and modules built for a
|
|
different version of the operating system.
|
|
.El
|
|
.Pp
|
|
The
|
|
.Fa props
|
|
argument points to an externalized property list which is passed to the
|
|
module's
|
|
.Fn modcmd
|
|
routine.
|
|
If a module is being loaded from the file system, and the
|
|
.Dv MODCTL_NO_PROP
|
|
flag is not set, the system searches for a file with the same name as the
|
|
module file, but with the suffix
|
|
.Dq Pa .plist .
|
|
If this file is found, the prop_dictionary it contains is loaded and
|
|
merged with the prop_dictionary from the
|
|
.Fa props
|
|
argument.
|
|
.Pp
|
|
The
|
|
.Fa class
|
|
argument can be any of:
|
|
.Pp
|
|
.Bl -tag -width MODULE_CLASS_SECMODEL -offset indent -compact
|
|
.It Dv MODULE_CLASS_ANY
|
|
.It Dv MODULE_CLASS_DRIVER
|
|
Device driver
|
|
.It Dv MODULE_CLASS_EXEC
|
|
Executable image handler
|
|
.It Dv MODULE_CLASS_MISC
|
|
Miscellaneous module
|
|
.It Dv MODULE_CLASS_SECMODEL
|
|
Security model (see
|
|
.Xr secmodel 9
|
|
for more details)
|
|
.It Dv MODULE_CLASS_VFS
|
|
Virtual file system
|
|
.El
|
|
.Pp
|
|
If the class is not
|
|
.Dv MODULE_CLASS_ANY ,
|
|
the class of the module being loaded
|
|
must match the requested
|
|
.Fa class .
|
|
Except when verifying a module's class when it is being loaded, module
|
|
classes other than
|
|
.Dv MODULE_CLASS_SECMODEL
|
|
are transparent to the module subsystem.
|
|
They are provided only for the benefit of the subsystem's clients.
|
|
Modules with class
|
|
.Dv MODULE_CLASS_SECMODEL
|
|
are automatically registered with
|
|
.Fn secmodel_register
|
|
after being successfully loaded, and automatically deregistered with
|
|
.Fn secmodel_deregister
|
|
when being unloaded.
|
|
.Pp
|
|
The
|
|
.Fn module_load
|
|
routine is primarily intended as the implementation of the
|
|
.Dv MODCTL_LOAD
|
|
option of the
|
|
.Xr modctl 2
|
|
system call.
|
|
.It Fn module_autoload "name" "class"
|
|
Auto-load a module, making it available for automatic unloading.
|
|
The
|
|
.Fa name
|
|
and
|
|
.Fa class
|
|
arguments are the same as for the
|
|
.Fn module_load
|
|
routine.
|
|
.Pp
|
|
The module subsystem uses a kernel thread to attempt to automatically
|
|
unload modules a short time (currently, 10 seconds) after being loaded by
|
|
.Fn module_autoload .
|
|
Before the module is unloaded, its
|
|
.Fn modcmd
|
|
is called with the
|
|
.Fa cmd
|
|
argument specified as
|
|
.Dv MODULE_CMD_AUTOUNLOAD .
|
|
A module can prevent itself from being unloaded by returning a non-zero
|
|
value.
|
|
.Pp
|
|
The
|
|
.Fn module_autoload
|
|
function is intended for use by kernel components to locate and load optional
|
|
system components.
|
|
The function is also used to load modules that are required by other modules.
|
|
.Pp
|
|
The directory from which the module is loaded will be searched for a file
|
|
with the same name as the module file, but with the suffix
|
|
.Dq Pa .plist .
|
|
If this file is found, the prop_dictionary it contains will be loaded and
|
|
passed to the module's
|
|
.Fn modcmd
|
|
routine.
|
|
If this prop_dictionary contains a
|
|
.Dq Pa noautoload
|
|
property which is set to
|
|
.Dq Pa true
|
|
then the system will refuse to load the module.
|
|
.It Fn module_unload "name"
|
|
Unload a module.
|
|
If the module's reference count is non-zero, the function returns
|
|
.Er EBUSY .
|
|
Otherwise, the module's
|
|
.Fn modcmd
|
|
routine is called with a
|
|
.Fa cmd
|
|
argument of
|
|
.Dv MODULE_CMD_FINI .
|
|
If the
|
|
.Fn modcmd
|
|
routine returns with an error, then the error is returned to the caller
|
|
otherwise the module is unloaded.
|
|
.Pp
|
|
The reference counts of all modules that were required by this module are
|
|
decremented, but the required modules are not unloaded by the call to
|
|
.Fn module_unload .
|
|
Instead, the required modules may be unloaded by subsequent calls to
|
|
.Fn module_unload .
|
|
.Pp
|
|
Unloading a built-in module causes the module to be marked as disabled.
|
|
This prevents the module from being re-loaded, except by the
|
|
.Fn module_load
|
|
function with the
|
|
.Fa flags
|
|
argument set to
|
|
.Dv MODULE_FORCE_LOAD .
|
|
.Pp
|
|
The
|
|
.Fn module_unload
|
|
function may be called by the
|
|
.Xr modctl 2
|
|
system call, by the module subsystem's internal auto-unload thread, or by
|
|
other kernel facilities.
|
|
Generally, other kernel facilities should not be calling this function.
|
|
.It Fn module_init_class "class"
|
|
Load and initialize all available modules of the specified
|
|
.Fa class .
|
|
Any built-in modules that have not been disabled, and any modules provided
|
|
by the boot loader are loaded.
|
|
.It Fn module_hold "module"
|
|
Increment the reference count of a module.
|
|
A module cannot be unloaded if its reference count is non-zero.
|
|
.It Fn module_rele "module"
|
|
Decrement the reference count of a module.
|
|
.It Fn module_find_section "name" "addr" "size"
|
|
Find the start address and size of linker section
|
|
.Ar name
|
|
within a module.
|
|
The miniroot module uses this routine to find the address and size of the
|
|
embedded file system image.
|
|
This routine can only examine the linker data for the module that is
|
|
currently being initialized; it cannot examine data for any other module.
|
|
.It Fn module_kernel "void"
|
|
Returns a pointer to a
|
|
.Ft module_t
|
|
structure describing the kernel module.
|
|
.It Fn module_name module
|
|
Returns a pointer to the module's name.
|
|
.It Fn module_source module
|
|
Returns the source of the module, one of
|
|
.Dv MODULE_SOURCE_KERNEL ,
|
|
.Dv MODULE_SOURCE_BOOT ,
|
|
or
|
|
.Dv MODULE_SOURCE_FILESYS .
|
|
.It Fn module_init "void"
|
|
Initialize the module subsystem.
|
|
Creates and initializes various data structures, locates all built-in
|
|
modules, and establishes the sub-system's
|
|
.Xr sysctl 8
|
|
tree.
|
|
.Fn module_init
|
|
is called early in system initialization to facilitate use of security model
|
|
modules.
|
|
.It Fn module_start_unload_thread "void"
|
|
Create the thread that attempts to automatically unload modules that were
|
|
loaded via the
|
|
.Fn module_autoload
|
|
routine.
|
|
The function is called only once,
|
|
after the scheduler and timer functions are initialized.
|
|
.It Fn module_builtin_require_force "void"
|
|
Mark as "disabled" any built-in modules that have not been successfully
|
|
initialized.
|
|
Modules marked "disabled" can only be loaded if the
|
|
.Dv MODCTL_LOAD_FORCE
|
|
is specified.
|
|
.Fn module_builtin_require_force
|
|
is called near the end of system initialization, after the
|
|
.Xr init 8
|
|
process is created.
|
|
.It Fn module_load_vfs_init "void"
|
|
The module subsystem is initialized early, long before any file systems
|
|
are available.
|
|
After the root file system is mounted,
|
|
.Fn module_load_vfs_init "void"
|
|
is used to enable loading modules from the file system.
|
|
Until this routine is called, modules can only be loaded if they were
|
|
built-in to the kernel image or provided by the boot loader.
|
|
.It Fn module_register_callbacks "void (*load)(struct module *)" \
|
|
"void (*unload)(struct module *)"
|
|
Register a new set of callbacks.
|
|
The
|
|
.Fa load
|
|
callback is invoked after any module (including this module) is
|
|
successfully loaded; the
|
|
.Fa unload
|
|
callback is invoked before any module is unloaded.
|
|
Each load or unload event can result in multiple invocations of the
|
|
callback routines.
|
|
An opaque cookie is returned which can be passed to
|
|
.Fn module_unregister_callbacks .
|
|
.It Fn module_unregister_callbacks "void *opaque"
|
|
Unregister a set of callback routines previously registered with
|
|
.Fn module_register_callbacks .
|
|
The
|
|
.Fa opaque
|
|
argument should be the return value from the previous
|
|
.Fn module_register_callbacks
|
|
call.
|
|
.It Fn module_specific_key_create "specificdata_key_t *keyp" \
|
|
"specificdata_dtor_t dtor"
|
|
Creates a new specificdata_key for use within the
|
|
.Nm
|
|
domain.
|
|
The key identifier is returned in
|
|
.Fa keyp .
|
|
.It Fn module_specific_key_delete "specificdata_key_t key"
|
|
Deletes the specified specificdata_key
|
|
.Fa key
|
|
from the
|
|
.Nm
|
|
domain.
|
|
.It Fn module_getspecific "module_t *mod" "specificdata_key_t key"
|
|
Retrieves the value associated with
|
|
.Fa key
|
|
from module
|
|
.Fa mod .
|
|
.It Fn module_setspecific "module_t *mod" "specificdata_key_t key" "void *data"
|
|
Stores
|
|
.Fa data
|
|
as the value associated with
|
|
.Fa key
|
|
for module
|
|
.Fa mod .
|
|
.El
|
|
.Sh PROGRAMMING CONSIDERATIONS
|
|
The module subsystem is designed to be called recursively, but only within
|
|
a single LWP.
|
|
This permits one module's
|
|
.Fn modcmd
|
|
routine to load or unload other modules.
|
|
.Pp
|
|
Additional considerations:
|
|
.Bl -bullet -offset indent
|
|
.It
|
|
A module is not permitted to load or unload itself.
|
|
Attempts to load or unload a module from within its own
|
|
.Fn modcmd
|
|
routine will fail with
|
|
.Er EEXIST
|
|
or
|
|
.Er EBUSY ,
|
|
respectively.
|
|
.It
|
|
Although a module can be loaded by using either
|
|
.Fn module_load
|
|
or
|
|
.Fn module_autoload ,
|
|
it is not possible for the module's
|
|
.Fn modcmd
|
|
routine to distinguish between the two methods.
|
|
Any module which needs to ensure that it does not get auto-unloaded must
|
|
either handle the
|
|
.Dv MODULE_CMD_AUTOUNLOAD
|
|
command in its
|
|
.Fn modcmd
|
|
routine, or use
|
|
.Fn module_hold
|
|
to increment its reference count.
|
|
Note however that modules loaded manually with
|
|
.Xr modload 8
|
|
are never auto-unloaded.
|
|
.El
|
|
.Sh EXAMPLES
|
|
A set of example modules is available in the
|
|
.Pa src/sys/modules/examples
|
|
directory hierarchy.
|
|
.Sh CODE REFERENCES
|
|
The core of the kernel module implementation is in
|
|
.Pa sys/kern/kern_module.c
|
|
and
|
|
.Pa sys/kern/kern_module_vfs.c .
|
|
.Pp
|
|
The routines for linking the module are in
|
|
.Pa sys/kern/subr_kobj.c .
|
|
.Pp
|
|
The routines for reading a module from the file system are in
|
|
.Pa sys/kern/subr_kobj_vfs.c .
|
|
.Pp
|
|
The header file
|
|
.In sys/sys/module.h
|
|
describes the public interface.
|
|
.Pp
|
|
In addition, each architecture is expected to provide
|
|
.Fn kobj_machdep ,
|
|
.Fn kobj_reloc ,
|
|
and
|
|
.Fn module_init_md .
|
|
.Fn kobj_machdep
|
|
is for any machine dependent actions, such as flushing caches, that are
|
|
needed when a module is loaded or unloaded.
|
|
.Fn kobj_reloc
|
|
deals with resolution of relocatable symbols.
|
|
.Fn module_init_md
|
|
is for finding modules passed in by the boot loader.
|
|
.Sh SEE ALSO
|
|
.Xr modctl 2 ,
|
|
.Xr module 7 ,
|
|
.Xr specificdata 9 ,
|
|
.Xr intro 9lua
|
|
.Sh HISTORY
|
|
The kernel module subsystem first appeared in
|
|
.Nx 5.0 .
|
|
It replaces the
|
|
.Dq LKM
|
|
subsystem from earlier releases.
|
|
.Sh AUTHORS
|
|
.An -nosplit
|
|
The
|
|
.Nm
|
|
system was written by
|
|
.An Andrew Doran Aq Mt ad@NetBSD.org .
|
|
This manual page was written by
|
|
.An Paul Goyette Aq Mt pgoyette@NetBSD.org .
|