Difference between Linux Loadable and built-in modules - linux

What's the difference between loadable modules and built-in (statically linked) modules?
I got this question while finding out an answer for difference between system calls subsys_initcall() and module_init()

Linux kernel supports inserting of modules (aka device drivers) in two ways:
Built-in kernel modules - When the kernel is booted up, the kernel automatically inserts this driver in to the kernel (it's more like it is already part of the kernel code).
Loadable kernel module (LKM) - A driver that is not automatically loaded by the kernel, the user can insert this module at run-time by insmod driver.ko or modprobe driver.ko
The advantage the loadable modules have over the built-in modules is that you can load unload them on run-time. This is good if you are working on a module and you need to test it. Every time you test it and you need to make changes to it, you can easily unload it (rmmod driver.ko or modprobe -r driver.ko) and then after making changes, you can insert it back. But for the built-in modules if you need to make any changes in the module then you need to compile the whole kernel and then reboot the system with the new image of the kernel.
Configuration:
You can configure a module to be either of the two by editing the .config file in the root folder of your kernel source:
DRIVER_1=y // y indicate a builtin module
DRIVER_1=m //m inicates a loadable module
Note: lsmod displays only the dynamically loaded modules not the built-in ones.
Read on: http://www.tldp.org/HOWTO/Module-HOWTO/x73.html

Related

Is there any module dependency definition for linux kernel module in source code level?

I know that we can check the Linux kernel module dependency at runtime with the lsmod or modprobe command.
But what if we only have the kernel code, is there a way to check the kernel module's dependency, or is there any dependency definition in the kernel source code?
Thanks in advance.
You can check the Kconfig entry for the driver. Dependency to external modules, subsystem is specified as
depends on (dependencies)
select (reverse dependencies)
You can find more details in Documentation/kbuild/kconfig-language.txt
For example, if CONFIG_MY_DRIVER depends on I2C, you can specify this as depends on in Kconfig. This means, if I2C is not selected in menuconfig, MY_DRIVER will not show up in menuconfig entry.
Opposite to which, when you use select, I2C is automatically selected when selecting MY_DRIVER.

Editing compiled kernel module for more compatibility

I want to edit compiled kernel module file (module.ko) to insert something like "MODULE_INFO(vermagic, "3.10.9-blabla");" because this module file does not load with insmod and i get the error "failed (Exec format error)", the module was made for 2.6.35-smp version, I'm new to linux.
You cannot edit a compiled module directly.
Whatever change you need to do, you have to edit the source file and then compile it again.
From version 2.6.35 to 3.10 quite a lot of things changed; most likely the module is not compatible at all and it will not work. So, even if you can change the vermagic in the binary file it will not work because it's incompatible.
In your case, as Hector said, you have to recompile the module against a different Linux version. This process will also highlight all the incompatibilities that you should fix too.
If you do not have the sources because it is not an open source module: complain with the vendor :)
Although you will not be able to edit your compiled module now, build your kernel with CONFIG_MODVERSIONS is not set from next time, for driver development. It will enable you to make any number of incremental changes to your driver and load it against the newly built kernel with CONFIG_MODVERSIONS is not set.
CONFIG_MODVERSIONS is a notion thought up to make people's lives easier. If your kernel is compiled with CONFIG_MODVERSIONS=y, it enables you
to only be able to load modules that were compiled specifically for
that kernel version. Whereas, if your kernel is built with CONFIG_MODVERSIONS is not set, it will enable your driver to load on any kernel where CONFIG_MODVERSIONS is not set. You can modify this field in the .config file of your linux-kernel directory.

How linux device drivers are loaded?

