Linux Kernel(2.6)の実装に関するメモ書き

ページフォルト - 個々のハンドラ


1. 概要

ページフォルトの処理ルーチンhandle_pte_fault()から呼び出される各do_xxxx()ルーチンのメモ。

2. 関数

2.1 do_anonymous_page()

Anonymous Page(匿名ページ)を割り当てるルーチン。Anonymous Pageとはストレージと関連付けられていないページ。ユーザプロセスのheapやstackなどのページがこれに該当する。

プロセスが変数などにアクセスしてページが未割り当てだった場合は、ここでページが割り当てられる。0で初期化したページを割り当てるため、ごみが残っていることはない。

do_anonymous_page()の処理概要
if (write_access) {
    /* Writeアクセスだった */
    /* HighMemから0 fillしたページを割り当て */
    page = alloc_zeroed_user_highpage(vma, address);
    /* 割り当てたページへのPTEを作成 */
} else {
    /* Readアクセスだった */
    /* Zero Page(ページ内が0 fillされているページ)への
     * PTEを作成 */
}

/* 作成したPTEを設定 */
set_pte_at(mm, address, page_table, entry);

2.2 do_no_page()

何か初期データが存在するアドレス空間(*1)へのページフォルトを処理するハンドラ。

vmaに登録されているNo Page時のハンドラ(vma->vm_ops->nopage)を呼び出すことによって、該当データが格納されたページを取得してアドレス空間とのマッピングを行う。


(*1) mmap()でファイルをアドレス空間にマップしている領域や共有領域。

do_no_page()の処理概要
/*
 * ページフォルト時のハンドラを呼び出す。
 * アドレス空間の種類によって異なるが、
 * ファイルにマップされているアドレス空間では
 * filemap_nopage()を呼び出す。
 * ハンドラはaddressに対応する空間のデータを
 * ページに格納して返す。
 */
new_page = vma->vm_ops->nopage(vma, address & PAGE_MASK, &ret);

/* 共有領域以外へのWriteだった場合は、
 * COW(Copy On Write)処理を行う */
if (write_access && !(vma->vm_flags & VM_SHARED)) {
    /* HighMemからページを割り当て */
    page = alloc_page_vma(GFP_HIGHUSER, vma, address);
    /* HignMemのページへコピー (new_page => page) */
    copy_user_highpage(page, new_page, address);
    new_page = page;
    anon = 1;
}

if (mapping && unlikely(sequence != mapping->truncate_count)) {
}

if (pte_none(*page_table)) {
    /* new_pageへのPTEを作成 */
    entry = mk_pte(new_page, vma->vm_page_prot);
    /* Write属性を必要なら設定 */
    if (write_access)
        entry = maybe_mkwrite(pte_mkdirty(entry), vma);
    /* PTE(page_table)を設定して、物理ページをマッピング */
    set_pte_at(mm, address, page_table, entry);

} else {
}


2.3 do_swap_page()

ページアウトされていたページをページインする。「Swap - ページイン」参照。



---------------------------
以下、編集中

coreの採取

do_coredump()
binfmt->core_dump() - バイナリ毎のcore採取処理を呼ぶ
(ELFの場合だとelf_core_dump())

elf_core_dump()

fill_elf_header() - ELFヘッダを作成
:
ELFヘッダ書き出し
:
current->mm->mmapの全vmaに対して
ProgramHeaderを書き出す。
(vma一つが一つのセグメント)
:
current->mm->mmapの全vmaに対して...
get_user_pages()
ページを書き出す

関連ページ

ページフォルト


最終更新 2011/03/31 02:04:40 - kztomita
(2006/12/30 20:01:52 作成)


リンク
最近更新したページ
検索