Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
プロセス空間の拡張は do_mmap関数で実現している. 第一引き数にNULLを指定してdo_mmap関数を呼び出した場合, 指定されたアドレス範囲を管理するvm_area_structが確保され, その範囲の仮想空間の生成のみを行う.
第一引き数にファイルを渡した場合, 上記処理に加え、生成した仮想空間へのファイルのマッピング処理を行う.
mmapシステムコールだけでなく、execシステムコール時のファイルマッピング、brkシステムコールによるヒープ領域の拡張にこのdo_mmap関数が利用される。
do_mmap(ファイル構造体、アドレス、サイズ、プロテクション...) { 固定仮想アドレス指定で無い場合、空いている仮想空間を検索する。 仮想空間管理構造体vm_area_structを確保する。 vm_area_structを初期化、仮想空間を予約する。 if (ファイル指定?) { ファイル構造体のmmapオペレーションを呼び出す。 (ext2fsの場合はgeneric_file_mmap関数) 仮想空間管理構造体vm_area_structにファイル構造体を登録 } 可能なら隣り合ったvm同士でマージする(merge_segments関数) }
ext2ファイルシステムの場合は、mmapファイルオペレーションとして以下の関数が登録されている。(他のファイルシステムやドライバは別の関数が登録されている)この関数では、仮想空間管理構造体に仮想空間オペレーションテーブルvm_operations_structを登録する。以後の空間操作処理ではこのテーブルを通して関数が呼び出される。
generic_file_mmap(ファイル構造体, 仮想空間管理構造体vm_area_struct) { if (共有モードのファイルマッピングか?) { file_shared_mmapを仮想空間オペレーションテーブル として仮想空間管理構造体vm_area_structに登録 } else { file_private_mmapを仮想空間オペレーションテーブル として仮想空間管理構造体vm_area_structに登録 } vm_operations_struct file_private_mmap = { NULL, /* open */ NULL, /* close */ NULL, /* unmap */ NULL, /* protect */ NULL, /* sync */ NULL, /* advise */ filemap_nopage, /* nopage */ NULL, /* wppage */ NULL, /* swapout */ NULL, /* swapin */ }; vm_operations_struct file_shared_mmap = { NULL, /* no special open */ NULL, /* no special close */ filemap_unmap, /* unmap - we need to sync the pages */ NULL, /* no special protect */ filemap_sync, /* sync */ NULL, /* advise */ filemap_nopage, /* nopage */ NULL, /* wppage */ filemap_swapout, /* swapout */ NULL, /* swapin */ };
今後の説明では、フィアルマップされた空間(プログラムのテキスト領域、データ領域など)と、ファイルマップされていない空間(bss領域やスタック領域など)を例にとり、その動作をイメージ的に示していく。PTE中のDはdirtyビット、Wは書き込み可能ビット、PはPTEの有効性を示すビットである。大文字はそのビットが立っていることを示し、小文字のときはビットが落ちていることを示す。
生成されたばかりのプロセス空間は、仮想空間だけは存在するが、PTEの中身は全て空であり、物理メモリは割り当てられていない。
(NIS)HirokazuTakahashi
2000年06月11日 (日) 22時29分57秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:45:38, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members