How are modules loaded

This forum is for users of Microchip MPUs and who are interested in using Linux OS.

Moderator: nferre

slevi
Posts: 3
Joined: Thu Jul 23, 2020 4:40 am

How are modules loaded

Thu Jul 23, 2020 4:50 am

Hi,
I am using a custom board with ATSAMA5D27C-LD2G.
I am trying to have modules loaded immediately at startup, but I don't see any modules-load.d or modprobe.d directories created (using obviously meta-atmel).
However, I do see atmel_usba_udc loaded automatically.

So my question is, how?

Thanks,
Sol
blue_z
Location: USA
Posts: 2151
Joined: Thu Apr 19, 2007 10:15 pm

Re: How are modules loaded

Thu Jul 23, 2020 9:05 pm

slevi wrote: How are modules loaded
Apparently you mean kernel module (for a driver).

slevi wrote: So my question is, how?
(Obviously you're asking an XY question.)
The simple answer is that an (active) driver mentioned in the Device Tree (referenced by the compatible string/property) will have its probe routine executed.
If the driver is statically linked into the kernel, then execution of its probe routine is performed during the kernel initialization phase.
Otherwise the probe is deferred until after the root filesystem is mounted and (e)udev will try to automatically load the appropriate kernel module.

Regards
slevi
Posts: 3
Joined: Thu Jul 23, 2020 4:40 am

Re: How are modules loaded

Thu Aug 13, 2020 7:08 am

First, @blue_z thanks for your response.
Second, I am sorry for the delay in response.
blue_z wrote: Apparently you mean kernel module (for a driver).
Yes, exactly, be it in or out of tree modules.
blue_z wrote: (Obviously you're asking an XY question.)
Not sure what that is... (I found XY problem where I ask about Y whereas my real problem is X).
I will give a better description of what I am looking for and maybe someone would be able to tell what am I really asking about.

So looking at the lsmod output right after bootup:

Code: Select all

:~# lsmod
Module                  Size  Used by    Tainted: G
usb_f_rndis            16702  2
u_ether                 8213  1 usb_f_rndis
usb_f_acm               5275  2
u_serial               10458  3 usb_f_acm
libcomposite           36180 12 usb_f_rndis,usb_f_acm
bt8xxx                 62630  0
sd8xxx                397143  0
mlan                  402434  1 sd8xxx
btmrvl_sdio            15489  0
mwifiex_sdio           23991  0
atmel_usba_udc         17516  0
Now in this list there are 2 sets of drivers that are loaded for the same piece of hardware (WiFi module):
1) mwifiex_sdio and btmrvl_sdio, "kernel supplied" drivers, built in the tree, not statically linked, built as modules.
2) sd8xxx, bt8xxx, manufacturer supplied modules, compiled out of tree inhereting from the "module" class.

As per your advice, I put the udev in debug log level, and got the following:

Code: Select all

