struct page *リストを取得して記述子テーブルを作成し、デバイスとメモリを共有する既存のコードがあります。そのコードの上位層は現在、ユーザー空間と一緒に、vmallocまたはユーザー空間から割り当てられたバッファーを期待しvmalloc_to_pageており、対応するstruct page *.
上位層は、 を介して取得したメモリだけでなく、あらゆる種類のメモリに対処する必要がありますvmalloc。これは、 で取得されたバッファkmalloc、カーネル スレッドのスタック内のポインタ、または私が認識していないその他のケースである可能性があります。私が持っている唯一の保証は、この上位層の呼び出し元が、問題のメモリ バッファがその時点でカーネル空間にマップされていることを確認する必要があることです (つまり、この時点buffer[i]ですべてにアクセスすることが有効です)。任意のポインタに対応するを取得するにはどうすればよいですか?0<=i<sizestruct page*
疑似コードに入れると、次のようになります。
lower_layer(struct page*);
upper_layer(void *buffer, size_t size) {
for (addr = buffer & PAGE_MASK; addr <= buffer + size; addr += PAGE_SIZE) {
struct page *pg = vmalloc_to_page(addr);
lower_layer(pg);
}
}
upper_layerそして、有効なバッファに対処するために変更する必要があります(変更せずにlower_layer)。
私はvirt_to_page、Linux デバイス ドライバーが「論理アドレス、vmallocまたはハイ メモリからのメモリではなく」で動作することを示していることを発見しました。さらに、is_vmalloc_addrアドレスが から来ているかどうかvmallocをvirt_addr_validテストし、アドレスが有効な仮想アドレスであるかどうかをテストします ( の飼料virt_to_page; これにはkmalloc(GFP_KERNEL)と カーネル スタックが含まれます)。他のケースについてはどうですか: グローバル バッファ、ハイ メモリ (今のところ無視できますが、いつか来るでしょう)、おそらく私が気付いていない他の種類ですか? したがって、質問を次のように再定式化できます。
- カーネル内のすべての種類のメモリ ゾーンとは?
- どうすればそれらを区別できますか?
- それぞれのページ マッピング情報を取得するにはどうすればよいですか?
問題がある場合、コードは ARM (MMU を使用) で実行されており、カーネルのバージョンは少なくとも 2.6.26 です。