1

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?

artless noise
  • 21,212
  • 6
  • 68
  • 105
whh4000
  • 905
  • 1
  • 12
  • 30

2 Answers2

3

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

Gil Hamilton
  • 11,973
  • 28
  • 51
  • I guess what I am wondering comming from the embedded microcontroller world, how do I access this piece of hardware that I would normally (without an operating system) just reference the registers and read and write to them? – whh4000 Apr 09 '14 at 12:30
  • If it's just the occasional tinkering with settings, a char device with ioctl support would probably be best. If it's something that you need to muck with constantly at runtime and if performance in doing so is critical, then it might make sense to use mmap. – Gil Hamilton Apr 09 '14 at 18:31
  • *"...comming from the embedded microcontroller world"* -- Using a uC has nothing to do with this. It's the lack of SW structure. You could organize the FW into layers and implement resource encapsulation. I've had to work with Z80 and 8051 FW that followed no concept of SW structure. – sawdust Apr 11 '14 at 03:01
  • *"A kernel module is merely a dynamically loadable..."* -- Not all kernel modules are loadable. Modules can be statically linked into the kernel image. Some modules may not even have the option of loadability (e.g. tty serial port driver (module) used by the system console has to be built-in). – sawdust Apr 11 '14 at 03:04
0

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

Sagar Jain
  • 7,475
  • 12
  • 47
  • 83