2017-12-04 13 views
-1

私の講師が私に与えたいくつかのサンプルコードを理解しようとしています。/procの下にファイルを作成して使用する

これは、ユーザー空間から/ procファイルを介してカーネル空間にデータを転送する方法です。これは彼が私に与えた唯一のコードであり、私はユーザースペースプログラムを逃しているように感じ、彼は何がうまくいっているのかを彼が説明しているとは思わない。

彼はセマフォを介してファイルをロックすることを実証し、私が信じているデータも転送しようとしています。私が理解するのに苦労していますものは、次のとおりです。

  • なぜ彼はprocファイルを使用する「参照カウント」(彼はprocfs_openとprocfs_closeのコメントでそれに言及)
  • 何ですか?それは何もしないようです。
  • module_putとtry_module_getの機能は何ですか?私は遠隔からの説明をオンラインで見つけることはできません。
  • ユーザー空間からkernelWrite関数をどのようにトリガーしますか?私は実際にデータを受け取るだけでなく、実際にデータを転送する方法を知っています。

ここではコードです:

#define BUFFERLENGTH 256 
#define INCREASE_COUNTER 'I' 
#define SHOW_COUNTER 'S' 

#define PROC_ENTRY_FILENAME "kernelWrite" 

DECLARE_RWSEM(counter_sem); /* semaphore to protect counter access */ 

static struct proc_dir_entry *Our_Proc_File; 

int counter1 = 0; 
int counter2 = 0; 

/* displays the kernel table - for simplicity via printk */ 
void show_table (void) { 

    int tmp1; 
    int tmp2; 

    down_read (&counter_sem); /* lock for reading */ 
    tmp1 = counter1; 
    tmp2 = counter2; 
    up_read (&counter_sem); /* unlock reading */ 
    printk (KERN_INFO "kernelWrite:The counters are %d, %d\n", tmp1, tmp2); 

} 

void increase_counter (void) { 

    down_write (&counter_sem); /* lock for writing */ 
    counter1++; 
    counter2++; 
    up_write (&counter_sem); 

} 

/* This function reads in data from the user into the kernel */ 
ssize_t kernelWrite (struct file *file, const char __user *buffer, size_t count, loff_t *offset) { 


    char command; 

    printk (KERN_INFO "kernelWrite entered\n"); 


    if (get_user (command, buffer)) { 
    return -EFAULT; 
    } 

    switch (command) { 
    case INCREASE_COUNTER: 
    increase_counter(); 
    break; 
    case SHOW_COUNTER: 
    show_table(); 
     break; 
    default: 
     printk (KERN_INFO "kernelWrite: Illegal command \n"); 
    } 
    return count; 
} 



/* 
* The file is opened - we don't really care about 
* that, but it does mean we need to increment the 
* module's reference count. 
*/ 
int procfs_open(struct inode *inode, struct file *file) 
{ 
    printk (KERN_INFO "kernelWrite opened\n"); 
    try_module_get(THIS_MODULE); 
    return 0; 
} 

/* 
* The file is closed - again, interesting only because 
* of the reference count. 
*/ 
int procfs_close(struct inode *inode, struct file *file) 
{ 
    printk (KERN_INFO "kernelWrite closed\n"); 
    module_put(THIS_MODULE); 
    return 0;  /* success */ 
} 

const struct file_operations File_Ops_4_Our_Proc_File = { 
    .owner = THIS_MODULE, 
    .write = kernelWrite, 
    .open = procfs_open, 
    .release = procfs_close, 
}; 


int init_module(void) 
{ 



    /* create the /proc file */ 
    Our_Proc_File = proc_create_data (PROC_ENTRY_FILENAME, 0644, NULL, &File_Ops_4_Our_Proc_File, NULL); 

    /* check if the /proc file was created successfuly */ 
    if (Our_Proc_File == NULL){ 
    printk(KERN_ALERT "Error: Could not initialize /proc/%s\n", 
      PROC_ENTRY_FILENAME); 
    return -ENOMEM; 
    } 

    printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_FILENAME); 

    return 0; /* success */ 

} 

void cleanup_module(void) 
{ 

    remove_proc_entry(PROC_ENTRY_FILENAME, NULL); 
    printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_FILENAME); 

    printk(KERN_INFO "kernelWrite:Proc module unloaded.\n"); 

} 
+1

いくつかの質問は、それぞれ簡単にグーグルです。例えば。最初のもの:https://www.kernel.org/doc/htmldocs/kernel-hacking/routines-module-use-counters.html。 (リンクにも説明があり、モジュールの参照カウンタを使用するために**与えられたコード**が必要ないのはなぜですか?) – Tsyvarev

答えて

2

いくつかの質問に、いくつかの答え:

1モジュールの参照カウントとtry_module_getとmodule_put:それがある場合 各カーネルモジュールは、特に、使用回数を持っているが、他のモジュールによって参照されるか、または他の方法で使用されます。この場合、ファイルを開くときにモジュールが削除されないようにし、ファイルを閉じた後で参照を削除します。なぜ使用してはならないのですか?here

2 Procファイル: File_Ops_4_Our_Proc_File構造を使用してください。 procファイル(つまり、open、close、write)に対して適切なアクションをトリガーするには、ユーザー空間でアクションを実行する必要があります。

3トリガーアクション。 (bashのから)たとえば、次のように

文字 'I' は効果的 kernelWriteを呼び出し、 File_Ops_4_Our_Proc_File.writeをトリガー、procファイルへの書き込みを行う
echo 'I' > /proc/kernelWrite 

関連する問題