記事ディレクトリ
- カーネル内の関数は動的メモリを直接取得し、
- これは、次の関数のいずれかを呼び出すことによって実現されます。
- __get_free_pagesまたはalloc_pagesは、分割されたページフレームアロケーターからページフレームを取得します
- kmem_cache_alloc()またはkmalloc()は、スラブアロケーターを使用してプライベートオブジェクトまたは一般オブジェクトにブロックを割り当て、vmalloc()またはvmalloc_32()を使用して非連続メモリ領域を取得します。
- 要求されたメモリ領域が満たされている場合、
- ページ記述子アドレスまたは線形アドレス(つまり、割り当てられた動的メモリ領域の開始アドレス)を返します
- カーネルの優先度
- カーネル関数が動的メモリを要求する場合、後退を試みても意味がありません
- カーネルは自分自身を信頼します。
- すべてのカーネル関数は正しいと想定されているため、カーネル関数はプログラミングエラーに対する保護を挿入する必要はありません。
- ユーザーモードプロセスにメモリを割り当てる場合、状況は異なります。
- 動的メモリのプロセス要求は、急いでいないと見なされます。
- プロセスの実行可能ファイルが読み込まれると、プロセスは必ずしもすべてのコードページにすぐにアクセスできるわけではありません。
- プロセスがma1loc()を呼び出して要求された動的メモリを取得しても、プロセスが取得したすべてのメモリにすぐにアクセスするわけではありません。
- カーネルは常に、ユーザーモードプロセスへの動的メモリの割り当てを延期しようとします。
- ユーザープロセスは信頼できないため、カーネルはユーザーモードプロセスによって引き起こされるすべてのアドレス指定エラーをキャッチする準備ができている必要があります。
- カーネルは新しいリソースを使用して、プロセスの動的メモリの遅延割り当てを実装します。
- ユーザーモードプロセスが動的メモリを要求すると、要求されたページフレームは取得されません。
- そして、新しい線形アドレス間隔を使用する権利のみを取得し、
- この線形アドレス範囲は、プロセスアドレス空間の一部になります。
- この間隔を「線形領域」と呼びます。
- プロセスが動的メモリを表示する方法
- 「線形領域」は、プロセスアドレス空間の基本構成を説明します
- ページフレームの割り当てプロセスを延期する際のページフォールト例外ハンドラーの役割。
- カーネルがプロセスのアドレス空間全体を作成および削除する方法。
- プロセスのアドレス空間管理に関連するAPIとシステムコール
プロセスアドレススペース
- プロセスのアドレス空間は、プロセスに許可されているすべての線形アドレスで構成されています。
- 各プロセスで認識される線形アドレスのセットは異なり、あるプロセスで使用されるアドレスと別のプロセスで使用されるアドレスの間に関係はありません。
- カーネルは、特定の線形アドレス範囲を追加または削除することにより、プロセスのアドレス空間を動的に変更できます。
- カーネルは、いわゆる線形領域のリソースを通じて線形アドレス範囲を表現します。線形領域は、開始線形アドレス、長さ、およびアクセス権によって記述されます。
- 線形領域の開始アドレスと長さは4096の倍数である必要があります。これにより、各線形領域によって識別されるデータは、割り当てられたページフレームを完全に満たします。
- ここでは、プロセスが新しい線形領域を取得するいくつかの典型的な状況を示します
- コンソールがコマンドを入力すると、シェルプロセスはコマンドを実行する新しいプロセスを作成します
- 新しいアドレス空間(一連の線形領域)が新しいプロセスに割り当てられます(「プロセスアドレス空間の作成と削除」およびこの章で後述する第20章を参照)。
- 実行中のプロセスは、まったく異なるプログラムをロードすることを決定しました。
- 変更されていないプロセス識別子
- このプログラムをロードする前に使用されていた線形領域が解放され、
- そして、このプロセスに割り当てられた新しい線形領域があります(第20章の「exec」を参照)
- 実行中のプロセスは、ファイル(またはその一部)に対して「メモリマッピング」を実行します。
- カーネルは、このプロセスに新しい線形領域を割り当てて、このファイルをマップします(第16章「メモリマップ」を参照)。
- プロセスは、このスタックを使用する線形領域が使い果たされるまでユーザー空間スタックにデータを追加し続ける場合があり、カーネルはこの線形領域のサイズを拡張することを決定します(この章で後述する「ページ欠落の例外ハンドラ」を参照)。
- プロセスは、他のプロセスとデータを共有するためにIPC共有線形領域を作成できます。
- カーネルはこのソリューションに新しい線形領域を割り当ててこのソリューションを実装します(第19章の「IPC共有メモリ」を参照)
- malloc()を転送して独自の動的領域(ヒープ)を拡張する
- カーネルは、このヒープに割り当てられた線形領域を拡張することを決定する場合があります(この章で後述する「ヒープ管理」を参照)。
- 「ページフォールト例外ハンドラ」は、
- プロセスの線形領域(つまり、プロセスのアドレス空間)がカーネルタスクであることを決定する
- これにより、ページ違反例外ハンドラーは、この例外ハンドラーを引き起こした2つの異なるタイプの無効な線形アドレスを効果的に区別できます。
- プログラミングエラーが原因の無効な線形アドレス
- ページ違反が原因で無効な線形アドレス
- この線形アドレスがプロセスのアドレス空間に属していても、
- ただし、このアドレスのフレームはまだ割り当てられていません。
- プロセスの観点からは、後者のアドレスは無効ではありません。
- カーネルは、要求の調整を達成するために、このページフォールトを使用する必要があります。
- カーネルは、ページフレームを提供してこのページフォールトを処理し、プロセスが実行を継続できるようにします。
- カーネルは、要求の調整を達成するために、このページフォールトを使用する必要があります。
メモリ記述子
- プロセスアドレス空間に関連するすべての情報は、メモリ記述子のデータ構造にあります。
- 表9-2に示すとおり
struct mm_struct {
struct vm_area_struct * mmap; /* list of VMAs */
struct rb_root mm_rb;
struct vm_area_struct * mmap_cache; /* last find_vma result */
unsigned long (*get_unmapped_area) (struct file *filp,
unsigned long addr, unsigned long len,
unsigned long pgoff, unsigned long flags);
void (*unmap_area) (struct vm_area_struct *area);
unsigned long mmap_base; /* base of mmap area */
unsigned long free_area_cache; /* first hole */
pgd_t * pgd;
atomic_t mm_users; /* How many users with user space? */
atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
int map_count; /* number of VMAs */
struct rw_semaphore mmap_sem;
spinlock_t page_table_lock; /* Protects page tables, mm->rss, mm->anon_rss */
struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
* together off init_mm.mmlist, and are protected
* by mmlist_lock
*/
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long rss, anon_rss, total_vm, locked_vm, shared_vm;
unsigned long exec_vm, stack_vm, reserved_vm, def_flags, nr_ptes;
unsigned long saved_auxv[42]; /* for /proc/PID/auxv */
unsigned dumpable:1;
cpumask_t cpu_vm_mask;
/* Architecture-specific MM context */
mm_context_t context;
/* Token based thrashing protection. */
unsigned long swap_token_time;
char recent_pagein;
/* coredumping support */
int core_waiters;
struct completion *core_startup_done, core_done;
/* aio bits */
rwlock_t ioctx_list_lock;
struct kioctx *ioctx_list;
struct kioctx default_kioctx;
unsigned long hiwater_rss; /* High-water RSS usage */
unsigned long hiwater_vm; /* High-water virtual memory usage */
};