読者です 読者をやめる 読者になる 読者になる

ページング開始

Monarm

startKernel関数のページング開始処理(PageManager::setup)まで移植が進みました(リビジョン5)。
新たに移植したモジュールは、

  • IDManager
  • PageManager
  • Segment
  • Messenger

です。
Paging開始処理に重点をおいたために、一部不完全で以下のようになっています。

  • Segments.cpp
    • Scheduler::FindProcess()呼び出し部分を無効
  • PageManager.cpp
    • DMA/VRAM領域のマッピングを無効
    • Process::getStackBottom()呼び出し部分を無効
    • ThreadOperation::Kill()呼び出し部分を無効
  • Messenger.cpp
    • Scheduler::send/EventComes()呼び出し部分を無効
  • Kernel.cpp
    • systemcall_mutex_create()呼び出し部分を無効
    • Paging設定後、panicで停止

移植概要

オリジナル(x86)のカーネル領域のページング初期化処理の概要は以下の通りです。

  • ページサイズは4KBを採用
  • マッピングサイズはトータル8MB
    • 従ってページテーブルは2つ(4M×2)
  • 8MBの後ろ500KBをDMAのページにマップ
  • VRAM用のページもマップ(詳細未調査)

上記に対してMonarmでは以下のように設定を行いました。

  • ページサイズは4KBを採用
  • マッピングサイズはトータル64MB
    • ページテーブルは64個(ARMでは1テーブルで1MBまで表現)
  • DMAとVRAMはとりあえず保留

以前のエントリカーネルを最低限動作可能にするため、既にMMUは開始済みでPagingも有効になっていましたが、PageManagerによる正式な初期設定を移植しました。

このため、実質は、

    • 固定メモリ領域(0x3100-0000)に生成した変換テーブル

から

    • カーネルメモリから動的に取得した領域に生成した変換テーブル

への置き換え*1のみでOKなので、既に有効であるMMUを再度有効にする(startPaging関数の実行)のは気持ちが悪いですので時間があったら見直したいと思います…。

ページング概要

Monarmカーネル領域のページングの概要はこんな感じになります。

カーネル領域である、SDRAMの先頭64MBはファインページテーブル経由の4KBのsmallページでのページングになります。

それ以外のI/O領域等のページは1MBのセクションページです。


次いで、各ディスクリプタの内訳です。

  • カーネルページはキャッシュ・バッファ有効、SVCモードのみアクセス可
  • それ以外のページはキャッシュ・バッファ無効、SVCモードのみアクセス可

としています。
来るユーザ領域もsmallページになるかと思いますが、カーネルのページのディスクリプタとアクセス許可のみが異なるだけOKと踏んでいます。

ドメインは現状、ドメイン0のみの設定で、クライアント設定に指定しています(アクセス許可を行う設定)。
(ドメインの設定はastart.S設定で行っています)

後は

  • ihandler
  • syscall
  • Scheduler
  • Process

を移植できれば、まがいなりにもカーネル初期化処理は完了して、カーネル内からユーザプロセスを生成するぐらいは可能になるかと思います。
先は長いー。

*1:CP15/レジスタ2の書き換え。x86で言うCR3