2

ユーザースペースメモリからカーネルモジュールの関数にポインタを渡したいのですが。使いたくないcopy_from_userget_user_pages関数を使うべきだと読みました。

たとえば、1ページ。

struct page **pages;
pages = kmalloc(1 * sizeof(*pages), GFP_KERNEL);

down_read(&current->mm->mmap_sem);
get_user_pages(current,current->mm,uaddr, 1, 1, 0,pages,NULL);
up_read(&current->mm->mmap_sem);

uaddrユーザースペースのアドレスです。

  1. uaddrこれを行った後、カーネルモジュール関数をキャストして渡すことはできますか?それとも私はこれらstruct pagesを何らかの方法で使用する必要がありますか?
  2. なぜダウン/アップリードを使用する必要があるのですか?
  3. すべての後、私は使用SetPageDirty()してpage_cache_release()機能する必要がありますか?
4

4 に答える 4

3
  1. いいえ、uaddrを介してユーザースペースページに直接アクセスすることはできません。カーネルがユーザースペースページに対応する物理ページにアクセスできるように、構造体ページに入力します。また、それらが連続している可能性はほとんどないため、uaddrの先頭から配列に正しいページインデックスを使用するように注意する必要があることにも注意してください。
  2. このプロセスのページマッピング構造を変更するため、カーネルでページマッピングを設定する間、それらを保護する必要があります。
  3. get_user_pages()によって設定されたマッピングが完了したら、参照されている関数によってそれらを「解放」する必要があります。
于 2011-03-03T03:36:56.780 に答える
2

ユーザー ページは、ユーザー空間メモリへの Scatter/Gather DMA の設定など、ページ タイプのアクティビティにのみ使用できます。これを使用して、カーネル モード コードからユーザー空間に直接アクセスすることはできません。したがって、そのための copy_to/from 関数があります。大量のデータを移動しない限り、これらの関数を使用しないのはなぜですか?

于 2009-12-08T15:33:23.717 に答える
2

これは目的ではありません(いいえ、キャストしてカーネルモジュール関数にget_user_pages渡すことはできません)。uaddr

呼び出し元の関数で呼び出したくない場合は、 aをモジュール関数にcopy_from_user渡し、.void __user *copy_from_user

于 2009-12-07T23:01:02.870 に答える
0

有効なユーザー空間アドレスを取得したら、get_user_pages を使用して構造体ページ ポインターを取得します。構造体ページ ポインターを受け取ったら、カーネル モードでアクセスするには、kmap を使用してカーネル仮想アドレスにマップする必要があります。それが役立つことを願っています

于 2013-06-21T16:11:17.177 に答える