1

私はこれをカーネルモジュールに持っています:

/*global scope declared*/ 
static int array[10]={1,2,3,4,5,6,7,8,9,10};

そして、open close read と write の関数が完全に機能するのでarray[8]、このページの下部にあるユーザー空間アプリケーションと共有したいと思います。

カーネルモジュールで:

static int *my_mmap (struct file *filep, struct vm_area_struct *vma ) {

    if (remap_pfn_range(vma,
                vma->vm_start,
                virt_to_phys(array)>> PAGE_SHIFT,
                10,
                vma->vm_page_prot) < 0) {
        printk("remap_pfn_range failed\n");
        return -EIO;
    }


    return 0;

ユーザー空間のソース コード内のアプリケーション:

#define LEN (64*1024)
/* prototype for thread routine */

#define FILE_PATH "/dev/my_module"


int main() 
{
    int i=0;
    int fd = open(FILE_PATH,O_RDWR);    
    int* vadr = mmap(0, LEN, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

    for (i=0;i<10;++i){

        printf("%d",*(vadr+i));
    }

    return 0;
}
4

4 に答える 4

1

これは非常に多くのレベルで間違っており、どこから始めればよいかわかりません :-)

  1. virt_to_phys は vmalloc に割り当てられたメモリでは実際には機能しない可能性があります。これは、Linux がほとんどのプラットフォームで動的モジュール データ セクションに使用するメモリです。
  2. あったとしても、データは物理メモリ内でまったく連続していない可能性があります。
  3. 配列がページ境界に整列していない可能性があります。
  4. データ構造は 40 バイトで、ランダムなカーネル メモリの 10 ページをマッピングしています。
  5. プロセッサーに Virtual Indexed Physical Tag (VIPT) キャッシュがある場合、同じ物理アドレスへの複数の仮想マッピングがあると、キャッシュの一致性の問題が発生する可能性があります。

おそらくもっと問題があるでしょうが、これが頭に浮かぶものです。

正しいことは、カーネルとユーザー空間の間でデータを共有するのではなく、copy_to_user とその友達を使用してデータをコピーすることです。ただし、自分が何をしているのか、その理由が本当にわかっている場合を除きます。

本当にメモリを共有する必要がある場合は、空きページを割り当て、カーネル空間 (kmap など) とユーザー空間 (あなたが行ったように) からマップし、プラットフォームに VIPT キャッシュがないことを願っています。

于 2012-08-09T08:28:04.473 に答える
0

配列はcharの配列ですが、ユーザー空間プログラムはintの配列としてアクセスしています。

于 2012-08-09T03:51:03.737 に答える
0

私はカーネルプログラミングに比較的慣れていないので、何かが欠けているかもしれませんが、この場合 copy_to_user を使用することはできませんか?

    unsigned long copy_to_user(void __user * to, const void * from, unsigned long n); 

簡単に言えば

to = address in userspace (destination)
from = address in kernel (source)
n = number of bytes to copy 
于 2012-08-08T20:01:06.823 に答える