20

我正在通过 ioctl 示例程序来检查它如何与内核空间通信。在程序中 WRITE_IOCTL 用作命令

#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)
ioctl(fd, WRITE_IOCTL, "hello world")

我无法理解是什么_IOW(MY_MACIG, 1, int)。这是我下载程序的链接。请帮我。 http://people.ee.ethz.ch/~arkeller/linux/multi/kernel_user_space_howto-4.html

4

2 回答 2

16

您可能知道,ioctl 应该是唯一的,如 Linux 设备驱动程序一书中所述:

ioctl 命令号在整个系统中应该是唯一的,以防止由于向错误的设备发出正确的命令而导致错误。这种不匹配并非不可能发生,并且程序可能会发现自己试图更改非串行端口输入流,例如 FIFO 或音频设备。如果每个 ioctl 编号都是唯一的,则应用程序会收到 EINVAL 错误,而不是成功地做一些非预期的事情。

此外,ioctl 可能需要向内核空间写入数据和/或从内核空间读取数据。

当一个人创建自己的执行 ioctl 的驱动程序时,他需要在 ioctl 命令中描述所有这些。

_IO、_IOW、_IOR、_IORW 是帮助宏,用于创建唯一的 ioctl 标识符并添加所需的 R/W 所需功能(方向)。

这些可以采用以下参数:幻数、命令 id 和将传递的数据类型(如果有)

幻数是一个唯一的数字,它将允许驱动程序检测错误,例如 LDD 书中引用中提到的错误。

命令 id 是您的驱动程序了解需要调用什么命令的一种方式。

最后一个参数(类型)将允许内核了解要复制的大小。

希望这可以帮助。

PS:您可以在 Linux 设备驱动程序书(第 6 章) https://lwn.net/images/pdf/LDD3/ch06.pdf中了解更多详细信息

于 2014-03-26T10:38:43.830 回答
12

来自http://www.circlemud.org/jelson/software/fusd/docs/node31.html

Linux 头文件/usr/include/asm/ioctl.h定义了必须用于创建 ioctl 命令号的宏。这些宏采用三个参数的各种组合:

  • type,选择特定于设备驱动程序的 8 位整数。应该选择类型,以免与其他可能正在“侦听”同一文件描述符的驱动程序冲突。(例如,在内核内部,TCP 和 IP 堆栈使用不同的数字,因为发送到套接字文件描述符的 ioctl 可能会被两个堆栈检查。)
  • number,一个 8 位整数命令编号。在驱动程序中,应该为驱动程序服务的每种不同类型的 ioctl 命令选择不同的数字
  • data_type,用于计算客户端和驱动程序之间交换多少字节的类型的名称。例如,此参数是结构的名称。

用于生成命令编号的宏是:

  • _IO(int type, int number),用于一个简单的 ioctl,它只发送类型和数字,只接收一个(整数)retval
  • _IOR(int type, int number, data_type),用于从设备驱动程序读取数据的 ioctl。驱动程序将被允许返回 sizeof(data_type) 字节给用户
  • _IOW(int type, int number, data_type),类似于_IOR,但用于向驱动写入数据
  • _IORW(int type, int number, data_type),_IOR 和 _IOW 的组合。也就是说,数据既被写入驱动程序,又被客户端从驱动程序中读回
于 2016-11-07T12:26:37.537 回答