Linuxマシンでは、ドライバを作成しようとして、パフォーマンス向上のためにカーネルメモリをアプリケーションにマッピングしようとしました。 mmapオンラインのドライバ実装を確認し、さまざまな実装を見つけます。 manページごとに、mmap - 呼び出しプロセスの仮想アドレス空間に新しいマッピングを作成します。Linuxプラットフォームでのmmapクエリ
1)誰がmmap呼び出し中に物理アドレス空間を割り当てますか?カーネルまたはデバイスドライバ?
ドライバmmap実装の次の種類が表示されます。
a)ドライバは、連続した物理的なカーネルメモリを作成し、それをプロセスアドレス空間にマップします。
static int driver_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start;
pos = kmalloc(size); //allocate contiguous physical memory.
while (size > 0) {
unsigned long pfn;
pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT; // Get Page frame number
if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) // creates mapping
return -EAGAIN;
start += PAGE_SIZE;
pos += PAGE_SIZE;
size -= PAGE_SIZE;
}
}
b)ドライバは仮想カーネルメモリを作成し、プロセスアドレス空間にマップします。
static struct vm_operations_struct dr_vm_ops = {
.open = dr_vma_open,
.close = dr_vma_close,
};
static int driver_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long size = vma->vm_end - vma->vm_start;
void *kp = vmalloc(size);
unsigned long up;
for (up = vma->vm_start; up < vma->vm_end; up += PAGE_SIZE) {
struct page *page = vmalloc_to_page(kp); //Finding physical page from virtual address
err = vm_insert_page(vma, up, page); //How is it different from remap_pfn_range?
if (err)
break;
kp += PAGE_SIZE;
}
vma->vm_ops = &dr_vm_ops;
ps_vma_open(vma);
}
c)この場合、誰がメモリを割り当てるかわからない。
static int driver_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) // creates mapping
return -EAGAIN;
}
2)カーネルはmmapのためにメモリを割り当てる場合は、& Bの場合には無駄なメモリがないですか?
3)remap_pfn_rangeは、複数のページをマップするためのもので、vm_insert_pageは単一ページマッピングのためのものです。これらの2つのAPIで唯一の違いはありますか?
ありがとう、
Gopinath。
詳細な返信はThanxハミルトンです。 – Gopinath