| | 1 | [[PageOutline]] |
| | 2 | |
| | 3 | = Linux Kernel modules |
| | 4 | If your kernel is built with loadable module support (CONFIG_MODULES=y) you can load and unload pre-built kernel modules to add, remove, and alter functionality of a running kernel. |
| | 5 | |
| | 6 | The userspace support for doing this comes from a set of commands typically packaged in a 'kmod' package name consisting of: |
| | 7 | - {{{lsmod}}} - show the status of modules currently loaded in the kernel (uses info from /proc/modules) |
| | 8 | - {{{insmod}}} - manually insert a module into the kernel |
| | 9 | - {{{rmmod}}} - manually remove a module from the kernel |
| | 10 | - {{{modinfo}}} - show info about a module |
| | 11 | - {{{depmod}}} - create a modules.dep and map file describing module dependencies |
| | 12 | - {{{modprobe}}} - add or remove a module from the kernel (handling dependencies and finding modules in the /lib/modules/$(uname -r) directory) taking into account module parameters from optional configuration files in /etc/modprobe.d |
| | 13 | |
| | 14 | Examples: |
| | 15 | * load a module: |
| | 16 | {{{#!bash |
| | 17 | insmod ./mymod.ko # by path |
| | 18 | modprobe mymod # from /lib/modules using dependencies |
| | 19 | }}} |
| | 20 | * remove a module: |
| | 21 | {{{#!bash |
| | 22 | rmmod mymod |
| | 23 | }}} |
| | 24 | * show loaded modules: |
| | 25 | {{{#!bash |
| | 26 | lsmod |
| | 27 | }}} |
| | 28 | * show kernel params for a given module: |
| | 29 | {{{#!bash |
| | 30 | $ modinfo g_ether | grep parm |
| | 31 | parm: idVendor:USB Vendor ID (ushort) |
| | 32 | parm: idProduct:USB Product ID (ushort) |
| | 33 | parm: bcdDevice:USB Device version (BCD) (ushort) |
| | 34 | parm: iSerialNumber:SerialNumber string (charp) |
| | 35 | parm: iManufacturer:USB Manufacturer string (charp) |
| | 36 | parm: iProduct:USB Product string (charp) |
| | 37 | parm: qmult:queue length multiplier at high/super speed (uint) |
| | 38 | parm: dev_addr:Device Ethernet Address (charp) |
| | 39 | parm: host_addr:Host Ethernet Address (charp) |
| | 40 | parm: use_eem:use CDC EEM mode (bool) |
| | 41 | }}} |
| | 42 | * show vermagic for a given module: |
| | 43 | {{{#!bash |
| | 44 | $ modinfo g_ether | grep vermagic |
| | 45 | vermagic: 6.12.0-g530fc2d305a3 SMP mod_unload aarch64 |
| | 46 | }}} |
| | 47 | |
| | 48 | == Building |
| | 49 | |
| | 50 | == Linux Kernel vermagic |
| | 51 | Vermagic is a magic string present in the Linux Kernel and added into the .modinfo section of the Linux Kernel Modules. |
| | 52 | |
| | 53 | This is used to verify whether the kernel module was compiled for the particular kernel version or not. |
| | 54 | |
| | 55 | This string is generated by the kernel configuration via the following in include/linux/vermagic.h: |
| | 56 | {{{#!bash |
| | 57 | #define VERMAGIC_STRING \ |
| | 58 | UTS_RELEASE " " \ |
| | 59 | MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ |
| | 60 | MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \ |
| | 61 | MODULE_ARCH_VERMAGIC \ |
| | 62 | MODULE_RANDSTRUCT |
| | 63 | }}} |
| | 64 | |
| | 65 | A typical VERMAGIC_STRING for an aarch64 kernel would look something like:{{{6.12.0-g530fc2d305a3 SMP mod_unload aarch64}}} |
| | 66 | |
| | 67 | While you can easily find the kernel version and arch of a running kenrel, perhaps the best way to see this exact string would be to use modinfo command on an existing module: |
| | 68 | {{{#!bash |
| | 69 | # modinfo $(find /lib/modules/$(uname -r)/ -name "*.ko" | head -n1) | grep vermagic |
| | 70 | vermagic: 6.12.0-g530fc2d305a3 SMP mod_unload aarch64 |
| | 71 | }}} |
| | 72 | |
| | 73 | The vermagic string is checked upon module loading and if the string in the module does not match the string in the kernel the module loading will fail by design: |
| | 74 | {{{#!bash |
| | 75 | # insmod mymod.ko |
| | 76 | mymod: version magic '6.12.0-00017-g530fc2d305a3 SMP mod_unload aarch64' should be '6.12.0-g530fc2d305a3 SMP mod_unload aarch64' |
| | 77 | insmod: ERROR: could not insert module ./mymod.ko: Invalid module format |
| | 78 | }}} |
| | 79 | |
| | 80 | There is no easy way to disable the kernel module loading vermagic string unless you disable a lot of security measures and the vermagic check is there for a very important reason: to disallow loading of modules that are not compatible with the specific version of kernel running. |
| | 81 | |
| | 82 | There are times however as a developer building an out-of-tree kernel module that you may wish to avoid this check. For example, if your running kernel version varies only slightly in ways you know are compatible. In such a case where you assume full responsibility for breaking something you could use the [https://dev.gateworks.com/sources/setvermagic.sh setvermagic.sh] script to modify the vermagic string: |
| | 83 | {{{#!bash |
| | 84 | $ wget https://dev.gateworks.com/sources/setvermagic.sh |
| | 85 | $ chmod +x setvermagic.sh |
| | 86 | $ modinfo mymod.ko | grep vermagic |
| | 87 | vermagic: 6.6.8-00035-gc6ef8b5e47a0 SMP mod_unload aarch64 |
| | 88 | Show quoted text |
| | 89 | $ ./setvermagic.sh mymod.ko "6.6.8-gc6ef8b5e47a0 SMP mod_unload aarch64" |
| | 90 | Current vermagic: 6.6.8-00035-gc6ef8b5e47a0 SMP mod_unload aarch64 |
| | 91 | New vermagic : 6.6.8-gc6ef8b5e47a0 SMP mod_unload aarch64 |
| | 92 | Modified module saved as: mymod-modified.ko |
| | 93 | You can load it with: insmod mymod-modified.ko |
| | 94 | }}} |