B3 Linking and Unlinking Modules

A user can link a module into the running kernel by executing the insmod external program. This program performs the following operations:

1. Reads from the command line the name of the module to be linked.

2. 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.

3. Computes the size of the memory area needed to store the module code, its name, and the module object.

4. 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:

a. 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.

b. 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.

c. Invokes vmalloc( ) to allocate a memory area for the new module.

d. 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.

e. Inserts the module object into the list pointed to by module_list.

f. Returns the starting address of the memory area allocated to the module.

5. Invokes the query_module( ) system call with the qm_modules subcommand to get the name of all already linked modules.

6. 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.

7. 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.

8. 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.

9. 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.

10. 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:

a. Checks whether the user is allowed to link the module (the current process must have the cap_sys_module capability).

b. Invokes find_module( ) to find the proper module object in the list to which module_list points.

c. Overwrites the module object with the contents of the corresponding object in the User Mode memory area.

d. Performs a series of sanity checks on the addresses in the module object.

e. Copies the remaining part of the User Mode memory area into the memory area allocated to the module.

f. Scans the module list and initializes the ndeps and deps fields of the module object.

g. Sets the module usage counter to 1.

h. Executes the init method of the module to initialize the module's data structures properly.

i. Sets the module usage counter to 0 and returns.

11. Releases the User Mode memory area and terminates.

To unlink a module, a user invokes the rmmod external program, which performs the following operations:

2. Invokes the query_module( ) system call with the qm_modules subcommand to get the list of linked modules.

3. 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.

4. 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.

5. 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.

6. 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:

a. Checks whether the user is allowed to remove the module (the current process must have the cap_sys_module capability).

b. Invokes find_module( ) to find the corresponding module object in the list to which module_list points.

c. Checks whether the refs field is null; otherwise, returns an error code.

d. 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.

e. 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.

f. Scans the deps list of the module and removes the module from the refs list of any element found.

g. Removes the module from the list to which module_list points.

h. Invokes vfree( ) to release the memory area used by the module and returns 0 (success).

7. If the list of modules to be unloaded is not empty, jumps back to Step 6; otherwise, terminates.

Was this article helpful?

0 0

Post a comment