Linux kernel load drivers

How does newer Linux kernels load non-removable hardware device drivers during boot?

Multiple device drivers (specified in the device tree) are not loading during boot. All built in drivers get loaded with no issue. The drivers successfully load and function if modprobe is used at the command line. Linux Kernel: 5.4.24 Hardware: Custom board with an iMX6 (ARM), ov5640 Camera, TI WL1831 Wifi chip, and an audio amp tied to a PWM output of the iMX6. Yocto (Dunfell) is used to build an SD card image for this embedded device. Root is only/always mounted read only during the boot of the kernel. The following device drivers are not loading: wl18xx, wlcore_sdio, wlcore, ov564x_mipi (ov5640_camera_int.ko), mxc_v4l2_capture, pwm-imx. The TI WL18XX drivers are patched into the kernal from Texas Instruments source. The pwm-imx driver is something I wrote. I am using stock ov564x_mipi and mxc_v4l2_capture drivers at the moment. Side Note: This works as desired in an older 3.14 kernel. So I suspect I am missing something that the newer kernels require. The device tree is getting loaded by u-boot. The /proc/device-tree matches the device tree as expected.

My Actions:

  • There are no errors or indication that drivers are even attemped to get loaded in the dmesg output.
  • Reverse compile device tree to verify all devices are enabled and have a compatible attribute defined. I had to fix the device tree attribute to get these drives to function correctly after loading them with modprobe.
  • Checked that all of these kernel modules use the MODULE_DEVICE_TABLE() macro.
  • Checked that all the /sys/firmware/devicetree listings have a “compatible” entry that contains a matching of_device_id string that is in the source of each driver.
  • Checked that the expected module alias shows up in modinfo
  • Checked the depmod database. It lists all modules and the correct dependancies.
  • After boot an lsmod shows nothing. No kernel modules are loaded at all.
  • I have tried loading these based on info found at https://wiki.archlinux.org/index.php/Kernel_module#Loading
  • There is no listing in /sys/bus/*/drivers for any of these drivers after a clean boot. When I manually load each driver with modprobe the an appropriate listing shows up in /sys/bus/*/drivers
  • Researching udev has not provided answers. udev handles events that are driven by actions triggered by loading kernel modules. I can not find anything stating how, when, or why udev actually loads kernel modules.
  • Tried posting this first at https://stackoverflow.com/questions/66754562/linux-device-drivers-not-loading-during-boot
Читайте также:  Linux название с пробелом

My Opinions:

  • Systemd is capable of running scripts that call modprobe. I do not believe systemd should load kernel modules for hardware that is not removable.

Information:

These kernel modules are present at:

/lib/modules/5.4.24+g5303049bda95/kernel/drivers/media/platform/mxc/capture/ov5640_camera_mipi_int.ko /lib/modules/5.4.24+g5303049bda95/extra/pwm-imx.ko /lib/modules/5.4.24+g5303049bda95/kernel/drivers/media/platform/mxc/capture/mxc_v4l2_capture.ko /lib/modules/5.4.24+g5303049bda95/kernel/drivers/net/wireless/ti/wl18xx/wl18xx.ko /lib/modules/5.4.24+g5303049bda95/kernel/drivers/net/wireless/ti/wlcore/wlcore.ko /lib/modules/5.4.24+g5303049bda95/kernel/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko 

The following sys paths are present upon boot:

/sys/bus/platform/devices/2080000.pwm /sys/bus/platform/devices/20d4000.v4l2_cap_0 /sys/bus/platform/devices/21a0000.i2c /sys/bus/platform/devices/2190000.usdhc /sys/devices/soc0/soc/2000000.aips-bus/2080000.pwm /sys/devices/soc0/soc/2000000.aips-bus/20d4000.v4l2_cap_0 /sys/devices/soc0/soc/2100000.aips-bus/21a0000.i2c /sys/devices/soc0/soc/2100000.aips-bus/2190000.usdhc /sys/firmware/devicetree/base/soc/aips-bus@2000000/pwm@2080000 /sys/firmware/devicetree/base/soc/aips-bus@2000000/v4l2_cap_0@20d4000 /sys/firmware/devicetree/base/soc/aips-bus@2100000/i2c@21a0000/ov5640_mipi@3c /sys/firmware/devicetree/base/soc/aips-bus@2100000/usdhc@2190000/wlcore@0 

