![如何在 Linux 2.6.29 中的 ioctl 中解码 cmd = 3222823425](https://linux22.com/image/44687/%E5%A6%82%E4%BD%95%E5%9C%A8%20Linux%202.6.29%20%E4%B8%AD%E7%9A%84%20ioctl%20%E4%B8%AD%E8%A7%A3%E7%A0%81%20cmd%20%3D%203222823425.png)
我只是很困惑,如何将cmd=3222823425
值分解为不同的部分来弄清楚这个命令在 Linux 内核中的实际含义。我知道,有些函数正在ioctl
使用以下参数发出命令,但我想知道这些参数值的含义。
fd=21, cmd=3222823425 and arg=3203118816
我一直在研究各种论坛、手册页和其他链接来弄清楚这一点,比如当系统调用cmd
中ioctl
的值为时,这意味着什么3222823425
。我发现 cmd 是一个命令号type
,由number
和组成,data_type
前两个是8-bit
整数(0-255)。
所以我的问题是如何解码这些参数值以找出这个调用想要做什么?
答案1
ioctl 传递给驱动程序,因此要弄清楚 ioctl 正在做什么,最重要的是哪个驱动程序正在处理它。
您所读到的内容type
是number
驱动data_type
程序编写者在选择 ioctl 数字时应该使用的约定。虽然不同的驱动程序可以使用相同的值来表示完全不同的事物,但最好避免这种情况,这样如果 ioctl 意外发送到错误的设备,则很有可能返回错误而不是导致一些灾难性事件。
书中对约定有很好的描述Linux 设备驱动程序(LDD),第6章。事实上data_type
(从 2.6.x 系列 IIRC 的早期开始)由两部分组成,direction
和size
。
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 字节缓冲区的指针。