Adding and Removing
From the user point of view, modules can be added into a running kernel by two different system programs: modprobe and insmod. The former takes into account the dependencies that arise between individual modules when a module depends on the functions of one or more partner modules. In contrast, insmod loads only a single module into the kernel, and this module may depend only on the code already
3 To counter the criticisms levied by license purists: GPL does not, of course, stand for Open Source but for free software. However, because the details are of a legal rather than a technical nature, I do not consider them here.
4Notice that during the development of kernel 2.5, the module implementation was revised from top to bottom. The userspace interface differs completely from the old version, which also necessitated a full rewrite of the modutils.
in the kernel, regardless of whether the code was generated dynamically by modules or is permanently compiled into the kernel.
modprobe also accesses insmod internally once it has identified the additional modules needed for the desired module. Before discussing how this is implemented, I will first describe the mode of operation of insmod on which work with modules in userspace is based.
The actions needed when loading a module show strong similarities with the linking of application programs by means of ld and with the use of dynamic libraries with ld.so. Externally, modules are just normal relocatable object files, as a file call will quickly confirm:
[email protected]> file vfat.ko vfat.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped
They are, of course, neither executable files nor program libraries as normally found in system programming; however, the basic structure of the binary module file is based on the same scheme also used for the above purposes.
The output of the file command indicates that the module file is relocatable, a familiar term in userspace programming. Relocatable files have no function references to absolute addresses but point only to relative addresses within the code and can therefore be loaded at any offsets in memory provided the addresses are modified accordingly by the dynamic linker ld.so. The same applies for kernel modules. Addresses are again given in relative and not absolute units. However, it is the kernel itself and not the dynamic loader that performs relocation.
Whereas in earlier kernel versions (up to 2.4) modules had to be loaded in a multistep process (reservation of memory in the kernel, followed by relocation of data in userspace and copying of the binary code into the kernel), only one system call — init_module — is now needed to perform all actions in the kernel itself.
When the system call is processed, the module code is first copied from the kernel into kernel memory; this is followed by relocation and the resolution of as yet undefined references in the module. These occur because the module uses functions that are permanently compiled into the kernel and whose addresses are not known at compilation time.
Continue reading here: Handling Unresolved References
Was this article helpful?