I understand the basics behind a UIO driver, as described in the documentation. The part I'm missing is how to write data from the user space program back to the device driver. My guess is that you'd write this data to the mmap region, but then how to do you let the device driver know it should read said memory?
Ultimately I'm trying to write a block device that can be implemented by a user space program. I've got the block device code stubbed out and working: https://github.com/wspeirs/usbd. My thought was that UIO was the most efficient way to transfer blocks/sectors between the block device and the user space program. Is this the wrong way to go about communicating with the block device driver from user space? Should I be using sysfs or some other communication mechanism?
UIO is designed so that user space bypasses the kernel to communicate with a hardware device. That does not seem to fit your needs.
In a standard Linux block device, you can use mmap() to write data to your block and msync() to indicate to the driver which regions you have written.
Related
My understanding of network cards is that when receiving data, that data is DMA'd into main memory through the network card driver. The kernel then copies this memory into user space and sends any necessary messages.
My question is, in Windows, is it possible to set the address that the DMA is writing to? My goal is to eliminate the extra memory copy similar to the way NVidia's GPUDirect pipeline works.
Yes, this is possible. I believe this is called "common buffer DMA". It is used for intelligent network adapters. Taking advantage of this would require writing your own network driver. Here is some microsoft documentation on it. http://msdn.microsoft.com/en-us/library/windows/hardware/ff565359%28v=vs.85%29.aspx
From a general standpoint, I am trying to figure out how to access a platform device from userspace. To be more specific, I have a EMIF controller on and SoC of which I have added to my device tree and I believe it is correctly bound to a pre-written EMIF platform device driver. Now I am trying to figure out how I can access this EMIF device from a userspace application. I have come accross a couple different topics that seem to have some connection to this issue but I cannot quite find out how they relate.
1) As I read it seems like most I/O is done through the use of device nodes which are created by mknod(), do I need to create a device node in order to access this device?
2) I have read a couple threads that talk about writting a Kernel module (Character?, Block?) that can interface with both userspace and the platform device driver, and use it as an intermediary.
3) I have read about the possibility of using mmap() to map the memory of my platform device into my virtual memory space. Is this possible?
4) It seems that when the EMIF driver is instantiated, it calls the probe() fucntion. What functions would a userpace application call in the driver?
It's not completely clear what you're needing to do (and I should caveat that I have no experience with EMIF or with "platform devices" specifically), but here's some overview to help you get started:
Yes, the usual way of providing access to a device is via a device node. Usually this access is provided by a character device driver unless there's some more specific way of providing it. Most of the time if an application is talking "directly" to your driver, it's a character device. Most other types of devices are used in interfacing with other kernel subsystems: for example, a block device is typically used to provide access from a file system driver (say) to an underlying disk drive; a network driver provides access to the network from the in-kernel TCP/IP stack, etc.
There are several char device methods or entry points that can be supported by your driver, but the most common are "read" (i.e. if a user-space program opens your device and does a read(2) from it), "write" (analogous for write(2)) and "ioctl" (often used for configuration/administrative tasks that don't fall naturally into either a read or write). Note that mknod(2) only creates the user-space side of the device. There needs to be a corresponding device driver in the kernel (the "major device number" given in the mknod call links the user-space node with the driver).
For actually creating the device node in the file system, this can be automated (i.e. the node will automatically show up in /dev) if you call the right kernel functions while setting up your device. There's a special daemon that gets notifications from the kernel and responds by executing the mknod(2) system call.
A kernel module is merely a dynamically loadable way of creating a driver or other kernel extension. It can create a character, block or network device (et al.), but then so can a statically linked module. There are some differences in capability mostly because not all kernel functions you might want to use are "exported" to (i.e. visible to) dynamically loaded modules.
It's possible to support mapping of the device memory into user virtual memory space. This would be implemented by yet another driver entry point (mmap). See struct file_operations for all the entry points a char driver can support.
This is pretty much up to you: it depends on what the application needs to be able to do. There are many drivers in the kernel that provide no direct function to user-space, only to other kernel code. As to "probe", there are many probe functions defined in various interfaces. In most cases, these are called by the kernel (or perhaps by a 'higher level "class" driver') to allow the specific driver to discover, identify and "claim" individual devices. They (probe functions) don't usually have anything directly to do with providing access from user-space but I might well be missing something in a particular interface.
You need to create a device node in order to access the device.
The probe function is called when the driver finds a matching device.
For information on platform device API, the following articles could be useful.
The platform device API
Platform devices and device trees
I am first time trying debugfs to transfer data from the kernel to the user space. Please suggest how to proceed in this regard.
I do not want to use tty driver. It is just for practice from my side. Actually i am trying to write my kernel driver for USART where interrupt data will be pushed to user-space application using debugfs ring buffer.
Long before i found a post by a fellow Stackexchange friend to his GIT repository -- where he had implemented debugfs as ring buffer ... but that link is lost to me... so not able to find some refrence to proced in this regard.
Please suggest.
i know few links which i tried from eugene :---
ioctl vs netlink vs memmap to communicate between kernel space and user space
writing data to debugfs --- from a device driver
http://code.google.com/p/kernel-strider/source/browse/sources/core/resolve_ip.c
I think you should use netlink .
Netlink socket is a special IPC used for transferring information
between kernel and user-space processes. It provides a full-duplex
communication link between the two by way of standard socket APIs for
user-space processes and a special kernel API for kernel modules.
I have received a driver (PCAN driver for PCI card, using rtdm), that creates /dev/pcan0 and /dev/pcan1 is compiled as a netdev driver.
There are many facilities that come with this driver, but they are all targeted at a user-level program reading CAN messages. What I need however is to read these messages from a kernel module. The PCAN driver doesn't export any variables/functions which means it doesn't provide a kernel-level API for me to use.
I looked briefly at the code and reading from the /dev device and writing to it don't use copy_from_user or copy_to_user. Therefore, I thought it should be safe for me to open the /dev/pcan0 from my kernel module and read from it.
Now my question is, how do I open/read from a /dev device from a kernel module?
P.S. I want to read from the CAN bus from an RTAI real-time thread, do you think that would cause a problem (for example every read passing through linux kernel and thus breaking real-time conditions?)
You can use syscalls directly from kernel space: sys_open(), sys_read(), sys_close().
There's Linuxjournal article about that.
P/S: copy_from_user() works perfectly with kernel-space addresses.
Given that I was using RTDM, there were two options:
Using RTDM direct functions, such rt_dev_open, rt_dev_read etc
This is not implemented in the current version of pcan driver
Using RTDM ioctl
This was the solution and it worked
Hello Linux Kernel Driver Gurus!
I'm writing a v4l2 driver for a camera that uses a serial interface for configuration. I'd like the driver to configure the camera, as it keeps the client code consistent across camera models. The question is: what's the best way to access the camera's serial interface from the driver module?
From what I hear, accessing files from a kernel driver is a big no-no, but it can be done. As such, I'm currently using the following code snippet, but it feels like a hack.
oldfs = get_fs();
set_fs(KERNEL_DS);
fd->f_pos=0;
fd->f_op->write(fd, data, data_len, &fd->f_pos);
set_fs(oldfs);
My question is really: what's the right way to do this?
I presume that since a serial port is involved, this must be some kind of embedded system. After all, not many PCs even have serial ports. I also assume that the serial port can be considered a permanent connection, at least from the user's perspective. If that is all true, then you don't really want a TTY device. You want to access the device as a private UART.
If you have a look at the Wolfson audio codecs (sound/soc/wm*.c) you will see an example of devices that primarily communicate over I2S but have an auxiliary I2C interface for configuration. This is conceptually what you want, I believe. The driver presents a unified interface to software, and issues commands to whatever hardware is appropriate. Obviously this is much cleaner than having to expose hardware implementation details to userspace.
I couldn't find a good example of a UART driver in the kernel that works this way, but hopefully I've described what to look for. From a practical rather than technical purity point of view, it might just be better to do file I/O from the kernel.
First I would advise you to find a way to do this from the userspace if possible: what you try to achieve here really is userspace code in kernel code.
But if you don't find a way to do it, this article shows you how to do userspace calls in kernelspace.
Since you want to access a serial port, you should have calls that tty oriented, for instance for open:
serial_fd = sys_open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NONBLOCK))