# メモリ管理マネージャ

# このメモについて

このメモは、B-Free OS のメモリ管理マネージャについて記述したもの です。

# メモリ管理マネージャの役割

メモリ管理マネージャは、B-Free OS 上で動いているアプリケーション のメモリ割り当てを管理します。 アプリケーションは、動作するためにメモリを必要とします。 B-Free OS では、アプリケーションは仮想メモリ上で動作するため、物理メモリの 割り当てを行う機能が必要になります。 また、 B-Free OS は、物理メモリよりも多いメモリを塔載しているかの ように見せかけるための機能 --- 仮想メモリ機能があります。そのため、 実メモリ中にないページをアクセスしたときに、二次記憶装置から実メモリへ ページ内容を読み込むための機能 --- ページイン と アクセス頻度の低いペー ジを実メモリから二次記憶装置へ書き込む機能 --- ページアウトのふたつの 機能が必要になります。 B-Free OS のメモリ管理の機能は大きくわけると次のように分けられます。

- メモリ関連システムコールの実行
- ページフォールト時のページイン処理
- ページアウト処理

これらの機能は、メモリ管理マネージャの異なったモジュールが提供します。

# OS 環境による動作の違いについて

このメモリマネージャは、以下の OS 環境にて動作します。

- BTRON OS 環境
- POSIX 環境

メモリマネージャは、これらの環境を区別することはせず同等に扱います。 OS 環境の違いによる処理の変化は、各プロセスの OS 環境提供層である、 LOWLIB が行います。 具体的には、OS 環境によって次の違いが出てきます。

- ユーザプロセスの仮想メモリ上のレイアウト
- メモリ取得方法
- コード部分の扱い

これらの項目の違いについては、メモリマネージャは意識しません。 lowlib は、自分が提供する環境に合わせてこれらの項目に関係する情 報を操作します。 たとえば、仮想メモリ上のレイアウトについては、OS 環境ごとに決まったレ イアウトをとるように region の作成およびパラメータの設定を行います。

# プロセスの仮想メモリマップ

BTRON OS 環境で動作するプロセスの仮想空間は、図 のようになっています。

プロセスの仮想空間

各プロセスには、固有空間として 2G バイト割り当てられます。 ただし、固有空間の上位部の共有メモリ部については、他のプロセスと共有し ます。

# 関連システムコール

メモリ管理マネージャと関連のあるシステムコールは、表 のように分類できます。

分類 | 内容
ローカルメモリ操作 | プロセス毎にもつヒープ領域の操作
共有メモリ操作 | すべてのプロセス

関連システムコール分類
ただし、次のメモリ操作関係のシステムコールはメモリ管理マネージャを呼び 出さずに、ライブラリ または LOWLIB で処理します。メモリ管理マネージャ との通信を省略することによって、速度向上を図るためです。

- map_mem 仮想メモリに物理メモリをマップします。
- ump_mem 物理メモリのマップを解除します。

また、BTRON 1 または BTRON 3 仕様で規定している次のシステムコールにつ いては、B-Free では、サポートしません。

- set_brk BTRON3 で追加されたシステムコール (詳細不明)
- apd_mem 物理メモリの追加。
- get_ptr BTRON1 での 80286 依存システムコール
- rel_ptr BTRON1 での 80286 依存システムコール

メモリを確保するシステムコール (get_lmb()) は、そのプロセスに 仮想メモリを割り当てます。このとき、割り当てた仮想メモリに物理メモリ は割り当てません。

get_lmb() を使用する場合、取得したいローカルメモリのサイズをバ イト単位で指定します。get_lmb() は、取得サイズをページサイズに 切上げてから仮想メモリを取得します。

仮想メモリ(ページ) を取得するとき、ページの属性として NULL ページを指 定します。ユーザプロセスが該当ページをアクセスしたとき、メモリ管理マネー ジャは物理メモリ(ページ)を割り当てます。そのときページ内容は 0 でクリ アします。

