如何在 Linux 2.6.29 中的 ioctl 中解码 cmd = 3222823425

如何在 Linux 2.6.29 中的 ioctl 中解码 cmd = 3222823425

我只是很困惑,如何将cmd=3222823425值分解为不同的部分来弄清楚这个命令在 Linux 内核中的实际含义。我知道,有些函数正在ioctl使用以下参数发出命令,但我想知道这些参数值的含义。

fd=21, cmd=3222823425 and arg=3203118816 

我一直在研究各种论坛、手册页和其他链接来弄清楚这一点,比如当系统调用cmdioctl的值为时,这意味着什么3222823425。我发现 cmd 是一个命令号type,由number和组成,data_type前两个是8-bit整数(0-255)。

所以我的问题是如何解码这些参数值以找出这个调用想要做什么?

答案1

ioctl 传递给驱动程序,因此要弄清楚 ioctl 正在做什么,最重要的是哪个驱动程序正在处理它。

您所读到的内容typenumber驱动data_type程序编写者在选择 ioctl 数字时应该使用的约定。虽然不同的驱动程序可以使用相同的值来表示完全不同的事物,但最好避免这种情况,这样如果 ioctl 意外发送到错误的设备,则很有可能返回错误而不是导致一些灾难性事件。

书中对约定有很好的描述Linux 设备驱动程序(LDD),第6章。事实上data_type(从 2.6.x 系列 IIRC 的早期开始)由两部分组成,directionsize

  • type(8 位)是一个常量,必须在驱动程序中实现的 ioctl 之间保持一致,并且如果可能,应与不相关设备的 ioctl 不同。有一个过时的type值存储库Documentation/ioctl/ioctl-number.txt
  • number(8 位)对于驱动程序中的所有 ioctl 应该不同。
  • direction(2 位)指示数据传输方向(0=无、1=写入、2=读取、3=两者)。
  • size如果 ioctl 参数是指向数据缓冲区的指针,则为数据缓冲区的大小。

ioctl 编号应为

 direction << 30 | size << 16 | type << 8 | number

(如果您正在编写驱动程序,请使用_IOC_*中定义的宏asm-generic/ioctl.h.)

对于 ioctl 编号 3222823425 = 0xc0186201,我们得到 type=0x62(1999 年称为“bit3 vme 主桥”)、number=1、direction=2 和 size=0x18=24,因此 ioctl 采用 24 字节输入参数。

该 ioctl 值应定义为_IOR(0x62, 0x01, struct somestruct)或类似的等效值_IOR('b', 1, struct somestruct),其中struct somestruct是 24 字节结构。如果您不知道哪个驱动程序正在处理 ioctl,您可以在内核源代码中搜索类似的调用来收集候选者。但是,请注意,简单的文本搜索通常找不到驱动程序,因为它们通常使用宏,例如#define FOOIO_TYPE 0x62后跟#define FOOIO_SOMETHING _IOR(FOOIO_TYPE, 1, struct foobar).

除了 ioctl 作用的文件描述符之外,ioctl 调用还有两个参数: ioctl numbercmd和 argument arg。该参数可以是立即值或指向缓冲区的指针。这里,如果驱动程序编写者遵循约定,则arg应该是指向应用程序内存空间中的 24 字节缓冲区的指针。

相关内容