IOCTL写入崩溃

问题描述:

我想在内核空间中实现ioctl来向寄存器中写入一些日期,我得到了ioctl的cmd崩溃。IOCTL写入崩溃

下面是我的代码:

内核端:

static struct file_operations fops = { 
.compat_ioctl = device_ioctl 
}; 

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

    int len = 200; 

    printk (KERN_INFO "In Device_ioctl !!\n"); 
    switch(cmd) 
    { 
    case IOCTL_WRITE_REG: 
     write_ioctl((unsigned long *)arg); 
     break; 

    default: 
     printk (KERN_INFO "default\n"); 
     return -ENOTTY; 
    } 
    printk (KERN_INFO "device_ioctl out\n"); 
    return len; 
} 

用户侧

#define IOCTL_WRITE_REG _IOW(MAJOR_NUM, 1, int *) 
void write_to_device(int write_fd) 
{ 

    int retval; 
    unsigned int to_write1 = 1; 

    retval = ioctl(write_fd, IOCTL_WRITE_REG, &to_write1); 
    if(retval < 0) 
    { 
     printf("fd: %d, write error: %d\n", write_fd, errno); 
     exit(-1); 
    } 
} 

它不进入device_ioctl功能, 我要去哪里错了?

+0

你需要使用'unlocked_ioctl'代替'compat_ioctl的'。 – Tuxdude 2013-03-26 04:29:15

几件事我碰巧发现:

  • 您需要使用unlocked_ioctl而不是compat_ioctlcompat_ioctl允许32位用户空间程序在64位内核上调用ioctl调用。
  • 您的ioctl处理函数的签名不正确(对于unlocked_ioctl)。预期的签名是:

    long (*unlocked_ioctl) (struct file * filep, unsigned int, unsigned long); 
    

我还没有尝试过真正的编译的代码,但我认为这应该工作:

static struct file_operations fops = { 
    .unlocked_ioctl = device_ioctl 
}; 

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

    int len = 200; 

    printk (KERN_INFO "In Device_ioctl !!\n"); 
    switch(cmd) 
    { 
    case IOCTL_WRITE_REG: 
     write_ioctl((unsigned long *)arg); 
     break; 

    default: 
     printk (KERN_INFO "default\n"); 
     return -ENOTTY; 
    } 
    printk (KERN_INFO "device_ioctl out\n"); 
    return len; 
} 
+0

谢谢Tuxdude !! 工作良好。 upvoted :) – San 2013-03-26 05:31:59

+0

你能给我一个简单的定义compat_ioctl和closed_ioctl,appart从这个32-64位转换? – San 2013-03-26 05:40:33