linux - 64 位系统中 32 位用户代码的 ioctl 命令错误

标签 linux 64-bit 32-bit

我正在将设备驱动程序从 32 位 RHEL 2.6.32 升级到 64 位 RHEL 2.6.33.9。

我有一个使用 ioctl 与该驱动程序通信的程序。当驱动程序和程序都是 64 位或 32 位时,它可以完美运行。但是当驱动程序是64位,而我的程序是32位时,驱动程序接收到的ioctl命令(在compat_ioctl中)与_IOR和_IOW宏定义的值不匹配。

在我的驱动程序的 switch 语句中,default case 打印出所有有效命令的值,即 1-12。 32 位 ioctl 命令与这些值相差甚远。

有人能告诉我什么会导致 32 位用户程序的命令在 64 位驱动程序中收到时出现困惑吗?

这是一些代码:我必须输入它;该代码位于无法访问互联网的安全系统上,因此请原谅任何拼写错误。它实际上确实编译并运行了!

// IOCTL commands from the include file - most omitted
// ...
#define PORTIO_GET_IRQ_CNT_CMD  10
#define PORTIO_CLR_IRQ_CNT_CMD  11
#define PORTIO_GET_IRQ_TIME_CMD 12

#define PORTIO_IOCTL     'k'  // magic number for ioctl

// IOCTL Macros
#define PORTIO_GET_IRQ_CNT_IOCTL    _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_CNT_CMD, unsigned long)
#define PORTIO_CLR_IRQ_CNT_IOCTL    _IOR(PORTIO_IOCTL, PORTIO_CLR_IRQ_CNT_CMD, unsigned long)
#define PORTIO_GET_IRQ_TIME_IOCTL   _IOR(PORTIO_IOCTL, PORTIO_GET_IRQ_TIME_CMD, unsigned long)

这是来自 portio.c 的 32 位兼容 IOCTL 例程。我已经确认,只有当我的程序编译为 32 位且驱动程序为 64 位时才会调用此函数。

static long portio_compat_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
unsigned char cmd_number;
int cmd_size=0;
//...
cmd_number = _IOC_NR( cmd );
cmd_size = _IOC_SIZE( cmd );

printk( KERN_ALERT "Portio Compat IOCTL number,size = %d,%d, cmd_number, cmd_size );
//... Switch statement and cases, based on cmd_number
}

输出如下所示:

Portio Compat IOTCL 编号,大小 = 224,3157

当然,代码期望 IOCTL 数字为 1-12,大小约为 4 或 8。当代码和驱动程序均为 64 位或 32 位时,这正是返回的结果。

最佳答案

在我看来,您的函数compat_ioctl采用了太多参数。查看Linux内核中的其他定义:

long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)

http://lxr.linux.no/#linux+v3.5.3/block/compat_ioctl.c#L654

关于linux - 64 位系统中 32 位用户代码的 ioctl 命令错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12146146/

相关文章:

c++ - 为 VS2010、WINDOWS7、64BIT 构建 CUDA 示例时出现错误 MSB3721

c - 32 位系统中的 64 位变量读取顺序(低位和高位)

c++ - "pthread_cond_wait"没有等待主线程休眠,为什么?

windows - 要编写基于 64 位的软件,我必须使用 64 位 IDE 吗?

c++ - 64 位移植 c++ - 跟踪基本类型、指针、算术的使用

sql-server - SQL Server DSN-Less ODBC 指定 32 位驱动程序

C# 适用于 32 位但不适用于 64 位

regex - 如何使用 gnu utils 从这三行中选择一行?

linux - 使用继承时覆盖 Puppet 类

Android 模拟器无法在 Linux 中启动