Can anyone explain me in simple terms the following thing.
How Linux drivers are loaded into kernel space?
Which functions are exported, after drivers being loaded?
How driver functions are called?
Normally you will use insmod or modprobe userspace application to load module (and possibly its dependencies in case of the 2nd one). Both of them do the same under the hood to actually load single module - they read the file into memory and use init_module system call, providing address of memory where this module was loaded. This call tells kernel that module should be loaded.
Now kernel modules are actually ELF files and are not much different from shared libraries used in userspace. The kernel has an equivalent of shared library linker, that will parse those files, get a list of symbols that are provided by it, updating the list of functions known to kernel. It will also check if all the symbols that this module needs are already in the kernel and do proper relocations. One of the last thing that it will do is to call initialization function in the module.
Note that you cannot compile the kernel that will directly call any function that is provided by module. Similarly, you can call any function provided by a module in another module before loading the first one. Kernel will refuse to load any module with symbols that are not known. Most of the modules will, however, register its functions as some kind of callbacks that can be called indirectly.

Hard time in understanding MODULE_DEVICE_TABLE(usb, id_table) usage

I have a hard time understanding the exact usage of MODULE_DEVICE_TABLE(usb, id_table)
AFAIK this will generate the map files that will be used later by modprobe whenever a new device is inserted, it will match it against those map files and load the module if it matches.
But my misunderstanding is "isn't the module loaded anyway?"
I mean I already loaded it when I did insmod module-name. or am I missing something?
It is usually used to support hot-plugging, by loading/inserting the driver for a device if not already loaded.
There is a similar question here: Detect the presence of a device when it's hot plugged in Linux
(From my ans)
It works as follows:
Each driver in the code exposes its vendor/device id using:
MODULE_DEVICE_TABLE(of, omap_mcspi_of_match);
At compilation time the build process extracts this infomation from all the drivers and prepares a device table.
When you insert the device, the device table is referred by the kernel and if an entry is found matching the device/vendor id of the added device, then its module is loaded and initialized.
According to Linux Device Drivers:
MODULE_DEVICE_TABLE is used to generate map files by depmod program;
When device is hot-plugged, bus driver generates hotplug event. Kernel calls /sbin/hotplug with appropriate environmental variables set;
Given map files and information from environment, /sbin/hotplug decides which module to load and actually loads it. If the module is already loaded, it's OK.
I should mention again that this mechanism just ensures that needed module is in-place when device is plugged. That doesn't link module with that device or anything else. Just loads module.
To check if driver is OK for specific device, match() function from bus_type is used.
Here is how I understands the things [Xbuntu 14.04 compatible].
Once we wrote a module, we can either load it manually, or automatically.
Manually -> insmod modulename.ko or modprob modulename.ko
Automatically-> There are multiple ways.
copy to /lib/modules/`uname -r`/kernel/modulename.ko and update /etc/modules. System will load the module while booting.
Write a script/command to load the module.ko for an specific harware add/change/remove event in a udev rule /etc/udev/rules.d/10-local.rules. You can do both load/unload using this method.
Code your module with MODULE_DEVICE_TABLE registration. Then load your modulename.ko once and run depmod command [sudo depmod -a] to add the new module to /lib/modules/3.16.0-34-generic/modules.alias /lib/modules/3.16.0-34-generic/modules.dep files. As I know, system will load only if the module is not loaded.
You can monitor module loading/unloading using udev events using :
udevadm monitor
command.

Is modeprobe automatically creates a sysfile interface - /sys/module/?

My embedded box doesn't support modeprobe because of security issue. I am trying to do an insmod of the kernel modules. The code I am using lttng. I see that lttng does the kernel object insertion using modeprobe. For my case, I have disabled those modeprobe and I am doing an insmod for it. I am suspecting that because I am doing insmod the sys interface is not created. On the other hand, the modeprobe part I am assuming that it is creating a sys interface. Is it true that modeprobe creates a sysfile interface? If it is true, then what can I do here as I am using insmod.
Actually modprobe is just like 'insmod' except that modprobe resolves module dependencies and finally invokes init_module system call to insert the module. So, in both the cases (modprobe and insmode) init_module() system call is invoked which actually creates sysfs entry for the module.
In lttng case I think there are a lot of modules that needs to be loaded, and there may be dependencies among them, inserting modules one by one using insmod will be very difficult task, first of all you need to find which module depends on what and you have to insert the modules accordingly.
So better thing is use the modprobe or just use the lttng on another machine where you have the modprobe and note the order of the modules and write a script to insert them all.

Resources