0

特定の物理アドレスを特定の仮想アドレスにマップする必要がある Linux カーネル モジュールを作成していますが、それを行う方法が見つかりません。

4

2 に答える 2

2

OK、これが私の現在の解決策です。にマップphys_addrするには、次のvirt_addrコードを使用します。

page = pfn_to_page(virt_addr >> PAGE_SHIFT);
pte = get_locked_pte(&init_mm, phys_addr, &ptl);
set_pte_at(&init_mm, phys_addr, pte, mk_pte(page, VM_READ | VM_WRITE | VM_EXEC));
spin_unlock(ptl);
flush_tlb_all();

いくつかの説明: pfn_to_pagefunc を使用して、 my に対応するページ構造体を取得しますvirt_addr。必要な物理アドレスと初期化されていないスピンロック ( )を必要とする func を使用して、ページ テーブル エントリ ( pte)を取得します。次に、 func とマクロを使用して実際にページをマップし、スピンロックのロックを解除して、tlb キャッシュをフラッシュします。get_locked_ptepteptlset_pte_atmk_pte

このソリューションは、コンテキストの切り替えには耐えられませんが、かなりうまく機能しているようです。

于 2013-04-02T07:48:13.073 に答える
0

使用しているカーネルのバージョンと CPU アーキテクチャ/タイプを教えてください。一般的に言えば、マッピング先の特定の仮想アドレスがカーネル仮想アドレス (0xC0000000 など) と重複しない場合、およびデバイスが使用している物理アドレスがシステム メモリの物理アドレス範囲と重複しない場合は、以下を使用できます。低レベル関数 (存在しない場合は、アセンブル言語を使用して、カーネルの起動中に直接 MMU TLB エントリを設定できます) を使用して、カーネルの起動中に特定のアドレスを特定の仮想アドレスにマップするように MMU TLB エントリを設定します。2.6.10 カーネル バージョンと Freescale PowerPC CPU に基づく 1 つの例を提供できます。必要なことを行う関数 io_block_mapping があります。

于 2013-03-21T10:36:11.483 に答える