カーネルメモリの割り当てを[ターン]:kmallocの、vmalloc、kzalloc、kcalloc、get_free_pagesを

転送します。https://www.cnblogs.com/yfz0/p/5829443.html

メモリの割り当てのためのカーネルモジュールは、特別なカーネルのAPIを使用する必要がありますkmallocの、vmalloc、kzalloc、 kcalloc、get_free_pagesを、 当然のことながら、デバイスドライバも例外ではありません。
MMU機能プロセッサを提供するため、Linuxは、複雑なを提供していますプロセスは、アドレス空間の4GBまでアクセスできるようにメモリ管理システムは、到達することができ、二つの部分に分割された4GBの空間:領域0ギガバイト〜3ギガバイト使用されるプロセス(PAGE_OFFSETは、x86の値0xC0000000です)ユーザ空間領域が3ギガバイト〜4GBのカーネル空間を使用され、
カーネル空間では、メモリマップされた領域への物理vmalloc_start 3ギガバイトの間の領域から、このアドレスを使用して、内側領域は、コアセグメントマップイメージ、物理ページフレームを含みます物理メモリマップされた領域の後、仮想メモリvmalloc領域です;テーブルmem_mapなど、例えば、我々は、システムの物理メモリを使用するには、160メガバイトが、その後、3ギガバイト〜3ギガバイト+ vmalloc_start物理メモリをマッピングする必要があるとの間の領域である160メガバイトのためにシステムの場合、位置は、物理メモリマップされた領域との間vmalloc_start 8M Gの位置がある(vmalloc_start 3ギガバイト+ 160メガバイトの位置の近傍にあるべきです )クロスボーダーを防ぐために、AP、vmalloc_end位置に近い4GBの位置(領域サイズは、最後の位置に特定のページマッピング128キロバイトに保持されます);
、kmallocの
書式#include <Linuxの/ slab.h>
静的インライン無効* kmallocの(size_tのサイズ、gfp_tフラグ);
パラメータ:サイズ:ブロックのサイズはバイト単位で割り当てられる指定し、フラグを:指定された制御モードメモリの割り当てと、
この関数は、カーネルのメモリ空間を割り当てるために使用され、それが返されます速度(ブロックされた場合を除く)、および任意の初期化(クリア)動作せず、そのメモリの割り当て、割り当てられたメモリ領域は、まだ彼の元のコンテンツを保持しています。
kmallocのアプリケーションが、物理メモリマップ領域に位置する物理メモリを、得るが、物理アドレスに連続した;しかしながら、メモリアドレスは、仮想アドレス(リニアアドレス)である戻りkmallocの、仮想アドレス(リニアアドレス)トランザクションを返します従って、最初のアプリケーションの仮想アドレスとの間の比較的単純な変換は、メモリのkmallocの物理アドレスは、その戻りのブロックが存在である;物理アドレスとの間の唯一の固定のオフセット値を異なるカーネル(によって提供virt_to_phys機能)実装することができます実際のカーネル物理アドレスへの仮想アドレス間の変換:
の#define __pa(X)((unsigned long型)(X)-PAGE_OFFSET)
静的インライン符号なしのロングvirt_to_phys(揮発性ボイド*アドレス)
{
 __pa(アドレス)を返します;
}
アドレスが返された仮想アドレスパラメータkmallocのある、変換プロセスは、仮想アドレスマイナス3ギガバイト(PAGE_OFFSET = 0xC0000000)である。
一般に、PAGE_OFFSET = 3 * 1024 * 1024 * 1024 = 0xC0000000(3G);
機能それに対応されます物理アドレスのカーネルに仮想アドレスを変換するためのphys_to_virt():
の#define __va(X)((void *型)((unsigned long型)(X)+ PAGE_OFFSET))
静的インライン * phys_to_virtボイド(unsigned long型アドレス)
{
 __va(アドレス)を返します;
}
これら二つの機能はに含める/ ASM-I386 / io.hで定義されている;
kmallocの()関数が小さなメモリメモリを適用するために使用され、最小のアプリケーションは、32バイトまたは64バイトとすることができ、適用することができる最大メモリ128キロバイト-16、ページ記述構造を格納するための16のバイトを減算し、それらは、アーキテクチャで使用されるページ・サイズに依存している; kmallocのメモリアプリケーションが物理アドレスに連続している、それはのためにあるべきですDMA転送装置は、非常に重要である;
kmallocの()メモリ割り当て機構がスラブに基づいて実装され、スラブ機構は、割り当てられた小さなメモリを提供するための効率的な機構であり、スラブ機構が独立していないが、それそれは、ページのページアロケータ最小単位、kmallocの(システムの第1の連続物理アドレスである)、次いで、これに基づいて、ページ自体に基づいて、発呼者によって使用される、よりきめの細かいメモリの分配を分割され発信者セグメンテーションのための必要性、また、仮想アドレスと物理アドレス(リニアアドレス/論理アドレス)にメモリを割り当てるためスラブ機構は連続している、
メモリkmallocのための()アプリケーション、使用kfree()解放する機能 ;
備考:; kmallocの機構はベーススラブ実装されている
2つのget_free_pages
の#include <ASM / pages.h>
fastcall、符号なしのロング__get_free_pages(gfp_tのgfp_mask、unsigned int型のオーダー)
{
 構造体のページのページ*、
 ページalloc_pages =(gfp_mask、オーダー)。
 IF(ページ!)
  の戻り0;
 戻り値(符号なしロング)page_address(ページ)。
}
パラメータgfp_mask制御モードは、メモリアプリケーション用に指定されたページの数を指定するアプリケーションのためであり、それは、アプリケーションメモリ(PAGE_OFFSET、HIGH_MEMORY)に位置している間、
__get_free_pages()関数は、ページ配信発信者の底部に設けられています。アプリケーションは、連続した物理メモリであるメモリ割り当て機能、メモリは、物理メモリマップ領域に位置し、それはバディメカニズムベースの実装であり、物理メモリ管理システムを達成するために、バディ・メカニズムを使用して、最小の割り当ての粒度(単位)でありますalloc_pages()を呼び出すことによって、物理メモリページを割り当てる内部)(中__get_free_pages;ページ単位で
物理メモリが連続して割り当てる__get_free_page()関数を、連続プロセスは、物理アドレスであるが、(仮想アドレスを返しますリニアアドレス);あなたは適切な物理アドレスを取得したい場合にも必要とされてvirt_to_physは()に切り替えることができ
、解放する__free_pages()関数の使用を必要とし、)(メモリ__get_free_pages用アプリケーションの機能を
__ get_free_pages機構がバディに基づいています注意してください実装;
3、vmalloc
の#include <Linuxの/ vmalloc.h>
void *型vmalloc(unsigned long型のサイズ)
{
 戻り__vmall OC(サイズ、GFP_KERNEL | __GFP_HIGHMEM、PAGE_KERNEL);
}
ボイド* __vmalloc(unsigned long型サイズ、gfp_t gfp_mask、pgprot_t Protの)
{
 戻り__vmalloc_node(サイズ、gfp_mask、PROT、-1)。
}
ボイド* __vmalloc_node(unsigned long型サイズ、gfp_t gfp_mask、pgprot_t PROT、INTノード)
{
 構造体vm_struct *エリア;
 サイズ= PAGE_ALIGN(サイズ)。
 もし(サイズ||(サイズ>> PAGE_SHIFT)> num_physpages!)
   戻りNULL;
 面積= get_vm_area_node(サイズ、VM_ALLOC、ノード)。
 (!エリア)であれば
   、戻りNULL;
 __vmalloc_area_node(面積、gfp_mask、PROT、ノード)を返します。
}
ボイド* __vmalloc_area_node(構造体vm_struct *エリア、gfp_t gfp_mask、pgprot_t PROT、INTノード)。
ボイド* __vmalloc_area(構造体vm_struct *エリア、gfp_t gfp_mask、pgprot_t PROT)
{
 戻り__vmalloc_area_node(面積、gfp_mask、PROT、-1)。
}
vmalloc()関数は、メモリ用途に使用されているが、その適用はVMALLOC_END間の仮想メモリvmalloc_startにメモリに配置され、仮想アドレス(リニアアドレス/論理アドレス)へのアプリケーションのメモリが連続的であるが、必須ではありません連続した物理アドレスではなく、戻りアドレスと簡単な変換関係の物理アドレスと、
vmalloc()関数は、大容量メモリのアプリケーション環境で動作し、アプリケーションが、メモリは直接そのDMA転送に使用することができない、DMA転送のため、連続したメモリブロックの物理アドレスを必要とする
メモリvmalloc()アプリケーションのために、放出するvfree()関数を使用し;
注:実施vmalloc基づいスラブ機構;
IV比較
1).kmalloc / __ get_free_pages割り当てられたメモリブロック物理メモリマッピング領域で、すなわち(PAGE_OFFSET、hIGH_MEMORY)との間に、処理は、物理アドレス、物理アドレス空間内で連続であることが保証され、必要に応じて両方の仮想アドレスが正しい物理アドレスを取得するために、返され必要virt_to_phys()変換が、kmallocのとvmallocバイトが適用される、と__get_free_pages()は、単一のページに基づいています ;適用
仮想メモリとの間(VMALLOC_START、VMALLOC_END)すなわち、2)仮想メモリマッピング領域のメモリブロック.vmalloc機能が配置されて処理され、仮想アドレス空間が連続していることを保証するために、しかし、物理アドレススペース要件は、連続していない。フェア交換領域、メモリ使用量モジュール;
3)スラブvmallocの.kmallocと実装機構を基に、より高速kmallocのvmalloc速度よりれ、__ get_free_pages機構は、バディに基づいて実施され、速度より速く、
4)一般的に、メモリブロックサイズがアプリケーション(32/64バイト、128キロバイト-16)の間とすることができる、アプリケーションのための小さなメモリを.kmallocとメモリのvmalloc割り当てられたチャンクは、ケースに使用することができます。
5)それはアプリケーションのDMA転送に直接使用することができるように、物理アドレス空間における.kmallocアプリケーションメモリブロックは、メモリの連続ブロックであるメモリの連続ブロックが、アプリケーションvmallocの仮想アドレス空間内の物理アドレス空間を必要としません連続したメモリのブロックアプリケーションは直接DMA転送に使用できないように;
6)メモリブロック.kmalloc kfreeリリースアプリケーションと、アプリケーションとvfree放出vmallocメモリブロック; __free_pagesと__ get_free_pagesアプリケーションメモリページ;
7).kmallocアプリケーションがカーネルアドレス論理アドレスと呼ばれ、アプリケーションのアドレスが呼ぶvmallocカーネル仮想アドレスである。
V.他の機能
1).STATICインラインボイド* kzalloc( size_tのサイズ、gfp_tフラグ);
 この関数は、特徴kmallocのよりも大きいです得られたメモリブロックを初期化するアプリケーションは、0である;
