kmallocで割り当てられたバッファをユーザ空間で処理する正しい方法はどれですか?たぶん私はまだメモリマッピングを理解できませんでした...このバッファ(たとえば120バイト)を割り当てるカーネルモジュールを作成し、ユーザー空間プロセスで読み書きします。明らかに、私は文字デバイスを作成し、file_operations
構造体にmmap
メソッドを実装しました。私の方法がある:mmap:ユーザ空間でのマッピングkmallocで割り当てられたカーネルバッファ
mem_area
点は、モジュールのinitで
kmalloc
が割り当て
static int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
//printk(KERN_INFO "Allocated virtual memory length = %d", vma->vm_end - vma->vm_start);
long unsigned int size = vma->vm_end - vma->vm_start;
if (remap_pfn_range(vma, vma->vm_start,
__pa(mem_area) >> PAGE_SHIFT, //what about vma->vm_pgoff?
size,
vma->vm_page_prot) < 0)
return -EAGAIN;
vma->vm_flags |= VM_LOCKED;
vma->vm_ops = &vmops;
vma->vm_flags |= VM_RESERVED;
my_vm_open(vma);
return 0;
}
。領域は同じ値で埋められます(たとえば0x10)。すべての作品が、私はこのコードで何かが間違っていると思う:
kmalloc
がページ揃えではないポインタを返すことができそして、その場合には、私は三番目のパラメータの値が正しいとは思いません実際にはユーザー空間で私は間違った値を読み取ったremap_pfn_range
の。代わりにすべてが私が__get_free_page
を使用する場合(関数が常にページを揃えたポインタを返すため)、またはkmalloc
がページを揃えたポインタを返す場合にはすべて機能します。メモリマッピングはPAGE_SIZE
の倍数であるメモリ領域で動作するので、kmalloc
ではなくページ全体を割り当てる必要がありますか?my_mmap
が呼び出されると、カーネルはまだいくつかのページを割り当てていますか?私はカスタムmmap
メソッドのいくつかの実装を発見したのでこれを尋ねますvma->vm_pgoff
とremap_pfn_range
を呼び出すメソッドは3番目のパラメータとして...どのように有用なことができますか?これは最初に割り当てられた新しいページのページフレームですか?私がmy_mmap
で行うようなページフレームを3番目のパラメータとして渡すと、ページから始まるvma->vm_pgoff
のページを解放する必要がありますか?しかし、
kmalloc
で割り当てられたバッファをマップするmmap
メソッドの実装が見つかりました。バッファを正しくマップするには、remap_pfn_range
より前に操作(私が今のところundestandしていない)を実行します。mem_area
、mem
はkmalloc
によって返されたポインタであると仮定し、この方法で初期化されます:mem_area=(int *)(((unsigned long)mem + PAGE_SIZE - 1) & PAGE_MASK);
のでmem_area
がmem
の同じ値が含まれていmem
がそう整列ページである場合にのみ、IS先頭にポインタが含まれている必要があります次のページのしかし、この操作で、remap_pfn_range
の3番目のパラメータとして渡すと、値__pa(mem_area) >> PAGE_SHIFT
のマッピングがうまく機能します。どうして?
ありがとうございました!
私は同様の質問がありますが、ブートパラメータ 'mmap'を使用しています:http://stackoverflow.com/q/12790382/143897?あなたの発見のいくつかを提供できますか?ありがとう。 –
ここでvm_operations_struct.faultにページフォールトハンドラは必要ありませんか? –
最小限の実行可能な例:https://stackoverflow.com/questions/10760479/how-to-mmap-a-linux-kernel-buffer-to-user-space/45645732#45645732 –