get_lmb() によって、取得した仮想メモリ領域はユーザプロセスが終 了した時点で解放されます。もし、仮想メモリ領域をアクセスしているプロセ スがひとつだけの場合には、仮想メモリ領域にマッピングしていた物理メモリ ページも解放します。

## ローカルメモリ操作用のシステムコール

B-Free OS では、BTRON1 に合わせて各プロセスが独自にもつヒープメ モリをローカルメモリと呼びます。

ローカルメモリ操作用のシステムコールは、次のものがあります

関数名 | 内容
get_lmb | ローカルメモリを取得する
rsz_lmb | 取得したローカルメモリのサイズを変更する
rel_lmb | ローカルメモリを解放する
lmb_siz | ローカルメモリのサイズを測定する
lmb_sts | ローカルメモリに関する情報を取得する

ローカルメモリ操作用システムコール

## 共有メモリ操作用システムコール

共有メモリを操作するためのシステムコールを表 に示します。

関数名 | 内容
cre_mpl | メモリプールの獲得
del_mpl | メモリプールの削除
get_smb | 共有メモリのブロックを取得する
rel_smb | 共有メモリのブロックを解放する
rea_smb | 共有メモリのブロックの内容を読み取る
wri_smb | 共有メモリのブロックに書き込む
smb_adr | 共有メモリブロックのアドレスの取得
smb_key | 共有メモリブロックのアクセスキーを取得する
get_sma | 共有メモリブロックの属性情報を取得する
set_sma | 共有メモリブロックの属性情報を設定する
get_smi | 共有メモリブロックのユーザ情報のとりだし
set_smi | 共有メモリブロックのユーザ情報の設定
smb_sts | 共有メモリブロック情報の取得
mpl_sts | 共有メモリプール状態の取得

共有メモリ操作用システムコール
共有メモリの概念図を 図に示します。

共有メモリの概念図

共有メモリは、共有メモリブロックを取得することによって、使用できます。

共有メモリブロックはメモリプール中にあるメモリ領域のうち指定したサイズ の領域のことを言います。このメモリブロックへのアクセスはブロックを取得 したプロセス以外にも、アクセスキーを取得したプロセスならばアクセスする ことができます。

アクセスキーが、ないプロセスの場合には共有メモリブロックへのアクセスは できません。アクセスキーは、smb_key() システムコールによって 取得することができます。

## その他のシステムコール

その他のシステムコールを表に示します。

関数名 | 内容
map_mem | 実メモリのマップ
ump_mem | 実メモリのアンマップ
add_swap | スワップデバイス/ファイルの追加
del_swap | スワップデバイス/ファイルの登録取り消し

その他のメモリ操作用システムコール
map_mem/ump_mem の2つのシステムコールは、ユーザプロセスが任意 の物理メモリを仮想メモリに割り付けるために使用します。

通常のメモリを使用する場合には、これらのシステムコールを使う必要はあり ません。これらのシステムコールは次の目的のために使用できます。

- グラフィック画面(VRAM) を仮想空間にマッピングして、ピクセルを直 接操作する。
- I/O デバイスが用している物理メモリを仮想空間にマッピングする。

なお、仮想空間はプロセスごとに分離している固有空間とすべてのプロセスで 共通にアクセス可能な共有空間の2つがあります。{\tt map_mem()} は、両方 の種類の仮想空間に物理メモリを割り付けることができます。

固有空間に物理メモリをマッピングした場合、マッピングしたプロセスがいな くなると自動的にマップを解除します。

共有空間にマッピングした場合、共有空間が破棄されるまでマッピングは解除 しません。共有空間にアクセスしたプロセスがいなくなってもマッピングは保 持したままです。

add_swap は、スワップデバイスを追加します。

# メモリ管理マネージャの内部構造

この章では、メモリ管理マネージャの内部構造について説明します。

メモリ管理マネージャは、いくつかのモジュールに分かれています。

それぞれのモジュールは、次の処理を行います。

