Personal tools
You are here: Home ブログ 学習経過 64 bit 環境におけるメモリマップの話 (その 2/2)
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
sysfs tips 02 ohyama 2010-09-09
sysfs tips ohyama 2010-09-02
Haskell で周波数スペクトルを得る ohyama 2010-07-29
Haskell で線形識別関数の学習を行う ohyama 2010-07-19
Haskell で逆行列を求める ohyama 2010-07-16
Recent comments
Re:vim に lisp 機能をつける t.mimori 2010-12-16
Re:Haskell で周波数スペクトルを得る H.OHYAMA 2010-08-01
Re:lkml でお勉強 (その1-1) Hiroyasu OHYAMA 2009-08-21
Re:lkml でお勉強 (その1-1) kosaki 2009-08-20
Re:vim に lisp 機能をつける ohyama 2008-05-08
Categories
学習経過
GNU/Linux
 
Document Actions

64 bit 環境におけるメモリマップの話 (その 2/2)

○ 64 bit 環境におけるメモリマップ (その 2/2)

 前回は、64bit 版 x86 互換アーキテクチャ (以下、x86_64) のページングによるアドレス解決がどのように行われているのかという事と x86_64 上で動作する GNU/Linux (以下、Linux) でのメモリマップについての話をした。
 今回は、同じく x86_64 環境の Linux におけるページテーブルの初期化処理について、アドレス解決の基礎の話を交えて示す。

 前回に示したように、x86_64 アーキテクチャでは、4 段階のアドレス解決を行っている。まずは、このアドレス解決の方法について示す。
 x86_64 アーキテクチャでは、特定のアドレスに対するアクセスを受けたとき、セグメンテーション機構がこれを処理する。x86_64 の実装は詳しく知らないが、32bit 版 x86 アーキテクチャ (以下、x86) では、ユーザ、カーネル双方の CPU 特権レベルにおけるコードセグメント、及びデータセグメントの範囲を仮想アドレス空間全体に設定したセグメントディスクリプタをセグメントレジスタに設定する。
 つまり、Linux において主要なメモリアクセス制限は、ページテーブルで行っている事になる。
 セグメンテーション機構をパスしたメモリアクセス要求は、ページング機構が処理する。ここでは、アドレス解決について注視する。
 x86 及び x86_64 アーキテクチャでは、cr3 特殊レジスタがページグローバルディレクトリ (以下、pgd) テーブルの物理アドレスを保持している。そして、pgd を含めた各レベルにおいて 9 ビット幅のページテーブルを保持しており、最終的にページまで到着する。
 アドレス解決の仕組みはこうだ。まず、アクセス対象のアドレスを (48 - 9) だけ右シフトさせる。こうする事で、pgd テーブルにおけるオフセットがわかる。そして、下位のテーブル (pud) テーブルに対して、pmd オフセット (30-38 bit) をマスクして、30 だけ右シフトさせ、下位のページテーブルを参照。これを 4 回 (*1) 行う事でページに到着する
 また、ページの属性情報については、ページテーブルの下位 12 ビットを用いて行われる。

 では、x86_64 のアドレス解決の基礎がわかった所で、Linux におけるページテーブルの初期化処理について見てゆく。
 正確には、ページテーブルに対して物理ページをカーネル空間の先頭 (PAGE_OFFSET) からストレートマップさせる処理を覗く。

 cpu 動作モードがプロテクトモードに以降してから、Linux は init/main.c の start_kernel() を実行する。そして、リンク時に決定した各アーキテクチャの初期化処理 setup_arch() を呼び出す。

 x86_64 互換アーキテクチャにおける setup_arch() 処理は arch/x86/kernel/setup.c で定義され、ここからページテーブルの初期化処理である init_memory_mapping() を呼び出す。

 init_memory_mapping() [arch/x86/mm/init.c] の処理をザックリと示すと、save_mr() を呼び出し、物理アドレスのどの範囲をどのページに分けるかという設定を行い、kernel_physical_mapping_init() を呼び出し、カーネル空間のページテーブルの初期化設定を行う。

 kernel_physical_mapping_init() [arch/x86/mm/init_64.c] 以下の処理は流れ作業であり単純である。ここでは、各 pgd 毎に初期化設定を行う。尚、pgd エントリ初期化処理の開始点のアドレスは、__va() マクロによって、仮想アドレスに変換される。つまり、カーネル空間の先頭の先頭からの処理となる。
 ループ処理ではまず pgd_offset_k() によって pgd エントリを取得し、phys_pud_init() を呼び出し、下位テーブル (pud) の初期化設定を行う。
 そして、ここでも同様の処理を行い phys_pmd_init() を呼び出し、最後に phys_pte_init() を呼び出す。

 arch/x86/mm/init_64.c の static 関数 phys_pte_init() では、pfn_pte() 関数によってページフレーム番号からページテーブルエントリを作成する。ページディレクトリがページを指す場合、アドレスの下位 12 ビットは、ページの属性情報を表現する為に使われる。
 ここでは、上位 35 ビット (12-46) でページフレームのアドレスを表し、下位 12 ビットで存在フラグ、RW フラグ、アクセスフラグ、汚れフラグ等を設定している。

 ここまでで、ページフレームのストレートマップ処理が完了した。
 先に、x86_64 のアドレス解決は 4 段階のページテーブルのアドレス解決によって行われると言い、その 4 段のページテーブルの初期化処理について見てきたわけだが、実際には、4 段全てのページテーブルが使われるとは限らない。
 4 段のページテーブルを用いたアドレス解決を行う時、ページサイズは 4KB (48 - 9*4bit) となる。しかし、途中のページテーブルにおけるアドレス解決を省く事で、大きなページを扱う事ができる。

 x86_64 環境において init_memory_mapping() の mr_save() によるページテーブル初期化のページ範囲と伴に、ページのサイズを決定する。ここでは、4 段階のページテーブルによるアドレス解決を行う場合と、3 段ないし 2 段階のアドレス解決によるページの特定を行うかを決定する。これによって、pmd や pud テーブルから直接ページを参照する事になり、それに応じてページサイズも変わってくる。
 通常、init_memory_mapping() では、2MB のページフレームをストレートマッピングさせる。そして、余った領域を 4KB のページでその後ろをマップする。
 また DIRECT_GBPAGES カーネルオプションを設定すると init_memory_mapping() では、pud テーブルが直接ページを参照する 1GB のページをマッピングする。

 以上が x86_64 におけるページテーブルの初期化処理になる。x86 互換環境におけるページ設定よりも柔軟に ー例えば、pmd 以下で、拡張ページと通常ページを混在させるなどー (*2) 異なるサイズのページが設定できている事がわかる。
 Linux ではページサイズが統一されていると信じていたので、x86_64 の特異な点に気づく事が出来てよかった。
 
 
(*1) ページサイズが 2^12(=4K) バイトの場合
(*2) といっても x86 環境でも、cr4 の PSE フラグをセットしておいて、ページディレクトリエントリの PS ビットを寝かせて 4K と 4M のページを混在させる、なんて事も出来た (onix ではそうやってた)。
 

Category(s)
学習経過
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/ohyama/64-bit-74b05883306b304a3051308b30e130e230ea30de30c3-305d306e-2-2/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.