2016-12-27 11 views
1

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。

答えて

2

どちらを使用するかは、達成しようとしていることによって異なります。

(1)デバイスドライバは、のカーネルの部分であり、そのように区別するのは実際には意味がありません。これらの場合、デバイスドライバは、カーネル全体で使用可能な(物理的な)メモリリソースから、それ自身の使用のために割り当てられるメモリを要求しています。

(a)では、物理的に連続した領域が割り当てられています。メモリを読み書きする外部ハードウェア(PCIデバイスなど)がある場合にこれを行うことができます。 kmallocの戻り値はすでにカーネルの仮想アドレス空間へのマッピングを持っています。 remap_pfn_rangeは、ページを現在のプロセスのユーザー仮想アドレス空間にもマップするために使用されています。

(b)については、は実質的に連続スペースが割り当てられています。外部ハードウェアが関与していない場合は、これが通常使用する方法です。物理メモリがまだドライバに割り当てられていますが、ページが物理的には連続していることが保証されていないため、割り当てることのできるページの制約が少なくなります。 (それらはまだカーネルアドレス空間の仮想の連続しています。)そして、あなたは単に異なるAPIを使って、ユーザーの仮想アドレス空間に同じ種類のマッピングを実装しています。

(c)の場合、マッピングされるメモリは、他のサブシステムの制御下で割り当てられます。 vm_pgoffフィールドは、すでにリソースの基本物理アドレスに設定されています。たとえば、メモリはPCIデバイスのアドレス領域(ネットワークインタフェースコントローラのレジスタ)に対応しています。その物理アドレスはBIOS(またはマシンが使用するどのようなメカニズム)によって決定/割り当てられます。

(2)わかりません。私はこの質問を理解しています。デバイスドライバと協力するユーザプロセスがメモリを使用している場合、メモリをどのように「無駄にする」ことができますか?カーネルがメモリを読み書きする必要がある場合は、カーネルの仮想アドレス空間が割り当てられていなければなりません。また、カーネルの仮想アドレス空間は、基本となる物理メモリにマップする必要があります。同様に、ユーザ空間プロセスがメモリにアクセスする場合、ユーザ仮想アドレス空間が割り当てられ、であり、も物理メモリにマッピングされなければならない。

「仮想アドレス空間の割り当て」とは、本質的にメモリ用のページテーブルエントリの割り当てを意味します。これは物理メモリを実際に割り当てることとは別に行われます。そしてそれはカーネル空間とユーザ空間のために別々に行われます。また、「マッピング」とは、ページテーブルエントリ(ページの先頭の仮想アドレス)を正しい物理ページアドレスを指すように設定することを意味します。

(3)はい。彼らは、同じことを達成する異なるAPIです。場合によってはstruct page、時にはpfnがあります。紛らわしいことがあります。同じことを達成するには、しばしばいくつかの方法があります。開発者は通常、すでに持っているアイテム(「既にstruct pageがあります。pfnを計算することができますが、struct pageを受け入れるこの他のAPIがある場合はどうしますか」)を使用します。

+0

詳細な返信はThanxハミルトンです。 – Gopinath

関連する問題