设备驱动程序 IOCTL 传递 int

Posted

技术标签:

【中文标题】设备驱动程序 IOCTL 传递 int【英文标题】:Device Driver IOCTL pass int 【发布时间】:2012-08-26 08:03:10 【问题描述】:

我编写了一个设备驱动程序,需要将一个 int 值传递给它。为此,我正在使用 copy_from_user() 。这是我到目前为止所做的,

#define MY_MAGIC 'G'
#define TEST_IOCTL _IO(MY_MAGIC, 0)
#define PASS_STRUCT_ARRAY_SIZE _IOW(MY_MAGIC, 1, int )
#define TEST_IOCTL_ONE _IO(MY_MAGIC, 2)


int major;

int device_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)

int ret, SIZE;

switch(cmd)

    case TEST_IOCTL:
        printk("NO argument IOCTL called\n");
        break;

    case PASS_STRUCT_ARRAY_SIZE:
            printk("Inside PASS_STRUCT_ARRAY_SIZE\n");
        ret = copy_from_user(SIZE, arg, sizeof(int));
        if(ret < 0)
            printk("Error in PASS_STRUCT_ARRAY_SIZE\n");
            return -1;  
        
        printk("Struct Array Size : %d\n",SIZE);
        break;

    case TEST_IOCTL_ONE:
        printk("NO argument IOCTL_ONE called\n");
        break;

    default :
        return -ENOTTY;


return 0;


当我调用TEST_IOCTLTEST_IOCTL_ONE 时,模块可以正常工作。但是,当我致电PASS_STRUCT_ARRAY_SIZE 时,系统会冻结。

用户空间代码是这样的,

if(ioctl(fd, PASS_STRUCT_ARRAY_SIZE, 10) < 0)
    perror("PASS_STRUCT_ARRAY_SIZE : ");
        return -1;

我做错了什么?

【问题讨论】:

您永远不应该通过ioctl 传递int,因为它在内核和用户空间中的大小可能不同。 【参考方案1】:

对不起,我之前的回答是错误的。由于参数是一个整数,你应该只使用它而不使用copy_from_user

SIZE = arg;

只有当参数是指针时才需要copy_from_user

【讨论】:

@kani 然后它不起作用:-?我不确定,我有一段时间没有这样做了。 谢谢 :) 新的工作..实际上你之前的回答很有帮助我想从用户空间传递一个结构(下一步)内存地址问题很有帮助:)

以上是关于设备驱动程序 IOCTL 传递 int的主要内容,如果未能解决你的问题,请参考以下文章

:高级字符驱动程序操作

在 FreeBSD 中实现 ioctl() 命令

IOCTL Linux 设备驱动程序 [关闭]

Linux设备驱动程序 之 ioctl

将 ioctl 代码从内核模块传递到用户空间程序

块设备驱动程序 - 了解收到的 ioctl