Linux: How does communication with kernel module from user space happen - linux

I am reading Embedded Linux Primer book and The Linux Kernel Module Programming Guide and I am confused about user space application communication with kernel module
User space App --> Device node/proc file --> kernel module ( which resides in /lib/modules/)
1) What is exact difference when we communicate with device node method ( /dev/ - with open,read,write,close calls) and /proc/file method ?

procfs (/proc) should be reserved for process information a module should not put any file there. At some point, procfs was the only available pseudo filesystem, that is why you can find sound system or RTC information. Then, sysfs was created to properly contain those information.
The main difference between using a device file (usually residing in /dev) and a file from procfs is the way it is handled in the kernel.
Operations used for the device files are registered using the file_operations structure usually with cdev_init and cdev_add for a character device. Your module may not do that as quite often, the subsytem is the one registering your device.
While the operations for files in procfs are registered using proc_create

Related

Determining filesystem for block device if module not loaded

I've been wondering this for a while now. When using Linux and plugging in an e.g. USB stick or external storage device via USB, how does the kernel determine which filesystem is on that device, if the correct module is not currently loaded in memory?
Assume that the external storage device is ext4 formatted. At the time of plugging in the device, the ext4 module has not been loaded into memory yet. Now, usually the kernel tries to probe the different filesystems by calling the appropiate *_fill_super function of the respective module. But that only works if the module is even present at the time of probing. How does the kernel handle mounting devices in situations where the correct filesystem module is not yet loaded in memory?
For me it seems to be a kind of chicken-egg problem as the *_fill_super function needed to determine the correct module is located in the module itself. So the kernel wants to probe the filesystem on the device, but for that it requires the appropiate module to be loaded. But it is not loaded at that time, so the kernel neither knows what filesystem is on the device and thus does not know what filesystem module to load in the first place.
How does the kernel handle this? I'm thankful for any explanation or even references to the code where this logic happens.
In short: Unless some user space configuration file is aware of a filesystem, mount will fail to auto-detect this filesystem if its driver is not loaded.
.. usually the kernel tries to probe the different filesystems by calling the appropiate *_fill_super function of the respective module.
This is not quite true. The mount system call accepts filesystem name as a parameter, and this parameter is required for all cases except re-mount, which is out of scope of the current question. Moreover, the filesystem driver is expected to be already loaded at the time mount system call is performed.
That is, the kernel by itself never "probes" a filesystems, the kernel just tries the filesystem requested by the user space.
Actually, it is user space tool mount which performs probing.
Before probing, the mount tool could attempts to deduce a filesystem by inspecting /etc/fstab, by using blkid or other mechanisms.
After all deducing mechanisms have failed, the mount tool probes filesystems according to /etc/filesystems file. This file could contain a predefined (static) list of filesystems.
After attempts for every line in /etc/filesystems have failed (or if the file doesn't exist), the mount tool probes filesystems listed in /proc/filesystems. This file is provided by the kernel and contains all filesystems which are registered (for which a driver is loaded).
After attempts for every line in /proc/filesystems have failed, the mount tool reports an error.
The algorithm of choosing a filesystem by the mount tool is described in man mount under the paragraph "If no -t option is given ..". The question and its answers describe similar things.

what is the difference between accessing a pci device using procfs vs sysfs

procfs file: /proc/bus/pci/00/00.0
vs.
sysfs file: /sys/bus/pci/devices/0000:00:00.0/resource
I have seen some drivers use the procfs file and some use sysfs. What is the difference? For what I need, I find that mmap-ing the sysfs/resource<n>? file and read/write works as I need it to, but similar operation on the procfs file does not work. But obviously the procfs file is used successfully elsewhere.
The procfs file you cite (/proc/bus/pci/00/00.0) provides access to the device's configuration header. It is also accessible in sysfs as /sys/bus/pci/devices/0000:00:00.0/config.
The sysfs file you're talking about (/sys/bus/pci/devices/0000:00:00.0/resource<N>) provides access to the device's BAR regions. See https://en.wikipedia.org/wiki/PCI_configuration_space for an explanation of the relationships. Also, you may want to read the linux kernel documentation at
https://www.kernel.org/doc/Documentation/filesystems/sysfs-pci.txt

User Space sysfs

I want to be able to create, read and write attributes in sysfs from user space. I've tried this in a UIO driver (which supposedly runs in user space, so they say) but I came across the same issue with accessing sysfs from user space apps... no access to kobject, sysfs_create_*(), etc.
The sysfs is ideal for me to use to pull data from an IP stream and populate a virtual file system with information that can be exported using NFS. Why? The data is highly cooked for a very specific application I am developing.
I'm cross compiling from a Linux PC box to a Beaglebone board which is running Jessie.
Any recommendations?

How to get USB device details in kernel programming?

I am new to kernel programming and I have dev_t value of a USB device.
I want to get the details of the device like vendor ID, product ID, or some other attribute which will vary from device to device. I want to do this in kernel space, and without loading my program as an external module.
I have came across a libusb library, however, as far as I know, it is used in user space. Is it possible to use libusb in kernel space also, like my requirement? If possible, how to import and set-up libusb so that I can compile kernel?
It is better to write a loadable kernel module for this task. Every time you find a bug you just have to compile your module against your kernel and load it. There is a defined framework in kernel for USB, use APIs that are provided by kernel to do things you are looking for.
Except That libusb is a user space library and there is no point of using it inside kernel.
In user space you can access USB related information using procfs/sysfs also.

How to communicate with a Linux kernel module from user space without littering /dev with new nodes?

What are the ways to communicate with a kernel module from user space? By communication i mean sending information and commands between the kernel module and a user space process.
I currently know of two way:
open/close/read/write/ioctl on published device node.
read/write on exported and hooked /proc file.
More specifically, can someone advice the best way to communicate with a kernel module that does not actually drives any hardware and therefore should not be littering /dev with stub nodes that exists solely for ioctl calls? I mostly need to check its various status variables and send it a block of data with a request type tag and see if the request succeeded.
Netlink sockets are designed for that kind of requirements, too...
Also see
man 7 netlink
libnl - Netlink library
The libnl Archives
There's also the /sys filesystem (sysfs):
Sysfs exports information about
devices and drivers from the kernel
device model to userspace, and is also
used for configuration.
(from Wikipedia)
You could also read/write from /dev device nodes.
IMHO, /dev is already littered with stuff and adding your own nodes there isn't a big issue. Don't forget that you can have lots of ioctl codes for a single device node, and the ioctl paramters are passed by reference so can be as big as you like.
Third one is add a new syscall, but the two you have written are the preferred ones, I think. I've found this document that might help, but I still think this option is unadvised: http://www.csee.umbc.edu/courses/undergraduate/CMSC421/fall02/burt/projects/howto_add_systemcall.html
Another acceptable option might be sharing memory.
You could also use Shared Memory and IOCTL
debugfs is another good possibility for APIs that are less stable than sysfs, but the API is basically the same. Here is a minimal runnable example.
configfs is another one. It allows easy dynamic creation of kernel objects from userspace through the filesystem: https://www.kernel.org/doc/Documentation/filesystems/configfs/configfs.txt
In any case, you will have to dirty some namespace... a filesystem entry in case of sysfs and debugfs. Just choose your poison.
Also, udev rules make /dev very similar to sysfs and debugfs: How to create a device in /dev automatically upon loading of the kernel module for a device driver?

Resources