我正在将设备驱动程序从32位RHEL 2.6.32升级到64位RHEL 2.6.33.9。
我有一个使用ioctl与该驱动程序通信的程序。当驱动程序和程序都是64位或32位时,它可以很好地工作。但是当驱动程序是64位,而我的程序是32位时,驱动程序收到的ioctl命令(在compat_ioctl中)与_IOR和_IOW宏定义的值不匹配。
在我的驱动程序的switch语句中,默认情况下会打印出所有有效命令的值,即1-12。 32位ioctl命令远不及这些值。
有人能告诉我在64位驱动程序中接收到32位用户程序的命令会导致什么??
以下是一些代码:我必须输入;代码是在没有互联网访问的安全系统上,所以请原谅任何错别字。它确实可以运行并运行!
// 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位时的情况。
答案 0 :(得分:2)
在我看来,你的函数compat_ioctl
需要太多参数。查看Linux内核中的其他定义:
long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
答案 1 :(得分:0)
#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)
将unsigned long更改为unit64_t(固定数据类型) 从ioctl宏参数中删除所有指针, 有:
.compat_ioctl
.unlocked_ioctl in kernel pointing to same function.