link もっと前
   2008年 5月 13日 -
      2008年 5月 13日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

struct page って何

以前から 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 のイメージ

上の絵で注目して欲しいのは 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年 5月 14日 03:46]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2008年 5月 13日 -
      2008年 5月 13日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 9/17 20:03

カレンダー

<2008>
<<<05>>>
----123
45678910
11121314151617
18192021222324
25262728293031

最近のコメント 5件

  • link 18年09月07日
    すずき 「ありがとう!\nこちらこそ、楽しみにして...」
    (更新:09/11 19:30)
  • link 18年09月07日
    よしだあ 「おつかれさまでした!\nまた仕事できるの...」
    (更新:09/11 19:17)
  • link 18年08月15日
    すずき 「うーん、なんか暴走したり、動かなかったり...」
    (更新:08/15 10:52)
  • link 18年08月15日
    すずき 「実行できた。あと実行ファイルパスについて...」
    (更新:08/15 10:42)
  • link 18年08月15日
    すずき 「さすがに x86_64 と arm のク...」
    (更新:08/15 10:35)

最近の記事 3件

link もっとみる
  • link 18年09月13日
    すずき 「[府民から都民へ] 家が決まりました。今月末から東京都民です。さよ...」
    (更新:09/17 20:03)
  • link 18年09月11日
    すずき 「[エアコン浄化] 今年の 7月に(2018年 7月 17日の日記参...」
    (更新:09/17 19:38)
  • link 18年09月10日
    すずき 「[引っ越し準備] 引っ越し用の新品の段ボールが 50箱以上届き、家...」
    (更新:09/17 19:32)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報