Example of changes in /sys:

$> find / -name *ov564* /sys/firmware/devicetree/base/soc/aips-bus@2100000/i2c@21a0000/ov5640_mipi@3c /lib/modules/5.4.24+g5303049bda95/kernel/drivers/media/platform/mxc/capture/ov5640_camera_mipi_int.ko $> modprobe ov5640_camera_mipi_int $> find / -name *ov564* /sys/firmware/devicetree/base/soc/aips-bus@2100000/i2c@21a0000/ov5640_mipi@3c /sys/bus/i2c/drivers/ov564x_mipi /sys/module/ov5640_camera_mipi_int /sys/module/ov5640_camera_mipi_int/drivers/i2c:ov564x_mipi /sys/module/v4l2_int_device/holders/ov5640_camera_mipi_int /lib/modules/5.4.24+g5303049bda95/kernel/drivers/media/platform/mxc/capture/ov5640_camera_mipi_int.ko 
/usr/lib/modprobe.d/ does not exist /etc/conf.d/modules does not exist $> ls -als /lib/modprobe.d total 12 4 drwxr-xr-x 2 root root 4096 Mar 9 12:34 . 4 drwxr-xr-x 9 root root 4096 Mar 9 12:34 .. 4 -rw-r--r-- 1 root root 765 Mar 9 12:34 systemd.conf $> ls -als /etc/modprobe.d/ total 12 4 drwxr-xr-x 2 root root 4096 Mar 9 12:36 . 4 drwxr-xr-x 39 root root 4096 Mar 9 2018 .. 4 -rw-r--r-- 1 root root 70 Mar 9 12:38 ov564x-mipi.conf cat /etc/modprobe.d/ov564x-mipi.conf # Load ov5640_camera_mipi_int at boot options ov5640_camera_mipi_int $> ls -als /etc/modules-load.d/ total 12 4 drwxr-xr-x 2 root root 4096 Mar 9 2018 . 4 drwxr-xr-x 39 root root 4096 Mar 9 2018 .. 4 -rw-r--r-- 1 root root 62 Mar 9 2018 ov564x-mipi.conf cat /etc/modules-load.d/ov564x-mipi.conf # Load ov5640_camera_mipi_int at boot ov5640_camera_mipi_int 

Example of udev Events that get fired when a driver is loaded

$> udevadm monitor & $>modprobe ov5640_camera_int KERNEL[225.175451] add /module/v4l2_int_device (module) UDEV [225.181252] add /module/v4l2_int_device (module) KERNEL[225.183581] add /module/ov5640_camera_int (module) KERNEL[225.183956] add /bus/i2c/drivers/ov564x (drivers) UDEV [225.186825] add /module/ov5640_camera_int (module) UDEV [225.190633] add /bus/i2c/drivers/ov564x (drivers) $>modprobe mxc_v4l2_capture KERNEL[267.876151] add /module/ipu_fg_overlay_sdc (module) KERNEL[267.880571] add /module/ipu_csi_enc (module) UDEV [267.882058] add /module/ipu_fg_overlay_sdc (module) KERNEL[267.885927] add /module/ipu_prp_enc (module) UDEV [267.887871] add /module/ipu_csi_enc (module) UDEV [267.888047] add /module/ipu_prp_enc (module) KERNEL[267.889285] add /module/ipu_still (module) UDEV [267.890705] add /module/ipu_still (module) KERNEL[267.891847] add /module/ipu_bg_overlay_sdc (module) UDEV [267.894052] add /module/ipu_bg_overlay_sdc (module) KERNEL[267.901998] add /module/mxc_v4l2_capture (module) UDEV [267.903648] add /module/mxc_v4l2_capture (module) KERNEL[267.904599] add /devices/soc0/soc/2000000.aips-bus/20d4000.v4l2_cap_0/video4linux/video0 (video4linux) KERNEL[267.906944] bind /devices/soc0/soc/2000000.aips-bus/20d4000.v4l2_cap_0 (platform) KERNEL[267.907472] add /bus/platform/drivers/mxc_v4l2_capture (drivers) UDEV [267.910128] add /bus/platform/drivers/mxc_v4l2_capture (drivers) UDEV [267.924422] add /devices/soc0/soc/2000000.aips-bus/20d4000.v4l2_cap_0/video4linux/video0 (video4linux) UDEV [267.927830] bind /devices/soc0/soc/2000000.aips-bus/20d4000.v4l2_cap_0 (platform) 

