1

カーネル モジュールを介して作成したループバック デバイスを 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"); 

私のメイクファイル:

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 
4

2 に答える 2

0

カーネル タイマー関数はアトミックであるべきです。ファイル操作にはプロセス コンテキストが必要です。クラッシュは、読み取り操作に存在するファイル操作が原因です。

Linux デバイス ドライバー - 第 7 章では、カーネル タイマーについて説明します。

于 2013-09-16T14:33:22.557 に答える
0

ファイルの読み取りは、対処すべき多くの特殊なケースがあるため、かなり複雑です。(VM マッピングを拡張する必要がある場合はどうすればよいでしょうか?ディスクを待機している間にスレッドを一時停止する必要がある場合はどうすればよいでしょうか?など)。

この記事では、代わりに何をすべきかについて説明しています: http://www.linuxjournal.com/article/8110

残念ながら、この記事では、問題を回避するためのサンプル コードをいくつか提供しており、人々に希望を与えています。ただし、サンプル コードは「カーネルへのユーザー プロセス呼び出し」のコンテキストでのみ機能します。この場合、カーネルは現在のユーザー プロセス コンテキストを再利用できますが、これはハックです。

一般的なケース (割り込み、タイマー、エッチング) では、単に「ランダムなユーザー コンテキストを取得する」ことはできません。これは、大きな問題につながるからです。

代わりに、必要なデータをカーネルに渡すユーザー空間プロセスを作成する必要があります。

于 2013-07-06T19:31:48.273 に答える