5

デバイスメモリのページフレーム番号はどのように決定しますか? LDD3/Ch.から 15/ セクション「remap_pfn_range の使用」および「簡単な実装」では、pfn は vm_pgoff フィールドと同一視されています。私はこれに混乱しています。どうしてそうなるの?

vm_pgoff は次のように記述されていることに注意してください。

ファイル内の領域のオフセット (ページ単位)。ファイルまたはデバイスがマップされている場合、これはこの領域にマップされた最初のページのファイル位置です。

したがって、マップされた最初のページがファイルの最初のページにも対応する場合 (これは非常に一般的だと思います)、vm_pgoff は 0 になります。正しいですか? もしそうなら、これは remap_pfn_range( ) の pfn パラメータの正しい値ではないようです。ここで何が欠けていますか?正しい値は? 参照しやすいように、以下の LDD3 から関連するコードを再掲します (ページ番号 426)。

static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma)
{
if (remap_pfn_range(vma, vma->vm_start, vm->vm_pgoff,
                    vma->vm_end - vma->vm_start,
                    vma->vm_page_prot))
    return -EAGAIN;
...
}
4

1 に答える 1

5

ベンク、私はただの初心者です。私はあなたの質問に非常に興味があり、Linux デバイス ドライバーで指摘された部分も読みました。

もう 1 つお勧めしたい本があります。Professional Linux kernel architecture です。そこでは、mmap に関する詳細が説明されています。

上記の本の中から、Linux カーネル ソース コードには存在しない例として関数 simple_remap_mmap() を呼び出す前に、vm->vm_pgoff への変換がいくつかあるようです。

そのため、vm_pgoff が 0 であっても、何らかの変換を行った後、そのメンバー変数 vm_pgoff に正しい値が存在する可能性があります。

以下のコードは、Linux カーネル ソース コード 3.3.5 に含まれています。

#ifdef CONFIG_DEVKMEM

static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
{

    unsigned long pfn;

    /* Turn a kernel-virtual address into a physical page frame */

    pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;   <----- Here

    /*
     * RED-PEN: on some architectures there is more mapped memory than
     * available in mem_map which pfn_valid checks for. Perhaps should add a
     * new macro here.
     *
     * RED-PEN: vmalloc is not supported right now.
     */
    if (!pfn_valid(pfn))
        return -EIO;

    vma->vm_pgoff = pfn;
    return mmap_mem(file, vma);
}
#endif
于 2012-07-17T09:02:36.243 に答える