daemon.info kernel: [   10.570000] udevd[239]: starting eudev-3.2
user.warn kernel: [   15.470000] CPU: 0 PID: 267 Comm: udevd Tainted: G           O    4.9.36-00619-g7e82b52-dirty #1
user.warn kernel: [   15.620000] CPU: 0 PID: 267 Comm: udevd Tainted: G        W  O    4.9.36-00619-g7e82b52-dirty #1
user.warn kernel: [   15.790000] CPU: 0 PID: 267 Comm: udevd Tainted: G        W  O    4.9.36-00619-g7e82b52-dirty #1
daemon.debug kernel: [   15.930000] udevd[239]: seq 883 queued, 'add' 'module'
daemon.debug kernel: [   15.930000] udevd[326]: seq 883 running
daemon.debug kernel: [   15.930000] udevd[326]: no db file to read /run/udev/data/+module:mbt8xxx: No such file or directory
daemon.debug kernel: [   15.930000] udevd[326]: passed device to netlink monitor 0x65318
daemon.debug kernel: [   15.930000] udevd[326]: seq 883 processed
daemon.debug kernel: [   15.930000] udevd[239]: passed 129 byte device to netlink monitor 0x5d0b0
daemon.debug kernel: [   15.940000] udevd[239]: seq 884 queued, 'remove' 'module'
daemon.debug kernel: [   15.940000] udevd[326]: seq 884 running
daemon.debug kernel: [   15.940000] udevd[326]: no db file to read /run/udev/data/+module:mbt8xxx: No such file or directory
daemon.debug kernel: [   15.940000] udevd[326]: passed device to netlink monitor 0x65318
daemon.debug kernel: [   21.080000] udevd[239]: seq 893 queued, 'add' 'module'
daemon.debug kernel: [   21.080000] udevd[239]: passed 133 byte device to netlink monitor 0x5d0b0
daemon.debug kernel: [   21.080000] udevd[326]: seq 893 running
daemon.debug kernel: [   21.080000] udevd[326]: no db file to read /run/udev/data/+module:usb_f_rndis: No such file or directory
daemon.debug kernel: [   21.080000] udevd[326]: passed device to netlink monitor 0x65318
daemon.debug kernel: [   21.080000] udevd[326]: seq 893 processed
daemon.debug kernel: [   21.150000] udevd[239]: seq 894 queued, 'add' 'tty'
daemon.debug kernel: [   21.150000] udevd[239]: passed 176 byte device to netlink monitor 0x5d0b0
daemon.debug kernel: [   21.150000] udevd[326]: seq 894 running
daemon.debug kernel: [   21.150000] udevd[326]: no db file to read /run/udev/data/c247:0: No such file or directory
daemon.debug kernel: [   28.770000] udevd[239]: cleanup idle workers
daemon.debug kernel: [   28.770000] udevd[239]: Validate module index
daemon.debug kernel: [   28.770000] udevd[326]: Unload module index
daemon.debug kernel: [   28.770000] udevd[323]: Unload module index
daemon.debug kernel: [   28.770000] udevd[324]: Unload module index
daemon.debug kernel: [   28.770000] udevd[239]: worker [323] exited
daemon.debug kernel: [   28.770000] udevd[239]: worker [324] exited
daemon.debug kernel: [   28.770000] udevd[239]: worker [326] exited
daemon.debug kernel: [   28.960000] udevd[239]: seq 902 queued, 'change' 'platform'
daemon.debug kernel: [   28.960000] udevd[239]: seq 902 forked new worker [497]
daemon.debug kernel: [   35.360000] udevd[239]: Validate module index
daemon.debug kernel: [   35.360000] udevd[239]: seq 905 queued, 'change' 'platform'
daemon.debug kernel: [   35.360000] udevd[239]: passed 189 byte device to netlink monitor 0x5d0b0
daemon.debug kernel: [   35.360000] udevd[498]: seq 905 running
daemon.debug kernel: [   35.360000] udevd[498]: no db file to read /run/udev/data/+platform:regulatory.0: No such file or directory
daemon.debug kernel: [   35.360000] udevd[498]: IMPORT builtin 'hwdb' /lib/udev/rules.d/50-udev-default.rules:15
daemon.debug kernel: [   35.360000] udevd[498]: IMPORT builtin 'hwdb' returned non-zero
daemon.debug kernel: [   35.360000] udevd[498]: RUN 'kmod load $env{MODALIAS}' /lib/udev/rules.d/80-drivers.rules:5
daemon.debug kernel: [   35.360000] udevd[498]: Execute 'load' 'platform:regulatory'
daemon.debug kernel: [   35.360000] udevd[498]: No module matches 'platform:regulatory'
daemon.debug kernel: [   41.690000] udevd[239]: cleanup idle workers
daemon.debug kernel: [   41.690000] udevd[506]: Unload module index
daemon.debug kernel: [   41.690000] udevd[239]: Validate module index
daemon.debug kernel: [   41.690000] udevd[239]: worker [506] exited
daemon.debug kernel: [   41.760000] udevd[239]: seq 908 queued, 'change' 'platform'
daemon.debug kernel: [   41.760000] udevd[239]: seq 908 forked new worker [507]
daemon.debug kernel: [   41.760000] udevd[507]: seq 908 running
daemon.debug kernel: [   41.770000] udevd[507]: no db file to read /run/udev/data/+platform:regulatory.0: No such file or directory
daemon.debug kernel: [   41.770000] udevd[507]: IMPORT builtin 'hwdb' /lib/udev/rules.d/50-udev-default.rules:15
daemon.debug kernel: [   41.770000] udevd[507]: IMPORT builtin 'hwdb' returned non-zero
daemon.debug kernel: [   47.980000] udevd[239]: cleanup idle workers
daemon.debug kernel: [   47.980000] udevd[239]: Validate module index
daemon.debug kernel: [   47.980000] udevd[508]: Unload module index
daemon.debug kernel: [   47.980000] udevd[239]: worker [508] exited
daemon.debug kernel: [   86.530000] udevd[239]: Validate module index
daemon.debug kernel: [   86.530000] udevd[239]: seq 910 queued, 'change' 'power_supply'
daemon.debug kernel: [   86.530000] udevd[239]: seq 910 forked new worker [509]
daemon.debug kernel: [   86.540000] udevd[509]: seq 910 running
daemon.debug kernel: [   86.540000] udevd[509]: no db file to read /run/udev/data/+power_supply:bq24257-charger: No such file or directory
daemon.debug kernel: [   86.540000] udevd[509]: passed device to netlink monitor 0x64b38
daemon.debug kernel: [   86.540000] udevd[509]: seq 910 processed
daemon.debug kernel: [   89.550000] udevd[239]: cleanup idle workers
daemon.debug kernel: [   89.550000] udevd[509]: Unload module index
daemon.debug kernel: [   89.550000] udevd[239]: Validate module index
The log (to my understanding) does not indicate how those drivers are loaded.
/etc/udev/rules.d is empty.
I tried greping /lib/udev/rules.d/ for any sensible string, but couldn't find anything.
How do I proceed from here?