Relevant sections from reverse compiled device tree:

soc < #address-cells = ; #size-cells = ; compatible = "simple-bus"; interrupt-parent = ; ranges; aips-bus@2000000 < compatible = "fsl,aips-bus", "simple-bus"; #address-cells = ; #size-cells = ; reg = ; ranges; pwm@2080000 < #pwm-cells = ; compatible = "fsl,pwm-imx"; reg = ; interrupts = ; clocks = ; clock-names = "ipg", "per"; status = "okay"; pinctrl-names = "default"; pinctrl-0 = ; >; v4l2_cap_0@20d4000 < compatible = "fsl,imx6q-v4l2-capture"; reg = ; interrupts = ; interrupt-names = "epit2"; clocks = ; clock-names = "ipg", "per"; ipu_id = ; csi_id = ; mclk_source = ; mipi_camera = ; default_input = ; io3-gpios = ; io4-gpios = ; HREF-gpios = ; LED_EN-gpios = ; LASER2-gpios = ; LASER3-gpios = ; LED2_EN-gpios = ; LASER1-gpios = ; LED1_EN-gpios = ; FLEN-gpios = ; LED_CUR1-gpios = ; LED_CUR2-gpios = ; CHARGE_EN-gpios = ; FLASH_FLAG-gpios = ; status = "okay"; >; >; aips-bus@2100000 < compatible = "fsl,aips-bus", "simple-bus"; #address-cells = ; #size-cells = ; reg = ; ranges; usdhc@2190000 < compatible = "fsl,imx6q-usdhc"; reg = ; interrupts = ; clocks = ; clock-names = "ipg", "ahb", "per"; bus-width = ; status = "okay"; pinctrl-names = "default"; pinctrl-0 = ; vmmc-supply = ; mmc-pwrseq = ; no-1-8-v; enable-sdio-wakeup; non-removable; ti,non-removable; ti,needs-special-hs-handling; cap-power-off-card; keep-power-in-suspend; #address-cells = ; #size-cells = ; wlcore@0 < compatible = "ti,wl1831"; reg = ; interrupts = ; interrupt-parent = ; platform-quirks = ; >; >; i2c@21a0000 < #address-cells = ; #size-cells = ; compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c"; reg = ; interrupts = ; clocks = ; status = "okay"; clock-frequency = ; pinctrl-names = "default"; pinctrl-0 = ; ov5640_mipi@3c < compatible = "ovti,ov564x_mipi"; reg = ; pintctrl-names = "default"; pinctrl-0 = ; clocks = ; clock-names = "csi_mclk"; clock-rates = ; DOVDD-supply = ; AVDD-supply = ; DVDD-supply = ; pwn-gpios = ; rst-gpios = ; ipu_id = ; csi_id = ; default_input = ; mclk = ; mclk_source = ; status = "okay"; >; >; >; >; 

Источник

Читайте также:  Copy disk with linux

How to Load and Unload Kernel Modules in Linux

A kernel module is a program which can loaded into or unloaded from the kernel upon demand, without necessarily recompiling it (the kernel) or rebooting the system, and is intended to enhance the functionality of the kernel.

In general software terms, modules are more or less like plugins to a software such as WordPress. Plugins provide means to extend software functionality, without them, developers would have to build a single massive software with all functionalities integrated in a package. If new functionalities are needed, they would have to be added in new versions of a software.

Likewise without modules, the kernel would have to be built with all functionalities integrated directly into the kernel image. This would mean having bigger kernels, and system administrators would need to recompile the kernel every time a new functionality is needed.

A simple example of a module is a device driver – which enables the kernel to access a hardware component/device connected to the system.

List All Loaded Kernel Modules in Linux

In Linux, all modules end with the .ko extension, and they are normally loaded automatically as the hardware is detected at system boot. However a system administrator can manage the modules using certain commands.

To list all currently loaded modules in Linux, we can use the lsmod (list modules) command which reads the contents of /proc/modules like this.

