目次: Linux
以前からLinuxのページディスクリプタ(要はstruct page)って何なの?という疑問が晴れないまま居ました。特に実際のページフレームとの対応をどうやって取っているのかが全くわからん。どこかに対応が書いてあるにしては、それらしい場所がない…。
分からんながらも、機会を見つけては調べたり考えたりしていたら、なんとなーく分かった気がする。
分かった気がすることを書き散らしますが、間違っててもご勘弁下さい。自信ないです。
前提知識として簡単に説明します。Linuxではメモリ領域をゾーンという固まりで管理しています。ゾーンはページフレーム(普通は4KBのメモリ領域)をいくつかまとめた固まりです。ページフレームがずらーっと並んでいるようなイメージ。
厳密にはもっと書くべきことがあるのでしょうが、今回はこのくらいの理解で進めるはず。たぶん。
では本題に入ります。
まず私の疑問点は「ページディスクリプタ(以下、struct page)のポインタをもらったとき、どうやって対応するページフレームを得るのか?」です。
ここでstruct pageのメンバに直接書いてあれば話は早いのですが、struct pageにページフレーム番号を示す情報などはありません。残念。
実はstruct pageは中身も大事ですが、ポインタ値が非常に重要な意味を持ちます。というのも実メモリのページフレームとの対応を取るために、ポインタの計算を行うからです。計算についてはまた説明します。
ページフレームを求めるためには、
ページディスクリプタ -> ゾーン -> ページフレーム
の順に求めます。まどろこしいですが、直接求められないのです。
ページディスクリプタが対応するページフレーム、こいつが属するゾーンを求めます。自分でも何言ってるのかわかんないけど、まあいいや。
まずstruct pageにpage_flags_t flagsというメンバを見ます。こいつはその名の通りページの属性や状態を示すフラグを格納する変数なのですが、上位3ビット(または8ビット)だけは意味が違っていて(※1)、このページが所属するゾーンを表す数値が入っています。
なのでflags >> NODEZONE_SHIFTによってページが何番目のゾーンに所属しているのかがわかります。例えば1だとしたら、ゾーンの配列zone_table[1](グローバル変数)を見ればゾーンの情報が見られます(※2)。
(※1)不思議な設計に見えますが、むやみにメンバを増やすとstruct pageだけで相当量のメモリを圧迫(struct pageはページフレームの数だけ存在する)してしまいます。
(※2)最近のLinuxではゾーンの一覧(zone_table)はグローバル配列ではありません。struct pglist_dataという構造体(ゾーンが必要ならnode_dataというグローバル配列(アーキテクチャ依存)、ゾーンが不要ならcontig_page_dataという変数)経由でゾーンを見るようになっています。ゾーンが要らないというアーキテクチャを考慮したのでしょう。
長くなってきましたが、本題のページフレームの求め方に行きます。先ほど苦労して求めたゾーンにはzone_mem_mapというメンバが居て、ゾーンに属するstruct pageの一覧を持っています(※3)。
上の絵で注目して欲しいのはzone_mem_mapと、ページディスクリプタのポインタ(pとします)がわかれば、zone_mem_mapの何番目にpが存在しているかわかるということです。上の絵では5番目に位置しています。
薄い水色の四角内で具体的な数値(数値は適当ですが)を当てはめてpのアドレスからzone_mem_mapのアドレスを引くことで、pがzone_mem_mapの何番目にいるか求められる様子を示しています。
これでstruct pageがゾーンの先頭から何番目のページなのかがわかりました。あとはページフレームを求めるだけです。ゾーンの構造体のメンバzone_start_pfnがゾーンの開始ページフレーム番号を表しているので、そこへ先ほどの数字(5)を足します。
これにてstruct pageと対応するページフレームが求められました。
もし物理アドレスに興味があるのならば、ページフレームの番号にページフレームのサイズ(普通は4KBのはず)を掛けてあげればよいです。
高位メモリや非連続なメモリモデルを持つアーキテクチャだと、単純に掛けるだけではダメかもしれません。
(※3)最近のLinuxにはありません。恐らくzone_pgdat->node_mem_mapが等価だと思われます。たぶん…。
< | 2008 | > | ||||
<< | < | 05 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | - | 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 |
合計:
本日: