Article Outline
メモリのセグメント機構について
メモリのセグメント機構について学習したため、そのまとめとしてここに整理する。
セグメントセレクタ
- セグメントを一意に識別するための16bitのフィールド
- 各フィールドの役割
- RPL (0 ~ 1bit目)
- Requestor Priviledge Level
- セグメントセレクタをCSに読み込んださいのCPUの特権レベルを指す
- TI (2bit目)
- Table Indicator
- セグメントディスクリプタがGDTにあるか、またはLDTにあるかを示す
- GDT = 0, LDT = 1
- インデックス (3 ~ 15bit目)
- GDTもしくはLDTにある、セグメントディスクリプタのアドレス
- RPL (0 ~ 1bit目)
セグメントディスクリプタ
- 8byte長、対応するセグメントの特性を表す
- GDTもしくはLDTに保存される
- Linuxでの主なセグメントディスクリプタの用途
- コードセグメントディスクリプタ
- データセグメントディスクリプタ
- 各フィールドの役割
- リミット (0 ~ 15bit)
- セグメントの終端メモリアドレス = セグメント長
- ベース (16 ~ 39bit)
- セグメント先頭のリニアアドレス
- タイプ (40 ~ 43bit)
- セグメントの種類とアクセス権
- S (44bit)
- システムフラグ。0ならばLDTなどの重要なデータ、1ならば通常のコードセグメント・データセグメントであることを表す
- DPL (45 ~ 46bit)
- Descriptor Priviledge Level
- セグメントへのアクセスを制限するために使用 (該当セグメントにアクセスするために必要な最低限のCPU権限を表す)
- 1 (47bit)
- リミット (48 ~ 51bit)
- AVL (52bit)
- オペレーティングシステム用だがLinuxでは使用していない
- 0 (53bit)
- D もしくは B (54bit)
- 該当セグメントがコード用かデータ用かで呼び方が変わる
- セグメントオフセットが32ビットの場合は1を設定し、16ビットの場合は0を設定する
- G (55bit)
- 粒度(Granularity)を表すフラグ
- セグメント長をバイト単位で表す場合は0、ページ単位の場合は1
- ベース (56 ~ 63bit)
- リミット (0 ~ 15bit)
GDT / LDT
- セグメントディスクリプタの一覧を保存するテーブル
- GDTは通常1つだけ、各プロセスごとにLDTを持つことも可能
- GDTのアドレスとサイズはCPUのgdtrレジスタに保存される
- GDT
- Global Descriptor Table
- LDT
- Local Descriptor Table
Linuxにおける主なセグメント
- ユーザーコードセグメント / ユーザーデータセグメント
- ユーザーモードで動作するコードとデータが配置される
__USER_CS
・__USER_DS
マクロでセグメントセレクタを定義
- カーネルコードセグメント / カーネルデータセグメント
- カーネルモードで動作するコードとデータが配置される
__KERNEL_CS
・__KERNEL_DS
マクロでセグメントセレクタを配置