我正在研究具有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