要求受け付けモジュール | メモリ管理マネージャへの要求メッセージの受信処理を行います。 受信したメッセージの要求の種類ごとに処理モジュールを呼び出します。 そして最後に処理した結果を要求メッセージを送信元へ送ります。 処理要求メッセージには、ページフォールトへの対応処理も含まれます。
ページアウト可能ページ選択モジュール | ページアウト可能な仮想ページを選択します。 このモジュールは、ハードウェアの情報を見るためカーネルモードで動 作します。
ページアウトモジュール | ページアウト可能ページ選択モジュールが選択したページを二次記憶装 置に記録し、物理メモリを解放します。

他の周辺核と違っているのは、メモリ管理マネージャはカーネルモードで動作 しているモジュールがあるということです。

## 仮想ページ管理情報

メモリ管理マネージャは、各プロセスのもっている仮想メモリ領域の各ページ の情報を管理しています。

各ページの管理情報は、図 のようになっています。

仮想ページの管理情報

仮想ページの管理情報は、仮想メモリページがページアウト時の場合と実メモ リにマッピングしている場合とで異なった情報を管理しています。

ページアウト中の仮想メモリページは、属性情報の他にスワップデバイスまた はファイルを示すインデックスとスワップデバイス中の位置の2つの情報を保 持しています。

仮想メモリページが物理メモリをマッピングしている場合、物理メモリのペー ジ番号によって物理メモリの位置を保持します。 この情報はページアウト時の処理で使用します。

## ページフォールト処理

ページフォールトは、物理メモリをマップしていない仮想メモリにアクセスし たときに発生します。 そのとき、ページフォールトを起こした仮想ページの属性によって、メモリ管 理マネージャの対応が異なります。 表 に、ページの属性を示します。
仮想ページの属性

ページの属性 | 内容
ページアウト中ページ | スワップエリアにページアウトしている状態。 ページフォールトが発生したときには、スワッ プからページの内容をもってきます
NULL ページ | 物理ページは割り当てていない。ページフォールト したときは、NULL クリアするページ
未変更ページ | 物理メモリにマップしている。内容を変更していな いページ。物理ページを再使用する場合に中身を保存 する必要はありません
変更済ページ | 物理メモリにマップしている。内容を変更したペー ジ。物理ページを再使用する場合には、ページアウ トして内容を保存する必要があります
ページイン中 | ページインの途中であることを示します。ページイ ン処理が終るまで、このページをアクセスしようと したプロセスは、SUSPEND されます

さらにこれらの属性に加えてページの read only, read/write のどちらかで あるかを示す情報が加わります。 ページの属性とページフォールトの処理の関係を表 \ref{tab:fault-doing} に示します。
ページの属性とページフォールト処理の関係

ページ属性 | 処理
ページアウト中ページ | ページアウト後、物理メモリを解放せずにも との内容をそのまま使用する
NULL ページ | 物理メモリをマップし、ページの内容を NULL クリ アする
未変更ページ | ページフォールトは発生しない
変更済ページ | ページフォールトは発生しない
ページイン中 | ページイン処理が終わるまで SUSPEND

ページフォールトは、ユーザプロセスの実行中に発生します。 また、ユーザプロセスがシステムコールを呼び出した時のように、 ユーザプロセスが自発的に行うわけではありません。

そのため、ページフォールトの発生および対応をメモリマネージャに通知する ための仕組みが必要になります。

ページフォールトの発生から、メモリマネージャがページフォールトを処理す るまでのフローは、次のようになります。

- > ページフォールト割り込み発生 <
- 中心核のページフォールトハンドラが起動
- 中心核は、割り込みテーブルに登録しているプロセスの LOWLIB のページフォールトハンドラを呼び出す。
- LOWLIB のフォールトハンドラは、プロセスの仮想ページ情報 から、仮想メモリの属性を得る(メモリ管理マネージャへの問い合 わせ)。
- プロセスに割り当てていない仮想ページの場合は、アプリケー ションにエラーを返し、 (不正メモリアクセスエラー) 処理を終了 する。
- 仮想メモリに物理メモリを割り当てる(中心核の vmap_reg() システムコール)。
- もし、二次記憶装置にページアウトされていたページの場合に は、ファイルマネージャもしくはデバイスマネージャからページの 内容を読み込む。
- 未初期化済ページの場合には、仮想メモリページを NULL クリ アする。

