A user can link a module into the
running kernel by executing the
insmod
external program. This program performs
the following operations:
Reads from the command line the name of the module to be linked.
Locates the file containing the module’s object code
in the system directory tree. The file is usually placed in some
subdirectory below /lib/modules
.
Computes the size of the memory area needed to store the module code,
its name, and the module
object.
Invokes the create_module( )
system call, passing
to it the name and size of the new module. The corresponding
sys_create_module( )
service routine performs the
following operations:
Checks whether the user is allowed to link the module (the current
process must have the CAP_SYS_MODULE
capability).
In any situation where one is adding functionality to a kernel, which
has access to all data and processes on the system, security is a
paramount concern.
Invokes the find_module( )
function to scan the
module_list
list of module
objects looking for a module with the specified name. If it is found,
the module has already been linked, so the system call terminates.
Invokes vmalloc( )
to allocate a memory area for
the new module.
Initializes the fields of the module
object at the
beginning of the memory area and copies the name of the module right
below the object.
Inserts the module
object into the list pointed to
by module_list
.
Returns the starting address of the memory area allocated to the module.
Invokes the query_module( )
system call with the
QM_MODULES
subcommand to get the name of all
already linked modules.
Invokes the query_module( )
system call with the
QM_INFO
subcommand repeatedly, to get the starting
address and the size of all modules that are already linked in.
Invokes the query_module( )
system call with the
QM_SYMBOLS
subcommand repeatedly, to get the
kernel symbol table and the symbol tables of all modules that are
already linked in.
Using the kernel symbol table, the module symbol tables, and the
address returned by the create_module( )
system
call, the program relocates the object code included in the
module’s file. This means replacing all occurrences
of external and global symbols with the corresponding logical address
offsets.
Allocates a memory area in the User Mode address space and loads it
with a copy of the module
object, the
module’s name, and the module’s
code relocated for the running kernel. The address fields of the
object point to the relocated code.
In particular, the init
field is set to the
relocated address of the module’s function named
init_module( )
, or equivalently to the address of
the module’s function marked by the
module_init
macro. Similarly, the
cleanup
field is set to the relocated address of
the module’s cleanup_module( )
function or, equivalently, to the address of the
module’s function marked by the
module_exit
macro. Each module should implement
these two functions.
Invokes the init_module( )
system call, passing to
it the address of the User Mode memory area set up in the previous
step. The sys_init_module( )
service routine
performs the following operations:
Checks whether the user is allowed to link the module (the current
process must have the CAP_SYS_MODULE
capability).
Invokes find_module( )
to find the proper
module
object in the list to which
module_list
points.
Overwrites the module
object with the contents of
the corresponding object in the User Mode memory area.
Performs a series of sanity checks on the addresses in the
module
object.
Copies the remaining part of the User Mode memory area into the memory area allocated to the module.
Scans the module list and initializes the ndeps
and deps
fields of the module
object.
Sets the module usage counter to 1.
Executes the init
method of the module to
initialize the module’s data structures properly.
Sets the module usage counter to 0 and returns.
Releases the User Mode memory area and terminates.
To unlink a module, a user invokes the rmmod
external program, which performs the following operations:
From the command line, reads the name of the module to be unlinked.
Invokes the query_module( )
system call with the
QM_MODULES
subcommand to get the list of linked
modules.
Invokes the query_module( )
system call with the
QM_SYMBOLS
subcommand repeatedly, to get the
kernel symbol table and the symbol tables of all modules that are
already linked in.
If the option -r
has been passed to
rmmod
, invokes the query_module( )
system call with the QM_REFS
subcommand several times to retrieve dependency information on the
linked modules.
Builds a list of modules to be unloaded: if the option
-r
has not been specified, the list includes only
the module passed as argument to rmmod
;
otherwise, it includes the module passed as argument and all loaded
modules that ultimately depend on it.
Invokes the delete_module( )
system call, passing
the name of a module to be unloaded. The corresponding
sys_delete_module( )
service routine performs
these operations:
Checks whether the user is allowed to remove the module (the current
process must have the CAP_SYS_MODULE
capability).
Invokes find_module( )
to find the corresponding
module
object in the list to which
module_list
points.
Checks whether the refs
field is null; otherwise,
returns an error code.
If defined, invokes the can_unload
method;
otherwise, checks whether the uc.usecount
fields
of the module
object is null. If the module is
busy, returns an error code.
If defined, invokes the cleanup
method to perform
the operations needed to cleanly shut down the module. The method is
usually implemented by the cleanup_module( )
function defined inside the module.
Scans the deps
list of the module and removes the
module from the refs
list of any element found.
Removes the module from the list to which
module_list
points.
Invokes vfree( )
to release the memory area used
by the module and returns 0 (success).
If the list of modules to be unloaded is not empty, jumps back to Step 6; otherwise, terminates.