Thanks,
Sol
blue_z
Location: USA
Posts: 2151
Joined: Thu Apr 19, 2007 10:15 pm

Re: How are modules loaded

Fri Aug 14, 2020 1:03 am

slevi wrote: Now in this list there are 2 sets of drivers that are loaded for the same piece of hardware (WiFi module):
1) mwifiex_sdio and btmrvl_sdio, "kernel supplied" drivers, built in the tree, not statically linked, built as modules.
2) sd8xxx, bt8xxx, manufacturer supplied modules, compiled out of tree inhereting from the "module" class.
So is "2 sets of drivers ... are loaded for the same piece of hardware" the elusive X problem statement?

slevi wrote: As per your advice, I put the udev in debug log level, ...
Which "advice" is that?

slevi wrote: How are modules loaded
...
The log (to my understanding) does not indicate how those drivers are loaded.
An explanation of "how those drivers are loaded" would provide the details of the software flow.
IMO what you should be inquiring about is the "why" rather than the "how".

IOW you should be asking: why are "2 sets of drivers ... loaded for the same piece of hardware"?

I've already mentioned the Device Tree and the compatible string/property.
Have you used this information or ignored it?
What is specified in your DT for this hardware?
What are the compatible strings declared in these drivers? Are they unique or duplicates of each other?

Regards
slevi
Posts: 3
Joined: Thu Jul 23, 2020 4:40 am

Re: How are modules loaded

Fri Aug 14, 2020 2:11 am

blue_z wrote: So is "2 sets of drivers ... are loaded for the same piece of hardware" the elusive X problem statement?
...
An explanation of "how those drivers are loaded" would provide the details of the software flow.
IMO what you should be inquiring about is the "why" rather than the "how".
Yes and no, this is the immidiate problem I am trying to solve, but I would have liked to gain a better understanding of the mechanisms while doing it rather then just solving the problem. As you stated, I am trying to understand the "how" and by understanding it, solving the "why" should be straight forward by having the tools to investigate it.
blue_z wrote: I've already mentioned the Device Tree and the compatible string/property.
Have you used this information or ignored it?
What is specified in your DT for this hardware?
What are the compatible strings declared in these drivers? Are they unique or duplicates of each other?
I did not ignore it, just didn't find anything useful, but I did forget to ask an additional question: you mentioned a probing method being called on the driver. I didn't see anything that looks like that. Can you point me to the member in the driver struct (the struct that is passed on to the kernel to register the driver) that is resposible for it?
Here are the relevant sections from my device tree:

Top of the file:

Code: Select all

/dts-v1/;

#include "sama5d2.dtsi"
#include "sama5d2-pinfunc.h"
#include <dt-bindings/mfd/atmel-flexcom.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/linux-event-codes.h>
SD related sections:

Code: Select all

               sdmmc1: sdio-host@b0000000 {
			pinctrl-names = "default";
			pinctrl-0 = <&pinctrl_sdmmc1_default>;
			mmc-pwrseq = <&sdhci0_pwrseq>;
			bus-width = <4>;
			status = "okay"; /* conflict with qspi0 */
		};

Code: Select all

				pinctrl_sdmmc1_default: sdmmc1_default {
					cmd_data {
						pinmux = <PIN_PA28__SDMMC1_CMD>,
							 <PIN_PA18__SDMMC1_DAT0>,
							 <PIN_PA19__SDMMC1_DAT1>,
							 <PIN_PA20__SDMMC1_DAT2>,
							 <PIN_PA21__SDMMC1_DAT3>;
						bias-pull-up;
					};

					conf-ck_cd {
						pinmux = <PIN_PA22__SDMMC1_CK>,
							 <PIN_PA30__SDMMC1_CD>;
						bias-disable;
					};
				};

