システムコールのオーバーヘッドを余分にかけずに、カーネルメモリをユーザースペースに公開したいと思います。これを行うためにmmapルートを選択しました。これがドライバーからのサンプルコードです。
int mmp_mmap(struct file *filp, struct vm_area_struct *vma)
{
struct page *page = NULL;
struct mmp * mpdev=NULL;
unsigned long pfn;
mpdev=filp->private_data;
vma->vm_flags |= VM_RESERVED|VM_IO;
/*
* Get the page corresponding to the buffer address
*/
page=virt_to_page(mpdev->buf);
pfn=page_to_pfn(page);
/*
* Now create a entry corresponding to this pfn in the page table.
*/
if (remap_pfn_range(vma,vma->vm_start,pfn,vma->vm_end-
vma->vm_start,vma->vm_page_prot)) {
printk(KERN_ERR "remap_pfn_range failed\n");
return -EAGAIN;
}
return 0;
}
問題は、ユーザースペースプログラムがこのデバイスを開き、メモリをmmapして変更すると、初めて正常に動作することです。その後のメモリのオープンとマッピングは、カーネルバッファを変更しません。ユーザーlandプログラムは、このmmapされたバッファーのマップ解除を明示的に実行します。