Linux 通过内核模块轮询循环设备

Linux 通过内核模块轮询循环设备,linux,linux-kernel,linux-device-driver,kernel,Linux,Linux Kernel,Linux Device Driver,Kernel,我试图读取一个在200毫秒内通过内核模块创建的环回设备,但当我尝试插入它时,它正在使内核崩溃 我认为我的读取模块有问题,但没有定时器它工作正常 我是内核编程新手,请帮忙。 提前谢谢你:D #include <linux/kernel.h> #include <linux/module.h> #include <linux/timer.h> #include<linux/fs.h> #include <linux/init.h> #inc

我试图读取一个在200毫秒内通过内核模块创建的环回设备,但当我尝试插入它时,它正在使内核崩溃

我认为我的读取模块有问题,但没有定时器它工作正常

我是内核编程新手,请帮忙。 提前谢谢你:D

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
#include<linux/fs.h>
#include <linux/init.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>

static struct timer_list my_timer;

static void read_file(char *filename)
{
  struct file *fd;
  char buf[1];
  unsigned long long offset=0;
  mm_segment_t old_fs = get_fs();
  set_fs(KERNEL_DS);

  fd = filp_open(filename, O_RDONLY, 0);
  if (fd >= 0) {
    printk(KERN_DEBUG);
    while (vfs_read(fd, buf, 1,&offset) == 1)
    {
      if((0 <= buf[0]) && (buf[0] <=255))
        printk("%c", buf[0]);
    } 
    printk(KERN_ALERT "Loop Ran\n");
    filp_close(fd,NULL);
  }
  set_fs(old_fs);
}

void my_timer_callback( unsigned long data )
{
  int ret;
  printk( "my_timer_callback called (%ld).\n", jiffies );  
  printk( "Starting timer to fire in 200ms (%ld)\n", jiffies );  
  read_file("/dev/loop0");  
  ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(3000) );
  if(ret)  
    printk("Error in mod_timer\n");  
}

int init_module( void )
{
  int ret;
  printk("Timer module installing\n");

  setup_timer( &my_timer, my_timer_callback, 0 );

  printk( "Starting timer to fire in 200ms (%ld)\n", jiffies );
  ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(200) );
  if(ret)
    printk("Error in mod_timer\n");

  return 0;
}

void cleanup_module( void )
{
  int ret;

  ret = del_timer( &my_timer );
  if(ret)
    printk("The timer is still in use...\n");

  printk("Timer module uninstalling\n");

  return;
}`enter code here`

MODULE_LICENSE("GPL"); 

读取文件是相当复杂的,因为有许多角落的情况需要处理。(如果VM映射需要扩展怎么办?如果在等待磁盘时必须挂起线程怎么办?等等)

本文讨论了您应该做什么:

不幸的是,本文给出了一些围绕这个问题进行黑客攻击的示例代码,这给了人们希望。但是示例代码仅在“用户进程调用内核”的上下文中工作。在这种情况下,内核可以重用当前用户进程上下文,但这是一种黑客行为

在一般情况下(中断、定时器、蚀刻),您不能仅仅“获取随机用户上下文”,因为这将导致大量问题


相反,您应该创建一个用户空间进程,将所需的数据交给内核

内核计时器函数应该是原子的。文件操作需要一个进程上下文。崩溃是由于读取操作中存在的文件操作造成的


Linux设备驱动程序-第7章应该让您了解内核计时器。

@BraveNewCurrency因为读取在没有计时器的情况下工作正常,所以我认为问题在于当读取模块作为中断服务例程工作时,ISR太大了。你能帮我吗?从内核读取文件是一件不好的事情。你为什么不结束这个问题,发布你真正想做的事情,也许我们可以帮你。
obj-m := timer2.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD)   clean