IOCTL Linux设备驱动程序(IOCTL Linux device driver)

2019-08-19 10:49发布

谁能给我解释一下,

  1. 什么是IOCTL
  2. 它是干什么用的?
  3. 我如何使用它?
  4. 为什么我不能定义新的功能,做同样的工作IOCTL

Answer 1:

一个ioctl ,意思是“输入输出控制”是一种特定于设备的系统调用。 只有少数系统调用在Linux中(300-400),这是不足以表达所有独特功能的设备可能有。 因此,司机可以定义一个ioctl,它允许一个用户空间应用程序发送订单。 然而,读写控制不是很灵活,往往会变得有点混乱(几十个“幻数”,这只是工作...与否),也可以是不安全的,当你经过一个缓冲到内核 - 处理不好可以打破事情很容易。

另一种方法是在sysfs界面,在这里设置下的文件/sys/和读/写,从和驱动器获取信息。 如何设置这个了一个例子:

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);

和驱动程序安装过程中:

device_create_file(dev, &dev_attr_version);

这样,你会为您的设备在文件/sys/ ,例如/sys/block/myblk/version块驱动程序。

对于较重使用的另一种方法是网络链路,这是一个IPC(进程间通信)方法来跟你的驱动器通过BSD套接字接口。 这是使用,例如,由WiFi驱动程序。 然后你可以从用户空间使用通讯libnllibnl3库。



Answer 2:

ioctl当一个正在执行的设备驱动器,以在设备上设置的配置的功能是有用的。 例如打印机配置选项检查并设置字体,字号等ioctl可以用来获取当前字体,以及字体集到另一个。 在用户应用程序使用ioctl的代码发送到打印机,告诉它返回当前的字体或字体设置为一个新的。

int ioctl(int fd, int request, ...)
  1. fd是文件描述符,由open返回的一个
  2. request是请求代码。 例如GETFONT将获得当前字体从打印机相同,setFont将设置字体的打印机上。
  3. 第三个参数是void * 。 根据第二个参数,第三可能或可能不存在。 例如,如果第二个参数是setfont程序,第三个参数可以给字体名称作为ARIAL。

所以,现在INT请求不是只是一个宏,需要一个产生请求的代码由用户应用程序和设备驱动程序模块一起使用,以确定哪些设备配置必须被播放。 一个发送使用请求代码ioctl从用户应用程序,然后使用在设备驱动程序模块的请求代码,以确定要执行的操作。

的请求的代码具有4个主要部分

    1. A Magic number - 8 bits
    2. A sequence number - 8 bits
    3. Argument type (typically 14 bits), if any.
    4. Direction of data transfer (2 bits).  

如果请求代码是setfont程序设置在打印机上的字体,用于数据传输的方向是从用户的应用程序的设备驱动程序模块。 用户发送字型名Arial打印机。 如果请求代码是GETFONT,方向是从打印机到用户应用程序。

要生成请求代码的Linux提供像宏一些预定义的功能。

1. _IO(MAGIC, SEQ_NO)都是8位,0到255,例如让我们说,我们要暂停打印机。 这并不需要转移ADATA。 因此,我们将下面生成请求代码

    #define PRIN_MAGIC 'P'
    #define NUM 0
    #define PAUSE_PRIN __IO(PRIN_MAGIC, NUM) 

现在使用ioctl作为

    ret_val = ioctl(fd, PAUSE_PRIN);

在驱动模块对应的系统调用将收到的代码,并暂停打印机。

  1. __IOW(MAGIC, SEQ_NO, TYPE) MAGICSEQ_NO同上,但第三部分对下一个参数的类型,回忆的第三个参数ioctlvoid * 。 W的__IOW指示数据的方向是从用户应用到驱动模块。 让我们举个例子,假设一个告诉打印机字体设置为宋体。

     #define PRIN_MAGIC 'S' #define SEQ_NO 1 #define SETFONT __IOW(PRIN_MAGIC, SEQ_NO, unsigned long) 

进一步,

    char *font = "Arial";
    ret_val = ioctl(fd, SETFONT, font); 

现在font是一个指针,这意味着它是最好的表示为一个地址unsigned long ,因此,第三部分_IOW提到类型本身。 此外,字体的这个地址被传递到设备驱动模块实现为对应的系统调用unsigned long ,我们需要在使用前将其转换为正确的类型。 内核空间可以访问用户空间,因此这个工程。 另外两个函数像宏__IOR(MAGIC, SEQ_NO, TYPE)__IORW(MAGIC, SEQ_NO, TYPE)其中数据流的方向是从内核空间向用户空间和分别是双向的。

请让我知道这可不可以帮你!



文章来源: IOCTL Linux device driver