Can hardware registers be mapped to userspace - linux-kernel

I'm developing an LED driver on Freescale MPC8306. In driver code, I do ioremap on GPIO registers and call remap_pfn_range upon the remapped GPIO register address, then, call mmap in userspace to map the GPIO register to userspace. I haven't done this before and I want to know if this method work or not. Can some help me? Thanks in Advance.

You should be using /dev/mem interface for accessing the GPIO registers. A good reference for controlling LEDs via GPIOs on another embedded board is given here.

An easier way would probably just to mmap the relevant offset of /dev/mem in your userspace program directly. This allows you to access the physical memory layout by seeking into it.
AFAIK, this is what the RaspberryPi developers have done to make GPIO memory mapped I/O registers available to userspace programs.

Related

Sharing I2C driver by kernel and userspace

My hardware design uses the same I2C controller for chips controlled by kernel modules (DAC and ADC in sound ASoC) and for devices I want to control from userspace (I2C port expanders -> relays). Can I use the controller in the ASoC devicetree files and use it from user-space libraries at the same time? If so, how can I guard/lock access to the controller between kernel and userspace to avoid clashing I2C transactions?

Linux PCIe DMA driver

I'm currently writing a driver for a PCIe device that should send data to a Linux system using DMA. As far as I can understand my PCIe device needs a DMA controller (DMA master) and my Linux system too (DMA slave). Currently the PCIe device has no DMA controller and should not get one. That confuses me.
A. Is the following possible?
PCIe device sends interrupt
Wait for interrupt in the Linux driver
Start DMA transfer from memory mapped PCIe registers to Linux system DMA.
Read the data from memory in userspace
I have everything setup for this, the only thing I miss is how to transfer the data from the PCIe registers to the memory.
B. Which system call (or series of) do I need to call to do a DMA transfer?
C. I probably need to setup the DMA on the Linux system but what I find points to code that assumes there is a slave, e.g. struct dma_slave_config.
The use case is collecting data from the PCIe device and make it available in memory to userspace.
Any help is much appreciated. Thanks in advance!
DMA, by definition, is completely independent of the CPU and any software (i.e. OS kernel) running on it. DMA is a way for devices to perform memory reads and writes against host memory without the involvement of the host CPU.
The way DMA usually works is something like this: software will allocate a DMA accessible region in memory and share the physical address with the device, say, by performing memory writes against the address space associated with one of the device's BARs. Then, the device will perform a DMA read or write against that block of memory. When that operation is complete, the device will issue an interrupt to the device driver so it can handle the data and/or free the memory.
If your device does not have the capability of issuing a DMA read or write against host memory, then you'll have to interact with it with using the CPU only. Discrete DMA controllers have not been a thing for a very long time.

Write to a UIO Device

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.

Sysfs or read() system call for userspace interrupt notification

I have created a driver that uses sysfs_notify_dirent() to wake up a userspace thread asynchronously when a PCIe device interrupts the kernel driver. I see that this is the interface the most GPIO drivers use to pass interrupts up to userspace. After doing some research though I see that UIO uses the read() system call to do pretty much the same thing. Is there any advantage (speed or otherwise) to using the read() system call instead of the sysfs interface to pass interrupts. I like the sysfs interface because it allows me to create multiple attributes so I can pass different interrupts to userspace separately.

debugfs -- ring buffer implementation -- linux

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.

Resources