Accessing Linux Drivers - linux

Simply put, can a user space application access device drivers running in kernel mode? If I want to read from the I2C Linux character driver, can a basic C executable (extensionless) do that or do I need to develop a kernel module specifically for that task? If a basic C app can access the I2C character driver, what does that gcc makefile look like?

Yes. User space application can access the kernel driver if the driver is character device or the driver exposing the stream interfaces.
Specific to i2c, user space application can write and reads to the i2c device via sysfs api.
Refer the kernel document here https://www.kernel.org/doc/Documentation/i2c/dev-interface

Related

How to access an IIO device driver in linux

I a noob to Linux device drivers.
I have an IIO driver with me (for OPT3001 ambient light sensor) , operating over the I2C bus, which has been compiled successfully in the kernel (version 3.18). The device tree is modified to match the compatible field, present in the driver.
The problem is how do I access this driver to get some data in the userspace ?
The driver has some callbacks for read and write registered in a structure. Should I call them directly in my C file ?
you have differents possibilities :
your driver provide a /dev node you can open in you C file.
your driver provide informations through sysfs.
in case of a /dev node, you can have access to file operations (open, read, write, ioctl). you just have to open your file 1 time and each read() call will read the value from the sensor.
in case of sysfs, you should find the file to open/read in /sys/class/...
You can use the userspace API provided by:
#include <linux/i2c-dev.h>
Using it you can open de bus /dev/i2c-X (X=0,1,2,...), set device address using ioctl call, and use read and write operations to read and write to/from the bus.
Also, you can install "i2c-tools" package (apt-get install i2c-tools), to install userspace tools like i2cset, i2cget and i2cdetect, very useful for testing the I2C bus and the device connected to it.

How to access a registered I2C device in the linux kernel from userspace

I want to be able to modify registers in a I2C slave device.
The device has a driver in the kernel, and the driver registers an I2C client with the address of it.
The driver is very basic and does output all the device functionality.
I want to access the registers from user space, but when I try to access it with I2C-dev, I get the error - Device or resource busy.
I don't want to add functionality to the driver, and I prefer to write a user space application to modify the device registers.
How can use I2C-dev to modify the registers in such a case?
So after investigating the I2C-dev I managed to overcome the problem. I noticed the flag I2C_SLAVE_FORCE inside the ioctl function. With the flag set, the function ignores if the I2C address is already registered.

difference between device file and device driver

I am currently reading the Linux Module Programming Guide and I have stumbled onto two terms that have confused a bit - device files and device driver. Upon goggling these terms I have come across the following-
A device driver is a piece of software that operates or controls a particular type of device.
A device file is an interface for a device driver that appears in a file system as if it were an ordinary file. In Unix-like operating systems, these are usually found under the /dev directory and are also called device nodes.
What I would like to know is -
1) Are device files an interface between user space programs and the device driver?
2) Does the program access the driver in the kernel via the appropriate device special file?
eg, when using say spidev char dev file, does that allow my userspace program to interact with spi.c and omap2_mcspi.c etc using simple read, write and ioctl calls?
One of the primary abstractions in Unix is the file (source):
Programs, services, texts, images, and so forth, are all files. Input and output devices, and generally all devices, are considered to be files, according to the system.
This lets users treat a variety of entities with a uniform set of operations, even through the implementation of those operations may be wildly different.
As you were getting at with your question, device files are the user facing side of the abstraction. This is what the user sees; a file that they can write to, read from, open, close, etc. The device drivers are the implementation of those operations.
So the user will make a call to a file operation such as write, and then the kernel will then use the device driver to carry out the operation.
Device File like /dev/spidevX.Y is a SW abstraction of a SPI device which exposes Linux low level SPI API to the userspace with syscalls (in Linux driver world known as "file operations"):
That is read(), write(), ioctl()...
spidev.c is a special kind of driver which is registered for generic SPI client(chip) devices, and it's main goal is to export Kernel low level SPI API to userspace.
There is a whole Linux SPI layer in between defined in spi.c
Device driver representing real HW SPI controller is where callbacks (hooks) are implemented and registered to the kernel as a part of spi_master (spi_controller)structure.
Here is a callback initialization for SPI message transfer:
master->transfer_one_message = atmel_spi_transfer_one_message;
everything in linux is a file.
device driver is a software used by operating system to communicate with device.
device driver makes use of device files.

USB user Space device driver for a custom device

What is a "USB user Space device driver for a custom device?"
A user-space device driver is a piece of software (a library or a daemon) that is used to get access to a custom device (a gadget). The difference with a kernel driver is that the user-space driver is run from the normal user-space, not from the kernel. That is, it is compiled and run as normal code just as any other program/library.
In order to do this, you need to access the low-level USB features from your program, but the Linux kernel gently provides that. Anyway, do not try to talk to the kernel directly, that is madness. Instead use a USB library, such as libusb

Linux user space PCI driver

I'm trying to write a PCI device driver that runs in user space. Not my idea, what the client wants. Target is an embedded Linux board that will never have more than a single user. I'm an experienced C programmer and know Linux, just not familiar with Linux driver development.
Is this really a device driver or just a library? Do I need to use the typical calls pci_register_driver, etc. or can I just access the device using fopen, and using mmap and ioperm to get to it?
Interrupts will be done using the MSI model. Also need to handle DMA transfers. The device will be streaming lots of data to the user.
There's not much info out there on this subject, LDD3 only devotes a couple of pages to it, and there's nothing else that I could find here on SO.
Thanks in advance!
If there is no driver handling the PCI card it would be possible to access it using ioperm (or iopl - depending on the address) if only port accesses are required.
Using DMA and interrupts is definitely impossible without a kernel-mode driver.
By googleing I found some text about something like a "generic kernel-mode driver" that allows writing user-mode drivers (including DMA and interrupts).
You should ask your customer which kind of kernel-mode drivers for accessing PCI cards is installed on the Linux board.
There is now a proper way to do high performance userspace PCI drivers, called vfio. There is not much documentation, but see the kernel docs http://lxr.free-electrons.com/source/Documentation/vfio.txt and the header file /usr/include/linux.vfio.h. It is available since Linux 3.6.

Resources