IOCTL Linux device driver

driver, ioctl, linux, linux-device-driver, linux-kernel

Solution

An `ioctl`, which means "input-output control" is a kind of device-specific system call. There are only a few system calls in Linux (300-400), which are not enough to express all the unique functions devices may have. So a driver can define an ioctl which allows a userspace application to send it orders. However, ioctls are not very flexible and tend to get a bit cluttered (dozens of "magic numbers" which just work... or not), and can also be insecure, as you pass a buffer into the kernel - bad handling can break things easily.

An alternative is the `sysfs` interface, where you set up a file under `/sys/` and read/write that to get information from and to the driver. An example of how to set this up:

static ssize_t mydrvr_version_show(struct device *dev,
        struct device_attribute *attr, char *buf)
{
    return sprintf(buf, "%s\n", DRIVER_RELEASE);
}

static DEVICE_ATTR(version, S_IRUGO, mydrvr_version_show, NULL);

And during driver setup:

device_create_file(dev, &dev_attr_version);

You would then have a file for your device in `/sys/`, for example, `/sys/block/myblk/version` for a block driver.

Another method for heavier use is netlink, which is an IPC (inter-process communication) method to talk to your driver over a BSD socket interface. This is used, for example, by the WiFi drivers. You then communicate with it from userspace using the `libnl` or `libnl3` libraries.

Problem

Can anyone explain me, - What is `IOCTL`? - What is it used for? - How can I use it? - Why can't I define new function that does the same work as `IOCTL`?

Original source