Code: Select all

	sdhci0_pwrseq: sdhci0_pwrseq {
		compatible = "mmc-pwrseq-sd8787";
		pwrdn-gpio = <&pio PIN_PA14 GPIO_ACTIVE_LOW>;
		reset-gpio = <&pio PIN_PA27 GPIO_ACTIVE_LOW>;
		power-supply = <&wifi_reg>;
	};
And sam5d2.dtsi (though we did not modify it):

Code: Select all

		sdmmc0: sdio-host@a0000000 {
			compatible = "atmel,sama5d2-sdhci";
			reg = <0xa0000000 0x300>;
			interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
			clocks = <&sdmmc0_hclk>, <&sdmmc0_gclk>, <&main>;
			clock-names = "hclock", "multclk", "baseclk";
			status = "disabled";
		};

		sdmmc1: sdio-host@b0000000 {
			compatible = "atmel,sama5d2-sdhci";
			reg = <0xb0000000 0x300>;
			interrupts = <32 IRQ_TYPE_LEVEL_HIGH 0>;
			clocks = <&sdmmc1_hclk>, <&sdmmc1_gclk>, <&main>;
			clock-names = "hclock", "multclk", "baseclk";
			status = "disabled";
		};

Code: Select all

					sdmmc0_hclk: sdmmc0_hclk {
						#clock-cells = <0>;
						reg = <31>;
					};

					sdmmc1_hclk: sdmmc1_hclk {
						#clock-cells = <0>;
						reg = <32>;
					};

Code: Select all

					sdmmc0_hclk: sdmmc0_hclk {
						#clock-cells = <0>;
						reg = <31>;
					};

					sdmmc1_hclk: sdmmc1_hclk {
						#clock-cells = <0>;
						reg = <32>;
					};
Thanks again,
Sol
blue_z
Location: USA
Posts: 2151
Joined: Thu Apr 19, 2007 10:15 pm

Re: How are modules loaded

Fri Aug 14, 2020 11:54 pm

slevi wrote: ... I would have liked to gain a better understanding of the mechanisms while doing it rather then just solving the problem. As you stated, I am trying to understand the "how" and by understanding it, solving the "why" should be straight forward by having the tools to investigate it.
You would be better off trying to learn the "how" by using 'tools" such as studying authoritative sources such as documentation, datasheets, and the source code.
Web forums are an unreliable "tool" for accurate answers, especially for comprehensive and detailed information. For instance I intentionally omitted in my original response to you any mention of module-init-tools and loadable modules for USB gadgets (which are not described in the Device Tree), assuming that they were irrelevant to the problem.
You naively assume that you can obtain comprehensive and accurate answers, and insight will be "straight forward".

slevi wrote: Here are the relevant sections from my device tree:
...
SD related sections:
...
So what, are you asserting that there are no references to these SDIO WiFi devices in your DT?

Another mechanism for loading kernel modules is through the hotplug program as used by the USB subsystem.
However I can find no evidence that the SDIO subsystem also uses any hotplug scheme. Of course not finding evidence is not conclusive.
However the mainline kernel does have a few board DTs that do declare/describe SDIO (WiFi) devices.
If SDIO has hotplug loading of drivers (just like USB), then declaring the device in the DT is redundant (i.e. you won't find any USB gadgets in any DT).
Therefore my assumption that SDIO devices can/should be declared/described in the DT is reasonable, and that is the scheme for specifying/loading the device driver.

These previously mentioned schemes typically utilize device events that are sent to userspace (i.e. uevent) and are handled by a daemon (e.g. [e]udev).
Alternatively, requests from within the kernel for loading a module can funnel through request_module(), and then a userspace application assists in performing the load. The crypto, filesystem and other subsystems use this mechanism.

Yet another method of automatic kernel module loading but initiated from userspace involves [e]udev (or init) and explicit naming of the module in /etc/ configuration files. If you have edited such configuration files in /etc/, then you need to provide more information and/or should be answering your question yourself.
There could be other mechanisms, since Linux has been developed over many years by many persons with different agenda.

You have not responded to all of my questions.
This is not a one-way answering service.

Regards

Return to “LINUX”

Who is online

Users browsing this forum: No registered users and 9 guests