Module Size Used by rfcomm 69632 2 pci_stub 16384 1 vboxpci 24576 0 vboxnetadp 28672 0 vboxnetflt 28672 0 vboxdrv 454656 3 vboxnetadp,vboxnetflt,vboxpci bnep 20480 2 rtsx_usb_ms 20480 0 memstick 20480 1 rtsx_usb_ms btusb 45056 0 uvcvideo 90112 0 btrtl 16384 1 btusb btbcm 16384 1 btusb videobuf2_vmalloc 16384 1 uvcvideo btintel 16384 1 btusb videobuf2_memops 16384 1 videobuf2_vmalloc bluetooth 520192 29 bnep,btbcm,btrtl,btusb,rfcomm,btintel videobuf2_v4l2 28672 1 uvcvideo videobuf2_core 36864 2 uvcvideo,videobuf2_v4l2 v4l2_common 16384 1 videobuf2_v4l2 videodev 176128 4 uvcvideo,v4l2_common,videobuf2_core,videobuf2_v4l2 intel_rapl 20480 0 x86_pkg_temp_thermal 16384 0 media 24576 2 uvcvideo,videodev .

How to Load and Unload (Remove) Kernel Modules in Linux

To load a kernel module, we can use the insmod (insert module) command. Here, we have to specify the full path of the module. The command below will insert the speedstep-lib.ko module.

# insmod /lib/modules/4.4.0-21-generic/kernel/drivers/cpufreq/speedstep-lib.ko

To unload a kernel module, we use the rmmod (remove module) command. The following example will unload or remove the speedstep-lib.ko module.

# rmmod /lib/modules/4.4.0-21-generic/kernel/drivers/cpufreq/speedstep-lib.ko

How to Manage Kernel Modules Using modprobe Command

modprobe is an intelligent command for listing, inserting as well as removing modules from the kernel. It searches in the module directory /lib/modules/$(uname -r) for all the modules and related files, but excludes alternative configuration files in the /etc/modprobe.d directory.

Читайте также:  Подключить виртуальный диск линукс

Here, you don’t need the absolute path of a module; this is the advantage of using modprobe over the previous commands.

To insert a module, simply provide its name as follows.

To remove a module, use the -r flag like this.

Note: Under modprobe, automatic underscore conversion is performed, so there is no difference between _ and – while entering module names.

For more usage info and options, read through the modprobe man page.

Do not forget to check out:

That’s all for now! Do you have any useful ideas, that you wanted us to add to this guide or queries, use the feedback form below to drop them to us.

Источник

How to load and unload linux drivers that are built into kernel

I want to follow the 2nd option but I do not know how to unload and load the device driver, can the open source community please help me out here !

How would you remove something that’s not built as removable module? Also, this sounds like an «XY problem» (research that term!) so it may be the wrong question you’re asking.

If there’s a way within the power cycle ,where I can unload and load device driver when its built into kernel ?

You cannot load and unload built-in device drivers, but you can «unbind» devices that are being used by drivers, and then «bind» them again afterwards. (In other words, you can cause the driver’s «remove» and «probe» handlers to be called for a device.)

1 Answer 1

It’s easy as that. You find a device and driver which you want to unbind. For example, on my Intel Minnownboard (v1) I have PCH UDC controller (a PCI device):

% lspci -nk . 02:02.4 0c03: 8086:8808 (rev 02) Subsystem: 1cc8:0001 Kernel driver in use: pch_udc 

Now I know necessary bits:

  • bus on which the device is located: PCI
  • device name: 0000:02:02.4 (note that lspci gives reduced PCI address, i.e. without domain or i.o.w. BDF, while driver expects domain:BDF)
  • driver name: pch_udc

Take altogether we can unbind the device:

% echo 0000:02:02.4 > /sys/bus/pci/drivers/pch_udc/unbind [ 3042.531872] configfs-gadget 0000:02:02.4: unregistering UDC driver [g1] [ 3042.540979] udc 0000:02:02.4: releasing '0000:02:02.4' 

You may bind it again. Simple use bind node in the same folder.

The feature appeared more than 15 years ago and here is the article on LWN that explains it.

Источник

Оцените статью
Adblock
detector