今天遇到一个ioctl访问失败的问题,做个记录,主要是用户态是32位,内核态时64位的。对于字符设备,内核中ioctl的挂接有不同,
一:写64位driver驱动时,必须实现compat_ioctl实现,用户态是32位时,会调用这个接口,否则会出现ioctl调用失败的情况。
https://www.cnblogs.com/pengdonglin137/p/8111272.html
Linux内核中struct file_operations含有下面两个函数指针:
struct file_operations {
... ...
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
... ...
};
注意:
1、compat_ioctl:支持64bit的driver必须要实现的ioctl,当有32bit的userspace application call 64bit kernel的IOCTL的时候,这个callback会被调用到。如果没有实现compat_ioctl,那么32位的用户程序在64位的kernel上执行ioctl时会返回错误:Not a typewriter
2、如果是64位的用户程序运行在64位的kernel上,调用的是unlocked_ioctl,如果是32位的APP运行在32位的kernel上,调用的也是unlocked_ioctl
#ifdef CONFIG_COMPAT
static long debussy_compat_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
{
return debussy_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#endif
static const struct file_operations debussy_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = debussy_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = debussy_compat_ioctl,
#endif
};
二:特别是在写IOCTL的时候,由于有32bit userspace + 64bit kernel的问题,而且由于architecture的不同,不同data type的length也不同,所以在IOCTL中建议用u32, u64, s32这样无视architecture fix size的data type。
参看LDD十一章中有关Nature Alignment的描述。Alignment主要是牵涉到性能问题,不对齐的数据在fetch的时候会有exception,从而降低performance。
这里是网上搜到的一些建议。
参考资料: https://www.cnblogs.com/super119/archive/2012/12/03/2799967.html