compat_ioctl 被使用在用户空间为32位模式,而内核运行在64位模式时常使用.unlocked_ioctl 属性指定ioctl,。这时候,需要将64位转成32位。例如PCBA测试
如何转换?
请参考下面的方式在内核中添加
1. 在 file_operations 中添加属性并指定函数
static const struct file_operations bcm2079x_dev_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.poll = bcm2079x_dev_poll,
.read = bcm2079x_dev_read,
.write = bcm2079x_dev_write,
.open = bcm2079x_dev_open,
.unlocked_ioctl = bcm2079x_dev_unlocked_ioctl,
.compat_ioctl = bcm2079x_dev_compat_ioctl
};
2. 实现新指定的函数,实现指针的转换
static long bcm2079x_dev_compat_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
void __user *arg64 = compat_ptr(arg);
int result = 0;
if (!file->f_op || !file->f_op->unlocked_ioctl) {
printk("%s >> file->f_op or file->f_op->unlocked_ioctl is null\n",__func__);
return -ENOTTY;
}
switch (cmd) {
// 这里表省略.....
case BCMNFC_CHANGE_ADDR:
if (file->f_op->unlocked_ioctl)
result = file->f_op->unlocked_ioctl(file, BCMNFC_CHANGE_ADDR, (unsigned long)arg64);
break;
case BCMNFC_POWER_CTL:
if (file->f_op->unlocked_ioctl)
result = file->f_op->unlocked_ioctl(file, BCMNFC_POWER_CTL, (unsigned long)arg64);
break;
default:
printk("%s unknown cmd \n", __func__);
return 0;
}
return 0;
}