ファイルで詳しく説明されている手順を使用して、/proc/{pid}/pagemap ファイルを使用して、ヒープ変数、スタック変数、およびメモリにマップされたペリフェラルアドレスの物理アドレスを見つけようとします。http://lxr.free-electrons.com/source/Documentation/vm/pagemap.txt。スタック変数とヒープ変数には詳細な手順が適用されます。ただし、メモリマップされた周辺機器の場合は、/proc/{pid}/pagemap ファイルにページが見つかりません。 'cat /proc/{pid}/maps' の出力は次のようになります。
00008000-0000a000 r-xp 00000000 b3:02 289852 /home/linaro/ocm_test/write-memory
00011000-00012000 r--p 00001000 b3:02 289852 /home/linaro/ocm_test/write-memory
00012000-00013000 rw-p 00002000 b3:02 289852 /home/linaro/ocm_test/write-memory
00013000-00034000 rw-p 00000000 00:00 0 [heap]
b2efe000-b6dfe000 rw-s 00001000 b3:02 284849 /dev/uio0
b6dfe000-b6ed2000 r-xp 00000000 b3:02 282416 /lib/arm-linux-gnueabihf/libc-2.15.so
b6ed2000-b6eda000 ---p 000d4000 b3:02 282416 /lib/arm-linux-gnueabihf/libc-2.15.so
b6eda000-b6edc000 r--p 000d4000 b3:02 282416 /lib/arm-linux-gnueabihf/libc-2.15.so
b6edc000-b6edd000 rw-p 000d6000 b3:02 282416 /lib/arm-linux-gnueabihf/libc-2.15.so
b6edd000-b6ee0000 rw-p 00000000 00:00 0
b6ee0000-b6ee2000 r-xp 00000000 b3:02 27519 /usr/lib/libinterface.so
b6ee2000-b6ee9000 ---p 00002000 b3:02 27519 /usr/lib/libinterface.so
b6ee9000-b6eea000 r--p 00001000 b3:02 27519 /usr/lib/libinterface.so
b6eea000-b6eeb000 rw-p 00002000 b3:02 27519 /usr/lib/libinterface.so
b6efb000-b6f12000 r-xp 00000000 b3:02 282407 /lib/arm-linux-gnueabihf/ld-2.15.so
b6f13000-b6f14000 rw-p 00000000 00:00 0
b6f14000-b6f15000 rw-s 00000000 b3:02 284849 /dev/uio0
b6f15000-b6f19000 rw-p 00000000 00:00 0
b6f19000-b6f1a000 r--p 00016000 b3:02 282407 /lib/arm-linux-gnueabihf/ld-2.15.so
b6f1a000-b6f1b000 rw-p 00017000 b3:02 282407 /lib/arm-linux-gnueabihf/ld-2.15.so
bee36000-bee57000 rw-p 00000000 00:00 0 [stack]
bef1f000-bef20000 r-xp 00000000 00:00 0 [sigpage]
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
0x00013000または0xbee36000の物理アドレスを見つけようとすると、正常に動作します。ところで、/dev/uio0に属する0xb2efe000に対応する物理アドレスを見つけようとすると、ページマップファイルからPage Not Foundを返します。検証目的でこれを実行しようとしています。私は0x1b90000でmmapを使って0xb2efe000を見つけたので、物理アドレスが存在することを知っています。 /proc/{pid}/pagemapファイルに物理アドレスが含まれていない理由を誰かが説明できますか?
答え1
短い答え:ページマッピングインタフェースは、アドレスに関連する構造ページに格納された情報を公開します。 I / Oアドレスは、関連する構造ページを持たないraw pfnマップであるため、露出は0です。
より長い答え
物理アドレス(I / Oアドレスを含む)をユーザースペースに再マップすることは、呼び出しによって行われますremap_pfn_range
。これらの再マップされたアドレスは何もstruct page
接続されません(元のpfnマッピングです)。これらのアドレスは特別で、この関数はVM_PFNMAP
これをvmaに設定することに注意してください。
ページマッピングインタフェースは、一連のstruct page
アドレス関連フィールドを公開する。しかし、このアドレスにはそのような構造はありません。したがって、ページマップはただスキップされます。
ページマッピングを使用すると、カーネルはページナビゲーションを実行するために使用されますwalk_page_range
。 vmas 表示はVM_PFNMAP
異なって処理されます。
/*
* vma(VM_PFNMAP) doesn't have any valid struct pages behind VM_PFNMAP
* range, so we don't walk over it as we do for normal vmas. However,
* Some callers are interested in handling hole range and they don't
* want to just ignore any single address range. Such users certainly
* define their ->pte_hole() callbacks, so let's delegate them to handle
* vma(VM_PFNMAP).
*/
ページマップの pte_hole には 0 個のエントリしか含まれません(いくつかの追加フラグをモジュールとしてVM_SOFTDIRTY
)。だから見ることができないのです…
私はマッピングされた物理アドレスを取得できるカーネルインターフェイスを知りません。しかし、カーネルモジュールを使用するかcrash
、 。