## ページアウト処理

ページアウトは、ページインの反対の処理を行います。 ページインは、二次記憶装置に追い出された仮想メモリページを実メモリに 読み込む処理でした。 ページアウトは、実メモリにある仮想メモリページを二次記憶装置に追い出す 処理を行います。 ページアウト処理は、大きく二つの別々の処理を行います。

- ページアウトする仮想ページの選択
- 選択した仮想ページを二次記憶装置に書き出す

以下では、それぞれの処理について説明します。

### ページアウト用仮想ページの選択

ページアウト可能な仮想ページの選択は、カーネルモードで動作する モジュールが行います(中心核にリンクしたモジュールです)。 このモジュールでは、ページアウトすることができる仮想ページの選択を行い ます。二次記憶装置へのアクセス(書き込み)は行いません。 ページアウト可能なページの選択は、一定時間アクセスしていないページを検索 することによって行います。 このモジュールの処理フローを以下に示します。

            for (すべてのタスクの最初から最後まで)
              {
                for (タスクのマップテーブルの最初から最後まで)
                  {
                     アクセスビットをクリア。
                  }
              }

            for (すべてのタスクの最初から最後まで)
              {
                for (タスクのマップテーブルの最初から最後まで)
                  {
                    アクセスビットをチェック。
                    もし、アクセスビットが立っていなかった(クリアしてから今まで
                    誰もアクセスしていない)場合には、ページアウト可能ページとして
                    ユーザモードで動いているモジュールに情報を送信。
                  }
              }

ページアウト処理は、全実メモリサイズのうち空きページの割合によってペー ジアウトする頻度を調節します。

ページアウトの頻度は、図のようになります。 定数 PAGE_MAX_FREE で示す数値より多く空いている実メモリがある 場合、ページアウト処理は行いません。空いている実メモリが PAGE_MAX_FREE よりも少くなった場合、PAGE_MIN_FREE よりも 多い場合には、ユーザプロセスを実行したままページアウト処理を行います。 さらに、PAGE_MIN_FREE よりも空いている実メモリが少なくなった場合、 メモリ管理マネージャは、緊急処理モードに入ります。ページアウトモジュー ルのもっているタスクのプライオリティを上げ、ユーザプロセスのもつタスク を停止させます。そして、実メモリをマッピングしている仮想ページのうち、 未変更ページをすべてパージします。もし、これでも PAGE_MIN_FREE より空きメモリが増えなかった場合、変更済ページをページアウトします。

ページアウトの頻度

#### 二次記憶装置にページの内容を書き込む

ページアウト仮想ページの選択モジュールが選んだページアウト可能な仮想ペー ジは、ユーザレベルで動作しているモジュールが行います。

このモジュールは、ページアウト可能なページの内容を中心核のシステムコー ル (vrea_reg())を使って読み取ります。このシステムコールは、指定 したタスクの任意のページの内容を読み取ることができます。

次に、読み込んだページの内容を二次記憶装置に書き込みます。 そのとき、単に二次記憶装置に書き込んだだけではページインの時に困ってし まうので、メモリマネージャのもつ仮想ページテーブルにどこにページアウト したかを記録します。

このテーブルは、ページインのときにどこから読み取ればいいかを決定するた めに参照します。

ページアウトは、スワップ領域が HD のパーティションとして独立している場 合には、デバイスマネージャを、BTRON 上の独立したファイルがスワップ用と して使われている場合には、ファイルマネージャを介して出力します。

B-Free オフィシャルホームページへ戻る

Copyright (C) 1996,1997 B-Free Project