假设我定义了以下内容。
#define MY_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, arg1)
#define MY_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, arg2)
#ifdef CONFIG_COMPAT
#define MY_COMPAT_IOCTL_CMD1 _IOR(MAGIC_NUMBER, 0x01, compat_arg1)
#define MY_COMPAT_IOCTL_CMD2 _IOW(MAGIC_NUMBER, 0x02, compat_arg2)
#endif
现在当我们从用户空间执行 ioctl 时,我们通常会这样做
ioctl(fd, MY_IOCTL_CMD1, &arg1)
问:我们真的需要一个带有 MY_COMPAT_IOCTL_CMD1
的 ioctl 作为请求吗?
在设备代码中,我有如下定义的处理程序。 ioctl: 设备_ioctl
#ifdef CONFIG_COMPAT
compat_ioctl: device_compat_ioctl
#endif
有人可以对此提供一些解释吗?
最佳答案
这个兼容的东西用于在 64 位内核中运行 32 位程序。当您从 64 位内核上的 32 位程序调用 ioctl(fd, MY_IOCTL_CMD1, &arg1)
时,内核会将 ioctl 转移到 .compat_ioctl
函数在 file_operations
结构中。此 compat_ioctl
函数负责复制用户参数 arg1
,就好像它是 compat_arg1
,它使用 32 位布局。 compat_arg1
typedef 在内核中定义,因此在为 64 位编译时,结构与为 32 位编译的 arg1
的布局完全相同。
MY_IOCTL_CMD1
的定义将在创建 cmd id 时考虑 sizeof arg1
。当您为 32 位机器编译程序时,MY_IOCTL_CMD1
的值将不同于为 64 位机器编译的程序。但是,32 位 MY_IOCTL_CMD1
应与内核中的 64 位 MY_COMPAT_IOCTL_CMD1
具有相同的值。
永远不需要在用户空间应用程序中使用 compat_arg1
或 MY_COMPAT_IOCTL_CMD1
。这些仅适用于在内核中编译的代码。
关于linux - 如何从用户空间调用 compat ioctl?有人可以提供一些例子吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6278824/