keigo1216 / ketchup

raspberrypi 3A+用のOS
1 stars 0 forks source link

implement simple page table #24

Closed keigo1216 closed 11 months ago

keigo1216 commented 11 months ago

ページテーブルと仮想アドレスの実装

ARMv8-Aの仮想アドレスの仕様

それぞれのページテーブルのサイズは1ページに収まるように設定する. 今回実装しているOSのページサイズは4KB. AArch64アーキテクチャなので, 一つのアドレスに8バイト(64bit)の値が入る. つまり, 一つのテーブルのエントリ数を512(9bit)に設定すれば, 512 ・8 = 4096 ( = 4KB)になる 二段のページテーブルを構成する場合

| level1 [29:21] | level2 [20:12] | PA [11:0] |

ページテーブルエントリの仕様

テーブルディスクリプタ (Table descriptor)

これは中段のページテーブルエントリに使う

| upper attributes [63:48] | Next-level table address [47:12] | ignore[11:2] | 1 | 1 |

upper attibutesの中身は

| NSTable [63] | AP Table [62:61] | UXN Table [60] | PXNTable [59] | ignore [58:52] | 

NS Table セキュアレベルで実行するときに使うビット. OSやユーザーアプリケーションはノンセキュアなのでこのビットは無視される

AP Table

UXN Table 下位レベルのルックアップで特定されて領域からフェッチされた命令のEL0の実行が許可されるかどうか決定する

PXN Table 下位レベルのルックアップで特定された領域からフェッチされた命令の特権状態の実行が許可されるかどうかを決定する

ページディスクリプタ

| Upper attributes [63:52] | UNK/SBZP [51:48] | Output address [47:12] | Lower attributes [11:2] | 1 | 1 |

UNK/SBZPres0(reserved, should be zero)としてARMV8-Aで定義されている.これは「予約済みでゼロに設定されるべき」ことを示している.その他のビットは同じ(たぶん)

有効化ビット

ページテーブルエントリの0bit目が1のとき、有効なエントリ. 0のとき、無効なエントリ

ページテーブルのベースアドレスの登録

TTBR0_EL1(ユーザー用)とTTBR1_EL1(カーネル用)にページテーブルのベースアドレス(物理アドレス)を設定する.

| ASID [63:48] | BADDR[47:1] | CnP [0] |

CnP : 別々のプロセッサでページテーブルを共有するかどうか

MMUの各種設定

TCR_EL1レジスタに設定する

TG0 [15:14] : EL0のページサイズ TG1 [31:30] : EL1のページサイズ T0SZ [5:0] : 64bitの仮想アドレスのうち、無視する上位ビットの長さを設定する(EL0T1SZ [21:16] : 64bitの仮想アドレスのうち、無視する上位ビットの長さを設定する(EL1

実装方法

  1. 最上段のページテーブルを静的に確保する(.bss領域に配置される?)、たぶん__free_ram上に配置されればいいはずなので, 動的に確保してもいいはず
  2. ブート時にカーネル空間の物理アドレスを全て仮想アドレスにマップする
  3. 仮想アドレスを有効化?することで, 仮想アドレスでカーネルの全領域にアクセスできる(はず)
  4. 各プロセスにtableフィールドを作成して, ページテーブルの最上段の先頭アドレスを保持する(4KBで揃える)
  5. コンテキストスイッチ時にTTBR0_EL1にページテーブルのベースアドレスを保存する。この際に、特殊な命令を打たないといけないらしいのでチェックする
  6. map関数を作成する
  7. 本実装では簡単のために、物理アドレスと仮想アドレスを一致させる(どのように割り当てるかは別途アルゴリズムを調べる必要がある)

RISC-Vでの実装と異なる点

ARMではページテーブルのベースアドレスを保存するレジスタが二つ(ユーザー空間用、カーネル空間用)がある 基本的にはカーネル空間のマッピングはブート時に行いそれ以降変更しない ユーザー領域のページテーブルレジスタTTBR0_EL1レジスタにセットする

参考文献

https://qiita.com/eggman/items/a8862d165cc0b4965f70

keigo1216 commented 11 months ago

ページテーブル構成の例

(これは4KBで三段のページテーブルを構成している例であることに注意)

スクリーンショット 2023-12-04 22 45 13
keigo1216 commented 11 months ago

テーブルディスクリプタの仕様

中段のテーブルのエントリに使うもの

スクリーンショット 2023-12-04 22 53 27
keigo1216 commented 11 months ago

ページディスクリプタの仕様

ページテーブルの最後に使うエントリ

スクリーンショット 2023-12-04 22 54 47
keigo1216 commented 11 months ago

アクセス権限の表

SCTLR_EL1レジスタのWXN, bit [19] ここは, 書き込み可能領域に設定されているページは実行可能にしない設定のこと 悪意のあるコードを実行しないようにするため

スクリーンショット 2023-12-05 23 11 31
keigo1216 commented 11 months ago

https://grasslab.github.io/NYCU_Operating_System_Capstone/labs/lab8.html