linux内核模块的读取例程被称为无限次

时间:2018-08-01 23:45:14

标签: linux-kernel

我正在研究具有file_operations结构的基本Linux内核模块(字符设备驱动程序)。我已经在其中实现了open,release,read,write方法。除读取外,所有方法均按预期工作。

我编写的驱动程序将反转写在关联的设备节点上的字符串(回显Hello / dev / rev)。一旦我读回,它应该返回反向字符串(cat / dev / rev)。输出应为“ olleH”。

问题: 当我读取(cat / dev / rev)时,驱动程序中的读取例程被调用无限次。所以我得到如下的连续输出:

olleH
olleH
olleH
olleH
..

我已经搜索过,但是找不到答案。所以请在这里告诉我我在做什么错。

代码: 反向。

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

#define MYDRIVER "revese"

static int major = 0;
static int open_cnt = 0;
static char kbuf[100];

static int myDev_open(struct inode *in, struct file *filp)
{
    open_cnt++;
    printk(KERN_INFO "myDev_open: open_cnt = %d\n", open_cnt);
    return 0;
}

static int myDev_close (struct inode *in, struct file *filp)
{
    if(open_cnt > 0)
        open_cnt--;
    printk(KERN_INFO "myDev_close:\n");
    return 0;
}

static ssize_t myDev_read(struct file *filp, char __user *buf, size_t n, loff_t *off)
{
    int i;

    printk("n from the userspace = %ld\n", n);
    for(i = 0; i < n && kbuf[i] != 0; ++i) {
        put_user(kbuf[i], buf++);
    }
    *buf = '\0';

    printk(KERN_INFO "myDev_read: read length = %d; buf = %s\n", i, buf-i);

    return i;
}

static ssize_t myDev_write(struct file *filp, const char __user *buf, size_t n, loff_t *off)
{
    int i, ind;

    printk(KERN_INFO "myDev_write: n = %ld\n", n);
    memset(kbuf, 0, 100);

    for(i = 0, ind = (n-1); i < n; ++i, --ind) {
        kbuf[i] = buf[ind];
    }
    kbuf[i] = '\0';

    return i;
}

static struct file_operations file_ops = {
    .owner = THIS_MODULE,
    .open = myDev_open,
    .release = myDev_close,
    .read = myDev_read,
    .write = myDev_write,
};

static int __init myDev_init(void)
{
    int rval;

    printk(KERN_INFO "myDev_init: \n");
    rval = register_chrdev(0, MYDRIVER, &file_ops);
    if(rval < 0) {
        printk(KERN_ERR "myDev_init: driver registration failed\n");
        return rval;
    }
    major = rval;
    printk(KERN_INFO "myDev_init: driver reg success, major number = %d\n", major);

    return 0;
}

static void __exit myDev_exit(void)
{
    printk(KERN_INFO "myDev_exit: \n");
    unregister_chrdev(major, MYDRIVER);
}

module_init(myDev_init);
module_exit(myDev_exit);

Makefile:

TARGET_MODULE := reverse
BUILDSYSTEM_DIR := '/lib/modules/$(shell uname -r)/build'
PWD := $(shell pwd)

obj-m := $(TARGET_MODULE).o

defult:
    $(MAKE) -C $(BUILDSYSTEM_DIR) SUBDIRS=$(PWD) modules
clean:
    $(MAKE) -C $(BUILDSYSTEM_DIR) SUBDIRS=$(PWD) clean

命令:

sudo insmod reverse.ko
sudo mknod /dev/rev c 250 0
sudo chmod a+w+r /dev/rev

echo Hello > /dev/rev
cat /dev/rev

0 个答案:

没有答案