メモリアドレッシング
2017-12-24 /
アドレスというのはメモリの番地を指す。 その番地のメモリセルには電気的に記録されたデータが保存されているため、 番地を指定することでデータを読み書きできる。
論理アドレス
リニアアドレス
物理アドレス
それぞれの違いについて
###, Segment
メモリの「セグメント」ってなに?
セグメントとは
コードセグメント データセグメント
などの役割をもったメモリ領域のグループを指す。
セグメントの先頭アドレスとそこからのオフセットによって、 位置を表現する。
このセグメンテーション方式はプロセッサの要請からくるもので、 Linuxカーネルとして採用しているものではない。
このセグメントの位置情報を含む論理アドレスが、 ページテーブルの位置情報であるリニアアドレス(仮想アドレス)に 変換され、ページ管理機構がそれを物理アドレスに変換する。
Linuxカーネルから見ると3つのアドレスを変換しながら メモリが運用されている。
Linuxカーネルではページング機構を有効的に使うために、 いくつかの決まったセグメントを使って管理している。
ユーザ用・カーネル用それぞれ2つずつセグメントがあり、 それだけを使っている。 (たしかにどんな単位でセグメントを作るのか謎だったが、 少なくともLinuxでは大雑把な単位でセグメントを作っている、ということらしい)
Linuxがページ機構を優先するのは、x86の仕様であるセグメンテーション方式に 大きく依存してしまうとRISC系プロセッサとの相性が悪くなるかららしい。 そのためアーキテクチャ依存しないページング機構の方を有効活用している。
###, Paging
物理メモリをページフレームという区画に分割することから考える。
とあるメモリ領域を参照する時にはカーネルから ページN番の先頭から数えてM番目を参照せよ という命令を発行することでメモリへとアクセスをする。
よってメモリアクセスにはページ番号とオフセットが必ずセットになる。
これは住所でいうと「Nどおりの入り口からM番目の家」 という覚え方をした方が楽だよね、という直感に対応している。
ページフォルト リニアアドレスで指定されたアドレスを解決して物理メモリを見に行くも、 存在フラグが降りている場合に発生する例外。 プロセスに与えられたリニアアドレス以外のアドレス参照でも起こる。 いわゆるsegfaultだと思うのだが何がちがうのか。
なるほどページフォルトの中にもいろいろあるらしい。 ページフォルトをトリガとして物理メモリ確保に動くのが大半。 無効アドレスならsegfault扱いになる。 good, fault, と, bad, faultがあるということのようだ。
###, TLB, Cache
リニアアドレスと物理アドレスの変換表をページテーブルというが、 このテーブル自体もメモリに確保されている。 メモリアクセスはCPUの近くにあるキャッシュと比べるととても遅い。 そのためTLBキャッシュという機構を用いて、アドレスの対応をキャッシュすることでアドレス変換を高速化する。
(このあたりプロセッサを支える技術で勉強したのでいくらかイメージが湧く)
高速化の基本は空間をコストとして払って時間を縮めるのだな。
###, Paging
Linuxでは原則的に4段テーブルでアドレス管理する。
*, global *, upper *, middle *, page, table
の4種類
###, TODO
何故4段なのか?なにが嬉しいのか? 初期化時のテーブルの作り方