这个问题与我从用户空间到内核空间的ioctl错误调用有关,Ubuntu操作系统在Oracle的Virtual中作为虚拟机运行。在编译模块代码之后,使用"sudo insmod ioctl_module.ko“命令将其加载到Linux内核中,您可以看到下面的消息列表成功地实现了这一点。出于某种原因,从用户空间到内核模块函数的ioctl调用说其中一个参数无效,我不认为它是无效的。(此外,这也是我第二次发布堆叠溢出的问题,所以我希望我正确地遵循了你们的惯例!)谢谢,凯伦
用户级代码错误消息:
saasbook@saasbook:~/cs552/osPrimer/invokeKernelServices/user_level_code$ ./ioctl试验
testStruct.field1大小=1
testStruct.field2大小=1
第一个ioctl:无效参数
Ioctl_test.c的代码列表:
https://gist.github.com/KarenWest/6629582
可以看到ioctl_module在内核中:
/invokeKernelServices$ dmesg
13563.849593加载模块
13578.846063 pseudo_device_ioctl
code_listing for ioctl_module.c:
https://gist.github.com/KarenWest/6629557
从几天前开始,我可以更具体地回答我的问题了。使用ioctl.h位定义,使用_IOW的#define宏,移动它们并将它们放在一起,我看到IOCTL_TEST = 0x4002006是正确的,cmd = 0x804a030是不正确的,但是我不知道为什么cmd有错误的值。cmd是上述ioctl入口点的论点:
static int pseudo_device_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)因此,我查看了proc_fs.h输入文件的proc_dir_entry结构,该结构中的proc_fops指针被设置为ioctl入口点函数,其中pseudo_dev_proc_operations初始化为file_operations结构,proc_entry初始化为指向proc_dir_entry结构的指针(在上面的git上的代码链接中),所有这些都是在ioctl_module.c's initialization_routine()中初始化的,我了解到ioctl _module.c()设置了这个ioctl具有正确值的ioctl,一旦代码在ioctl_test.c级别运行,而操作系统应该被设置为将它指向我的ioctl函数,它确实如此。但是,发送给我的ioctl函数设置(cmd)的参数是不正确的,并且不匹配IOCTL_TEST,这就是失败的原因。
pseudo_dev_proc_operations.unlocked_ioctl = pseudo_device_ioctl;
pseudo_dev_proc_operations.compat_ioctl = pseudo_device_ioctl;
proc_entry = create_proc_entry("ioctl_test", 0666, NULL);
proc_entry->proc_fops = &pseudo_dev_proc_operations;因此,我遵循proc_fs.h的proc_fops指针(初始化为pseudo_dev_proc_operations,它将它带到ioctl pseudo_device_ioctl函数中),以了解为什么cmd参数在处理过程中会出现混乱,而且我也不知道为什么会发生这种情况。
如果任何人有进一步的评论,他们可以帮助我找出我哪里错了,请告诉我。谢谢!凯伦
这可能会有帮助-只要读一读:
“Linux内核模块编程指南:
第7章.与设备文件对话
7.1。与设备文件(写和IOCTL)对话“
发布于 2013-09-20 07:03:00
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
/*
* Let any architecture override either of the following before
* including this file.
*/
#ifndef _IOC_SIZEBITS
# define _IOC_SIZEBITS 14
#endif
#ifndef _IOC_DIRBITS
# define _IOC_DIRBITS 2
#endif
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
/*
* Direction bits, which any architecture can choose to override
* before including this file.
*/
#ifndef _IOC_NONE
# define _IOC_NONE 0U
#endif
#ifndef _IOC_WRITE
# define _IOC_WRITE 1U
#endif
#ifndef _IOC_READ
# define _IOC_READ 2U
#endif
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#define _IOC_TYPECHECK(t) (sizeof(t))
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))**
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),nr),_IOC_TYPECHECK(size)))如您所见,在您的用户空间中使用的_IOW (在您的用户空间ioctl_test.c中使用)和在您的模块ioctl函数中使用的_IOWR对相同参数的不同值进行计算。因此,您的开关箱失败了。也可以在模块中使用_IOW。
https://stackoverflow.com/questions/18904646
复制相似问题