如何使用ioctl读取和写入chardev?

时间:2014-08-14 13:48:17

标签: linux-kernel ioctl

我正在尝试使用一个简单的ioctl函数构建一个内核模块,该函数可以读取和写入chardev。这是我的模块的代码:

#include <linux/kernel.h>
#include <linux/module.h> 
#include <linux/fs.h>
#include <asm/uaccess.h>

#define MY_MACIG 'G'
#define READ_IOCTL _IOR(MY_MACIG, 0, int)
#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)

static int major; 
static char msg[200];

static ssize_t device_read(struct file *filp, char __user *buffer, size_t length, loff_t *offset)
{
    printk("I am in device read!\n");
    return simple_read_from_buffer(buffer, length, offset, msg, 200);
}


static ssize_t device_write(struct file *filp, const char __user *buff, size_t len, loff_t *off)
{
    printk("I am in device write!\n");
    if (len > 199)
        return -EINVAL;
    copy_from_user(msg, buff, len);
    msg[len] = '\0';
    return len;
}

char buf[200];
static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
    int len = 200;
    switch(cmd) {
    case READ_IOCTL:
        trace_printk("read ioctl\n");   
        printk(KERN_INFO "read ioctl");
        copy_to_user((char *)arg, buf, 200);
        break;
    case WRITE_IOCTL:
        trace_printk("write ioctl");
        copy_from_user(buf, (char *)arg, len);
        break;
    default:
        return -ENOTTY;
    }

    return len;

}

static const struct file_operations fops = {
    read: device_read, 
    write: device_write,
    unlocked_ioctl: device_ioctl
};

static int __init cdevexample_module_init(void)
{
    major = register_chrdev(0, "Arnold-dev", &fops);
    if (major < 0) {
            printk ("Registering the character device failed with %d\n", major);
            return major;
    }
    printk("Arnold-dev: assigned major: %d\n", major);
    printk("create node with mknod /dev/Arnold-dev c %d 0\n", major);
    return 0;
}

static void __exit cdevexample_module_exit(void)
{
    unregister_chrdev(major, "Arnold-dev");
}  

module_init(cdevexample_module_init);
module_exit(cdevexample_module_exit);
MODULE_LICENSE("GPL");

这是我在用户空间的代码:

#include <stdio.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>

#define MY_MACIG 'G'
#define READ_IOCTL _IOR(MY_MACIG, 0, int)
#define WRITE_IOCTL _IOW(MY_MACIG, 1, int)

int marker_fd = -1;

int main(){
    char buf[200];
    int fd = -1;
    if ((fd = open("/dev/Arnold-dev", O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO)) < 0) {
        perror("open");
        return -1;
    }   

    char debugfs[] =  "/sys/kernel/debug";
    char path[200];
    char rd[] = "read in user";
    char wr[] = "write in user"; 
    strcpy(path, debugfs);
    strcat(path, "/tracing/trace_marker");
    marker_fd = open(path, O_WRONLY);
    if (marker_fd < 0)
        perror("open marker");

    if(ioctl(fd, WRITE_IOCTL, "hello world") < 0)
        write(marker_fd,wr,strlen(wr));
    if(ioctl(fd, READ_IOCTL, buf) < 0)
        write(marker_fd,rd, strlen(rd));

    printf("message: %s\n", buf);
    return 0;

}

构建模块,我可以插入它,init工作正常,但write,read和device_ioctl()函数不起作用。创建了chardev,来自init的消息显示在dmesg中,但其他任何内容都被跳过。 插入跟踪以测量ioctl()调用和ioctl()返回之间的时间。 我的device_ioctl()函数是否与unlocked_ioctl不兼容?和读写一样吗? 我正在使用XUbuntu和Linux内核3.13.0-24-generic。

0 个答案:

没有答案