2).STATIC kcallocインラインボイド*(N-size_tの、size_tのサイズ、フラグをgfp_t)
   {
     IF(N-サイズ= 0 &&> ULONG_MAXが)/ N-ある!
        NULLを返す;
     (戻りkzalloc n個の*サイズ、フラグ);
   }
   この関数は、メモリアレイを適用するために使用され、そして得られたメモリを0に初期化される適用し;
6、GFPマーカー
kmallocの、kzalloc、kcalloc、vmalloc、 get_free_pagesのメモリ制御用のメモリ割り当てを制御する場合、このフラグは使用され、コールがgfp_t型制御フラグのフラグを有する機能する#include <リナックス/ gfp.h>
で標識されたGFP ;二重のアンダースコアの接頭辞を持つと、二重アンダースコアの接頭辞なし:2つの方法で
:ダブルアンダースコアの接頭辞なしのGFPサイン
GFP_ATOMIC:コンテキストとメモリを割り当てるプロセスのコンテキストの外で他のコードのために中断、眠ることはありません。
GFP_KERNEL:カーネルメモリを適切に割り当てる;眠ること
GFP_USER:;;寝てメモリ空間を割り当てるユーザー用のページを
GFP_USERとして、それが高いメモリから適用することです。:GFP_HIGHUSER
GFP_NOIOとGFP_NOFS:GFP_KERNELとしての機能が、タリアが制限数を増やすためにカーネルは、要求を満たすために行うことができます。タリアは、主にファイルシステムと仮想メモリのコードが配布睡眠を許可しますが、再帰的に使用されます。GFP_NOFS割り当ては任意のファイルシステム呼び出し、およびGFP_NOIOの割り当ては任意のIO初期化を許可しなかったことはできません。ファイルシステムコールは悪い考えです。
ダブルアンダースコアの接頭辞を持つGFPフラグ:
__GFP_DMA:この DMAの可能な割り当てられたメモリのメモリ領域を必要なフラグ、プラットフォーム依存;
__GFP_HIGHMEM:このフラグは、割り当てられたメモリは、上位メモリ領域に配置することができる示し、プラットフォーム依存;
__GFP_COLD:通常は、メモリアロケータに戻りしようと「熱いバッファー」プロセッサーバッファページで見つけることがありますページ---;逆に、このフラグが「冷たい」ページを要求する---ページがいくつかの時間のために使用されていない。それは、アロケーション・ページを読んでDMAを行う必要があり便利です、このプロセッサがバッファに無用である場合に発生します。
__GFP_NOWARN:このフラグ停止割当要求を満たすことができない場合、カーネルの警告のためにメモリを割り当てる。
__GFP_HIGH:このフラグは、優先度の高い要求を識別し、最後のメモリ緊急事態のために予約もカーネルを消費することが許可されページ;
__GFP_REPEAT:運動のディストリビューター;ディスペンサーは、「試してみてみてください」を繰り返し試みの方法により、時に割り当て要求を満たすことは困難ですが、配信動作は、まだ失敗する可能性があります。
__GFP_NOFAIL:アクションディスペンサー、ディスペンサーを満たすことが困難であるときとき割り当て要求は、このフラグは失敗しない、割り当て要求を満たすために最善を尽くしていない代理店に指示します。
__GFP_NORETRY:アクションの販売代理店、ディスペンサーは、割り当て要求を満たすことは困難であるとき、このフラグは、すぐにあきらめて販売店に伝え、もはやいずれかを実行します。試み、
一つ以上のバンドまたはマーカーと、典型的に、二重下線プレフィックス、二重下線プレフィックスなし対応する数字を得るため、
最も一般的に使用されるマーカーはGFP_KERNELあり、それは、カーネル空間における現在の実行は、の代わりに割り当てられていることを意味します処理を行う。つまり、これは、関数が代わって呼び出されることを意味し それは、現在のプロセスがスリープすることによってメモリページを待つために、より少ないメモリの場合にkmallocのできることを意味し、GFP_KERNELマークを使用する;プロセスは、システムの実装に呼び出し従って、機能GFP_KERNEL使用は再入可能でなければならない、とすることはできませんアトミックコンテキストで実行されている、とき睡眠の現在のプロセス、カーネルは、いくつかの空きメモリ・ページを検索するために是正措置をとる、またはディスクにキャッシュをフラッシュすることにより、またはユーザプロセスのメモリページをスワップアウト;
メモリ割り当てアクションは、割り込み処理中に発生した場合、またはタイマーがカーネルコンテキストでは、現在のプロセスがスリープ状態に設定することができないとき、あなたは、もはやGFP_KERNELマークを使用することはできませんが、この時間ではなくGFP_ATOMICフラグを使用する必要があり、通常、カーネルが割り当て原子を満足させるために、いくつかの空きページを維持しようとします; GFP_ATOMICフラグ、kmallocのロゴも、最後の空きページを使用することができたときに、この最後の空きページが存在しない場合は、その割り当ては失敗します。

おすすめ

転載: www.cnblogs.com/eleclsc/p/11531589.html